Import grub-1.97.tar.gz release from gnu.org
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..8de5c4d
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,23 @@
+The following authors assigned copyright on their work to the Free
+Software Foundation:
+
+Yoshinori K. Okuji designed and implemented the initial version.
+
+Jeroen Dekkers added initrd support, Multiboot support, and fixed bugs
+in ext2fs.
+
+Marco Gerards added ext2fs support, grub-emu, a new command-line
+engine, and fixed many bugs.
+
+Omniflux added terminfo and serial support.
+
+Vincent Pelletier added Sparc64 support.
+
+Hollis Blanchard implemented many parts of PowerPC support.
+
+Tomas Ebenlendr added the command chainloader into the normal mode,
+fixed some bugs.
+
+Guillem Jover merged architecture-independent ELF support code.
+
+Vesa Jaaskelainen added VBE support.
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  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.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU 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 that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  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.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            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
+state 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 3 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, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program 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, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU 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 Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..123a52c
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,20242 @@
+2009-10-25  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/i386/pc/grub-setup.c (setup): Add missing parameter to
+	grub_util_error() call.
+
+2009-10-25  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/fs.h [GRUB_UTIL] (struct grub_fs): Add
+	`reserved_first_sector' member.
+	* fs/ext2.c [GRUB_UTIL] (grub_ext2_fs): Initialize
+	`reserved_first_sector' to 1.
+	* fs/fat.c [GRUB_UTIL] (grub_fat_fs): Likewise.
+	* fs/ntfs.c [GRUB_UTIL] (grub_ntfs_fs): Likewise.
+	* fs/hfsplus.c [GRUB_UTIL] (grub_hfsplus_fs): Likewise.
+	* util/i386/pc/grub-setup.c (setup): Add safety check that probes for
+	filesystems which begin at first sector.
+	(options): New option --skip-fs-probe.
+	(main): Handle --skip-fs-probe and pass it to setup().
+
+2009-10-25  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/misc.h: Fix wrong evaluation of APPLE_CC.
+	(memset): Fix function prototype.
+
+2009-10-25  Robert Millan  <rmh.grub@aybabtu.com>
+2009-10-25  Vasily Averin  <vvs@parallels.com>
+
+	* fs/ext2.c (grub_ext2_iterate_dir): Avoid infinite loop when
+	`dirent.direntlen == 0'.
+
+2009-10-25  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* fs/cpio.c [MODE_USTAR]: Initialize `tar' module instead of
+	`cpio'.
+	[! MODE_USTAR]: Initialize `cpio' module instead of `tar'.
+
+2009-10-25  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* configure.ac: Check for `__ashldi3', `__ashrdi3', `__lshrdi3',
+	`__trampoline_setup' and `__ucmpdi2'.
+	* include/grub/powerpc/libgcc.h: Only export symbols for functions
+	that libgcc provides.
+
+2009-10-25  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/powerpc/libgcc.h (memset): Remove function prototype.
+	* include/grub/sparc64/libgcc.h (memset): Likewise.
+	* include/grub/misc.h (memset, memcmp): New function prototypes.
+
+2009-10-25  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* fs/cpio.c [MODE_USTAR]: Finish `tar' module instead of
+	`cpio'.
+	[! MODE_USTAR]: Finish `cpio' module instead of `tar'.
+
+2009-10-25  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Patch from Samuel Thibault <samuel.thibault@ens-lyon.org>
+	* docs/grub.cfg: Compensate for recent change in multiboot
+	loader (since 2009-08-14 it won't pass filename to payload).
+	* util/grub.d/10_hurd.in: Likewise.
+
+2009-10-21  Felix Zielcke  <fzielcke@z-51.de>
+
+	* config.guess: Update to latest version from config git
+	repository.
+	* config.sub: Likewise.
+
+2009-10-20  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Fix build on sparc64.
+
+	* configure.ac: Perform checks for libgcc symbols before
+	adding `-nostdlib' to LDFLAGS.
+
+2009-10-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Let user specify OpenBSD root device.
+
+	* loader/i386/bsd.c (openbsd_root): New variable.
+	(openbsd_opts): New option 'root'.
+	(OPENBSD_ROOT_ARG): New macro.
+	(grub_openbsd_boot): Use 'openbsd_root'.
+	(grub_cmd_openbsd): Fill 'openbsd_root'.
+
+2009-10-16  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* NEWS: Misc adjustments.
+
+2009-10-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* NEWS: Mentioned XNU, ACPI, gptsync, password and parttool.
+
+2009-10-16  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* configure.ac: Bump version to 1.97.
+
+2009-10-16  Colin Watson  <cjwatson@ubuntu.com>
+
+	* configure.ac (TARGET_CFLAGS): Add -mno-mmx -mno-sse -mno-sse2
+	-mno-3dnow on x86 architectures.  Some toolchains enable these
+	features by default, but they rely on registers that aren't enabled
+	in GRUB.  Thanks to Vladimir Serbinenko for the suggestion.
+
+2009-10-15  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Make entry text a bit more readable.
+
+	* util/grub.d/10_linux.in: Add `with' before `Linux'.
+
+2009-10-15  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* loader/i386/pc/xnu.c (grub_xnu_set_video): Fix loading splash image.
+
+2009-10-15  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* commands/xnu_uuid.c (grub_cmd_xnu_uuid): Remove duplicated bitwise
+	operations.
+
+2009-10-15  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* configure.ac: Add missing dollar.
+
+2009-10-15  Vladimir Serbinenko  <phcoder@gmail.com>
+
+        Revert 2009-06-10  Pavel Roskin  <proski@gnu.org>
+
+	* configure.ac: Put checks for __bswapsi2 and __bswapdi2.
+	* include/grub/powerpc/libgcc.h: Don't use weak attribute for all
+	exports.
+	* include/grub/sparc64/libgcc.h: Likewise.  Use
+	preprocessor conditionals.
+
+2009-10-14  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* conf/common.rmk (grub-dumpbios): Remove rule.
+	(sbin_SCRIPTS, CLEANFILES): Remove `grub-dumpbios'.
+	* util/grub-dumpbios.in: Remove file.
+
+2009-10-14  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Refer to kernel of FreeBSD "kFreeBSD" to avoid confusion between
+	the Operating System (FreeBSD) and its kernel (kernel of FreeBSD).
+
+	* loader/i386/bsd.c (grub_freebsd_boot): Read kernel environment
+	from "kFreeBSD" namespace (rather than "FreeBSD").  Update all
+	users.
+
+	(GRUB_MOD_INIT (bsd)): Rename "freebsd" command to "kfreebsd",
+	"openbsd" to "kopenbsd", "netbsd" to "knetbsd", "freebsd_loadenv"
+	to "kfreebsd_loadenv", "freebsd_module" to "kfreebsd_module",
+	and "freebsd_module_elf" to "kfreebsd_module_elf".  Update all
+	users.
+
+2009-10-12  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* term/tparm.c: Switch to GPLv3.
+
+2009-10-09  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/i386/cpuid.h: Add header protection.
+
+2009-10-09  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Fail gracefuly when attempting to load 64-bit kFreeBSD on IA32 CPU.
+
+	* include/grub/i386/cpuid.h: New file.
+	* commands/i386/cpuid.c: Include `<grub/i386/cpuid.h>'.
+	(has_longmode): Rename to ...
+	(grub_cpuid_has_longmode): ... this.  Update all users.  Remove
+	`static' attribute.
+	* loader/i386/bsd.c: Include `<grub/i386/cpuid.h>'.
+	(grub_bsd_load_elf): Fail if load of 64-bit kernel was requested
+	on a CPU that doesn't implement AMD64 instruction set.
+
+2009-10-06  Colin Watson  <cjwatson@ubuntu.com>
+
+	* Makefile.in (docs/stamp-vti): Depend on configure.ac as well, so
+	that version.texi is rebuilt on version number changes.
+
+2009-10-06  Colin Watson  <cjwatson@ubuntu.com>
+
+	* Makefile.in: Don't set info_INFOS unless makeinfo was found.
+	Fixes bug #27602.
+
+2009-10-06  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/i386/pc/grub-install.in: Source
+	${libdir}/grub/grub-mkconfig_lib before option processing, in order
+	that the --grub-probe option will work.
+	* util/sparc64/ieee1275/grub-install.in: Likewise.
+
+2009-10-05  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* configure.ac: Bump version to 1.97~beta4.
+
+2009-10-03  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Resync grub-mkdevicemap in x86_64-efi.
+
+	* conf/x86_64-efi.rmk (sbin_UTILITIES): Enable `grub-mkdevicemap'.
+	(grub_mkdevicemap_SOURCES): Add missing `util/deviceiter.c' and
+	`util/devicemap.c'.
+
+2009-10-01  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/grub-editenv.c (create_envblk_file): Write new block with a
+	.new suffix and then rename it into place, to ensure atomic
+	creation.
+
+2009-09-28  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Do not automatically install headers.
+
+	* Makefile.in (include_DATA): Remove.  Update all users.
+
+2009-09-26  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* conf/common.rmk (pkglib_MODULES): Remove `lua.mod'.
+	(lua_mod_SOURCES, lua_mod_CFLAGS, lua_mod_LDFLAGS): Remove.
+
+	* util/osdetect.lua: Remove.
+	* script/lua/lauxlib.c: Likewise.
+	* script/lua/ldebug.c: Likewise.
+	* script/lua/grub_main.c: Likewise.
+	* script/lua/lauxlib.h: Likewise.
+	* script/lua/ldebug.h: Likewise.
+	* script/lua/ltablib.c: Likewise.
+	* script/lua/liolib.c: Likewise.
+	* script/lua/lstrlib.c: Likewise.
+	* script/lua/lualib.h: Likewise.
+	* script/lua/ldo.c: Likewise.
+	* script/lua/ldump.c: Likewise.
+	* script/lua/ldo.h: Likewise.
+	* script/lua/loslib.c: Likewise.
+	* script/lua/lundump.c: Likewise.
+	* script/lua/grub_lib.c: Likewise.
+	* script/lua/ldblib.c: Likewise.
+	* script/lua/lundump.h: Likewise.
+	* script/lua/lmem.c: Likewise.
+	* script/lua/grub_lib.h: Likewise.
+	* script/lua/lmathlib.c: Likewise.
+	* script/lua/lstate.c: Likewise.
+	* script/lua/ltm.c: Likewise.
+	* script/lua/lvm.c: Likewise.
+	* script/lua/lmem.h: Likewise.
+	* script/lua/lstate.h: Likewise.
+	* script/lua/ltm.h: Likewise.
+	* script/lua/ltable.c: Likewise.
+	* script/lua/lvm.h: Likewise.
+	* script/lua/llex.c: Likewise.
+	* script/lua/lgc.c: Likewise.
+	* script/lua/grub_lua.h: Likewise.
+	* script/lua/loadlib.c: Likewise.
+	* script/lua/lfunc.c: Likewise.
+	* script/lua/lopcodes.c: Likewise.
+	* script/lua/lparser.c: Likewise.
+	* script/lua/ltable.h: Likewise.
+	* script/lua/llex.h: Likewise.
+	* script/lua/lgc.h: Likewise.
+	* script/lua/lfunc.h: Likewise.
+	* script/lua/lbaselib.c: Likewise.
+	* script/lua/lopcodes.h: Likewise.
+	* script/lua/lparser.h: Likewise.
+	* script/lua/lzio.c: Likewise.
+	* script/lua/linit.c: Likewise.
+	* script/lua/lobject.c: Likewise.
+	* script/lua/llimits.h: Likewise.
+	* script/lua/lstring.c: Likewise.
+	* script/lua/lzio.h: Likewise.
+	* script/lua/lapi.c: Likewise.
+	* script/lua/lcode.c: Likewise.
+	* script/lua/lua.h: Likewise.
+	* script/lua/lobject.h: Likewise.
+	* script/lua/lstring.h: Likewise.
+	* script/lua/lapi.h: Likewise.
+	* script/lua/lcode.h: Likewise.
+	* script/lua/luaconf.h: Likewise.
+
+2009-09-26  Colin Watson  <cjwatson@ubuntu.com>
+
+	* docs/grub.texi (Command-line and menu entry commands): Document
+	date and echo commands.
+
+2009-09-24  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/kernel.h (struct grub_module_header): Remove
+	`grub_module_header_types'.  Make `type' unsigned.  Make `size'
+	32-bit on all platforms.
+	* util/elf/grub-mkimage.c (load_modules): Treat `type' as an
+	8-bit field.  Use grub_host_to_target32() for `size'.
+	* util/i386/efi/grub-mkimage.c (make_mods_section): Likewise.
+	* util/i386/pc/grub-mkimage.c (generate_image): Likewise.
+	* util/sparc64/ieee1275/grub-mkimage.c (generate_image): Likewise.
+
+2009-09-24  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Fix "lost keypress" bug in at_keyboard.
+
+	* term/i386/pc/at_keyboard.c (grub_at_keyboard_checkkey): New function.
+	Checks for readyness of input buffer (without flushing it).
+	(grub_at_keyboard_term): Use grub_at_keyboard_checkkey() rather
+	than grub_at_keyboard_getkey_noblock() for `checkkey' struct member.
+
+2009-09-24  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/i386/pc/grub-mkimage.c (generate_image): Enclose BIOS-specific
+	size check within GRUB_MACHINE_PCBIOS section.
+
+2009-09-24  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/i386/at_keyboard.h (KEYBOARD_ISREADY): Negate
+	return value.
+	* term/i386/pc/at_keyboard.c (grub_keyboard_getkey): Negate
+	KEYBOARD_ISREADY check.
+	(grub_at_keyboard_checkkey): Rename to ...
+	(grub_at_keyboard_getkey_noblock): ... this.  Update all users.
+	Remove gratuitous cast.
+
+2009-09-23  Colin Watson  <cjwatson@ubuntu.com>
+
+	* configure.ac: Call AC_PROG_MKDIR_P.
+	* Makefile.in (docs/stamp-vti): Create docs directory.  Create
+	version.texi in $(builddir) rather than $(srcdir).
+	(docs/grub.info): Create docs directory.  Prepend $(builddir)/docs
+	to makeinfo's @include search path.
+
+2009-09-23  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub-mkconfig_lib.in (grub_file_is_not_garbage): Cope with `*.dpkg-*'
+
+2009-09-23  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub-mkconfig_lib.in (grub_file_is_not_garbage): Add support
+	for `*.dpkg-new'.
+
+2009-09-21  Colin Watson  <cjwatson@ubuntu.com>
+
+	Build info documentation.  Some code borrowed from Automake.
+
+	* configure.ac: Check for makeinfo.
+	* Makefile.in (MAKEINFO, INFOS, info_INFOS): New variables.
+	(MAINTAINER_CLEANFILES): Add $(INFOS), docs/stamp-vti, and
+	docs/version.texi.
+	(MOSTLYCLEANFILES): Add vti.tmp.
+	(docs/version.texi, docs/stamp-vti): Update automatically.
+	(docs/grub.info): Build info documentation.  Use --force and ignore
+	errors for now.
+	(all-local): Add $(INFOS).
+	(install-local): Install info files.
+	(uninstall): Uninstall info files.
+	* docs/version.texi: Remove from revision control.  This file is
+	automatically generated on build now.
+	* gendistlist.sh: Add `*.info'.
+
+2009-09-21  Felix Zielcke  <fzielcke@z-51.de>
+
+	* kern/term.c: Fix indentation.
+
+2009-09-21  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/hostdisk.c: Fix a comment.
+
+2009-09-20  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Fix regression introduced in r2539.
+
+	* term/usb_keyboard.c (USB_HID_DEVICE_TO_HOST): Change from 0x61
+	to 0xA1.
+
+2009-09-19  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/grub.d/30_os-prober.in: Don't throw away stderr from
+	os-prober. Under normal operation, it does not print anything to
+	stderr; if it does, we need to debug it, and throwing away stderr
+	makes that excessively difficult.
+
+2009-09-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* mmap/mmap.c (grub_cmd_badram): Fix off-by-one error.
+
+2009-09-16  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* aclocal.m4 (AC_LANG_PROGRAM): New macro.  Overrides stock
+	AC_LANG_PROGRAM from autoconf.
+	(grub_ASM_USCORE, grub_PROG_OBJCOPY_ABSOLUTE): Add missing
+	prototypes (fixes warning).
+
+	* configure.ac: Add `-Werror' to TARGET_CFLAGS unless
+	`--disable-werror' was used.
+
+2009-09-16  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* partmap/msdos.c (pc_partition_map_iterate): Fix possible use of
+	uninitialized `lastaddr'.
+
+2009-09-15  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* partmap/msdos.c (pc_partition_map_iterate): Detect and break loops.
+
+2009-09-14  Colin Watson  <cjwatson@ubuntu.com>
+
+	* commands/test.c (get_fileinfo): Return immediately if
+	grub_fs_probe fails.
+
+2009-09-14  José Martínez  <xosemp@gmail.com>
+
+	* commands/acpi.c (grub_cmd_acpi): Fix loading ACPI tables from file.
+
+2009-09-14  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/grub.d/30_os-prober.in: Cope with Windows 7 in os-prober
+	output.
+
+2009-09-13  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* configure.ac: Remove --enable-grub-pe2elf.  Only build
+	grub-pe2elf when needed by the build system itself.
+	* conf/common.rmk: Remove $(enable_grub_pe2elf) check.
+
+2009-09-12  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* configure.ac: Bump version to 1.97~beta3.
+	* docs/version.texi: Likewise.
+
+2009-09-12  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* video/i386/pc/vbe.c (grub_vbe_get_video_mode_info): Move packed
+	mode special handling (grub_vbe_bios_set_dac_palette_width() call)
+	from here ...
+	* loader/i386/linux.c [GRUB_MACHINE_PCBIOS]
+	(grub_linux_setup_video): ... to here (with some adjustments).
+
+2009-09-12  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Fix memory corruption issue (spotted by Colin Watson).
+
+	* kern/i386/pc/startup.S (grub_vbe_bios_getset_dac_palette): Fix bug
+	causing returned size to be stored in an incorrect memory location.
+	Fix use of uninitialized value when storing the returned size.
+
+2009-09-12  Yves Blusseau  <blusseau@zetam.org>
+
+	Change clean rules to properly remove files
+
+	* genmk.rb: add new clean rules
+	* Makefile.in (clean): add the new targets
+	(mostlyclean): likewise
+
+2009-09-11  Colin Watson  <cjwatson@ubuntu.com>
+
+	* include/grub/ntfs.h (struct grub_fshelp_node): Change `size'
+	to grub_uint64_t.
+	* fs/ntfs.c (init_file): Understand 64-bit sizes for
+	non-resident files.
+
+2009-09-11  Colin Watson  <cjwatson@ubuntu.com>
+
+	* configure.ac: Don't look for help2man when cross-compiling.  Fixes
+	part of bug #27349.
+
+2009-09-10  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub-mkconfig.in: Make the created config mode 400 and
+	print a warning if it fails.
+
+2009-09-10  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/grub.d/40_custom.in: Ask user to type custom entries below
+	comment, rather than below 'exec tail' line.
+
+2009-09-10  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/grub.d/40_custom.in: Make sure that the explanatory text is
+	visible in grub.cfg.
+
+2009-09-10  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/grub.d/40_custom.in: Make it a little clearer how to use this
+	file.
+
+2009-09-10  Felix Zielcke  <fzielcke@z-51.de>
+
+	* docs/grub.cfg: Add an example menu entry for memtest86+.
+
+2009-09-09  Felix Zielcke  <fzielcke@z-51.de>
+
+	* config.guess: Update to latest version from config git.
+	* config.sub: Likewise.
+
+2009-09-08  Colin Watson  <cjwatson@ubuntu.com>
+
+	* script/sh/execute.c (grub_script_execute_cmdline): Set "?" in
+	unknown-command case.  Fixes bug #27320.
+
+2009-09-08  Felix Zielcke  <fzielcke@z-51.de>
+
+	* kern/rescue_parser.c (grub_rescue_parse_line): Only suggest to try
+	`help' if the command exists.
+
+2009-09-06  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* INSTALL: Require GCC 4.1.3 or later.
+
+2009-09-06  Yves Blusseau  <blusseau@zetam.org>
+
+	* Makefile.in (RMKFILES): add i386-qemu.rmk
+	(MAINTAINER_CLEANFILES): add $(srcdir)/DISTLIST $(srcdir)/config.h.in
+	$(srcdir)/stamp-h.in
+
+2009-09-05  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/grub-probe.c (probe): Comment out buggy codepath, which
+	was unexpectedly enabled by Colin Watson's 2009-09-02 fix.  This
+	should be re-enabled after 1.97.
+
+2009-09-05  Felix Zielcke  <fzielcke@z-51.de>
+
+	* gendistlist.sh: Add `grub-dumpdevtree' and `*.lua' to the list
+	find searches for.
+
+2009-09-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* loader/i386/xnu.c (grub_cpu_xnu_fill_devicetree): Remove
+	unnecessary calls to grub_error.
+
+2009-09-04  Colin Watson  <cjwatson@ubuntu.com>
+
+	* NEWS: Mention `keystatus' and Unicode fonts.
+
+2009-09-04  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* configure.ac: Bump version to 1.97~beta2.
+	* docs/version.texi: Likewise.
+
+2009-09-03  Colin Watson  <cjwatson@ubuntu.com>
+
+	* configure.ac: By default, GCC 4.4 generates .eh_frame sections
+	containing unwind information in some cases where it previously did
+	not. Use -fno-dwarf2-cfi-asm if available to restore the old
+	behaviour. See http://patchwork.kernel.org/patch/8555/ for related
+	discussion.
+
+2009-09-02  Yves BLUSSEAU  <blusseau@zetam.org>
+
+	Embedding loadenv module into grub-emu
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): add lib/envblk.c and
+	commands/loadenv.c
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise
+	* conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise
+
+2009-09-03  Magnus Granberg  <zorry@ume.nu>
+
+	* aclocal.m4: Add grub_CHECK_PIE. It check if the compiler
+	include -fPIE in the default specs.
+	* configure.ac: Check if pie_possible is yes and add -fno-PIE
+	to TARGET_CFLAGS.
+
+2009-09-03  Felix Zielcke  <fzielcke@z-51.de>
+
+	* INSTALL: Note that GNU Bison 2.3 or later is required.
+
+2009-09-03  Colin Watson  <cjwatson@ubuntu.com>
+
+	* kern/i386/pc/startup.S: Fix typo.
+
+2009-09-02  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* efiemu/loadcore.c (SUFFIX (grub_efiemu_loadcore_load)): Fix style
+	according to GCS.
+
+2009-09-02  Colin Watson  <cjwatson@ubuntu.com>
+
+	* docs/grub.texi (Naming convention): Describe one-based partition
+	numbering.
+	(Device syntax): Likewise.
+	(File name syntax): Likewise.
+	(Block list syntax): Likewise.
+	(Making a GRUB bootable CD-ROM): Talk about grub.cfg rather than
+	menu.lst.
+	(File name syntax): Likewise.
+	(Command-line and menu entry commands): Document acpi, blocklist,
+	crc, export, insmod, keystatus, ls, set, and unset commands.
+
+2009-09-02  Colin Watson  <cjwatson@ubuntu.com>
+
+	* commands/keystatus.c (GRUB_MOD_INIT (keystatus)): Adjust summary
+	to avoid implying that only one of --shift, --ctrl, or --alt may be
+	used.
+
+2009-09-02  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/grub-probe.c (probe): Test st.st_mode using S_ISREG macro
+	rather than comparing against S_IFREG, which will almost never work.
+
+2009-09-01  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* commands/loadenv.c (check_blocklists): Fix off-by-one error.
+	(write_blocklists): Likewise.
+
+2009-09-01  Colin Watson  <cjwatson@ubuntu.com>
+
+	* script/lua/grub_lua.h (fputs): Supply a format string as the first
+	argument to grub_printf.
+
+2009-09-01  Felix Zielcke  <fzielcke@z-51.de>
+
+	* genmk.rb: Add quotes around $(TARGET_OBJ2ELF) to cope with
+	 non GNU test.
+
+2009-08-30  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* kern/file.c (grub_file_read): Spelling fix
+
+2009-08-30  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* loader/i386/bsdXX.c (SUFFIX (grub_freebsd_load_elfmodule)): Fix
+	loading of headers in some cases.
+
+2009-08-30  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* configure.ac: Bump version to 1.97~beta1.
+	* docs/version.texi: Likewise.
+
+2009-08-29  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* include/grub/i386/xnu.h: Add license header.
+	include grub/err.h explicitly.
+
+2009-08-29  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/grub.d/10_freebsd.in: Detect `ufs1' and `ufs2' and map them
+	to `ufs' in the vfs.root.mountfrom kernel parameter.
+
+2009-08-29  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* term/i386/pc/serial.c: Include `<grub/machine/memory.h>'.
+
+	[GRUB_MACHINE_PCBIOS] (serial_hw_io_addr): Macroify initialization
+	value (0x0400 -> GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR).
+
+	[! GRUB_MACHINE_PCBIOS] (GRUB_SERIAL_PORT_NUM): Calculate using
+	`ARRAY_SIZE' macro.
+
+2009-08-28  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* kern/file.c (grub_file_read): Check offset.
+	* fs/hfs.c (grub_hfs_read_file): Remove unnecessary offset check.
+	* fs/jfs.c (grub_jfs_read_file): Likewise.
+	* fs/ntfs.c (grub_ntfs_read): Likewise.
+	* fs/reiserfs.c (grub_reiserfs_read): Likewise.
+	* fs/minix.c (grub_minix_read_file): Correct offset check.
+	* fs/ufs.c (grub_ufs_read_file): Likewise.
+
+2009-08-28  Colin Watson  <cjwatson@ubuntu.com>
+
+	* term/i386/pc/console.c (bios_data_area): Cast
+	GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR explicitly.
+
+2009-08-28  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	1-bit optimised blitters.
+
+	* include/grub/fbblit.h (grub_video_fbblit_replace_32bit_1bit): New
+	prototype.
+	(grub_video_fbblit_replace_24bit_1bit): Likewise.
+	(grub_video_fbblit_replace_16bit_1bit): Likewise.
+	(grub_video_fbblit_replace_8bit_1bit): Likewise.
+	(grub_video_fbblit_blend_XXXA8888_1bit): Likewise.
+	(grub_video_fbblit_blend_XXX888_1bit): Likewise.
+	(grub_video_fbblit_blend_XXX565_1bit): Likewise.
+	* video/fb/fbblit.c (grub_video_fbblit_replace_32bit_1bit): New
+	function.
+	(grub_video_fbblit_replace_24bit_1bit): Likewise.
+	(grub_video_fbblit_replace_16bit_1bit): Likewise.
+	(grub_video_fbblit_replace_8bit_1bit): Likewise.
+	(grub_video_fbblit_blend_XXXA8888_1bit): Likewise.
+	(grub_video_fbblit_blend_XXX888_1bit): Likewise.
+	(grub_video_fbblit_blend_XXX565_1bit): Likewise.
+	* video/fb/video_fb.c (common_blitter): Use 1-bit optimised blitters
+	when possible.
+	* video/video.c (grub_video_get_blit_format): Return
+	GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED if bpp = 1.
+
+2009-08-28  Colin Watson  <cjwatson@ubuntu.com>
+
+	* normal/cmdline.c (grub_cmdline_get): Supply a format string as
+	the first argument to grub_printf.
+
+2009-08-28  Colin Watson  <cjwatson@ubuntu.com>
+2009-08-28  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Add `getkeystatus' terminal method.  Add a new `keystatus' command
+	to query it.
+
+	* include/grub/term.h (GRUB_TERM_STATUS_SHIFT,
+	GRUB_TERM_STATUS_CTRL, GRUB_TERM_STATUS_ALT): Definitions for
+	modifier key bitmasks.
+	(struct grub_term_input): Add `getkeystatus' member.
+	(grub_getkeystatus): Add prototype.
+	* kern/term.c (grub_getkeystatus): New function.
+
+	* include/grub/i386/pc/memory.h
+	(GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR): New macro.
+	(struct grub_machine_bios_data_area): Define necessary parts of BIOS
+	Data Area layout.
+	* term/i386/pc/console.c (grub_console_getkeystatus): New function.
+	(grub_console_term_input): Set `getkeystatus' member.
+	* term/usb_keyboard.c (grub_usb_hid): Macroify HID protocol
+	constants.
+	(grub_usb_keyboard_getreport): Likewise.
+	(grub_usb_keyboard_checkkey): Likewise.
+	(grub_usb_keyboard_getkeystatus): New function.
+	(grub_usb_keyboard_term): Set `getkeystatus' member.
+
+	* commands/keystatus.c: New file.
+	* conf/common.rmk (pkglib_MODULES): Add keystatus.mod.
+	(keystatus_mod_SOURCES): New variable.
+	(keystatus_mod_CFLAGS): Likewise.
+	(keystatus_mod_LDFLAGS): Likewise.
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Add
+	commands/keystatus.c.
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise.
+
+2009-08-28  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Split befs.mod and afs.mod into *_be.mod and *.mod
+
+	* conf/common.rmk (grub_probe_SOURCES): Add afs_be.c and befs_be.c.
+	(grub_fstest_SOURCES): Likewise.
+	(pkglib_MODULES): Add afs_be.mod and befs_be.mod.
+	(afs_be_mod_SOURCES): New variable.
+	(afs_be_mod_CFLAGS): Likewise.
+	(afs_be_mod_LDFLAGS): Likewise.
+	(befs_be_mod_SOURCES): Likewise.
+	(befs_be_mod_CFLAGS): Likewise.
+	(befs_be_mod_LDFLAGS): Likewise.
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Add afs_be.c and befs_be.c.
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Likewise.
+	(grub_emu_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise.
+	* fs/afs_be.c: New file.
+	* fs/befs_be.c: New file.
+	* fs/afs.c (GRUB_AFS_FSNAME_SUFFIX): New definition.
+	(GRUB_AFS_FSNAME): Use GRUB_AFS_FSNAME_SUFFIX.
+	(U16): Replaced with ...
+	(grub_afs_to_cpu16): ...this. All users updated.
+	(U32): Replaced with ...
+	(grub_afs_to_cpu32): ...this. All users updated.
+	(U64): Replaced with ...
+	(grub_afs_to_cpu64): ...this. All users updated.
+	(GRUB_AFS_BO_LITTLE_ENDIAN): Remove.
+	(GRUB_AFS_BO_BIG_ENDIAN): Likewise.
+	(grub_afs_validate_sblock): Check only one endianness.
+	(GRUB_MOD_INIT (befs)) [MODE_BIGENDIAN && MODE_BFS]: Rename to ..
+	(GRUB_MOD_INIT (befs_be)) [MODE_BIGENDIAN && MODE_BFS]: ... this.
+	(GRUB_MOD_INIT (afs)) [MODE_BIGENDIAN && !MODE_BFS]: Rename to ..
+	(GRUB_MOD_INIT (afs_be)) [MODE_BIGENDIAN && !MODE_BFS]: ... this.
+	(GRUB_MOD_FINI (befs)) [MODE_BIGENDIAN && MODE_BFS]: Rename to ..
+	(GRUB_MOD_FINI (befs_be)) [MODE_BIGENDIAN && MODE_BFS]: ... this.
+	(GRUB_MOD_FINI (afs)) [MODE_BIGENDIAN && !MODE_BFS]: Rename to ..
+	(GRUB_MOD_FINI (afs_be)) [MODE_BIGENDIAN && !MODE_BFS]: ... this.
+
+2009-08-26  Bean  <bean123ch@gmail.com>
+
+	* fs/xfs.c (GRUB_XFS_INO_INOINAG): Replace 1L with 1LL to support
+	64-bit number.
+	(GRUB_XFS_FSB_TO_BLOCK): Likewise.
+	(grub_xfs_inode_block): Change return type to grub_uint64_t.
+	(grub_xfs_read_inode): Change type of block to grub_uint64_t.
+
+2009-08-25  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	NetBSD memory map support.
+
+	* include/grub/i386/bsd.h (NETBSD_BTINFO_MEMMAP): New definition.
+	(grub_netbsd_btinfo_mmap_header): New structure.
+	(grub_netbsd_btinfo_mmap_entry): Likewise.
+	* loader/i386/bsd.c (grub_netbsd_boot): Pass memory map.
+
+2009-08-25  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Enable bsd.mod on coreboot.
+
+	* conf/i386-coreboot.rmk (pkglib_MODULES): Add bsd.mod.
+	(bsd_mod_SOURCES): New variable.
+	(bsd_mod_CFLAGS): Likewise.
+	(bsd_mod_LDFLAGS): Likewise.
+	(bsd_mod_ASFLAGS): Likewise.
+	* loader/i386/bsd.c [!GRUB_MACHINE_PCBIOS]: Fix includes.
+	(grub_bsd_get_device) [!GRUB_MACHINE_PCBIOS]: Set *biosdev to 0xff.
+
+2009-08-25  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Cleanup NetBSD root support.
+
+	* loader/i386/bsd.c (grub_netbsd_boot): Remove call to
+	grub_bsd_get_device.
+	Fix typo.
+
+2009-08-25  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub.d/00_header.in: Move check for the video backend of
+	gfxterm from here ...
+	* util/grub-mkconfig.in: ... to here.  Enable gfxterm if there's
+	a suitable video backend.
+
+2009-08-25  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix breakage in grub-setup.
+
+	* util/i386/pc/grub-setup.c (setup): Use "part_msdos" instead of
+	"msdos_partition_map".
+
+2009-08-25  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix breakage in normal/auth.c.
+
+	* normal/auth.c (grub_iswordseparator): New function.
+
+2009-08-25  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Authentication support.
+
+	* commands/password.c: New file.
+	* conf/common.rmk (pkglib_MODULES): Add password.mod.
+	(password_mod_SOURCES): New variable.
+	(password_mod_CFLAGS): Likewise.
+	(password_mod_LDFLAGS): Likewise.
+	(normal_mod_SOURCES): Add normal/auth.c.
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Add commands/password.c and
+	normal/auth.c.
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise.
+	* include/grub/auth.h: New file.
+	* include/grub/err.h (grub_err_t): New enum value
+	GRUB_ERR_ACCESS_DENIED.
+	* include/grub/menu.h (grub_menu_entry): New fields 'restricted' and
+	'users'.
+	* include/grub/normal.h (grub_cmdline_get): New argument 'history'.
+	* normal/cmdline.c (grub_cmdline_get): New argument 'history'. All
+	users updated.
+	* normal/auth.c: New file.
+	* normal/main.c (grub_normal_add_menu_entry): Handle --users option.
+	(grub_cmdline_run): Don't allow to go to command line without
+	authentication.
+	* normal/menu.c (grub_menu_execute_entry): Handle restricted entries.
+	* normal/menu_entry.c (grub_menu_entry_run): Don't allow editing
+	menuentry without superuser rights.
+	* normal/menu_viewer.c (grub_menu_viewer_show_menu): Don't exit if
+	user isn't a superuser.
+
+2009-08-24  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Save space by inlining misc.c functions.
+
+	* kern/misc.c (grub_iswordseparator): Made static.
+	* kern/misc.c (grub_strcat): Moved from here ...
+	* include/grub/misc.h (grub_strcat): ... here. Inlined.
+	* kern/misc.c (grub_strncat): Moved from here ...
+	* include/grub/misc.h (grub_strncat): ... here. Inlined.
+	* kern/misc.c (grub_strcasecmp): Moved from here ...
+	* include/grub/misc.h (grub_strcasecmp): ... here. Inlined.
+	* kern/misc.c (grub_strncasecmp): Moved from here ...
+	* include/grub/misc.h (grub_strncasecmp): ... here. Inlined.
+	* kern/misc.c (grub_isalpha): Moved from here ...
+	* include/grub/misc.h (grub_isalpha): ... here. Inlined.
+	* kern/misc.c (grub_isdigit): Moved from here ...
+	* include/grub/misc.h (grub_isdigit): ... here. Inlined.
+	* kern/misc.c (grub_isgraph): Moved from here ...
+	* include/grub/misc.h (grub_isgraph): ... here. Inlined.
+	* kern/misc.c (grub_tolower): Moved from here ...
+	* include/grub/misc.h (grub_tolower): ... here. Inlined.
+
+2009-08-24  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* script/sh/function.c (grub_script_function_find): Cut error message
+	not to flood terminal.
+	* script/sh/lexer.c (grub_script_yylex): Remove command line length
+	limit.
+	* script/sh/script.c (grub_script_arg_add): Duplicate string.
+
+2009-08-24  Colin Watson  <cjwatson@ubuntu.com>
+
+	* term/usb_keyboard.c (grub_usb_keyboard_getreport): Make
+	`report' grub_uint8_t *.
+	(grub_usb_keyboard_checkkey): Make `data' elements grub_uint8_t.
+	Use a 50-millisecond timeout rather than just repeating
+	grub_usb_keyboard_getreport 50 times.
+	(grub_usb_keyboard_getkey): Make `data' elements grub_uint8_t.
+
+2009-08-24  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Rename *_partition_map to part_*
+
+	* partmap/acorn.c (grub_acorn_partition_map): Set name to 'part_acorn'.
+	* partmap/amiga.c (grub_amiga_partition_map): Set name to 'part_amiga'.
+	* partmap/apple.c (grub_apple_partition_map): Set name to 'part_apple'.
+	* partmap/gpt.c (grub_gpt_partition_map): Set name to 'part_gpt'.
+	All users updated.
+	* partmap/msdos.c (grub_msdos_partition_map): Set name to 'part_msdos'.
+	All users updated.
+	* partmap/sun.c (grub_sun_partition_map): Set name to 'part_sun'.
+	* util/grub-probe.c (probe_partmap): Don't transform partition name
+	to get module name.
+
+2009-08-24  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix OpenBSD and NetBSD support.
+
+	* include/grub/i386/bsd.h (GRUB_BSD_TEMP_BUFFER): Change to resolve
+	memory address conflict.
+	(OPENBSD_MMAP_ACPI): New definition.
+	(OPENBSD_MMAP_NVS): Likewise.
+	* loader/i386/bsd.c (grub_openbsd_boot): Support OPENBSD_MMAP_ACPI
+	and OPENBSD_MMAP_NVS.
+	Add memory map terminator
+	Explicit cast when calling grub_unix_real_boot.
+	(grub_netbsd_boot): Explicit cast when calling grub_unix_real_boot.
+
+2009-08-24  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Let user specify NetBSD root device.
+
+	* loader/i386/bsd.c (netbsd_root): New variable.
+	(netbsd_opts): New option 'root'.
+	(NETBSD_ROOT_ARG): New macro.
+	(grub_netbsd_boot): Use 'netbsd_root'.
+	(grub_bsd_unload): Free 'netbsd_root'.
+	(grub_cmd_netbsd): Fill 'netbsd_root'.
+
+2009-08-24  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Support for 64-bit NetBSD.
+
+	* loader/i386/bsd.c (grub_bsd_load_elf): Apply correct mask to entry
+	point when booting non-FreeBSD.
+
+2009-08-24  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Support --no-smp and --no-acpi for NetBSD.
+
+	* include/grub/i386/bsd.h (NETBSD_AB_NOSMP): New definition.
+	(NETBSD_AB_NOACPI): Likewise.
+	* loader/i386/bsd.c (netbsd_opts): New entries no-smp and no-acpi.
+	(netbsd_flags): Add NETBSD_AB_NOSMP, NETBSD_AB_NOACPI.
+
+2009-08-23  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* fs/hfsplus.c (grub_hfsplus_mount): Don't ignore grub_hfsplus_read_file
+	errors.
+	(grub_hfsplus_btree_iterate_node): Don't ignore grub_hfsplus_read_file
+	errors. Call grub_error when needed.
+
+2009-08-23  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* commands/search.c (search_fs): Try searching without autoload first.
+	* util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Load
+	filesystem module explicitly for faster booting.
+
+2009-08-23  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/grub-mkconfig.in: Export GRUB_DISABLE_OS_PROBER.
+
+2009-08-23  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/grub.d/30_os-prober.in: Disable os-prober if
+	`GRUB_DISABLE_OS_PROBER' was set to true.
+
+2009-08-23  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* partmap/pc.c: Rename to ...
+	* partmap/msdos.c: ... this.  Update all users.
+	(grub_pc_partition_map): Rename to ...
+	(grub_msdos_partition_map): ... this.  Update all users.
+
+	* parttool/pcpart.c: Rename to ...
+	* parttool/msdospart.c: ... this.  Update all users.
+
+	* include/grub/pc_partition.h: Rename to ...
+	* include/grub/msdos_partition.h: ... this.  Update all users.
+	(grub_pc_partition_bsd_entry): Rename to ...
+	(grub_msdos_partition_bsd_entry): ... this.  Update all users.
+	(grub_pc_partition_disk_label): Rename to ...
+	(grub_msdos_partition_disk_label): ... this.  Update all users.
+	(grub_pc_partition_entry): Rename to ...
+	(grub_msdos_partition_entry): ... this.  Update all users.
+	(grub_pc_partition_mbr): Rename to ...
+	(grub_msdos_partition_mbr): ... this.  Update all users.
+	(grub_pc_partition): Rename to ...
+	(grub_msdos_partition): ... this.  Update all users.
+	(grub_pc_partition_is_empty): Rename to ...
+	(grub_msdos_partition_is_empty): ... this.  Update all users.
+	(grub_pc_partition_is_extended): Rename to ...
+	(grub_msdos_partition_is_extended): ... this.  Update all users.
+	(grub_pc_partition_is_bsd): Rename to ...
+	(grub_msdos_partition_is_bsd): ... this.  Update all users.
+
+	* conf/common.rmk (amiga_mod_SOURCES, amiga_mod_CFLAGS)
+	(amiga_mod_LDFLAGS, apple_mod_SOURCES, apple_mod_CFLAGS)
+	(apple_mod_LDFLAGS, msdos_mod_SOURCES, msdos_mod_CFLAGS)
+	(msdos_mod_LDFLAGS, sun_mod_SOURCES, sun_mod_CFLAGS)
+	(sun_mod_LDFLAGS, acorn_mod_SOURCES, acorn_mod_CFLAGS)
+	(acorn_mod_LDFLAGS, gpt_mod_SOURCES, gpt_mod_CFLAGS)
+	(gpt_mod_LDFLAGS): Rename to ...
+	(part_amiga_mod_SOURCES, part_amiga_mod_CFLAGS, part_amiga_mod_LDFLAGS)
+	(part_apple_mod_SOURCES, part_apple_mod_CFLAGS, part_apple_mod_LDFLAGS)
+	(part_msdos_mod_SOURCES, part_msdos_mod_CFLAGS, part_msdos_mod_LDFLAGS)
+	(part_sun_mod_SOURCES, part_sun_mod_CFLAGS, part_sun_mod_LDFLAGS)
+	(part_acorn_mod_SOURCES, part_acorn_mod_CFLAGS, part_acorn_mod_LDFLAGS)
+	(part_gpt_mod_SOURCES, part_gpt_mod_CFLAGS)
+	(part_gpt_mod_LDFLAGS): ... this.
+	(pkglib_MODULES): Prefix partition modules with `part_'.  Rename
+	`pcpart.mod' to `msdospart.mod'.
+	(pcpart_mod_SOURCES, pcpart_mod_CFLAGS, pcpart_mod_LDFLAGS): Rename
+	to ...
+	(msdospart_mod_SOURCES, msdospart_mod_CFLAGS)
+	(msdospart_mod_LDFLAGS): ... this.
+
+2009-08-23  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* loader/i386/bsd.c (freebsd_opts): Rewritten to use extcmd.
+	(openbsd_opts): Likewise.
+	(netbsd_opts): Likewise.
+	(freebsd_flags): Added 0 terminator.
+	(openbsd_flags): Likewise.
+	(netbsd_flags): Likewise.
+	(grub_bsd_parse_flags): Rewritten to use extcmd. All users updated.
+	(grub_cmd_freebsd): Transformed into extended command.
+	(grub_cmd_openbsd): Likewise.
+	(grub_cmd_netbsd): Likewise.
+	(cmd_freebsd): Changed type to grub_extcmd_t.
+	(cmd_openbsd): Likewise.
+	(cmd_netbsd): Likewise.
+	(GRUB_MOD_INIT (bsd)): Register grub_cmd_freebsd, grub_cmd_netbsd and
+	grub_cmd_openbsd as extended commands.
+	(GRUB_MOD_FINI (bsd)): Use grub_unregister_extcmd for cmd_freebsd,
+	cmd_netbsd and cmd_openbsd
+
+2009-08-22  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* commands/xnu_uuid.c (transform): Use grub_memcpy instead of memcpy.
+
+2009-08-21  Pavel Roskin  <proski@gnu.org>
+
+	* Makefile.in (install-local): When checking if a file is in the
+	build directory, use "test -e" to detect symlinks.
+
+	* Makefile.in (install-local): Remove all files in
+	$(DESTDIR)$(pkglibdir) before installing new files there.
+
+2009-08-18  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/powerpc/ieee1275/grub-mkrescue.in (grub_mkimage): Use
+	grub-mkelfimage.
+
+2009-08-18  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub-mkconfig.in: Don't use gfxterm by default if not
+	explicitly specified by the user.
+
+2009-08-18  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/fbfill.h (struct grub_video_fbrender_target): Use
+	grub_uint8_t pointer for data.
+	* include/grub/fbutil.h (struct grub_video_fbblit_info):
+	Likewise.
+	* video/fb/fbutil.c: Remove unnecessary casts.
+
+2009-08-17  Michal Suchanek  <hramrach@centrum.cz>
+
+	VBE cleanup.
+
+	* video/i386/pc/vbe.c (vbe_mode_in_use): Removed (duplicate).
+	(grub_vbe_set_video_mode): Save active mode info
+	only after setting the mode.
+	(grub_video_vbe_setup): Call 'grub_vbe_set_video_mode' with NULL as
+	second argument.
+
+2009-08-17  Michal Suchanek  <hramrach@centrum.cz>
+
+	Rename variables for clarity.
+
+	* video/i386/pc/vbe.c (active_mode_info): Renamed to ...
+	(active_vbe_mode_info): ... this. All users updated.
+	(framebuffer): Rename 'active_mode' to 'active_vbe_mode'.
+	All users updated.
+	(initial_mode): Rename to ...
+	(initial_vbe_mode): ... this. All users updated.
+	(mode_in_use): Rename to ..
+	(vbe_mode_in_use): ... this. All users updated.
+	(mode_list): Rename to ..
+	(vbe_mode_list): ... this. All users updated.
+	(grub_vbe_set_video_mode): Rename 'mode' to 'vbe_mode', 'mode_info' to
+	'vbe_mode_info' and 'old_mode' to 'old_vbe_mode'.
+	(grub_video_vbe_init): Rename 'rm_mode_list' to 'rm_vbe_mode_list' and
+	'mode_list_size' to 'vbe_mode_list_size'.
+	(grub_video_vbe_setup): Rename 'mode_info' to 'vbe_mode_info',
+	'best_mode_info' to 'best_vbe_mode_info' and
+	'best_mode' to 'best_vbe_mode'
+
+2009-08-17  Michal Suchanek  <hramrach@centrum.cz>
+
+	Remove duplicate grub_video_fb_get_video_ptr.
+
+	* include/grub/fbutil.h (get_data_ptr): Rename to ...
+	(grub_video_fb_get_video_ptr): ... this.
+	* include/grub/video_fb.h (grub_video_fb_get_video_ptr): Removed.
+	* video/fb/fbutil.c: Add comment about addressing.
+	(get_data_ptr): Rename to ...
+	(grub_video_fb_get_video_ptr): ... this. All users updated.
+	* video/fb/video_fb.c (grub_video_fb_get_video_ptr): Remove.
+
+2009-08-17  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* fs/fat.c (grub_fat_read_data): Remove `#if 0' braces around the
+	grub_dprintf() that was just added.
+
+2009-08-17  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* loader/i386/linux.c (GRUB_ASSUME_LINUX_HAS_FB_SUPPORT)
+	(DEFAULT_VIDEO_MODE): Remove macros.
+	(grub_linux_boot): Remove assumption that Linux has FB support,
+	and use "text" as default video mode.
+
+2009-08-15  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* fs/affs.c (grub_affs_read_symlink): Change leftover grub_printf into
+	grub_dprintf.
+	* fs/fat.c (grub_fat_read_data): Likewise.
+
+2009-08-14  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* loader/i386/multiboot.c (grub_multiboot): Don't pass filename to
+	payload.
+	(grub_module): Likewise.
+
+2009-08-14  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* loader/i386/multiboot.c (grub_multiboot_unload): Don't free mbi and
+	mbi->cmdline but free playground.
+
+2009-08-14  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Handle group offset on UFS1.
+
+	* fs/ufs.c (grub_ufs_sblock): New field 'cylg_mask'.
+	(grub_ufs_read_inode) [!MODE_UFS2]: handle cylg_offset and cylg_mask.
+
+2009-08-14  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Split ufs.mod into ufs1.mod and ufs2.mod.
+
+	* conf/common.rmk (grub_probe_SOURCES): Add fs/ufs2.c.
+	(grub_fstest_SOURCES): Likewise.
+	(pkglib_MODULES): Remove ufs.mod. Add ufs1.mod and ufs2.mod.
+	(ufs_mod_SOURCES): Remove.
+	(ufs_mod_CFLAGS): Likewise.
+	(ufs_mod_LDFLAGS): Likewise.
+	(ufs1_mod_SOURCES): New variable.
+	(ufs1_mod_CFLAGS): Likewise.
+	(ufs1_mod_LDFLAGS): Likewise.
+	(ufs2_mod_SOURCES): New variable.
+	(ufs2_mod_CFLAGS): Likewise.
+	(ufs2_mod_LDFLAGS): Likewise.
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Add fs/ufs2.c.
+	* conf/i386-efi.rmk (util/i386/efi/grub-mkimage.c_DEPENDENCIES):
+	Likewise.
+	(grub_emu_SOURCES): Likewise.
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Likewise.
+	(grub_setup_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/sparc64.rmk (grub_emu_SOURCES): Likewise.
+	(grub_setup_SOURCES): Likewise.
+	* conf/x86_64-efi.rmk (util/i386/efi/grub-mkimage.c_DEPENDENCIES):
+	Likewise.
+	* fs/ufs2.c: New file.
+	* fs/ufs.c: Separate UFS1 from UFS2 by using preprocessor.
+
+2009-08-14  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Framebuffer split.
+
+	* commands/i386/pc/vbetest.c (grub_cmd_vbetest): Restore video
+	subsystem at the end.
+	* conf/common.rmk (pkglib_MODULES): Add video_fb.mod.
+	(video_fb_mod_SOURCES): New variable.
+	(video_fb_mod_CFLAGS): Likewise.
+	(video_fb_mod_LDFLAGS): Likewise.
+	* conf/i386-pc.rmk (vbe_mod_SOURCES): Remove video/i386/pc/vbeblit.c,
+	video/i386/pc/vbefill.c and video/i386/pc/vbeutil.c.
+	* video/i386/pc/vbeblit.c: Moved from here ...
+	* video/fb/fbblit.c: ..here. Replaced 'vbe' with 'fb'.
+	* video/i386/pc/vbefill.c: Moved from here ...
+	* video/fb/fbfill.c: ..here. Replaced 'vbe' with 'fb'.
+	* video/i386/pc/vbeutil.c: Moved from here ...
+	* video/fb/fbutil.c: ..here. Replaced 'vbe' with 'fb'.
+	* include/grub/i386/pc/vbeblit.h: Moved from here ...
+	* include/grub/fbblit.h: ... here. Replaced 'vbe' with 'fb'.
+	* include/grub/i386/pc/vbefill.h: Moved from here ...
+	* include/grub/fbfill.h: ... here. Replaced 'vbe' with 'fb'.
+	* include/grub/i386/pc/vbeutil.h: Moved from here ...
+	* include/grub/fbutil.h: ... here. Replaced 'vbe' with 'fb'.
+	* include/grub/i386/pc/vbe.h: Moved framebuffer part ...
+	* include/grub/video_fb.h: ... here. Replaced 'vbe' with 'fb'.
+	* include/grub/video.h (GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER): Removed.
+	(GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER): Likewise.
+	(grub_video_adapter): Added 'get_info_and_fini'.
+	(grub_video_get_info_and_fini): New prototype.
+	(grub_video_set_mode): make modestring const char *.
+	* loader/i386/linux.c (grub_linux_setup_video): Use
+	grub_video_get_info_and_fini.
+	(grub_linux_boot): Move modesetting just before booting.
+	* loader/i386/pc/xnu.c (grub_xnu_set_video): Use
+	grub_video_get_info_and_fini.
+	* video/i386/pc/vbe.c: Moved framebuffer part ...
+	* video/fb/video_fb.c: ... here. Replaced 'vbe' with 'fb'.
+	* video/i386/pc/vbe.c (grub_vbe_set_video_mode): Use
+	grub_video_fbstd_colors and grub_video_fb_set_palette.
+	(grub_video_vbe_init): Clear 'framebuffer' variable and use
+	grub_video_fb_init.
+	(grub_video_vbe_fini): Use grub_video_fb_fini.
+	(grub_video_vbe_setup): Use framebuffer.render_target instead of
+	render_target and use grub_video_fb_set_active_render_target and
+	grub_video_fb_set_palette.
+	(grub_video_vbe_set_palette): Use grub_video_fb_set_palette.
+	(grub_video_vbe_set_viewport): Use grub_video_fb_set_viewport.
+	(grub_video_vbe_adapter): Use framebuffer.
+	* video/video.c (grub_video_get_info_and_fini): New function.
+	(grub_video_set_mode): Make modestring const char *.
+	(GRUB_MOD_INIT(video_video)): Don't set variables to 0 since these
+	values are already initialised.
+
+2009-08-14  Pavel Roskin  <proski@gnu.org>
+
+	* boot/i386/pc/cdboot.S: Use LOCAL for local labels.  Eliminate
+	ABS and APPLE_CC.
+	* boot/i386/pc/diskboot.S: Likewise.
+	* boot/i386/pc/lnxboot.S: Likewise.  Hardcode the number of code
+	sectors allow compilation on MacOSX.
+	* conf/i386-pc.rmk: Enable unconditional compilation of
+	lnxboot.img.
+
+2009-08-13  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/grub-mkconfig.in: Export GRUB_HIDDEN_TIMEOUT.
+	* util/grub.d/00_header.in: Enter interruptible sleep if
+	GRUB_HIDDEN_TIMEOUT is set.
+
+2009-08-13  Yves Blusseau  <blusseau@zetam.org>
+
+	* include/grub/symbol.h: Add the LOCAL macro.
+	* boot/i386/pc/boot.S: Use the LOCAL macro for all labels
+	starting with "L_".
+
+2009-08-13  Pavel Roskin  <proski@gnu.org>
+
+	* boot/i386/pc/boot.S: Remove ABS macro, it's not required by
+	any modern compilers we support.
+
+	* boot/i386/pc/boot.S: Remove all code dependent on APPLE_CC.
+	Use local labels starting with "L_" so that Apple assembler
+	knows they are local.
+
+2009-08-10  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/i386/bsd.h (KERNEL_TYPE_NONE, KERNEL_TYPE_FREEBSD)
+	(KERNEL_TYPE_OPENBSD, KERNEL_TYPE_NETBSD): Convert to ...
+	(bsd_kernel_types): ... this enum.
+
+	* loader/i386/bsd.c (grub_cmd_freebsd_loadenv, grub_cmd_freebsd_module)
+	(grub_cmd_freebsd_module_elf): Abort with "You need to load the
+	kernel first." when `kernel_type' is set to KERNEL_TYPE_NONE.
+
+	(grub_bsd_load_aout, grub_bsd_load, grub_cmd_freebsd_loadenv)
+	(grub_cmd_freebsd_module, grub_cmd_freebsd_module_elf)
+	(GRUB_MOD_INIT (bsd)): Fix capitalization in a few error
+	messages.
+
+2009-08-08  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/grub-dumpdevtree: Moved from here ...
+	* util/i386/efi/grub-dumpdevtree: ... to here.
+	(hexify): New function.  Converts a string to its hex version.
+	Generate hex versions of "efi" and "device-properties" by calling
+	hexify() on the ASCII strings rather than by hardcoding numbers.
+
+2009-08-08  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* fs/jfs.c: Update copyright year.
+
+2009-08-08  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub.d/00_header.in: Fix a comment.
+	* util/grub.d/10_linux.in: Likewise.
+	* util/grub.d/10_windows.in: Likewise.
+	* util/grub.d/10_hurd.in: Likewise.
+
+2009-08-08  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub-mkconfig.in: Allow the user to specify the used font
+	with GRUB_FONT.
+
+2009-08-08  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/powerpc/libgcc.h: Export __ashrdi3() if
+	available, xfs.mod needs it now.
+
+	* util/grub-mkconfig_lib.in (version_test_numeric): Don't use
+	the "g" modifier in sed when the intention is to strip something
+	once.  This fixes comparison of kernels with multiple dashes.
+
+	* util/grub-mkconfig.in: Define datarootdir, datadir may depend
+	on it.  Add missing space before closing bracket.  Fix
+	misleading formatting.
+
+2009-08-07  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* docs/grub.texi: Major overhaul.  Remove all sections that are
+	specific to GRUB Legacy, or mostly composed of Legacy-specific
+	information.
+
+2009-08-07  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* docs/version.texi: New file.  Provides version information for
+	grub.texi.
+
+2009-08-07  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* docs/grub.texi: Update CVS information to SVN.
+	Replace outdated "GRUB 2 will include" phrase with "GRUB 2 includes".
+
+2009-08-07  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub-mkconfig.in: Remove a wrong `fi'.
+
+2009-08-07  Felix Zielcke  <fzielcke@z-51.de>
+
+	* fs/uuid.c (grub_jfs_superblock): New fields unused2 and uuid.
+	(grub_jfs_uuid): New function.
+	(grub_jfs_fs): Set uuid field to grub_jfs_uuid.
+
+2009-08-07  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub-mkconfig_lib.in (font_path): Move the functionality
+	of it to ...
+	* util/grub-mkconfig.in: ... here.  Prefer unicode.pf2 and
+	unifont.pf2 over ascii.pf2.  Export LANG=C in case ascii.pf2 gets used.
+
+2009-08-07  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/grub.d/10_linux.in (test_numeric): Moved from here ...
+	* util/grub-mkconfig_lib.in (version_test_numeric): ... to here.
+	Update all users.
+
+	* util/grub.d/10_linux.in (test_gt): Strip any basename prefix,
+	not just "vmlinu[zx]".
+	Moved from here ...
+	* util/grub-mkconfig_lib.in (version_test_gt): ... to here.  Update
+	all users.
+
+	* util/grub.d/10_linux.in (find_latest): Moved from here ...
+	* util/grub-mkconfig_lib.in (version_find_latest): ... to here.  Update
+	all users.
+
+2009-08-07  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/grub.d/10_freebsd.in: Use an absolute device path for
+	`vfs.root.mountfrom'.  Set `vfs.root.mountfrom.options=rw'.
+
+2009-08-06  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Fix
+	handling of multiple abstraction modules.
+
+2009-08-04  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Fix a bug resulting in black screen when loading Linux using a
+	packed video mode.
+
+	* kern/i386/pc/startup.S (grub_vbe_bios_getset_dac_palette_width): New
+	function.
+
+	* include/grub/i386/pc/vbe.h (GRUB_VBE_CAPABILITY_DACWIDTH): New macro.
+	(grub_vbe_bios_getset_dac_palette_width): New function.
+	(grub_vbe_bios_get_dac_palette_width)
+	(grub_vbe_bios_set_dac_palette_width): New macros (act as wrappers for
+	grub_vbe_bios_getset_dac_palette_width()).
+
+	* video/i386/pc/vbe.c (grub_vbe_probe): Use `GRUB_VBE_STATUS_OK' to
+	check for return status.
+	(grub_vbe_get_video_mode_info): When getting information for a packed
+	mode (<= 8 bpp), obtain DAC palette width using
+	grub_vbe_bios_getset_dac_palette_width(), and use that for initializing
+	{red,green,blue}_mark_size.
+
+2009-08-04  Felix Zielcke  <fzielcke@z-51.de>
+
+	* commands/search.c (options): Fix help output to match actual code.
+
+2009-08-02  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* commands/hexdump.c (grub_cmd_hexdump): Use grub_disk_read instead
+	of homegrown code.
+
+2009-08-01  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* util/hostfs.c (grub_hostfs_dir): Don't use DT_DIR: It doesn't work
+	on XFS or ReiserFS.
+
+2009-08-01  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Support Apple partition map with sector size different from 512 bytes.
+
+	* partmap/apple.c (grub_apple_header): New field 'blocksize'.
+	(apple_partition_map_iterate): Respect 'aheader.blocksize'
+	and 'apart.partmap_size'.
+
+2009-08-01  Vladimir Serbinenko  <phcoder@gmail.com>
+2009-08-01  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Fix cpuid command.
+
+	* commands/i386/cpuid.c (options): New variable.
+	(grub_cmd_cpuid): Return real error.
+	(GRUB_MOD_INIT(cpuid)): Declare options.
+
+2009-07-31  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* partmap/pc.c (pc_partition_map_iterate): Check that boot flags are
+	valid.
+
+2009-07-31  Bean  <bean123ch@gmail.com>
+
+	* fs/xfs.c (grub_xfs_sblock): Change unused5 field to log2_sect and
+	log2_inode.
+	(grub_fshelp_node): Move inode field to the end.
+	(grub_xfs_data): Remove inode field.
+	(grub_xfs_inode_block): Calculate inode size using sblock.
+	(grub_xfs_inode_offset): Likewise.
+	(grub_xfs_read_inode): Calculate inode size using sblock.
+	(grub_xfs_read_block): Replace XFS_INODE_EXTENTS with nrec.
+	(grub_xfs_iterate_dir): Calculate inode size using sblock.
+	(grub_xfs_mount): Use grub_zalloc instead of grub_malloc. Realloc data
+	to match inode size.
+	(grub_xfs_dir): goto mount_fail when mount fails, as data->diropen is
+	not accessible when data is null.
+	(grub_xfs_open): Likewise.
+
+2009-07-31  Bean  <bean123ch@gmail.com>
+
+	* disk/lvm.c (grub_lvm_scan_device): Ignore extra copy of metadata.
+	Don't change pv->disk if it's already set.
+
+	* disk/raid.c (grub_raid_scan_device): Merge this function into ...
+	(grub_raid_register): ... here.
+	(grub_raid_rescan): Removed.
+
+	* include/grub/raid.h (grub_raid_rescan): Removed.
+
+	* util/grub-fstest.c: Remove include file <grub/raid.h>.
+	(fstest): Replace grub_raid_rescan with module fini function followed
+	by init function.
+
+	* util/grub-probe.c: Add include file <grub/raid.h>.
+	(probe_raid_level): New function.
+	(probe): Detect abstraction by walking the disk device, support two
+	level of abstraction (LVM on RAID) when detecting partition map.
+
+2009-07-31  Pavel Roskin  <proski@gnu.org>
+
+	* disk/raid5_recover.c (grub_raid5_recover): Revert conversion
+	to grub_zalloc(), it was erroneous.
+	Reported by Bean <bean123ch@gmail.com>
+
+2009-07-30  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* util/i386/pc/grub-setup.c (setup): Check that no partition is in
+	embedding zone, not only the first one.
+
+2009-07-29  Joe Auricchio  <jauricchio@gmail.com>
+
+	* term/gfxterm.c (clear_char): New function.
+	(grub_virtual_screen_setup): Use clear_char.
+	(scroll_up): Likewise.
+	(grub_virtual_screen_cls): Likewise.
+
+2009-07-29  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/deviceiter.c (get_acceleraid_disk_name): New static
+	function.
+	(grub_util_iterate_devices): Handle Accelraid devices.
+	* util/hostdisk.c (convert_system_partition_to_system_disk): Likewise.
+
+2009-07-28  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* loader/i386/linux.c (grub_cmd_linux): Use ',' rather than ';' as
+	separator for the suggested gfxpayload string (';' collides with the
+	parser and needs escaping).
+
+2009-07-28  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* loader/i386/multiboot_helper.S (grub_multiboot_backward_relocator):
+	Clear direction flag before jumping to OS.
+	(grub_multiboot2_real_boot): Likewise.
+
+2009-07-28  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/i386/pc/grub-install: Fix parsing of --disk-module
+	option.
+
+2009-07-28  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/i386/pc/grub-setup.c (setup): Fix 2 incorrect checks
+	when embedding.
+
+2009-07-26  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub-mkconfig.in (package_version): New variable.
+	Use it do display the version.
+
+2009-07-25  Felix Zielcke  <fzielcke@z-51.de>
+
+	* kern/file.c (grub_file_open): Revert to previous check with
+	grub_errno.
+
+2009-07-25  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* commands/probe.c (GRUB_MOD_INIT (probe)): Remove "[--target=target]"
+	from help line. It's out of sync with code.
+
+2009-07-25  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* kern/parser.c (grub_parser_execute): Fix a bug causing truncated
+	entries on failed boot.
+
+2009-07-25  Felix Zielcke  <fzielcke@z-51.de>
+
+	* kern/file.c (grub_file_open): Fix an error check.
+
+2009-07-24  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* util/i386/pc/grub-setup.c (setup): Fix segmentation fault when
+	partition map couldn't be identified.
+
+2009-07-23  Pavel Roskin  <proski@gnu.org>
+
+	* commands/xnu_uuid.c (transform): Use GRUB_CPU_WORDS_BIGENDIAN
+	instead of WORDS_BIGENDIAN.  Use grub_le_to_cpu32(), so that the
+	case of little endian words becomes just an optimization.
+	Respect const modifier.
+	(md5_final): Use code that doesn't depend on endianness.
+
+	* include/grub/misc.h (ALIGN_UP): Cast align to the type of addr
+	to avoid loss of upper bits if align is unsigned and shorter
+	than addr.
+
+2009-07-21  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	UUID support for UFS
+
+	* fs/ufs.c (grub_ufs_sblock): Add uuidhi and uuidlow.
+	(grub_ufs_uuid): New function.
+	(grub_ufs_fs): add .uuid
+
+2009-07-21  Pavel Roskin  <proski@gnu.org>
+
+	* kern/dl.c (grub_dl_check_header): Make static.
+
+2009-07-21  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub.d/30_os-prober.in: Remove unused CHAINROOT.  Don't
+	add drivemap for Vista.  It breaks Windows 7.
+
+2009-07-21  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* fs/ufs.c (grub_ufs_sblock): Fix offset of mtime2 which was off by
+	128 bytes
+
+2009-07-20  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Add BFS support
+
+	* conf/common.rmk (grub_probe_SOURCES): Add fs/befs.c.
+	(grub_fstest_SOURCES): Likewise.
+	(pkglib_MODULES): Add befs.mod.
+	(befs_mod_SOURCES): New variable.
+	(befs_mod_CFLAGS): Likewise.
+	(befs_mod_LDFLAGS): Likewise.
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Likewise.
+	(grub_setup_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	(grub_setup_SOURCES): Likewise.
+	* fs/befs.c: New file.
+	* fs/afs.c (GRUB_AFS_FSNAME): New declaration.
+	(GRUB_AFS_SBLOCK_SECTOR): Likewise.
+	(GRUB_AFS_SBLOCK_MAGIC1) [MODE_BFS]: New conditional declaration.
+	(GRUB_AFS_BTREE_MAGIC) [MODE_BFS]: Likewise
+	(B_KEY_INDEX_ALIGN): New declaration.
+	(B_KEY_INDEX_OFFSET): Use B_KEY_INDEX_ALIGN.
+	(grub_afs_bnode) [MODE_BFS]: Make key_count and key_size 16-bit
+	(grub_afs_btree) [MODE_BFS]: New conditional declaration.
+	(grub_afs_sblock) [MODE_BFS]: Remove link_count.
+	(grub_afs_validate_sblock) [MODE_BFS]: Support BFS
+	(grub_afs_mount) [MODE_BFS]: Likewise.
+	(grub_afs_dir) [MODE_BFS]: Divide mtime by 65536 and not 1000000.
+	(grub_afs_fs): Use GRUB_AFS_FSNAME
+	(GRUB_MOD_INIT (afs)) [MODE_BFS]: Rename to ...
+	(GRUB_MOD_INIT (befs)) [MODE_BFS]: ... this
+	(GRUB_MOD_FINI (afs)) [MODE_BFS]: Rename to ...
+	(GRUB_MOD_FINI (befs)) [MODE_BFS]: ... this
+
+2009-07-19  Yves BLUSSEAU  <yves.grub-devel@zetam.org>
+
+	* util/getroot.c (find_root_device): Add support for MacOSX.
+	* util/hostdisk.c: Likewise.
+
+2009-07-20  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* font/font.c (find_glyph): Check whether a font is present to avoid
+	segmentation fault.
+
+2009-07-20  Joe Auricchio  <jauricchio@gmail.com>
+
+	* term/gfxterm.c (grub_virtual_screen_setup): Clear virtual_screen.
+
+2009-07-20  Pavel Roskin  <proski@gnu.org>
+
+	* configure.ac: Trim excessively wordy excuses.
+
+2009-07-20  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Add symlink, mtime and label support to AtheFS.
+
+	* fs/afs.c (grub_afs_sblock): Declare `name' as char.
+	(grub_afs_iterate_dir): Handle symlinks.
+	(grub_afs_open): Use grub_afs_read_symlink.
+	(grub_afs_dir): Likewise.
+	Pass mtime.
+	(grub_afs_label): New function.
+	(grub_afs_fs): Add grub_afs_label.
+	(grub_afs_read_symlink): New function.
+
+2009-07-20  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix AtheFS support.
+
+	* fs/afs.c: Fix comments style.
+	(grub_afs_blockrun): Declare as packed.
+	(grub_afs_datastream): Likewise.
+	(grub_afs_bnode): Likewise.
+	(grub_afs_btree): Likewise.
+	(grub_afs_sblock): Likewise.
+	Declare `name' as char.
+	(grub_afs_inode): Declare as packed.
+	Change void *vnode to grub_uint32_t unused.
+	(grub_afs_iterate_dir): Check that key_size is positive.
+	(grub_afs_mount): Don't read superblock twice.
+	(grub_afs_dir): Don't free node in case of error,
+	grub_fshelp_find_file already handles this.
+	(grub_afs_open): Likewise.
+
+2009-07-19  Pavel Roskin  <proski@gnu.org>
+
+	* Makefile.in: Remove LIBLZO and enable_lzo.
+	* conf/i386-pc.rmk: Remove lzo support.
+	* configure.ac: Remove checks for lzo, don't define ENABLE_LZMA.
+	* include/grub/i386/pc/kernel.h: Define ENABLE_LZMA.  Remove lzo
+	support.
+	* kern/i386/pc/lzo1x.S: Remove.
+	* kern/i386/pc/startup.S: Remove lzo support.
+	* util/i386/pc/grub-mkimage.c: Likewise.
+
+2009-07-19  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* disk/usbms.c (grub_usbms_transfer): Fix double semicolon.
+	* fs/xfs.c (grub_xfs_dir): Likewise.
+	* fs/afs.c (grub_afs_dir): Likewise.
+	* fs/iso9660.c (grub_iso9660_iterate_dir): Likewise.
+	(grub_iso9660_open): Likewise.
+	* fs/jfs.c (grub_jfs_open): Likewise.
+	* fs/ext2.c (grub_ext2_dir): Likewise.
+	* include/grub/macho.h (grub_macho_fat_arch): Likewise.
+	* script/sh/lexer.c (grub_script_yylex): Likewise.
+
+2009-07-16  Pavel Roskin  <proski@gnu.org>
+
+	* configure.ac: Never add "-c" to CFLAGS.
+
+	* configure.ac: Fix incorrect comparison for grub_cv_cc_efiemu.
+
+	* configure.ac: Fix wrong use of grub_cv_cc_no_red_zone where
+	grub_cv_cc_efiemu should be used.
+
+	* configure.ac: Typo fixes.
+
+	* kern/mm.c (grub_zalloc): New function.
+	(grub_debug_zalloc): Likewise.
+	* include/grub/mm.h: Declare grub_zalloc() and
+	grub_debug_zalloc().
+	* util/misc.c (grub_zalloc): New function.
+	* bus/usb/uhci.c (grub_uhci_pci_iter): Use grub_zalloc()
+	instead of grub_malloc(), remove unneeded initializations.
+	* bus/usb/usbhub.c (grub_usb_hub_add_dev): Likewise.
+	* commands/extcmd.c (grub_extcmd_dispatcher): Likewise.
+	* commands/parttool.c (grub_cmd_parttool): Likewise.
+	* disk/i386/pc/biosdisk.c (grub_biosdisk_open): Likewise.
+	* disk/raid5_recover.c (grub_raid5_recover): Likewise.
+	* disk/raid6_recover.c (grub_raid6_recover): Likewise.
+	* disk/usbms.c (grub_usbms_finddevs): Likewise.
+	* efiemu/mm.c (grub_efiemu_request_memalign): Likewise.
+	* efiemu/pnvram.c (grub_efiemu_pnvram): Likewise.
+	(grub_cmd_efiemu_pnvram): Likewise.
+	* fs/i386/pc/pxe.c (grub_pxefs_open): Likewise.
+	* fs/iso9660.c (grub_iso9660_mount): Likewise.
+	(grub_iso9660_iterate_dir): Likewise.
+	* fs/jfs.c (grub_jfs_opendir): Likewise.
+	* fs/ntfs.c (list_file): Likewise.
+	(grub_ntfs_mount): Likewise.
+	* kern/disk.c (grub_disk_open): Likewise.
+	* kern/dl.c (grub_dl_load_core): Likewise.
+	* kern/elf.c (grub_elf_file): Likewise.
+	* kern/env.c (grub_env_context_open): Likewise.
+	(grub_env_set): Likewise.
+	(grub_env_set_data_slot): Likewise.
+	* kern/file.c (grub_file_open): Likewise.
+	* kern/fs.c (grub_fs_blocklist_open): Likewise.
+	* loader/i386/multiboot.c (grub_module): Likewise.
+	* loader/xnu.c (grub_xnu_create_key): Likewise.
+	(grub_xnu_create_value): Likewise.
+	* normal/main.c (grub_normal_add_menu_entry): Likewise.
+	(read_config_file): Likewise.
+	* normal/menu_entry.c (make_screen): Likewise.
+	* partmap/sun.c (sun_partition_map_iterate): Likewise.
+	* script/sh/lexer.c (grub_script_lexer_init): Likewise.
+	* script/sh/script.c (grub_script_parse): Likewise.
+	* video/bitmap.c (grub_video_bitmap_create): Likewise.
+	* video/readers/jpeg.c (grub_video_reader_jpeg): Likewise.
+	* video/readers/png.c (grub_png_output_byte): Likewise.
+	(grub_video_reader_png): Likewise.
+
+2009-07-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Enable all targets that can be built by default
+
+	* configure.ac: enable efiemu runtime, grub-emu, grub-emu-usb,
+	grub-mkfont and grub-fstest if they can be built
+
+2009-07-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix hang and segmentation fault in grub-emu-usb
+
+	* disk/scsi.c (grub_scsi_open): return err and not grub_errno
+	* util/usb.c (grub_libusb_devices): likewise
+	(grub_libusb_init): rename to ...
+	(GRUB_MOD_INIT (libusb)):...this
+	(grub_libusb_fini): rename to ..
+	(GRUB_MOD_FINI (libusb)):...this
+	* disk/usbms.c (grub_usbms_transfer): fix retry logic
+	* include/grub/disk.h (grub_raid_init): removed, it's useless
+	(grub_raid_fini): likewise
+	(grub_lvm_init): likewise
+	(grub_lvm_fini): likewise
+	* util/grub-emu.c (main): don't call grub_libusb_init, it's done
+	by grub_init_all
+
+2009-07-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix libusb
+
+	* Makefile.in (LIBUSB): new macro
+	* genmk.rb (Utility/print_tail): new method
+	(Utility/rule): use intermediary variable #{prefix}_OBJECTS
+	(top level): call util.print_tail at the end.
+
+2009-07-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Make FreeBSD accept zpool.cache
+
+	* loader/i386/bsd.c (grub_freebsd_add_meta_module): spoof filename if
+	type is /boot/zfs/zpool.cache
+
+2009-07-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix 64-bit efiemu
+
+	* include/grub/efiemu/efiemu.h (grub_efiemu_configuration_table64_t):
+	correct wrong typedef
+	* efiemu/prepare.c (SUFFIX (grub_efiemu_prepare)): minor style fixes
+
+2009-07-15  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/disk.h (struct grub_disk_dev): Use enum for id.
+	* kern/disk.c (struct grub_disk_cache): Likewise.
+
+	* commands/probe.c (options): Typo fix.
+
+	* include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_BPB_END):
+	Increase to 0x5a to accommodate FAT32.  Adjust other offsets
+	accordingly.
+	Original patch by Yves Blusseau <yves.grub-devel@zetam.org>
+
+	* boot/i386/pc/boot.S (general_error_string): Add DOS newline at
+	the end of "Error" to make the message more readable.
+
+	* boot/i386/pc/boot.S (kernel_segment): Remove.
+	(copy_buffer): Use GRUB_BOOT_MACHINE_KERNEL_ADDR in segment 0
+	for destination.
+
+	* boot/i386/pc/boot.S (boot_version): Remove.
+	* include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_VER_MAJ):
+	Remove.
+
+	* include/grub/i386/pc/boot.h: Sort all offsets.
+	(GRUB_BOOT_MACHINE_KERNEL_ADDRESS): Remove, it's unused.
+	(GRUB_BOOT_MACHINE_KERNEL_SEGMENT): Likewise.
+	* boot/i386/pc/boot.S: Assert location of every offset listed in
+	include/grub/i386/pc/boot.h.
+
+2009-07-13  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/i386/coreboot/machine.h: Rename
+	GRUB_MACHINE_LINUXBIOS to GRUB_MACHINE_COREBOOT.
+	* loader/multiboot_loader.c (grub_cmd_multiboot_loader): Allow
+	multiboot 1 for GRUB_MACHINE_COREBOOT and GRUB_MACHINE_QEMU.
+
+	* kern/dl.c: Force native word size to suppress warnings when
+	compiling grub-emu.
+
+	* kern/device.c (grub_device_iterate): Change struct part_ent to
+	hold the name, not a pointer to it.  Use one grub_malloc() per
+	partition, not two.  Free partition_name if grub_malloc() fails.
+	Set ents to NULL only before grub_partition_iterate() is called.
+
+2009-07-11  Bean  <bean123ch@gmail.com>
+
+	* kern/ieee1275/openfw.c (grub_children_iterate): Fix size of
+	childname.
+
+2009-07-10  Bean  <bean123ch@gmail.com>
+2009-07-10  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* kern/ieee1275/openfw.c (grub_children_iterate)
+	(grub_devalias_iterate): Fix size evaluation for property or path
+	strings, which was broken since r2132.
+
+2009-07-07  Pavel Roskin  <proski@gnu.org>
+
+	* commands/search.c (search_file): Merge into ...
+	(search_fs): ... this.  Accept search type as argument.
+	(grub_cmd_search): Pass search type to search_fs().
+
+	* include/grub/util/console.h: New file.
+	* util/console.c: Use it instead of grub/machine/console.h.
+	* util/grub-emu.c: Likewise.
+
+	* lib/arg.c (find_long_option): Remove.
+	(find_long): Add `len' argument, make `s' const char *.
+	(grub_arg_parse): Parse long options in place, not in a
+	temporary buffer.
+
+2009-07-06  Pavel Roskin  <proski@gnu.org>
+
+	* commands/search.c (search_fs): Fix potential NULL pointer
+	dereference.
+
+	* commands/search.c (search_fs): Replace QUID macro with quid_fn
+	function pointer.
+
+2009-07-06  Daniel Mierswa  <impulze@impulze.org>
+
+	* commands/search.c (search_fs): Use grub_strcasecmp() for UUID
+	comparison.
+
+2009-07-05  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/i386/linux.h (struct linux_kernel_params):
+	Restore padding3, it's still needed.
+
+	* util/grub.d/10_freebsd.in: Fix spelling of `device.hints' on
+	FreeBSD.
+	* util/osdetect.lua: Likewise.
+
+2009-07-05  Bean  <bean123ch@gmail.com>
+
+	* conf/common.rmk (lua_mode_SOURCES): Add script/lua/lstrlib.c.
+
+	* script/lua/grub_lib.c (grub_lua_run): Check input parameter.
+	(grub_lua_getenv): Likewise.
+	(grub_lua_setenv): Likewise.
+	(save_errno): New function.
+	(push_result): Likewise.
+	(grub_lua_enum_device): Likewise.
+	(grub_lua_enum_file): Likewise.
+	(grub_lua_file_open): Likewise.
+	(grub_lua_file_close): Likewise.
+	(grub_lua_file_seek): Likewise.
+	(grub_lua_file_read): Likewise.
+	(grub_lua_file_getline): Likewise.
+	(grub_lua_file_getsize): Likewise.
+	(grub_lua_file_getpos): Likewise.
+	(grub_lua_file_eof): Likewise.
+	(grub_lua_file_exist): Likewise.
+	(grub_lua_add_menu): Likewise.
+
+	* script/lua/grub_lua.h (isupper): New inline function.
+	(islower): Likewise.
+	(ispunct): Likewise.
+	(isxdigit): Likewise.
+	(strcspn): Change to normal function.
+	(strpbkr): New function declaration.
+	(memchr): Likewise.
+
+	* script/lua/grub_main.c (scan_str): New function.
+	(strcspn): Likewise.
+	(strpbrk): Likewise.
+	(memchr): Likewise.
+
+	* script/lua/linit.c (lualibs): Enable the string library.
+
+	* util/osdetect.lua: New file.
+
+2009-07-04  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/i386/linux.h (struct linux_kernel_params): Add
+	`capabilities' member.
+
+2009-07-02  Pavel Roskin  <proski@gnu.org>
+
+	* genparttoollist.sh: Add missing newline at the end.
+
+2009-07-01  Pavel Roskin  <proski@gnu.org>
+
+	* kern/x86_64/efi/callwrap.S: Add missing newline at the end.
+
+	* util/hostdisk.c (open_device): Remove `const' from
+	`sysctl_size', as sysctlbyname() can change it (in this case it
+	doesn't actually happen).
+
+	* include/grub/types.h: Define GRUB_LONG_MAX and GRUB_LONG_MIN
+	using signed long int constants.
+
+	* util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Make `p'
+	constant to avoid a warning on FreeBSD.
+
+	* util/hostdisk.c (device_is_wholedisk): Compile only on systems
+	where it's needed.
+
+	* Makefile.in: Install include/grub/machine symlink.
+
+	* Makefile.in: When installing symlinks, use "cp -fR", which
+	works on FreeBSD and MacOSX.
+	From Yves Blusseau <cl7m42e02@sneakemail.com>
+
+	* kern/dl.c (grub_dl_resolve_symbol): Make static.
+	* include/grub/dl.h: Remove grub_dl_resolve_symbol().
+
+	* util/misc.c: Move grub_reboot() and grub_halt() ...
+	* util/grub-emu.c: ... here.  Make main_env static.
+	* include/grub/util/misc.h: Remove main_env.
+
+	* kern/mm.c: Use correct format to print size_t.
+
+	* include/grub/elf.h: Define Elf_Sword and Elf_Xword.
+	* kern/i386/dl.c: Use ELF symbols without "32" or "64".
+	* kern/powerpc/dl.c: Likewise.
+	* kern/sparc64/dl.c: Likewise.
+	* kern/x86_64/dl.c: Likewise.
+
+2009-07-01  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Fix grub-emu build on sparc64-ieee1275.
+
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Synchronize with ...
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): ... this.
+
+2009-07-01  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/misc.c: Include `<setjmp.h>' and `<grub/machine/machine.h>'.
+	(grub_reboot, grub_halt): New functions.
+
+	* util/i386/pc/misc.c: Delete.  Update all users.
+	* util/sparc64/ieee1275/misc.c: Likewise.
+	* util/powerpc/ieee1275/misc.c: Likewise.
+
+2009-07-01  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* conf/i386.rmk (setjmp_mod_SOURCES)
+	(setjmp_mod_ASFLAGS, setjmp_mod_LDFLAGS): Move to ...
+	* conf/common.rmk (setjmp_mod_SOURCES)
+	(setjmp_mod_ASFLAGS, setjmp_mod_LDFLAGS): ... here, and modify
+	to use $(target_cpu).
+	* conf/x86_64-efi.rmk (setjmp_mod_SOURCES)
+	(setjmp_mod_ASFLAGS, setjmp_mod_LDFLAGS): Remove.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	* conf/sparc64-ieee1275.rmk: Likewise.
+
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Use
+	$(target_cpu) for kern/$(target_cpu)/dl.c.
+	* conf/i386-efi.rmk: Likewise.
+	* conf/i386-ieee1275.rmk: Likewise.
+	* conf/x86_64-efi.rmk: Likewise.
+	* conf/i386-coreboot.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk (kernel_img_SOURCES): Use
+	$(target_cpu) for kern/$(target_cpu)/dl.c and for
+	kern/$(target_cpu)/cache.S.
+	* conf/sparc64-ieee1275.rmk: Likewise.
+
+2009-07-01  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/i386/linux.h (linux_kernel_params): Change `mmap_size'
+	type to `grub_uint8_t', and adjust `padding9' accordingly.
+
+2009-06-29  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/i386/linux.h (GRUB_VIDEO_TYPE_TEXT): New macro.
+
+	* loader/i386/linux.c [__i386__] (grub_linux_boot): Simplify inline
+	assembly in final jump, using register constraints.
+
+	(grub_linux_boot): For text mode, initialize `have_vga' using
+	GRUB_VIDEO_TYPE_TEXT rather than 0 (this changes its value to 1).
+
+	Initialize `video_cursor_x' and `video_cursor_y' as late as possible,
+	right before the final jump.
+
+	Set `video_mode' to 0x3.
+
+	Document initialization of `video_page', `video_mode' and
+	`video_ega_bx'.
+
+2009-06-29  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/i386/linux.h (GRUB_LINUX_FLAG_QUIET): New macro.
+	* loader/i386/linux.c (grub_cmd_linux): Recognize "quiet" option,
+	and set GRUB_LINUX_FLAG_QUIET appropriately.
+
+2009-06-29  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Fix build on Debian / sparc.
+
+	* configure.ac: Recognize `sparc' target_cpu (as sparc64).
+
+2009-06-28  Pavel Roskin  <proski@gnu.org>
+
+	* kern/i386/qemu/mmap.c (grub_machine_mmap_iterate): Use cast to
+	fix a warning.
+
+	* util/grub.d/10_linux.in: Match SUSE style initrd names.
+
+2009-06-27  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* loader/i386/linux.c (grub_linux_boot): Fix uninitialized use of
+	`err'.
+
+2009-06-27  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Revert r2338.
+
+	* loader/i386/linux.c (grub_cmd_linux): Don't call grub_error when
+	file can't be opened.  grub_file_open() is already supposed to set
+	grub_errno / grub_errmsg appropriately.
+	* loader/i386/pc/linux.c (grub_cmd_linux): Likewise.
+
+2009-06-27  Pavel Roskin  <proski@gnu.org>
+2009-06-27  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/dl.h: Include grub/elf.h.
+	(struct grub_dl): Add symtab field.
+	* kern/dl.c [GRUB_MACHINE_QEMU]: Define
+	GRUB_MODULES_MACHINE_READONLY.
+	(grub_dl_resolve_symbols): Populate mod->symtab, making a copy
+	of the header for read-only modules.
+	(grub_dl_unload): Free mod->symtab for read-only modules.
+	* kern/i386/dl.c: Use mod->symtab.
+	* kern/powerpc/dl.c: Likewise.
+	* kern/sparc64/dl.c: Likewise.
+	* kern/x86_64/dl.c: Likewise.
+
+	* conf/i386-qemu.rmk: New file.
+	* kern/i386/qemu/startup.S: Likewise.
+	* kern/i386/qemu/mmap.c: Likewise.
+	* boot/i386/qemu/boot.S: Likewise.
+	* include/grub/i386/qemu/time.h: Likewise.
+	* include/grub/i386/qemu/serial.h: Likewise.
+	* include/grub/i386/qemu/kernel.h: Likewise.
+	* include/grub/i386/qemu/console.h: Likewise.
+	* include/grub/i386/qemu/boot.h: Likewise.
+	* include/grub/i386/qemu/init.h: Likewise.
+	* include/grub/i386/qemu/machine.h: Likewise.
+	* include/grub/i386/qemu/loader.h: Likewise.
+	* include/grub/i386/qemu/memory.h: Likewise.
+
+	* conf/i386-coreboot.rmk (GRUB_BOOT_MACHINE_LINK_ADDR)
+	(GRUB_KERNEL_MACHINE_LINK_ADDR): New variables.
+	[qemu] (pkglib_IMAGES): Add `boot.img'.
+	[qemu] (boot_img_SOURCES, boot_img_ASFLAGS, boot_img_LDFLAGS)
+	[qemu] (boot_img_FORMAT): New variables.
+	[qemu] (bin_UTILITIES): Add `grub-mkimage'.
+	[qemu] (grub_mkimage_SOURCES, grub_mkimage_CFLAGS): New variables.
+	[qemu] (kernel_img_SOURCES, kernel_img_HEADERS, kernel_img_CFLAGS)
+	[qemu] (kernel_img_ASFLAGS, kernel_img_LDFLAGS)
+	[qemu] (kernel_img_FORMAT): New variables.
+
+	* configure.ac: Recognise `i386-qemu'.
+
+	* util/i386/pc/grub-mkimage.c (compress_kernel): Add dummy variant
+	(for no compression).
+	[GRUB_MACHINE_QEMU] (generate_image): Misc adjustments to produce
+	a valid i386 ROM image.  Make `GRUB_KERNEL_MACHINE_COMPRESSED_SIZE',
+	`GRUB_KERNEL_MACHINE_INSTALL_DOS_PART' and
+	`GRUB_KERNEL_MACHINE_INSTALL_BSD_PART' optional features (with
+	ifdefs).
+
+2009-06-27  Pavel Roskin  <proski@gnu.org>
+
+	* efiemu/prepare.c: Eliminate TYPE macro, it makes code hard to
+	read.
+	* efiemu/prepare32.c: Likewise.
+	* efiemu/prepare64.c: Likewise.
+
+2009-06-26  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/types.h: Define GRUB_TARGET_WORDSIZE.
+	* include/grub/elf.h: Define symbols without "32" or "64" based
+	on GRUB_TARGET_WORDSIZE.
+	* include/grub/multiboot2.h: Use GRUB_TARGET_WORDSIZE.
+	* efiemu/loadcore32.c: Redefine GRUB_TARGET_WORDSIZE, remove own
+	ELF definitions.
+	* efiemu/loadcore64.c: Likewise.
+	* loader/i386/bsd32.c: Likewise.
+	* loader/i386/bsd64.c: Likewise.
+	* kern/dl.c: Remove own ELF definitions.
+	* util/i386/efi/grub-mkimage.c: Likewise.
+
+2009-06-23  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* kern/i386/pc/startup.S (real_to_prot): Access `gdtdesc' using
+	segment 0x0 unconditionally, because the reference generated by
+	GAS is an absolute address.
+
+2009-06-22  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/i386/kernel.h: Include `<grub/machine/machine.h>'.
+	[! GRUB_MACHINE_IEEE1275]: Set `GRUB_MOD_ALIGN' to 0x1.
+
+2009-06-22  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* commands/search.c (grub_cmd_search): Macroify hardcoded args[]
+	indexes.  Check for -f explicitly.
+	(search_file): Improve error message.
+	(GRUB_MOD_INIT(search)): Add missing `-n' to help output.
+
+2009-06-22  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* conf/i386-pc.rmk (GRUB_MEMORY_MACHINE_LINK_ADDR): Rename to ...
+	(GRUB_KERNEL_MACHINE_LINK_ADDR): ... this.  Update all users.
+
+2009-06-22  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/i386/misc.S'.
+	* conf/i386-ieee1275.rmk: Likewise.
+	* conf/i386-coreboot.rmk: Likewise.
+
+	* kern/i386/pc/startup.S (grub_stop): Remove function.
+	* kern/i386/ieee1275/startup.S: Likewise.
+	* kern/i386/coreboot/startup.S: Likewise.
+	* kern/i386/misc.S (grub_stop): New function.
+
+2009-06-22  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* kern/i386/pc/startup.S (real_to_prot): Move from here ...
+	* kern/i386/realmode.S (real_to_prot): ... to here.
+
+2009-06-22  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* conf/i386-ieee1275.rmk (pkglib_PROGRAMS): Replace `kernel.elf'
+	with `kernel.img'.
+	(kernel_elf_SOURCES): Rename to ...
+	(kernel_img_SOURCES): ... this.
+	(kernel_elf_HEADERS): Rename to ...
+	(kernel_img_HEADERS): ... this.  Update all users.
+	(kernel_elf_ASFLAGS): Rename to ...
+	(kernel_img_ASFLAGS): ... this.
+	(kernel_elf_CFLAGS): Rename to ...
+	(kernel_img_CFLAGS): ... this.
+	(kernel_elf_LDFLAGS): Rename to ...
+	(kernel_img_LDFLAGS): ... this.
+	* conf/i386-coreboot.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+
+	* util/elf/grub-mkimage.c (add_segments): Replace "kernel.elf"
+	with "kernel.img".
+
+2009-06-21  Pavel Roskin  <proski@gnu.org>
+
+	* loader/powerpc/ieee1275/linux.c (offset_phdr): Fix prototypes
+	to match nested functions.
+	* loader/sparc64/ieee1275/linux.c: Likewise.
+
+	* conf/i386-ieee1275.rmk: Define kernel_elf_ASFLAGS.
+
+2009-06-21  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* configure.ac: Enable `END_SYMBOL' / `BSS_START_SYMBOL' test on
+	all i386 platforms.
+
+2009-06-21  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Fix asm file handling on ELF, and remove workarounds.
+
+	* genmk.rb (class Programs): Detect assembly files, and set ASFLAGS
+	and -DASM_FILE=1 appropriately (copied from `class Images' stanza).
+	* kern/i386/ieee1275/startup.S (ASM_FILE): Remove macro.
+	* kern/i386/coreboot/startup.S (ASM_FILE): Likewise.
+
+2009-06-21  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Load BSD ELF modules
+
+	* conf/i386-pc.rmk (bsd_mod_SOURCES): Add loader/i386/bsd32.c
+	and loader/i386/bsd64.c
+	* include/grub/i386/bsd.h (FREEBSD_MODTYPE_MODULE): Remove
+	(FREEBSD_MODTYPE_ELF_MODULE): New definition
+	(FREEBSD_MODTYPE_ELF_MODULE_OBJ): Likewise
+	(grub_freebsd_load_elfmodule32): New declaration
+	(grub_freebsd_load_elfmoduleobj64): Likewise
+	(grub_freebsd_load_elf_meta32): Likewise
+	(grub_freebsd_load_elf_meta64): Likewise
+	(grub_freebsd_add_meta): Likewise
+	(grub_freebsd_add_meta_module): Likewise
+	* loader/i386/bsd.c (grub_freebsd_add_meta): Make global
+	(grub_freebsd_add_meta_module): Likewise and move module-specific
+	parts to grub_cmd_freebsd and grub_cmd_freebsd_module
+	(grub_cmd_freebsd): Add elf-kernel specific parts
+	based on grub_freebsd_add_meta_module
+	(grub_cmd_freebsd_module): Add type parsing moved from
+	grub_freebsd_add_meta_module
+	(grub_cmd_freebsd_module_elf): New function
+	(cmd_freebsd_module_elf): New variable
+	(GRUB_MOD_INIT): Register freebsd_module_elf
+	* loader/i386/bsd32.c: New file
+	* loader/i386/bsd64.c: Likewise
+	* loader/i386/bsdXX.c: Likewise
+	* kern/elf.c (grub_elf32_load): Let hook decide which pheaders to load
+	(grub_elf64_load): Likewise
+	* include/grub/elfload.h (grub_elf32_load_hook_t): New parameter do_load
+	All users updated
+	(grub_elf64_load_hook_t): Likewise
+
+2009-06-21  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/grub-mkconfig.in (GRUB_DISABLE_LINUX_RECOVERY): Export
+	variable.
+	* util/grub.d/10_linux.in: If GRUB_DISABLE_LINUX_RECOVERY is true,
+	don't write a menu entry for recovery mode.
+
+2009-06-20  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/i386/pc/grub-mkimage.c (main): Oops, free `output' only
+	after it's no longer needed.
+
+2009-06-20  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/i386/loader.h (grub_linux_prot_size)
+	(grub_linux_tmp_addr, grub_linux_real_addr)
+	(grub_linux_is_bzimage, grub_linux16_boot): Declare only on
+	GRUB_MACHINE_PCBIOS.
+	* util/i386/pc/grub-mkimage.c (compress_kernel): Move
+	common grub_util_info() call to ...
+	(generate_image): ... here.
+	Fix use of uninitialized memory, comparison of signed with
+	unsigned integers and memory leak.
+	Remove bogus module address message.
+
+2009-06-20  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* disk/mdraid_linux.c (GRUB_MOD_FINI): use grub_raid_unregister and not
+	grub_raid_register
+	* disk/dmraid_nvidia.c (GRUB_MOD_FINI): likewise
+
+2009-06-19  Pavel Roskin  <proski@gnu.org>
+
+	* configure.ac: Remove stray AC_MSG_CHECKING.
+
+2009-06-19  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* disk/scsi.c (grub_scsi_open): use continue instead of big if
+
+2009-06-18  Pavel Roskin  <proski@gnu.org>
+
+	* conf/common.rmk: Add fs_file.mod.
+	* disk/fs_file.c: New file.
+	* include/grub/disk.h (enum grub_disk_dev_id): Add
+	GRUB_DISK_DEVICE_FILE_ID.
+
+2009-06-18  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix build with Apple's toolchain. Part 2
+
+	* aclocal.m4 (grub_PROG_TARGET_CC): add missing prototype for main and
+	a fake start
+
+2009-06-18  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix build with Apple's toolchain. Part 1
+
+	* commands/i386/pc/drivemap_int13h.S: use assembly-time constants
+	for long calls
+	* configure.ac: remove a leftover AC_MSG_RESULT
+	(CFLAGS): don't add -Wl,--defsym,___main=0x8100 when building with
+	Apple's toolchain
+
+2009-06-18  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix warnings
+
+	* fs/ntfscomp.c (decomp_get16): initialize c1 and c2
+	(decomp_block): initialize ch
+	use grub_memcpy instead of memcpy
+
+2009-06-17  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/i386/coreboot/console.h: Don't use the i386-pc
+	version, use declarations needed to use vga_text as the startup
+	console.
+
+	* conf/i386-coreboot.rmk (kernel_elf_SOURCES): Remove
+	term/i386/pc/at_keyboard.c, it doesn't need to be compiled into
+	the kernel.
+	* kern/i386/coreboot/init.c: Don't call grub_at_keyboard_init()
+	and grub_at_keyboard_fini(), it's done on module load and
+	unload.
+
+2009-06-17  Felix Zielcke  <fzielcke@z-51.de>
+
+	* loader/i386/linux.c (grub_cmd_linux): Set grub_error if the
+	file can't be found.
+	* loader/i386/pc/linux.c (grub_cmd_linux): Likewise.
+
+2009-06-17  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix newline handling
+
+	* include/grub/script_sh.h (grub_lexer_param): new field was_newline
+	* script/sh/lexer.c (grub_script_lexer_init): initialize was_newline
+	(grub_script_yylex): don't segfault on unterminated script
+	newline terminates command and variable
+
+2009-06-17  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	avoid double grub_adjust_range call. Bug reported by David Simner
+
+	* kern/disk.c (grub_disk_write): change to raw disk access before
+	calling disk_read
+
+2009-06-17  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/elf/grub-mkimage.c (usage): Prefix each option line with two
+	spaces, for the benefit of help2man.
+	* util/i386/efi/grub-mkimage.c (usage): Likewise.
+
+2009-06-16  Pavel Roskin  <proski@gnu.org>
+
+	* kern/i386/halt.c: Include grub/machine/init.h.
+	* kern/i386/reboot.c: Include grub/cpu/reboot.h.
+
+2009-06-16  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub.d/30_os-prober.in: Use ${root} in the generated
+	drivemap menuentry.
+
+2009-06-16  James Jarvis  <James.Jarvis@ed.ac.uk>
+
+	* commands/help.c GRUB_MOD_INIT(echo): Fix the help output of
+	`echo' command.
+
+2009-06-16  Pavel Roskin  <proski@gnu.org>
+
+	* boot/i386/pc/boot.S: Remove root_drive.  Assert offset of
+	boot_drive_check by using GRUB_BOOT_MACHINE_DRIVE_CHECK.  Don't
+	save %dx, we only need %dl and we never change it.
+	* boot/i386/pc/cdboot.S: Don't set the root drive.
+	* boot/i386/pc/pxeboot.S: Likewise.
+	* include/grub/i386/pc/boot.h: Remove
+	GRUB_BOOT_MACHINE_ROOT_DRIVE, adjust
+	GRUB_BOOT_MACHINE_DRIVE_CHECK.
+	* include/grub/i386/pc/kernel.h: Remove grub_root_drive.
+	* kern/i386/pc/init.c (make_install_device): Remove references
+	to grub_root_drive.
+	* kern/i386/pc/startup.S: Likewise.
+	* util/i386/pc/grub-setup.c (setup): Don't set root_drive.
+
+2009-06-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	xnu_uuid command
+
+	* commands/xnu_uuid.c: new file
+	* conf/common.rmk (pkglib_MODULES): add xnu_uuid.mod
+	(xnu_uuid_mod_SOURCES): new variable
+	(xnu_uuid_mod_CFLAGS): likewise
+	(xnu_uuid_mod_LDFLAGS): likewise
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): add commands/probe.c
+	* conf/i386-ieee1275.rmk: likewise
+	* conf/i386-pc.rmk: likewise
+	* conf/powerpc-ieee1275.rmk: likewise
+	* conf/sparc64-ieee1275.rmk: likewise
+	* util/grub.d/30_os-prober.in: use UUID for Mac OS X/Darwin
+
+2009-06-16  Pavel Roskin  <proski@gnu.org>
+
+	* configure.ac: Avoid '==' in test command, it's not portable.
+
+2009-06-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Probe command
+
+	* commands/probe.c: new file
+	* conf/common.rmk (pkglib_MODULES): add probe.mod
+	(probe_mod_SOURCES): new variable
+	(probe_mod_CFLAGS): likewise
+	(probe_mod_LDFLAGS): likewise
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): add commands/probe.c
+	* conf/i386-ieee1275.rmk: likewise
+	* conf/i386-pc.rmk: likewise
+	* conf/powerpc-ieee1275.rmk: likewise
+	* conf/sparc64-ieee1275.rmk: likewise
+
+2009-06-15  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix handling of string like \"hello\" and "a
+	b"
+
+	* script/sh/lexer.c (check_textstate): accept GRUB_PARSER_STATE_ESC
+	(grub_script_yylex): fix parsing of quoting, escaping and newline
+
+2009-06-13  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* loader/i386/multiboot.c (grub_multiboot_get_bootdev): fix partition
+	handling
+
+2009-06-13  Jun Inoue  <jun.lambda@gmail.com>
+
+	* util/grub-mkconfig.in: Fix parsing of --output option.
+
+2009-06-12  Pavel Roskin  <proski@gnu.org>
+
+	* Makefile.in (pkgdata_SRCDIR): Remove.  genmodsrc.sh and
+	genmk.rb don't need to be generated or installed.
+
+2009-06-12  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* commands/i386/pc/drivemap_int13h.S: add more comments
+
+2009-06-11  Pavel Roskin  <proski@gnu.org>
+
+	* Makefile.in (uninstall): Uninstall manuals.
+
+	* Makefile.in: Rename lib_DATA to lib_SCRIPTS, move it from
+	PKGLIB to SCRIPTS.  This fixes installation of grub-mkconfig_lib
+	and update-grub_lib in two places.
+	* conf/common.rmk: Rename lib_DATA to lib_SCRIPTS.
+
+	* disk/usbms.c (grub_usbms_transfer): Initialize `err' to fix
+	a compiler warning.
+
+	* loader/i386/bsd.c (grub_freebsd_boot): Rename `entry' to
+	`entry_lo' to fix variable shadowing.
+
+2009-06-11  Christian Franke  <franke@computer.org>
+
+	* kern/misc.c (__enable_execute_stack): Add missing return type
+	to prevent gcc warning.
+
+2009-06-11  Felix Zielcke  <fzielcke@z-51.de>
+
+	* conf/i386-ieee1275.rmk (COMMON_LDFLAGS): Remove `-static -lgcc'.
+
+2009-06-11  Pavel Roskin  <proski@gnu.org>
+
+	* Makefile.in: Don't rely on any scripts being executable.
+	Always use $(SHELL) to run shell scripts.
+
+	* configure.ac: Always define ___main if using -nostdlib.  This
+	fixes tests on Cygwin.
+
+2009-06-11  Giuseppe Caizzone  <acaizzo@gmail.com>
+
+	UDF fix
+
+	* fs/udf.c (grub_udf_read_block): handle the fact that ad->length
+	is in bytes and not in blocks
+
+2009-06-11  Pavel Roskin  <proski@gnu.org>
+
+	* kern/i386/halt.c (grub_halt): Make `i' unsigned to fix a
+	warning.
+
+2009-06-11  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub.d/30_os-prober.in: Fix a comment. Source
+	${libdir}/grub/grub-mkconfig_lib.  Use prepare_grub_to_access_device
+	to set the root device.  Place drivemap command in the generated
+	chain entry.
+
+2009-06-11  Pavel Roskin  <proski@gnu.org>
+
+	* configure.ac: Remove host_m32.  Issues with 64-bit utilities
+	have long been resolved.
+
+2009-06-11  Colin Watson  <cjwatson@ubuntu.com>
+
+	* util/grub.d/10_linux.in: Capitalise "Linux".
+
+	* util/grub-pe2elf.c (usage): Fix references to grub-editenv.
+
+2009-06-11  Pavel Roskin  <proski@gnu.org>
+
+	* kern/efi/efi.c (grub_exit): Add infinite loop at the end to
+	fix a gcc warning and ensure that the function won't ever exit.
+
+	* kern/i386/ieee1275/init.c: Add missing prototype for
+	grub_stop_floppy().
+
+	* loader/ieee1275/multiboot2.c [__i386__]: Include
+	grub/cpu/multiboot.h.
+
+	* term/i386/pc/serial.c (serial_translate_key_sequence): Avoid
+	casts to short - they are not portable and cause warnings.  Fix
+	use of uninitialized values in input_buf.  Use ARRAY_SIZE.
+
+2009-06-11  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Drivemap fixes
+
+	* commands/i386/pc/drivemap.c (grub_get_root_biosnumber_drivemap):
+	new function
+	(grub_get_root_biosnumber_saved): new variable
+	(GRUB_MOD_INIT): register grub_get_root_biosnumber_drivemap
+	(GRUB_MOD_FINI): unregister grub_get_root_biosnumber_drivemap
+	* commands/i386/pc/drivemap_int13h.S (grub_drivemap_handler): restore
+	%dx after the call if necessary
+	* conf/common.rmk (pkglib_MODULES): remove boot.mod
+	(boot_mod_SOURCES): remove
+	(boot_mod_CFLAGS): remove
+	(boot_mod_LDFLAGS): remove
+	* conf/i386-coreboot.rmk (pkglib_MODULES): add boot.mod
+	(boot_mod_SOURCES): new variable
+	(boot_mod_CFLAGS): likewise
+	(boot_mod_LDFLAGS): likewise
+	* conf/i386-efi.rmk: likewise
+	* conf/i386-ieee1275.rmk: likewise
+	* conf/i386-pc.rmk: likewise
+	* conf/powerpc-ieee1275.rmk: likewise
+	* conf/sparc64-ieee1275.rmk: likewise
+	* conf/x86_64-efi.rmk: likewise
+	* include/grub/i386/pc/biosnum.h: new file
+	* lib/i386/pc/biosnum.c: likewise
+	* loader/i386/bsd.c (grub_bsd_get_device): use grub_get_root_biosnumber
+	* loader/i386/multiboot.c (grub_multiboot_get_bootdev): likewise
+	* loader/i386/pc/chainloader.c (grub_chainloader_cmd): likewise
+
+2009-06-10  Pavel Roskin  <proski@gnu.org>
+
+	* io/gzio.c (test_header): Don't reuse one buffer for all data.
+	Use separate variables.  Read only the file size at the end, but
+	not the checksum that we don't use.
+
+	* kern/file.c (grub_file_read): Use void pointer for the buffer.
+	Adjust all callers.
+
+	* kern/ieee1275/openfw.c: Remove libc includes.
+	* kern/ieee1275/cmain.c: Likewise.
+	* include/grub/ieee1275/ieee1275.h: Likewise.
+
+	* kern/i386/coreboot/init.c: Include grub/cpu/tsc.h to fix
+	compiler warnings.
+
+2009-06-10  Felix Zielcke  <fzielcke@z-51.de>
+
+	* Makefile.in: Remove all trailing whitespace.
+	* conf/i386-pc.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	* conf/sparc64-ieee1275.rmk: Likewise.
+	* docs/grub.texi: Likewise.
+	* docs/texinfo.tex: Likewise.
+	* disk/fs_uuid.c: Likewise.
+	* disk/lvm.c: Likewise.
+	* disk/scsi.c: Likewise.
+	* disk/ata.c: Likewise.
+	* disk/ieee1275/ofdisk.c: Likewise.
+	* disk/i386/pc/biosdisk.c: Likewise.
+	* disk/host.c: Likewise.
+	* disk/raid.c: Likewise.
+	* disk/efi/efidisk.c: Likewise.
+	* disk/usbms.c: Likewise.
+	* disk/memdisk.c: Likewise.
+	* disk/loopback.c: Likewise.
+	* kern/powerpc/dl.c: Likewise.
+	* kern/device.c: Likewise.
+	* kern/dl.c: Likewise.
+	* kern/sparc64/dl.c: Likewise.
+	* kern/ieee1275/ieee1275.c: Likewise.
+	* kern/term.c: Likewise.
+	* kern/fs.c: Likewise.
+	* kern/i386/dl.c: Likewise.
+	* kern/i386/pc/startup.S: Likewise.
+	* kern/i386/pc/init.c: Likewise.
+	* kern/i386/pc/mmap.c: Likewise.
+	* kern/i386/pc/lzo1x.S: Likewise.
+	* kern/i386/ieee1275/init.c: Likewise.
+	* kern/i386/realmode.S: Likewise.
+	* kern/i386/tsc.c: Likewise.
+	* kern/partition.c: Likewise.
+	* kern/corecmd.c: Likewise.
+	* kern/file.c: Likewise.
+	* kern/efi/efi.c: Likewise.
+	* kern/efi/init.c: Likewise.
+	* kern/efi/mm.c: Likewise.
+	* kern/main.c: Likewise.
+	* kern/err.c: Likewise.
+	* kern/env.c: Likewise.
+	* kern/disk.c: Likewise.
+	* kern/generic/millisleep.c: Likewise.
+	* kern/generic/rtc_get_time_ms.c: Likewise.
+	* kern/misc.c: Likewise.
+	* kern/parser.c: Likewise.
+	* genmk.rb: Likewise.
+	* configure.ac: Likewise.
+	* boot/i386/pc/diskboot.S: Likewise.
+	* boot/i386/pc/pxeboot.S: Likewise.
+	* boot/i386/pc/boot.S: Likewise.
+	* boot/i386/pc/lnxboot.S: Likewise.
+	* boot/i386/pc/cdboot.S: Likewise.
+	* parttool/pcpart.c: Likewise.
+	* video/readers/tga.c: Likewise.
+	* video/video.c: Likewise.
+	* video/bitmap.c: Likewise.
+	* lib/envblk.c: Likewise.
+	* lib/i386/setjmp.S: Likewise.
+	* fs/xfs.c: Likewise.
+	* fs/afs.c: Likewise.
+	* fs/fat.c: Likewise.
+	* fs/ntfs.c: Likewise.
+	* fs/udf.c: Likewise.
+	* fs/affs.c: Likewise.
+	* fs/iso9660.c: Likewise.
+	* fs/hfs.c: Likewise.
+	* fs/fshelp.c: Likewise.
+	* fs/ext2.c: Likewise.
+	* fs/jfs.c: Likewise.
+	* fs/reiserfs.c: Likewise.
+	* fs/hfsplus.c: Likewise.
+	* fs/minix.c: Likewise.
+	* fs/cpio.c: Likewise.
+	* fs/sfs.c: Likewise.
+	* fs/ufs.c: Likewise.
+	* efiemu/prepare.c: Likewise.
+	* efiemu/loadcore_common.c: Likewise.
+	* efiemu/runtime/efiemu.sh: Likewise.
+	* efiemu/runtime/efiemu.S: Likewise.
+	* efiemu/runtime/efiemu.c: Likewise.
+	* efiemu/pnvram.c: Likewise.
+	* efiemu/main.c: Likewise.
+	* efiemu/i386/pc/cfgtables.c: Likewise.
+	* efiemu/i386/loadcore64.c: Likewise.
+	* efiemu/i386/loadcore32.c: Likewise.
+	* efiemu/loadcore.c: Likewise.
+	* efiemu/symbols.c: Likewise.
+	* efiemu/mm.c: Likewise.
+	* include/grub/autoefi.h: Likewise.
+	* include/grub/datetime.h: Likewise.
+	* include/grub/term.h: Likewise.
+	* include/grub/hfs.h: Likewise.
+	* include/grub/lvm.h: Likewise.
+	* include/grub/i386/tsc.h: Likewise.
+	* include/grub/i386/linux.h: Likewise.
+	* include/grub/i386/xnu.h: Likewise.
+	* include/grub/i386/efiemu.h: Likewise.
+	* include/grub/i386/pc/biosdisk.h: Likewise.
+	* include/grub/i386/pc/memory.h: Likewise.
+	* include/grub/i386/pc/vbe.h: Likewise.
+	* include/grub/parttool.h: Likewise.
+	* include/grub/video.h: Likewise.
+	* include/grub/memory.h: Likewise.
+	* include/grub/fs.h: Likewise.
+	* include/grub/partition.h: Likewise.
+	* include/grub/xnu.h: Likewise.
+	* include/grub/efi/api.h: Likewise.
+	* include/grub/efi/pe32.h: Likewise.
+	* include/grub/efi/memory.h: Likewise.
+	* include/grub/multiboot.h: Likewise.
+	* include/grub/usbdesc.h: Likewise.
+	* include/grub/multiboot2.h: Likewise.
+	* include/grub/acpi.h: Likewise.
+	* include/grub/efiemu/efiemu.h: Likewise.
+	* include/grub/disk.h: Likewise.
+	* include/grub/ieee1275/ieee1275.h: Likewise.
+	* include/grub/net.h: Likewise.
+	* include/grub/machoload.h: Likewise.
+	* include/grub/macho.h: Likewise.
+	* include/multiboot.h: Likewise.
+	* genmoddep.awk: Likewise.
+	* normal/main.c: Likewise.
+	* normal/menu_entry.c: Likewise.
+	* normal/menu_viewer.c: Likewise.
+	* normal/completion.c: Likewise.
+	* normal/cmdline.c: Likewise.
+	* normal/misc.c: Likewise.
+	* normal/datetime.c: Likewise.
+	* bus/usb/usbtrans.c: Likewise.
+	* bus/usb/ohci.c: Likewise.
+	* bus/usb/uhci.c: Likewise.
+	* bus/usb/usb.c: Likewise.
+	* mmap/efi/mmap.c: Likewise.
+	* mmap/i386/pc/mmap_helper.S: Likewise.
+	* mmap/i386/pc/mmap.c: Likewise.
+	* mmap/i386/mmap.c: Likewise.
+	* mmap/i386/uppermem.c: Likewise.
+	* mmap/mmap.c: Likewise.
+	* commands/acpi.c: Likewise.
+	* commands/echo.c: Likewise.
+	* commands/blocklist.c: Likewise.
+	* commands/loadenv.c: Likewise.
+	* commands/usbtest.c: Likewise.
+	* commands/boot.c: Likewise.
+	* commands/parttool.c: Likewise.
+	* commands/search.c: Likewise.
+	* commands/cat.c: Likewise.
+	* commands/i386/pc/play.c: Likewise.
+	* commands/i386/pc/drivemap.c: Likewise.
+	* commands/i386/pc/vbeinfo.c: Likewise.
+	* commands/i386/pc/acpi.c: Likewise.
+	* commands/i386/pc/vbetest.c: Likewise.
+	* commands/ls.c: Likewise.
+	* commands/cmp.c: Likewise.
+	* commands/test.c: Likewise.
+	* commands/efi/acpi.c: Likewise.
+	* commands/gptsync.c: Likewise.
+	* commands/help.c: Likewise.
+	* partmap/amiga.c: Likewise.
+	* partmap/apple.c: Likewise.
+	* partmap/acorn.c: Likewise.
+	* partmap/pc.c: Likewise.
+	* partmap/sun.c: Likewise.
+	* partmap/gpt.c: Likewise.
+	* script/sh/lexer.c: Likewise.
+	* script/sh/function.c: Likewise.
+	* font/font.c: Likewise.
+	* font/font_cmd.c: Likewise.
+	* loader/powerpc/ieee1275/linux.c: Likewise.
+	* loader/efi/chainloader.c: Likewise.
+	* loader/multiboot_loader.c: Likewise.
+	* loader/macho.c: Likewise.
+	* loader/i386/multiboot.c: Likewise.
+	* loader/i386/linux.c: Likewise.
+	* loader/i386/pc/linux.c: Likewise.
+	* loader/i386/pc/multiboot2.c: Likewise.
+	* loader/i386/pc/chainloader.c: Likewise.
+	* loader/i386/pc/xnu.c: Likewise.
+	* loader/i386/bsd_trampoline.S: Likewise.
+	* loader/i386/efi/linux.c: Likewise.
+	* loader/i386/multiboot_elfxx.c: Likewise.
+	* loader/i386/bsd_helper.S: Likewise.
+	* loader/i386/bsd.c: Likewise.
+	* loader/i386/linux_trampoline.S: Likewise.
+	* loader/i386/xnu_helper.S: Likewise.
+	* loader/i386/xnu.c: Likewise.
+	* loader/i386/bsd_pagetable.c: Likewise.
+	* loader/i386/multiboot_helper.S: Likewise.
+	* loader/xnu.c: Likewise.
+	* loader/xnu_resume.c: Likewise.
+	* io/gzio.c: Likewise.
+	* term/efi/console.c: Likewise.
+	* term/terminfo.c: Likewise.
+	* term/ieee1275/ofconsole.c: Likewise.
+	* term/i386/pc/serial.c: Likewise.
+	* term/i386/pc/vesafb.c: Likewise.
+	* term/i386/pc/vga.c: Likewise.
+	* term/usb_keyboard.c: Likewise.
+	* term/gfxterm.c: Likewise.
+	* aclocal.m4: Likewise.
+	* util/lvm.c: Likewise.
+	* util/grub.d/30_os-prober.in: Likewise.
+	* util/grub.d/10_hurd.in: Likewise.
+	* util/console.c: Likewise.
+	* util/grub-macho2img.c: Likewise.
+	* util/grub-probe.c: Likewise.
+	* util/hostfs.c: Likewise.
+	* util/i386/pc/grub-mkimage.c: Likewise.
+	* util/i386/pc/grub-setup.c: Likewise.
+	* util/i386/efi/grub-mkimage.c: Likewise.
+	* util/grub-mkconfig.in: Likewise.
+	* util/raid.c: Likewise.
+	* util/resolve.c: Likewise.
+	* util/grub-mkdevicemap.c: Likewise.
+	* util/grub-emu.c: Likewise.
+	* util/getroot.c: Likewise.
+	* util/hostdisk.c: Likewise.
+	* util/usb.c: Likewise.
+	* util/grub-editenv.c: Likewise.
+	* util/misc.c: Likewise.
+
+2009-06-10  Felix Zielcke  <fzielcke@z-51.de>
+
+	* gendistlist.sh (EXTRA_DISTFILES): Add `genhandlerlist.sh' and
+	`genparttoollist.sh'.
+	(DISTDIRS): Add `efiemu', `mmap', `parttool' and `script'.
+	Add `*.sh' to the list find searches for and change `mdate.sh'
+	to `mdate-sh'.
+
+2009-06-10  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/multiboot2.h: Provide compatibility defines for
+	multiboot2.h.
+	* include/multiboot2.h: Include stdint.h only if needed, using
+	angle brackets.
+	* loader/i386/pc/multiboot2.c: Include multiboot2.h after
+	grub/multiboot2.h.
+	* loader/ieee1275/multiboot2.c: Likewise.
+	* loader/multiboot2.c: Likewise.
+	* loader/multiboot_loader.c: Likewise.
+
+	* configure.ac: Use -nostdlib when probing for the target.  It
+	should not be required to have libc for the target.
+
+	* configure.ac: Remove checks for __bswapsi2 and __bswapdi2,
+	they fail without libc headers for the target.
+	* include/grub/powerpc/libgcc.h: Use weak attribute for all
+	exports.
+	* include/grub/sparc64/libgcc.h: Likewise.  Don't use
+	preprocessor conditionals.
+
+	* conf/common.rmk: Compile tar.mod from tar.c, not cpio.c.  The
+	build system doesn't need to be aware of the tar.c internals.
+
+2009-06-09  Michel Hermier  <michel.hermier@gmail.com>
+
+	* fs/i386/pc/pxe.c (grub_pxefs_read): Fix returned values.
+
+2009-06-09  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/deviceiter.c (grub_util_iterate_devices): Increase number of
+	disk limit to 26 for IDE, Virtio, Xen and SCSI.
+
+2009-06-09  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/i386/pc/grub-install.in: Change the error message if UUIDs
+	aren't available if ata.mod gets used.
+
+2009-06-09  Oliver Henshaw  <oliver.henshaw@gmail.com>
+
+	* bus/usb/ohci.c (grub_ohci_pci_iter): Link struct only after
+	initialising controller.
+	* bus/usb/uhci.c (grub_uhci_pci_iter): Likewise.
+
+2009-06-08  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/i386/pc/grub-install.in: Add a parameter --disk-module
+	to choose between ata and biosdisk module on i386-pc.
+
+2009-06-08  Oliver Henshaw  <oliver.henshaw@gmail.com>
+
+	* bus/usb/ohci.c (grub_ohci_pci_iter): Define the Class,
+	Subclass and Programming Interface fields in terms of the 3 byte
+	Class Code register.
+	* bus/usb/uhci.c (grub_uhci_pci_iter): Likewise.
+
+	* bus/usb/ohci.c (grub_ohci_pci_iter): Check that programming
+	interface is OHCI.  Add grub_dprintf for symmetry with
+	bus/usb/uhci.c.
+	* bus/usb/uhci.c (grub_uhci_pci_iter): Check that programming
+	interface is UHCI.  Add interf variable for programming
+	interface.  Print interface with class/subclass.
+
+	* bus/usb/ohci.c: Set interf with correct field.
+
+	* bus/usb/uhci.c: Remove unneeded doubled lines.
+	* bus/usb/ohci.c: Likewise. Change interf to grub_uint32_t.
+	Remove whitespace inside comment.
+
+2009-06-08  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* loader/i386/linux.c (grub_cmd_linux): When processing `vga=', use
+	as fallback an equivalent option without depth.
+
+2009-06-08  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Not fail if unable to retrieve C/H/S on LBA disks
+
+	* disk/i386/pc/biosdisk.c (grub_biosdisk_open): behave gracefully
+	if unable to retrieve C/H/S on LBA disks
+
+2009-06-08  Pavel Roskin  <proski@gnu.org>
+
+	* fs/hfs.c (grub_hfs_find_dir): Use union to avoid a warning
+	about aliasing.
+
+2009-06-08  Felix Zielcke  <fzielcke@z-51.de>
+
+	* Makefile.in (uninstall): Remove all $lib_DATA files.
+
+2009-06-08  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Bugfix: install on partitionless device
+
+	* util/hostdisk.c (grub_util_biosdisk_get_grub_dev): check if os_dev
+	is a whole disk
+
+2009-06-08  Felix Zielcke  <fzielcke@z-51.de>
+
+	* Makefile.in (uninstall): Remove all $include_DATA files.
+
+2009-06-08  Felix Zielcke  <fzielcke@z-51.de>
+
+	* commands/true.c: New file.  Implement the true and false commands.
+	* conf/common.rmk.c (pkglib_MODULES): Add `true.mod'.
+	(true_mod_SOURCES): New variable.
+	(true_mod_CFLAGS): Likewise.
+	(true_mod_LDFLAGS): Likewise.
+
+2009-06-05  Colin D Bennett  <colin@gibibit.com>
+
+	Optimized font character lookup using binary search instead of linear
+	search.  Fonts now are required to have the character index ordered by
+	code point.
+
+	* font/font.c (load_font_index): Verify that fonts have ordered
+	character indices.
+	(find_glyph): Use binary search instead of linear search to find a
+	character in a font.
+
+2009-06-05  Michael Scherer  <misc@mandriva.org>
+
+	* fs/hfsplus.c (grub_hfsplus_mount): Determine if the filesystem
+	uses case sensitive btree.
+	(grub_hfsplus_iterate_dir): Use GRUB_FSHELP_CASE_INSENSITIVE
+	only for case insensitive filesystems.
+
+2009-06-05  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* conf/i386-pc.rmk (efiemu_mod_CFLAGS): remove -Werror -Wall
+	* conf/common.rmk (search_mod_CFLAGS): likewise
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* kern/i386/pc/startup.S [APPLE_CC]: block of nops to
+	compensate a compiler bug
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* include/grub/term.h (GRUB_TERM_BACKSPACE): explicitly define as 8
+	instead of '\b'
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Definitions for creating asm symbols with Apple's CC
+
+	* include/grub/symbol.h [APPLE_CC] (FUNCTION): new macro
+	[APPLE_CC] (VARIABLE): likewise
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Disable lnxboot.img when compiled
+	with Apple's CC
+
+	* conf/i386-pc.rmk (pkglib_IMAGES): remove lnxboot.img
+	pkglib_IMAGES [! TARGET_APPLE_CC] (pkglib_IMAGES): add lnxboot.img
+	* boot/i386/pc/lnxboot.S [APPLE_CC]: define an #error
+	[! APPLE_CC] (CODE_LENG): skip
+	[! APPLE_CC] (setup_sects): likewise
+	[! APPLE_CC]: skip filling
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Address in trampolines based on 32-bit registers when compiled
+	with Apple's CC
+
+	* loader/i386/xnu_helper.S [APPLE_CC]: use 32-bit registers
+	for addresses
+	* loader/i386/linux_trampoline.S [APPLE_CC]: likewise
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Avoid aliases when compiling with Apple's CC for PCBIOS machine
+
+	* kern/misc.c [APPLE_CC] (memcpy): new function
+	[APPLE_CC] (memmove): likewise
+	[APPLE_CC && !GRUB_UTIL] (grub_err_printf): likewise
+	(memcpy): define alias conditionally on !APPLE_CC
+	(memset): likewise
+	(abort): likewise
+	* include/grub/misc.h (memove): don't define when both GRUB_UTIL and
+	APPLE_CC are defined
+	* include/grub/list.h [APPLE_CC] (grub_assert_fail): new function
+	(grub_assert_fail): make prototype conditional
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Use grub-macho2img when compiling with Apple's CC for PCBIOS machine
+
+	* conf/common.rmk (bin_UTILITIES): add (on false on condition)
+	grub-macho2img
+	(CLEANFILES): add grub-macho2img
+	(grub_macho2img_SOURCES): new variable
+	* kern/i386/pc/startup.S (bss_start): new variable
+	(bss_end): likewise
+	* genmk.rb: use grub-macho2img for *.img when compiled with Apple's CC
+	* util/grub-macho2img.c: new file
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Use objconv when compiling with Apple's CC
+
+	* conf/i386-pc.rmk (efiemu32.o): use OBJCONV if defined
+	(efiemu64.o): likewise
+	(efiemu64_c.o): omit -mcmodel=large and add -DAPPLE_CC=1
+	when compiling with Apple's CC
+	(efiemu64_s.o): likewise
+	* configure.ac: check for objconv when compiling with Apple's CC
+	* genmk.rb: use objconv for modules when compiled with Apple's CC
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Define segment as well as section when compiling with
+	Apple's CC
+
+	* efiemu/runtime/efiemu.c (PHYSICAL_ATTRIBUTE): new definition
+	(efiemu_set_virtual_address_map): declare with PHYSICAL_ATTRIBUTE
+	(efiemu_convert_pointer): likewise
+	(efiemu_set_virtual_address_map): likewise
+	(efiemu_convert_pointer): likewise
+	(efiemu_getcrc32): likewise
+	(init_crc32_table): likewise
+	(reflect): likewise
+	* include/grub/dl.h (GRUB_MOD_NAME): define segment with Apple's CC
+	(GRUB_MOD_DEP): likewise
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Allow a compilation without -mcmodel=large
+
+	* kern/efi/mm.c (grub_efi_allocate_pages): don't allocate >4GiB
+	when compiled without -mcmodel=large
+	(filter_memory_map): remove memory post 4 GiB when compiled
+	without -mcmodel=large
+	* configure.ac: fail gracefully and add -DMCMODEL_SMALL=1 to
+	TARGET_CFLAGS when -mcmodel=large isn't supported
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Remove nested functions in efiemu core
+
+	* efiemu/runtime/efiemu.c (reflect): make static instead of nested
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Avoid clobbering %ebx/%rbx in inline assembly with Apple's CC
+
+	* efiemu/runtime/efiemu.c (write_cmos): use %cl instead of %bl as
+	temporary storage
+	* include/grub/i386/tsc.h (grub_get_tsc): restore %rbx/%ebx when
+	using Apple's CC
+	(grub_cpu_is_tsc_supported): likewise
+	* loader/i386/xnu.c (guessfsb): restore %rbx/%ebx in inline assembly
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Absolute addressing through constant with Apple's cc
+
+	* kern/i386/pc/startup.S: Define necessary constants
+	and address through it when using ABS with Apple's CC
+	* boot/i386/pc/diskboot.S: likewise
+	* boot/i386/pc/boot.S: likewise
+	* boot/i386/pc/lnxboot.S: likewise
+	* boot/i386/pc/cdboot.S: likewise
+	* mmap/i386/pc/mmap_helper.S: likewise
+	* commands/i386/pc/drivemap_int13h.S: likewise
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Check if compiler is apple cc
+
+	* Makefile.in (ASFLAGS): new variable
+	(TARGET_ASFLAGS): likewise
+	(TARGET_MODULE_FORMAT): likewise
+	(TARGET_APPLE_CC): likewise
+	(OBJCONV): likewise
+	(TARGET_IMG_CFLAGS): likewise
+	(TARGET_CPPFLAGS): add includedir
+	* configure.ac: call grub_apple_cc and grub_apple_target_cc
+	(TARGET_IMG_LDFLAGS): Add -Wl,-Ttext,. All users updated
+	Check for linker script only if compiler isn't Apple's CC
+	(TARGET_MODULE_FORMAT): set
+	(TARGET_APPLE_CC): likewise
+	(TARGET_ASFLAGS): likewise
+	(ASFLAGS): likewise
+	Check for objcopy only if compiler isn't Apple's CC
+	Check for BSS symbol only if compiler isn't Apple's CC
+	* genmk.rb: adapt nm options if we use Apple's utils
+	* aclocal.m4 (grub_apple_cc): new test
+	(grub_apple_target_cc): likewise
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Simplify sed expressions and improve awk
+
+	* Makefile.in (install-local): simplify sed expression
+	* gencmdlist.sh: likewise
+	* genmoddep.awk: avoid adding module as a dependency of itself
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Add missing start symbols
+
+	* boot/i386/pc/boot.S: add start
+	* boot/i386/pc/pxeboot.S: likewise
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fix wrong assumptions with grub-mkimage on EFI
+
+	* i386/efi/grub-mkimage.c (read_kernel_module): don't write prefix here
+	(relocate_addresses): consider both r_addend and value at offset
+	(make_mods_section): zerofill modinfo and header
+	(convert_elf): write prefix here
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Use .asciz instead of .string
+
+	* i386/pc/diskboot.S: use .asciz instead of .string
+	* i386/pc/boot.S: likewise
+	* include/grub/dl.h (GRUB_MOD_DEP): likewise
+	(GRUB_MOD_NAME): likewise
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	gfxpayload support
+
+	* commands/videotest.c (grub_cmd_videotest): use grub_video_set_mode
+	* include/grub/video.h (GRUB_VIDEO_MODE_TYPE_PURE_TEXT): new definition
+	(grub_video_setup): remove
+	(grub_video_set_mode): new prototype
+	* loader/i386/linux.c (DEFAULT_VIDEO_MODE): new definition
+	(vid_mode): remove
+	(linux_vesafb_res): compile only on PCBIOS
+	(grub_linux_boot): support gfxpayload
+	* loader/i386/pc/xnu.c (video_hook): new function
+	(grub_xnu_set_video): support gfxpayload
+	* term/gfxterm.c (DEFAULT_VIDEO_WIDTH): removed
+	(DEFAULT_VIDEO_HEIGHT): likewise
+	(DEFAULT_VIDEO_FLAGS): likewise
+	(DEFAULT_VIDEO_MODE): new definition
+	(video_hook): new function
+	(grub_gfxterm_init): use grub_video_set_mode
+	* util/grub.d/30_os-prober.in: remove explicit modesetting before
+	loading xnu
+	* video/video.c (grub_video_setup): removed
+	(grub_video_set_mode): new function based on grub_gfxterm_init and
+	grub_video_setup
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Avoid calling biosdisk in drivemap
+
+	* commands/i386/pc/drivemap.c (parse_biosdisk): remove
+	(revparse_biosdisk): likewise
+	(list_mappings): derive name from id directly
+	(grub_cmd_drivemap): use tryparse_diskstring
+
+2009-06-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Script fixes
+
+	* include/grub/script_sh.h (grub_script_cmdline): remove cmdline
+	(grub_lexer_param): add tokenonhold
+	(grub_script_create_cmdline): remove cmdline. All callers updated
+	(grub_script_function_create): make functionname
+	grub_script_arg. All callers updated
+	(grub_script_execute_argument_to_string): new prototype
+	* kern/parser.c (state_transitions): reorder
+	(grub_parser_cmdline_state): fix a bug and make more compact
+	* script/sh/execute.c (grub_script_execute_argument_to_string):
+	make global
+	(grub_script_execute_cmdline): use new format
+	* script/sh/function.c (grub_script_function_create): make functionname
+	grub_script_arg. All callers updated
+	* script/sh/lexer.c (grub_script_lexer_init): initialize tokenonhold
+	(grub_script_yylex): remove
+	(grub_script_yylex2): renamed to ...
+	(grub_script_yylex): ...renamed
+	parse the expressions like a${b}c
+	* script/sh/parser.y (GRUB_PARSER_TOKEN_ARG): new typed terminal
+	(GRUB_PARSER_TOKEN_VAR): remove
+	(GRUB_PARSER_TOKEN_NAME): likewise
+	("if"): declare as typeless
+	("while"): likewise
+	("function"): likewise
+	("else"): likewise
+	("then"): likewise
+	("fi"): likewise
+	(text): remove
+	(argument): likewise
+	(script): accept empty scripts and make exit on error
+	(arguments): use GRUB_PARSER_TOKEN_ARG
+	(function): likewise
+	(command): move error handling to script
+	(menuentry): move grub_script_lexer_ref before
+	* script/sh/script.c (grub_script_create_cmdline): remove cmdline
+	argument. All callers updated
+
+2009-06-04  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Prevent GRUB from probing floppies during boot.
+
+	* conf/common.rmk (search_mod_CFLAGS): Use `-Werror -Wall'.
+	* commands/search.c (options): Add --no-floppy.
+	(search_fs, search_file, grub_cmd_search): Support --no-floppy.
+	* util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Use
+	--no-floppy when searching for UUIDs.
+
+2009-06-04  Robert Millan  <rmh.grub@aybabtu.com>
+
+	Simplify the code duplication in commands/search.c.
+
+	* commands/search.c (search_label, search_fs_uuid): Merge into ...
+	(search_fs): ... this.  Update all users.
+
+2009-06-03  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub-mkconfig.in (update_grub_dir): Rename to grub_mkconfig_dir.
+
+2009-05-28  Pavel Roskin  <proski@gnu.org>
+
+	* Makefile.in: Don't use "cp -d", it doesn't work on FreeBSD.
+	Remove the original symlink explicitly.
+
+	* fs/hfs.c (grub_hfs_find_dir): Skip sequences of slashes, not
+	just one slash.  That's how grub_fshelp_find_file() does it.
+
+2009-05-26  Pavel Roskin  <proski@gnu.org>
+
+	* genmk.rb: Avoid shadowing variable `s', rename the outer `s'
+	to `str'.
+
+	* util/getroot.c (grub_util_get_dev_abstraction): Mark os_dev as
+	possibly unused.
+
+2009-05-25  Christian Franke  <franke@computer.org>
+
+	* disk/ata.c (grub_ata_wait_not_busy): Add debug output of status
+	register.
+	(grub_atapi_identify): Add wait after drive select.
+	(grub_ata_identify): Do more strict status register check before
+	calling grub_atapi_identify ().  Suppress error message if status
+	register is 0x00 after command failure.  Add status register
+	check after PIO read to avoid bogus identify due to stuck DRQ.
+	Thanks to Pavel Roskin for testing.
+	(grub_device_initialize): Remove unsafe status register check.
+	Thanks to 'phcoder' for problem report and patch.
+	Prevent sign extension in debug message.
+
+2009-05-23  Colin D Bennett  <colin@gibibit.com>
+
+	Cleaned up `include/grub/normal.h'.  Grouped prototypes by
+	definition file, and functions defined in `normal/menu.c' have had
+	their prototypes moved to `include/grub/menu.h' for consistency.
+
+	* include/grub/menu.h (grub_menu_execute_callback): Added; moved
+	from normal.h.
+	(grub_menu_get_entry): Likewise.
+	(grub_menu_get_timeout): Likewise.
+	(grub_menu_set_timeout): Likewise.
+	(grub_menu_execute_entry): Likewise.
+	(grub_menu_execute_with_fallback): Likewise.
+	(grub_menu_entry_run): Likewise.
+
+	* include/grub/normal.h: Re-ordered and grouped function
+	prototypes by file that the function is defined in.
+	(grub_menu_execute_callback): Removed; moved to menu.h.
+	(grub_menu_get_entry): Likewise.
+	(grub_menu_get_timeout): Likewise.
+	(grub_menu_set_timeout): Likewise.
+	(grub_menu_execute_entry): Likewise.
+	(grub_menu_execute_with_fallback): Likewise.
+	(grub_menu_entry_run): Likewise.
+	(grub_menu_addentry): Renamed from this ...
+	(grub_normal_add_menu_entry): ... to this.
+
+	* normal/main.c (grub_menu_addentry): Renamed from this ...
+	(grub_normal_add_menu_entry): ... to this.
+
+	* script/sh/execute.c (grub_script_execute_menuentry): Update
+	reference to renamed grub_menu_addentry function.
+
+2009-05-23  Felix Zielcke  <fzielcke@z-51.de>
+
+	* commands/i386/pc/drivemap.c (MODNAME): Remove. Update all users.
+
+2009-05-22  Pavel Roskin  <proski@gnu.org>
+
+	* aclocal.m4 (grub_I386_CHECK_REGPARM_BUG): Remove.
+	* configure.ac: Don't call grub_I386_CHECK_REGPARM_BUG.  Define
+	NESTED_FUNC_ATTR using AH_BOTTOM.  Use regparm(1) only when
+	compiling for the i386 targets, but not for the utilities.
+
+	* include/grub/i386/pc/kernel.h (grub_boot_drive): Change type
+	to grub_uint8_t.
+	(grub_root_drive): Likewise.
+	* kern/i386/pc/startup.S (grub_boot_drive): Change size to byte,
+	remove alignment.
+	(grub_root_drive): Change size to byte.
+	(grub_start_addr): Remove.
+	(grub_end_addr): Likewise.
+	(grub_apm_bios_info): Likewise.
+
+2009-05-21  Felix Zielcke  <fzielcke@z-51.de>
+
+	* normal/i386: Remove.
+	* normal/powerpc: Likewise.
+	* normal/sparc64: Likewise.
+	* normal/x86_64: Likewise.
+
+2009-05-19  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* conf/x86_64-efi.rmk (linux_mod_ASFLAGS): Add missing variable
+	* loader/i386/linux_trampoline.S: Fix indentation
+	* loader/i386/xnu_helper.S: Likewise
+
+2009-05-18  Colin D Bennett  <colin@gibibit.com>
+
+	Display error messages when parsing a Lua statement fails.
+	Previously, executing a syntactically invalid statement like
+	")foo" or "bar;" would silently fail.
+
+	* script/lua/grub_main.c (handle_lua_error): New function.
+	(grub_lua_parse_line): Improved reporting of Lua parser and
+	execution errors.
+
+2009-05-17  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Remove -Werror which causes build to fail on some systems
+
+	* conf/i386-pc.rmk (xnu_mod_CFLAGS): Remove -Werror -Wall
+	* conf/i386-efi.rmk (xnu_mod_CFLAGS): Likewise
+	* conf/x86_64-efi.rmk (xnu_mod_CFLAGS): Likewise
+
+2009-05-17  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	trampoline for linux on 64-bit platform
+
+	* conf/x86_64-efi.rmk (linux_mod_SOURCES): added
+	loader/i386/efi/linux_trampoline.S
+	* include/grub/x86_64/efi/loader.h (grub_linux_real_boot): removed
+	declaration
+	* kern/x86_64/efi/startup.S (grub_linux_real_boot): moved from
+	here
+	* loader/i386/linux_trampoline.S: moved here
+	* loader/i386/efi/linux.c (allocate_pages): reserve space for
+	trampoline
+	(jumpvector): removed
+	(grub_linux_trampoline_start): new declaration
+	(grub_linux_trampoline_end): likewise
+	(grub_linux_boot): use trampoline when on 64-bit platform
+	* loader/i386/linux.c: likewise
+
+2009-05-16  Pavel Roskin  <proski@gnu.org>
+
+	* script/lua/grub_lib.c (grub_lua_getenv): Make name and value
+	const to avoid a warning.
+	(grub_lua_setenv): Likewise.
+	* script/lua/grub_main.c (grub_lua_parse_line): Use size_t for
+	lmsg to fix a warning.
+
+2009-05-16  Felix Zielcke  <fzielcke@z-51.de>
+
+	* conf/i386.rmk (setjmp_mod_CFLAGS): Rename to ...
+	(setjmp_mod_ASFLAGS): ... this. Set to $(COMMON_ASFLAGS).
+	* conf/x86_64-efi.rmk (setjmp_mod_CFLAGS): Rename to ...
+	(setjmp_mod_ASFLAGS): ... this. Set to $(COMMON_ASFLAGS).
+	* conf/powerpc-ieee1275.rmk (setjmp_mod_CFLAGS): Rename to ...
+	(setjmp_mod_ASFLAGS): ... this. Set to $(COMMON_ASFLAGS).
+	* conf/sparc64-ieee1275.rmk (setjmp_mod_CFLAGS): Rename to ...
+	(setjmp_mod_ASFLAGS): ... this. Set to $(COMMON_ASFLAGS).
+
+2009-05-16  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub-mkconfig.in: Export GRUB_TERMINAL_INPUT.
+
+2009-05-16  Bean  <bean123ch@gmail.com>
+
+	* conf/common.rmk (pkglib_MODULES): Add lua.mod.
+	(lua_mod_SOURCES): New variable.
+	(lua_mod_CFLAGS): Likewise.
+	(lua_mod_LDFLAGS): Likewise.
+
+	* conf/i386.rmk (pkglib_MODULES): Add setjmp.mod.
+	(setjmp_mod_SOURCES): New variable.
+	(setjmp_mod_CFLAGS): Likewise.
+	(setjmp_LDFLAGS): Likewise.
+
+	* conf/x86_64-efi.rmk (pkglib_MODULES): Add setjmp.mod.
+	(setjmp_mod_SOURCES): New variable.
+	(setjmp_mod_CFLAGS): Likewise.
+	(setjmp_LDFLAGS): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (pkglib_MODULES): Add setjmp.mod.
+	(setjmp_mod_SOURCES): New variable.
+	(setjmp_mod_CFLAGS): Likewise.
+	(setjmp_LDFLAGS): Likewise.
+
+	* conf/sparc64-ieee1275.rmk (pkglib_MODULES): Add setjmp.mod.
+	(setjmp_mod_SOURCES): New variable.
+	(setjmp_mod_CFLAGS): Likewise.
+	(setjmp_LDFLAGS): Likewise.
+
+	* normal/i386/setjmp.S: Moved from here ...
+	* lib/i386/setjmp.S: ... Moved here
+	* normal/x86_64/setjmp.S: Moved from here ...
+	* lib/x86_64/setjmp.S: ... Moved here
+	* normal/powerpc/setjmp.S: Moved from here ...
+	* lib/powerpc/setjmp.S: ... Moved here
+	* normal/sparc64/setjmp.S: Moved from here ...
+	* lib/sparc64/setjmp.S: ... Moved here
+
+	* include/grub/i386/setjmp.h (grub_setjmp): Don't use attribute
+	returns_twice in mingw.
+
+	* script/lua/grub_lib.c: New file.
+	* script/lua/grub_lib.h: Likewise.
+	* script/lua/grub_lua.h: Likewise.
+	* script/lua/grub_main.c: Likewise.
+	* script/lua/lapi.c: Likewise.
+	* script/lua/lapi.h: Likewise.
+	* script/lua/lauxlib.c: Likewise.
+	* script/lua/lauxlib.h: Likewise.
+	* script/lua/lbaselib.c: Likewise.
+	* script/lua/lcode.c: Likewise.
+	* script/lua/lcode.h: Likewise.
+	* script/lua/ldblib.c: Likewise.
+	* script/lua/ldebug.c: Likewise.
+	* script/lua/ldebug.h: Likewise.
+	* script/lua/ldo.c: Likewise.
+	* script/lua/ldo.h: Likewise.
+	* script/lua/ldump.c: Likewise.
+	* script/lua/lfunc.c: Likewise.
+	* script/lua/lfunc.h: Likewise.
+	* script/lua/lgc.c: Likewise.
+	* script/lua/lgc.h: Likewise.
+	* script/lua/linit.c: Likewise.
+	* script/lua/liolib.c: Likewise.
+	* script/lua/llex.c: Likewise.
+	* script/lua/llex.h: Likewise.
+	* script/lua/llimits.h: Likewise.
+	* script/lua/lmathlib.c: Likewise.
+	* script/lua/lmem.c: Likewise.
+	* script/lua/lmem.h: Likewise.
+	* script/lua/loadlib.c: Likewise.
+	* script/lua/lobject.c: Likewise.
+	* script/lua/lobject.h: Likewise.
+	* script/lua/lopcodes.c: Likewise.
+	* script/lua/lopcodes.h: Likewise.
+	* script/lua/loslib.c: Likewise.
+	* script/lua/lparser.c: Likewise.
+	* script/lua/lparser.h: Likewise.
+	* script/lua/lstate.c: Likewise.
+	* script/lua/lstate.h: Likewise.
+	* script/lua/lstring.c: Likewise.
+	* script/lua/lstring.h: Likewise.
+	* script/lua/lstrlib.c: Likewise.
+	* script/lua/ltable.c: Likewise.
+	* script/lua/ltable.h: Likewise.
+	* script/lua/ltablib.c: Likewise.
+	* script/lua/ltm.c: Likewise.
+	* script/lua/ltm.h: Likewise.
+	* script/lua/lua.h: Likewise.
+	* script/lua/luaconf.h: Likewise.
+	* script/lua/lualib.h: Likewise.
+	* script/lua/lundump.c: Likewise.
+	* script/lua/lundump.h: Likewise.
+	* script/lua/lvm.c: Likewise.
+	* script/lua/lvm.h: Likewise.
+	* script/lua/lzio.c: Likewise.
+	* script/lua/lzio.h: Likewise.
+
+2009-05-16  Bean  <bean123ch@gmail.com>
+
+	* include/grub/kernel.h (grub_module_header_types): Add type
+	OBJ_TYPE_CONFIG.
+
+	* kern/main.c (grub_load_config): New function.
+	(grub_main): Call grub_load_config to read boot config.
+
+	* grub-mkimage (generate_image): New parameter config_path.
+	(options): New option --config.
+	(main): Parse --config option, and pass it to generate_image.
+
+2009-05-14  Christian Franke  <franke@computer.org>
+
+	* commands/i386/pc/drivemap_int13h.S: Add missing EXT_C for symbols.
+	This fixes build on Cygwin.
+
+2009-05-14  Pavel Roskin  <proski@gnu.org>
+
+	* commands/i386/pc/drivemap_int13h.S: Eliminate unconditional
+	jump.  This saves two bytes, so the typical case of 2 swapped
+	drives would fit 32 bytes.
+
+2009-05-13  Pavel Roskin  <proski@gnu.org>
+
+	* loader/i386/multiboot.c (grub_multiboot): Cast mmap_addr to
+	grub_uint32_t to avoid a warning.
+
+	* loader/i386/linux.c (allocate_pages): When assigning
+	real_mode_mem, cast through grub_size_t to fix a warning.  The
+	code already makes sure that the value would fit a pointer.
+	(grub_linux_setup_video): Cast render_target->data to
+	grub_size_t to fix a warning.
+
+2009-05-13  Javier Martín  <lordhabbit@gmail.com>
+
+	* commands/i386/pc/drivemap.c: New file - implement drivemap
+	command.
+	* commands/i386/pc/drivemap_int13h.S: New file - int13 handler.
+	* conf/i386-pc.rmk: Add drivemap.c and drivemap_int13h.S.
+
+2009-05-13  Pavel Roskin  <proski@gnu.org>
+
+	* util/i386/pc/grub-setup.c (setup): Remove unused variable
+	embedding_area_exists.
+
+2009-05-13  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/i386/pc/grub-setup.c (setup): Restructure code flow to make
+	it easier to understand / work with.
+	Improve warning messages for cases where there's no embedding area,
+	or when it is too small (or core.img too large).
+
+2009-05-13  Pavel Roskin  <proski@gnu.org>
+
+	* loader/i386/pc/multiboot2.c: Add necessary includes for
+	grub_multiboot2_real_boot().
+
+	* fs/iso9660.c (grub_iso9660_iterate_dir): The file mode in the
+	PX record is always little-endian.  We only need the lower 2
+	bytes of the mode.
+
+	* fs/cpio.c: Use the same name "struct head" for tar and cpio to
+	facilitate code reuse.
+	(grub_cpio_mount): Use "struct head", not a char buffer.  This
+	fixes a warning reported by gcc 4.4.
+
+	* kernel/disk.c (grub_disk_read): Use void pointer for the
+	buffer.
+	(grub_disk_write): Use const void pointer for the buffer.
+	Adjust all callers.  Remove unnecessary casts.
+
+2009-05-10  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/i386/pc/grub-install.in: Update copyright year.
+
+2009-05-09  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	gptsync
+
+	* commands/gptsync.c: new file
+	* conf/common.rmk (pkglib_MODULES): add gptsync.mod
+	(gptsync_mod_SOURCES): new variable
+	(gptsync_mod_CFLAGS): likewise
+	(gptsync_mod_LDFLAGS): likewise
+	* include/grub/pc_partition.h (GRUB_PC_PARTITION_TYPE_NTFS):
+	new definition
+	(GRUB_PC_PARTITION_TYPE_HFS): likewise
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): add commands/gptsync.c
+	* conf/i386-ieee1275.rmk: likewise
+	* conf/i386-pc.rmk: likewise
+	* conf/powerpc-ieee1275.rmk: likewise
+
+2009-05-09  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Fixed grub-emu
+
+	* kern/dl.c (grub_dl_ref): omit when compiling grub-emu
+	(grub_dl_ref): likewise
+
+2009-05-08  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/i386/pc/grub-setup.c (setup): Factorize find_usable_region(),
+	split in two functions (one for msdos and one for gpt).
+
+2009-05-08  Pavel Roskin  <proski@gnu.org>
+
+	* disk/raid.c (grub_raid_block_xor): Make buf2 constant, it's
+	not modified.
+
+	* disk/raid6_recover.c (grub_raid6_recover): Fix warnings about
+	uninitialized err[0] and err[1].  Rename them to bad1 and bad2.
+	Initialize them with -1.  Add sanity check for bad1.  Eliminate
+	nerr variable.
+
+2009-05-08  David S. Miller  <davem@davemloft.net>
+
+	* util/sparc64/ieee1275/grub-ofpathname.c (main): Set progname.
+
+2009-05-06  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/i386/pc/grub-setup.c (setup): Fix check for embed region
+	existence.
+
+2009-05-05  Felix Zielcke  <fzielcke@z-51.de>
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add
+	`kern/rescue_reader.c', `kern/rescue_parser.c' and `normal/autofs.c'.
+
+2009-05-05  David S. Miller  <davem@davemloft.net>
+
+	* util/sparc64/ieee1275/grub-install.in: Fix sed arg quoting.
+
+2009-05-05  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/dl.h [GRUB_UTIL]: Provide inline implementations
+	of grub_dl_ref() and grub_dl_unref().
+	* commands/parttool.c: Remove preprocessor conditionals around
+	grub_dl_ref() and grub_dl_unref().
+	* fs/affs.c: Likewise.
+	* fs/afs.c: Likewise.
+	* fs/cpio.c: Likewise.
+	* fs/ext2.c: Likewise.
+	* fs/fat.c: Likewise.
+	* fs/hfs.c: Likewise.
+	* fs/hfsplus.c: Likewise.
+	* fs/iso9660.c: Likewise.
+	* fs/jfs.c: Likewise.
+	* fs/minix.c: Likewise.
+	* fs/ntfs.c: Likewise.
+	* fs/reiserfs.c: Likewise.
+	* fs/sfs.c: Likewise.
+	* fs/udf.c: Likewise.
+	* fs/ufs.c: Likewise.
+	* fs/xfs.c: Likewise.
+	* include/grub/dl.h: Likewise.
+	* loader/xnu.c: Likewise.
+
+2009-05-04  Pavel Roskin  <proski@gnu.org>
+
+	* commands/acpi.c: Remove unused variable my_mod.
+	* partmap/amiga.c: Likewise.
+	* partmap/apple.c: Likewise.
+	* partmap/gpt.c: Likewise.
+	* partmap/pc.c: Likewise.
+	* partmap/sun.c: Likewise.
+	* term/gfxterm.c: Likewise.
+	* term/i386/pc/vesafb.c: Likewise.
+	* term/i386/pc/vga.c: Likewise.
+
+2009-05-04  David S. Miller  <davem@davemloft.net>
+
+	* kern/ieee1275/openfw.c (grub_children_iterate): Fix string
+	pointer args to grub_ieee1275_get_property().
+
+	* conf/sparc64-ieee1275.rmk: Fix build due to missing '\'.
+
+	* disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Bypass cdrom
+	devices, and do not traverse down under controller nodes.
+
+	* disk/ieee1275/ofdisk.c (compute_dev_path): New.
+	(grub_ofdisk_open): Use it to un-escape "," characters.
+	* kern/disk.c (find_part_sep): New.
+	(grub_disk_open): Use it to find the first non-escaped ','
+	character in the disk name.
+	* util/ieee1275/devicemap.c (escape_of_path): New.
+	(grub_util_emit_devicemap_entry): Use it.
+	* util/sparc64/ieee1275/grub-install.in: Update script to
+	strip partition specifiers properly by not triggering on
+	'\' escaped ',' characters.
+
+2009-05-04  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* include/grub/i386/linux.h (GRUB_LINUX_VID_MODE_VESA_START): Set
+	to 0x300.
+	* loader/i386/linux.c (vga_modes, linux_vesafb_res): Add a few
+	resolutions.
+	(linux_vesafb_modes): Add a lot of additional modes to the list (based
+	on documentation from Wikipedia).
+
+2009-05-04  Pavel Roskin  <proski@gnu.org>
+
+	* disk/ata.c: Spelling fixes.
+	* disk/raid.c: Likewise.
+	* disk/usbms.c: Likewise.
+	* disk/dmraid_nvidia.c: Likewise.
+	* kern/ieee1275/openfw.c: Likewise.
+	* kern/ieee1275/init.c: Likewise.
+	* kern/ieee1275/cmain.c: Likewise.
+	* boot/i386/pc/cdboot.S: Likewise.
+	* video/readers/png.c: Likewise.
+	* video/i386/pc/vbe.c: Likewise.
+	* fs/udf.c: Likewise.
+	* fs/hfs.c: Likewise.
+	* fs/reiserfs.c: Likewise.
+	* efiemu/runtime/efiemu.c: Likewise.
+	* efiemu/main.c: Likewise.
+	* efiemu/mm.c: Likewise.
+	* include/grub/elf.h: Likewise.
+	* include/grub/xnu.h: Likewise.
+	* include/grub/usbdesc.h: Likewise.
+	* include/grub/usb.h: Likewise.
+	* include/grub/script_sh.h: Likewise.
+	* include/grub/lib/LzmaEnc.h: Likewise.
+	* include/grub/efiemu/efiemu.h: Likewise.
+	* include/grub/command.h: Likewise.
+	* normal/menu.c: Likewise.
+	* normal/main.c: Likewise.
+	* normal/datetime.c: Likewise.
+	* bus/usb/uhci.c: Likewise.
+	* mmap/i386/uppermem.c: Likewise.
+	* mmap/mmap.c: Likewise.
+	* commands/acpi.c: Likewise.
+	* commands/test.c: Likewise.
+	* partmap/apple.c: Likewise.
+	* font/font.c: Likewise.
+	* loader/sparc64/ieee1275/linux.c: Likewise.
+	* loader/macho.c: Likewise.
+	* loader/i386/bsd_trampoline.S: Likewise.
+	* loader/i386/bsd.c: Likewise.
+	* loader/xnu.c: Likewise.
+	* term/i386/pc/vesafb.c: Likewise.
+	* term/usb_keyboard.c: Likewise.
+	* util/resolve.c: Likewise.
+	* util/getroot.c: Likewise.
+
+2009-05-04  Felix Zielcke  <fzielcke@z-51.de>
+
+	* conf/i386-pc.rmk (libpkg_DATA): Rename to pkglib_DATA.
+
+2009-05-04  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* loader/i386/linux.c [GRUB_MACHINE_PCBIOS] (grub_cmd_linux): Fix
+	build error.
+
+2009-05-04  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* loader/i386/linux.c (grub_cmd_linux): Make "vga=" compatibility
+	parameter only available on BIOS.
+
+2009-05-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Removed wrong semicolon in declaration
+
+	* grub/misc.h (grub_dprintf): remove semicolon
+
+2009-05-04  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* loader/i386/linux.c (GRUB_ASSUME_LINUX_HAS_FB_SUPPORT): New macro.
+	(grub_linux_boot): Don't check for `linux_vesafb_modes' bounds (this
+	is done by grub_cmd_linux() now).
+	[! GRUB_ASSUME_LINUX_HAS_FB_SUPPORT]: If "vga=" parameter wasn't set,
+	restore video to text mode.
+	(grub_cmd_linux): Default `vid_mode' initialization to 0, which
+	indicates lack of "vga=" parameter.  "vga=0" is mapped to
+	`GRUB_LINUX_VID_MODE_NORMAL'.
+
+2009-05-04  Felix Zielcke  <fzielcke@z-51.de>
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Remove `normal/execute.c',
+	`normal/lexer.c', `kern/rescue.c', `normal/function.c', `normal/misc.c'
+	and `normal/script.c'.  Add `kern/rescue_reader.c',
+	`kern/rescue_parser.c', `script/sh/main.c', `script/sh/execute.c',
+	`script/sh/function.c', `script/sh/lexer.c', `script/sh/script.c' and
+	`grub_script.tab.c'.
+
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise.
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+	* Makefile.in: Remove duplicated 2008 in Copyright line.
+
+2009-05-04  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/misc.c (grub_util_warn): New function.  Emits a warning
+	unconditionally.
+	* include/grub/util/misc.h (grub_util_warn): New declaration.
+
+	* util/i386/pc/grub-install.in: Understand --force and pass it down
+	to grub-setup.
+
+	* util/i386/pc/grub-setup.c (main): Understand --force and pass it
+	down to setup().
+	(setup): Improve error messages and add warnings when requested to
+	install in odd layouts.  Refuse to install using blocklists unless
+	--force was set.
+
+2009-05-04  martin f. krafft  <madduck@madduck.net>
+
+	* disk/raid.c (grub_raid_scan_device): Improve debug message.
+
+2009-05-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Updated copyright year
+
+	* fs/hfsplus.c: updated copyright year
+
+2009-05-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	HFS+ UUID
+
+	* fs/hfsplus.c (grub_hfsplus_volheader): added num_serial field
+	in the space previously used by unused3
+	(grub_hfsplus_uuid): new function
+	(grub_hfsplus_fs): added uuid field
+
+2009-05-03  Pavel Roskin  <proski@gnu.org>
+
+	* disk/ata.c: Don't cast mod to void in GRUB_MOD_INIT to
+	suppress warnings.  It's no longer needed.
+	* disk/host.c: Likewise.
+	* disk/ata_pthru.c: Likewise.
+	* disk/loopback.c: Likewise.
+	* hook/datehook.c: Likewise.
+	* parttool/pcpart.c: Likewise.
+	* fs/i386/pc/pxe.c: Likewise.
+	* fs/ntfscomp.c: Likewise.
+	* efiemu/main.c: Likewise.
+	* mmap/mmap.c: Likewise.
+	* commands/crc.c: Likewise.
+	* commands/hexdump.c: Likewise.
+	* commands/hdparm.c: Likewise.
+	* commands/acpi.c: Likewise.
+	* commands/echo.c: Likewise.
+	* commands/minicmd.c: Likewise.
+	* commands/blocklist.c: Likewise.
+	* commands/memrw.c: Likewise.
+	* commands/loadenv.c: Likewise.
+	* commands/usbtest.c: Likewise.
+	* commands/lsmmap.c: Likewise.
+	* commands/boot.c: Likewise.
+	* commands/parttool.c: Likewise.
+	* commands/configfile.c: Likewise.
+	* commands/search.c: Likewise.
+	* commands/ieee1275/suspend.c: Likewise.
+	* commands/cat.c: Likewise.
+	* commands/i386/pc/pxecmd.c: Likewise.
+	* commands/i386/pc/play.c: Likewise.
+	* commands/i386/pc/halt.c: Likewise.
+	* commands/i386/pc/vbeinfo.c: Likewise.
+	* commands/i386/pc/vbetest.c: Likewise.
+	* commands/lspci.c: Likewise.
+	* commands/date.c: Likewise.
+	* commands/handler.c: Likewise.
+	* commands/ls.c: Likewise.
+	* commands/test.c: Likewise.
+	* commands/cmp.c: Likewise.
+	* commands/efi/loadbios.c: Likewise.
+	* commands/efi/fixvideo.c: Likewise.
+	* commands/halt.c: Likewise.
+	* commands/help.c: Likewise.
+	* commands/reboot.c: Likewise.
+	* hello/hello.c: Likewise.
+	* script/sh/main.c: Likewise.
+	* loader/xnu.c: Likewise.
+	* term/terminfo.c: Likewise.
+	* term/i386/pc/serial.c: Likewise.
+	* term/usb_keyboard.c: Likewise.
+
+2009-05-03  David S. Miller  <davem@davemloft.net>
+
+	* normal/menu.c: Include grub/parser.h
+
+2009-05-03  Pavel Roskin  <proski@gnu.org>
+
+	* mmap/efi/mmap.c (grub_mmap_malign_and_register): Return void*,
+	not char*.
+	* mmap/i386/mmap.c (grub_mmap_malign_and_register): Likewise.
+	Suggested by Javier Martín <lordhabbit@gmail.com>
+
+	* util/i386/pc/grub-mkrescue.in: Allow for the case when
+	efiemu??.o doesn't exist.
+	* util/i386/pc/grub-install.in: Likewise.  Use "cp -f" for
+	copying.
+
+2009-05-03  Bean  <bean123ch@gmail.com> Vladimir Serbinenko  <phcoder@gmail.com>
+
+	FreeBSD 64-bit support
+
+	* conf/i386-pc.rmk (bsd_mod_SOURCES): add loader/i386/bsd_helper.S
+	and loader/i386/bsd_trampoline.S
+	(bsd_mod_ASFLAGS): new variable
+	* include/grub/i386/bsd.h (FREEBSD_MODINFOMD_SMAP): new definition
+	(FREEBSD_MODTYPE_KERNEL64): likewise
+	(grub_bsd64_trampoline_start): likewise
+	(grub_bsd64_trampoline_end): likewise
+	(grub_bsd64_trampoline_selfjump): likewise
+	(grub_bsd64_trampoline_gdt): likewise
+	* include/grub/i386/loader.h (grub_unix_real_boot): moved from here ...
+	* include/grub/i386/bsd.h (grub_unix_real_boot): ... moved here
+	* kern/i386/loader.S (grub_unix_real_boot): moved from here ...
+	* loader/i386/bsd_helper.S (grub_unix_real_boot): moved here
+	* include/grub/gpt_partition.h (grub_gpt_partentry): Corrected the type
+	of "attrib" member
+	* loader/i386/bsd_pagetable.c: new file
+	* loader/i386/bsd_trampoline.S: likewise
+	* loader/i386/bsd.c (ALIGN_QWORD): new macro
+	(ALIGN_VAR): likewise
+	(entry_hi): new variable
+	(kern_end_mdofs): likewise
+	(is_64bit): likewise
+	(grub_freebsd_add_meta): use ALIGN_VAR
+	(grub_e820_mmap): new declaration
+	(grub_freebsd_add_mmap): new function
+	(grub_freebsd_add_meta_module): support 64 bit kernels
+	(grub_freebsd_list_modules): use ALIGN_VAR
+	(gdt_descriptor): new declaration
+	(grub_freebsd_boot): support 64 bit kernels
+	(grub_bsd_elf64_hook): new function
+	(grub_bsd_load_elf): support elf64
+
+2009-05-03  Bean  <bean123ch@gmail.com>
+
+	* script/sh/execute.c (grub_script_execute_cmdif): Reset grub_errno
+	after we get the result of if statement.
+
+2009-05-03  Bean  <bean123ch@gmail.com>
+
+	* Makefile.in (enable_efiemu): New variable.
+
+	* conf/i386-pc.rmk: Only compile efiemu runtimes when enable_efiemu is
+	set.
+	(efiemu32.o): Use macro $< for source file, add $(srcdir) to include
+	path.
+	(efi64_c.o): Use macro $< for source file, add $(srcdir) to include
+	path, add -mno-red-zone option.
+	(efiemu64_s.o): Likewise.
+	(efiemu64.o): Use macro $^ for source file.
+
+	* configure.ac (--enable-efiemu): New option.
+
+2009-05-03  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	xnu support
+
+	* conf/i386-efi.rmk (kernel_mod_HEADERS): added i386/pit.h
+	(pkglib_MODULES): add xnu.mod
+	(xnu_mod_SOURCES): new variable
+	(xnu_mod_CFLAGS): likewise
+	(xnu_mod_LDFLAGS): likewise
+	(xnu_mod_ASFLAGS): likewise
+	* conf/i386-pc.rmk: likewise
+	* conf/x86_64-efi.rmk: likewise
+	* include/grub/efi/efi.h (grub_efi_finish_boot_services):
+	new declaration
+	* include/grub/i386/macho.h: new file
+	* include/grub/i386/xnu.h: likewise
+	* include/grub/macho.h: likewise
+	* include/grub/machoload.h: likewise
+	* include/grub/x86_64/macho.h: likewise
+	* include/grub/x86_64/xnu.h: likewise
+	* include/grub/xnu.h: likewise
+	* kern/efi/efi.c (grub_efi_finish_boot_services): new function
+	* kern/efi/mm.c (MAX_HEAP_SIZE): increase
+	* loader/i386/efi/xnu.c: new file
+	* loader/i386/pc/xnu.c: likewise
+	* loader/i386/xnu.c: likewise
+	* loader/i386/xnu_helper.S: likewise
+	* loader/macho.c: likewise
+	* loader/xnu.c: likewise
+	* loader/xnu_resume.c: likewise
+	* util/grub-dumpdevtree: likewise
+	* include/grub/i386/pit.h: include grub/err.h
+	(grub_pit_wait): export
+	* util/grub.d/30_os-prober.in: support Darwin/Mac OS X
+
+2009-05-02  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Efiemu
+
+	* conf/i386-pc.rmk: new modules efiemu, efiemu_acpi, efiemu_pnvram,
+	_linux_efi, linux_efi.
+	new files in grub-emu
+	new targets efiemu32.o and efiemu64.o
+	* loader/linux_normal_efiemu.c: likewise
+	* loader/i386/efi/linux.c: added preliminary efiemu support
+	* util/i386/pc/grub-install.in: add efiemu??.o to the list of
+	files to copy
+	* include/grub/autoefi.h: new file
+	* include/grub/i386/efiemu.h: likewise
+	* include/grub/i386/pc/efiemu.h: likewise
+	* include/grub/efi/api.h: add LL suffix when necessary
+	new definitions relating to tables
+	* include/grub/efiemu/efiemu.h: new file
+	* include/grub/efiemu/runtime.h: likewise
+	* efiemu/prepare.c: likewise
+	* efiemu/loadcore_common.c: likewise
+	* efiemu/loadcore64.c: likewise
+	* efiemu/runtime/efiemu.sh: likewise
+	* efiemu/runtime/efiemu.S: likewise
+	* efiemu/runtime/efiemu.c: likewise
+	* efiemu/runtime/config.h: likewise
+	* efiemu/prepare32.c: likewise
+	* efiemu/main.c: likewise
+	* efiemu/modules/pnvram.c: likewise
+	* efiemu/modules/i386: likewise
+	* efiemu/modules/i386/pc: likewise
+	* efiemu/modules/acpi.c: likewise
+	* efiemu/i386/pc/cfgtables.c: likewise
+	* efiemu/i386/loadcore64.c: likewise
+	* efiemu/i386/loadcore32.c: likewise
+	* efiemu/prepare64.c: likewise
+	* efiemu/loadcore.c: likewise
+	* efiemu/symbols.c: likewise
+	* efiemu/mm.c: likewise
+	* efiemu/loadcore32.c: likewise
+
+2009-05-02  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	ACPI spoofing
+
+	* commands/acpi.c: new file
+	* commands/i386/pc/acpi.c: likewise
+	* commands/efi/acpi.c: likewise
+	* include/grub/acpi.h: likewise
+	* conf/i386-pc.rmk (pkglib_MODULES): added acpi.mod
+	(acpi_mod_SOURCES): new variable
+	(acpi_mod_CFLAGS): likewise
+	(acpi_mod_LDFLAGS): likewise
+	* conf/i386-efi.rmk: likewise
+	* conf/x86_64-efi.rmk: likewise
+
+2009-05-02  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Missing part from mmap patch
+
+	* mmap/efi/mmap.c (grub_machine_mmap_unregister): renamed to
+	(grub_mmap_unregister)
+	(grub_mmap_free_and_unregister): use grub_mmap_register
+
+2009-05-02  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Mmap services
+
+	* loader/i386/efi/linux.c (grub_linux_boot): use grub_mmap_iterate
+	* loader/i386/linux.c (find_mmap_size): likewise
+	(allocate_pages): likewise
+	* loader/i386/multiboot.c (grub_get_multiboot_mmap_len): likewise
+	(grub_fill_multiboot_mmap): likewise
+	(grub_multiboot): use grub_mmap_get_lower and grub_mmap_get_upper
+	* loader/i386/pc/linux.c (grub_cmd_linux): use grub_mmap_get_lower
+	* include/grub/i386/bsd.h (OPENBSD_MMAP_AVAILABLE): new definition
+	(OPENBSD_MMAP_RESERVED): likewise
+	* include/grub/i386/pc/memory.h: include grub/memory.h
+	(grub_lower_mem): removed
+	(grub_upper_mem): likewise
+	(GRUB_MACHINE_MEMORY_ACPI): new definition
+	(GRUB_MACHINE_MEMORY_NVS): likewise
+	(GRUB_MACHINE_MEMORY_MAX_TYPE): likewise
+	(GRUB_MACHINE_MEMORY_HOLE): likewise
+	(grub_machine_mmap_register): likewise
+	(grub_machine_mmap_unregister): likewise
+	(grub_machine_get_upper): likewise
+	(grub_machine_get_lower): likewise
+	(grub_machine_get_post64): likewise
+	* include/grub/i386/efi/memory.h: new file
+	* include/grub/x86_64/efi/memory.h: likewise
+	* include/grub/efi/memory.h: likewise
+	* conf/i386-pc.rmk (pkglib_MODULES): added mmap.mod
+	(mmap_mod_SOURCES): new variable
+	(mmap_mod_LDFLAGS): likewise
+	(mmap_mod_ASFLAGS): likewise
+	* conf/i386-coreboot.rmk: likewise
+	* conf/i386-ieee1275.rmk: likewise
+	* conf/i386-efi.rmk: likewise
+	* conf/x86_64-efi.rmk: likewise
+	* include/grub/types.h (UINT_TO_PTR): new macro
+	(PTR_TO_UINT32): likewise
+	(PTR_TO_UINT64): likewise
+	* include/grub/memory.h: new file
+	* mmap/i386/pc/mmap.c: likewise
+	* mmap/i386/pc/mmap_helper.S: likewise
+	* mmap/i386/uppermem.c: likewise
+	* mmap/mmap.c: likewise
+	* mmap/efi/mmap.c: likewise
+	* kern/i386/coreboot/init.c (grub_machine_init): don't use
+	grub_upper_mem
+	* kern/i386/pc/init.c (grub_lower_mem): removed variable
+	(grub_upper_mem): likewise
+	(grub_machine_init): don't use grub_upper_mem,
+	make grub_lower_mem local
+	* loader/i386/bsd.c (grub_openbsd_boot): use grub_mmap_get_lower,
+	grub_mmap_iterate and grub_mmap_get_upper
+	(grub_netbsd_boot): use grub_mmap_get_lower and grub_mmap_get_upper
+
+2009-05-02  Bean  <bean123ch@gmail.com>
+
+	* conf/common.rmk (grub_script.tab.c): Change normal/parser.y to
+	script/sh/parser.y.
+	(pkglib_MODULES): Add normal.mod and sh.mod.
+	(normal_SOURCES): New variable.
+	(normal_mod_CFLAGS): Likewise.
+	(normal_mod_LDFLAGS): Likewise.
+	(sh_mod_SOURCES): Likewise.
+	(sh_mod_CFLAGS): Likewise.
+	(sh_mod_LDFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (normal/lexer.c_DEPENDENCIES): Changed to
+	script/sh/lexer.c_DEPENDENCIES.
+	(kernel_img_SOURCES): Remove kern/rescue.c, and kern/reader.c,
+	kern/rescue_reader.c and kern/rescue_parser.c.
+	(kernel_img_HEADERS): Remove rescue.h, add reader.h.
+	(grub_emu_SOURCES): Change source files.
+	(pkglib_MODULES): Remove normal.mod.
+	(normal_SOURCES): Removed.
+	(normal_mod_CFLAGS): Likewise.
+	(normal_mod_LDFLAGS): Likewise.
+	* conf/i386-coreboot.rmk: Likewise.
+	* conf/i386-efi.rmk: Likewise.
+	* conf/i386-ieee1276.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	* conf/sparc64-ieee1275.rmk: Likewise.
+	* conf/x86_64-efi.rmk: Likewise.
+
+	* include/grub/command.h (grub_command_execute): New inline function.
+
+	* include/grub/menu.h (grub_menu_entry): Removed commands field.
+
+	* include/grub/normal.h: Remove <grub/setjmp.h>.
+	(grub_fs_module_list): Moved to normal/autofs.c.
+	(grub_exit_env): Removed.
+	(grub_command_execute): Likewise.
+	(grub_normal_menu_addentry): Renamed to grub_menu_addentry, removed
+	parameter script.
+	(read_command_list): New function declaration.
+	(read_fs_list): Likewise.
+
+	* include/parser.h: Include <grub/reader.h>.
+	(grub_parser_split_cmdline): Change type of getline parameter.
+	(grub_parser): New structure.
+	(grub_parser_class): New variable.
+	(grub_parser_execute): New function declaration.
+	(grub_register_rescue_parser): Likewise.
+	(grub_parser_register): New inline function.
+	(grub_parser_unregister): Likewise.
+	(grub_parser_get_current): Likewise.
+	(grub_parser_set_current): Likewise.
+
+	* include/grub/reader.h: New file.
+	* kern/reader.c: Likewise.
+	* kern/rescue_parser.c: Likewise.
+	* kern/rescue_reader.c: Likewise.
+	* normal/autofs.c: Likewise.
+	* normal/dyncmd.c: Likewise.
+
+	* include/grub/rescue.h: Removed.
+	* normal/command.h: Likewise.
+
+	* include/grub/script.h: Moved to ...
+	* include/grub/script_sh.h: ... Moved here.
+	* normal/execute.c: Moved to ...
+	* script/sh/execute.c: ... Moved here.
+	* normal/function.c: Moved to ...
+	* script/sh/function.c: ... Moved here.
+	* normal/lexer.c: Moved to ...
+	* script/sh/lexer.c: ... Moved here.
+	* normal/parser.y: Moved to ...
+	* script/sh/parser.y: ... Moved here.
+	* normal/script.c: Moved to ...
+	* script/sh/script.c: ... Moved here.
+
+	* normal/main.c: Remove <grub/rescue.h> and <grub/script.h>, include
+	<grub/reader.h>.
+	(grub_exit_env): Removed.
+	(fs_module_list): Moved to normal/autofs.c.
+	(grub_file_getline): Don't handle comment here.
+	(free_menu): Skip removed field entry->commands.
+	(grub_normal_menu_addentry): Removed as grub_menu_entry, removed
+	script parameter.
+	(read_config_file): Removed nested parameter, change getline function.
+	(grub_enter_normal_mode): Removed.
+	(grub_dyncmd_dispatcher): Moved to normal/dyncmd.c.
+	(read_command_list): Likewise.
+	(autoload_fs_module): Moved to normal/autofs.c.
+	(read_fs_list): Likewise.
+	(reader_nested): New variable.
+	(grub_normal_execute): Run parser.sh to switch to sh parser.
+	(grub_cmd_rescue): Removed.
+	(cmd_normal): Removed.
+	(grub_cmd_normal): Unregister itself at the beginning. Don't register
+	rescue command.
+	(grub_cmdline_run): New function.
+	(grub_normal_reader_init): Likewise.
+	(grub_normal_read_line): Likewise.
+	(grub_env_write_pager): Likewise.
+	(cmdline): New variable.
+	(grub_normal_reader): Likewise.
+	(GRUB_MOD_INIT): Register normal reader and set as current, register
+	pager hook, register normal command with grub_register_command_prio,
+	so that it won't show up in command.lst.
+	(GRUB_MOD_FINI): Unregister normal reader, unhook pager, clear
+	grub_fs_autoload_hook.
+
+	* normal/menu.c: Remove <grub/script.h>, add <grub/command.h>.
+	(grub_menu_execute_entry): Replace grub_script_execute with
+	grub_parser_execute, change parameter to grub_command_execute.
+
+	* normal/menu_text.c: Remove <grub/script.h>.
+
+	* normal/menu_entry.c: Remove <grub/script.h>, add <grub/command.h>
+	and <grub/parser.h>.
+	(run): Change editor_getline to use new parser interface. Change
+	parameter to grub_command_execute.
+
+	* kern/main.c: Remove <grub/rescue.h>, include <grub/command.h>,
+	<grub/reader.h> and <grub/parser.h>.
+	(grub_load_normal_mode): Execute normal command.
+	(grub_main): Call grub_register_core_commands,
+	grub_register_rescue_parser and grub_register_rescue_reader, use
+	grub_reader_loop to enter input loop.
+
+	* kern/parser.c (grub_parser_split_cmdline): Change type of
+	getline parameter.
+	(grub_parser_class): New variable.
+	(grub_parser_execute): New function.
+
+	* loader/i386/multiboot.c: Remove <grub/rescue.h>.
+	* loader/multiboot2.c: Likewise.
+	* loader/sparc64/ieee1275/linux.c: Likewise.
+
+	* util/grub-emu.c (read_command_list): New dummy function.
+
+2009-05-02  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* util/deviceiter.c (grub_util_iterate_devices): Increase max drive
+	count to 16 for CCISS and IDA.
+
+2009-05-02  Robert Millan  <rmh.grub@aybabtu.com>
+
+	* normal/menu_text.c  (grub_wait_after_message): Print a newline
+	after waiting for user input.
+
+	* loader/i386/linux.c: Include `<grub/normal.h>'.
+	(grub_cmd_linux): Improve the error message about `ask' mode, by
+	waiting for user input so it's not missed (we can do this, since
+	user requested interaction).
+
+2009-05-02  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Added missing lst to grub-mkrescue
+
+	* util/i386/pc/grub-mkrescue.in: added ${input_dir}/handler.lst
+	and ${input_dir}/parttool.lst
+
+2009-04-30  David S. Miller  <davem@davemloft.net>
+
+	* util/hostdisk.c (device_is_wholedisk): New function.
+	(grub_util_biosdisk_get_grub_dev): Shortcut when hdg.start is
+	zero only if device_is_wholedisk() returns true.
+
+	* util/hostdisk.c (convert_system_partition_to_system_disk):
+	Handle virtual disk devices named /dev/vdiskX as found on sparc
+	and powerpc.
+
+	* kern/sparc64/ieee1275/init.c (grub_machine_set_prefix): If
+	lettered partition specifier is found, convert to numbered.
+
+2009-04-29  David S. Miller  <davem@davemloft.net>
+
+	* include/grub/powerpc/ieee1275/memory.h: Include ieee1275.h.
+	* include/grub/sparc64/ieee1275/memory.h: Likewise.
+
+	* normal/command.c: Add missing newline at end of file.
+
+	* commands/lsmmap.c (grub_cmd_lsmmap): Add casts to avoid printf
+	warnings.
+	* kern/ieee1275/openfw.c (grub_claimmap): Likewise.
+	* disk/ieee1275/ofdisk.c (grub_ofdisk_open, grub_ofdisk_close,
+	grub_ofdisk_read): Likewise, and deal similarly with the fact that
+	ihandles have a 32-bit type but need to be stored in a "void *".
+
+2009-04-28  Pavel Roskin  <proski@gnu.org>
+
+	* disk/fs_uuid.c (grub_fs_uuid_open): Use parent->data for dev,
+	not disk.  Adjust all dependencies.
+	(grub_fs_uuid_close): Use grub_device_close(), not
+	grub_disk_close().
+
+	* disk/fs_uuid.c (grub_fs_uuid_open): Allocate memory to copy
+	parent's partition, don't copy it by reference, as it gets freed
+	on close.
+
+2009-04-27  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Preboot hooks support
+
+	* commands/boot.c (struct grub_preboot_t): new declaration
+	(preboots_head): new variable
+	(preboots_tail): likewise
+	(grub_loader_register_preboot_hook): new function
+	(grub_loader_unregister_preboot_hook): likewise
+	(grub_loader_set): launch preboot hooks
+	* include/grub/loader.h (grub_loader_preboot_hook_prio_t): new type
+	(grub_loader_register_preboot_hook): new declaration
+	(grub_loader_unregister_preboot_hook): likewise
+
+2009-04-27  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Warning fix
+
+	* disk/scsi.c (grub_scsi_open): added missing cast when
+	calling grub_dprintf
+
+2009-04-26  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Bug and warning fixes
+
+	* include/grub/i386/pc/init.h (grub_stop_floppy): added missing
+	declaration
+	* commands/test.c (test_parse): fixed bug with file tests and corrected
+	declaration of find_file
+
+2009-04-26  Pavel Roskin  <proski@gnu.org>
+
+	* Makefile.in: Don't install empty manual pages if help2man is
+	missing.  Use help2man option for output, not shell redirection.
+
+2009-04-26  David S. Miller  <davem@davemloft.net>
+
+	* util/grub-mkdevicemap.c (make_device_map): Add missing
+	NESTED_FUNC_ATTR to process_device().
+
+2009-04-25  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Test command
+
+	* commands/test.c: rewritten to use bash-like test
+
+2009-04-25  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Parttool autoloading and improvements
+
+	* Makefile.in (pkglib_DATA): add parttool.lst
+	(parttool.lst): new target
+	* genmk.rb: generate parttool-*
+	(CLEANFILES): add #{parttool}
+	(PARTTOOLFILES): new variable
+	* genparttoollist.sh: new file
+	* parttool/pcpart.c (grub_pcpart_boot): more feedback
+	(grub_pcpart_type): likewise
+	* commands/parttool.c (helpmsg): new variable
+	(grub_cmd_parttool): output help if not enough arguments are supplied
+	autoload modules
+	(GRUB_MOD_INIT(parttool)): use helpmsg
+
+2009-04-24  David S. Miller  <davem@davemloft.net>
+
+	Avoiding opening same device multiple times in device iterator.
+
+	* kern/device.c: (grub_device_iterate): Define struct part_ent,
+	and use it to build a list of partitions in iterate_disk() and
+	iterate_partition().
+
+	* disk/fs_uuid.c (grub_fs_uuid_close): Call grub_disk_close()
+	on disk->data.
+
+	* disk/ieee1275/nand.c (grub_nand_iterate): Return
+	grub_devalias_iterate() result instead of unconditional 0.
+	* disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Likewise.
+	Also, capture hook return value, either directly or via
+	grub_children_iterate(), and propagate to caller.
+	* include/grub/ieee1275/ieee1275.h (grub_devalias_iterate,
+	grub_children_iterate): Return value is now 'int' instead of
+	'grub_err_t'.
+	* kern/ieee1275/openfw.c (grub_children_iterate): Fix to behave
+	like a proper iterator, stopping when hooks return non-zero.
+	(grub_devalias_iterate): Likewise.
+
+2009-04-23  David S. Miller  <davem@davemloft.net>
+
+	* kern/sparc64/ieee1275/openfw.c: Unused, delete.
+
+2009-04-22  David S. Miller  <davem@davemloft.net>
+
+	* kern/ieee1275/mmap.c (grub_machine_mmap_iterate): If size_cells
+	is larger than address_cells, use that value for address_cells too.
+
+	* include/grub/ieee1275/ieee1275.h (IEEE1275_MAX_PROP_LEN,
+	IEEE1275_MAX_PATH_LEN): Define.
+	* kern/ieee1275/openfw.c (grub_children_iterate): Dynamically
+	allocate 'childtype', 'childpath', 'childname', and 'fullname'.
+	(grub_devalias_iterate): Dynamically allocate 'aliasname' and
+	'devtype'.  Explicitly NULL terminate devalias expansion.
+
+	* util/sparc64/ieee1275/misc.c: New file.
+	* util/sparc64/ieee1275/grub-setup.c: New file.
+	* util/sparc64/ieee1275/grub-ofpathname.c: New file.
+	* util/sparc64/ieee1275/grub-mkimage.c: New file.
+	* util/sparc64/ieee1275/grub-install.in: New file.
+	* util/ieee1275/ofpath.c: New file.
+	* util/ieee1275/devicemap.c: New file.
+	* util/devicemap.c: New file.
+	* util/deviceiter.c: New file.
+	* kern/sparc64/ieee1275/init.c: New file.
+	* include/grub/util/ofpath.h: New file.
+	* include/grub/util/deviceiter.h: New file.
+	* util/grub-mkdevicemap.c: Include deviceiter.h.
+	Implement using grub_util_emit_devicemap_entry and
+	grub_util_iterate_devices.
+	* conf/i386-corebook.rmk: Build util/deviceiter.c and
+	util/devicemap.c into grub-mkdevicemap
+	* conf/i386-efi.rmk: Likewise.
+	* conf/i386-ieee1275.rmk: Likewise.
+	* conf/i386-pc.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	* conf/sparc64-ieee1275.rmk: Add rules to build boot block
+	images and installation utilities.  Build kernel as image
+	instead of as elf binary.  Use common rules as much as possible.
+
+2009-04-19  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Correct GPT definition
+
+	* include/grub/gpt_partition.h (grub_gpt_partentry): Corrected the type
+	of "attrib" member
+
+2009-04-19  Felix Zielcke  <fzielcke@z-51.de>
+
+	* INSTALL: Replace `autogen.sh' with `./autogen.sh'.
+
+2009-04-19  David S. Miller  <davem@davemloft.net>
+
+	* loader/sparc64/ieee1275/linux.c: Include grub/command.h
+	(grub_rescue_cmd_linux): Rename to...
+	(grub_cmd_linux): and fix prototype.
+	(grub_rescue_cmd_initrd): Rename to...
+	(grub_cmd_initrd): and fix prototype.
+	(cmd_linux, cmd_initrd): New.
+	(GRUB_MOD_INIT(linux)): Use grub_register_command().
+	(GRUB_MOD_FINI(linux): Use grub_unregister_command().
+
+2009-04-17  Pavel Roskin  <proski@gnu.org>
+
+	* bus/usb/ohci.c (grub_ohci_transaction): Fix incorrect printf
+	format.
+	(grub_ohci_transfer): Likewise.
+
+	* bus/usb/usbtrans.c (grub_usb_control_msg): Warning fix.
+
+	* loader/multiboot_loader.c (grub_cmd_multiboot_loader): Fix
+	return without a value.  Fix inconsistent indentation.
+
+	* fs/i386/pc/pxe.c (grub_pxefs_dir): Fix function prototype to
+	match struct grub_fs.
+
+	* disk/ata.c (grub_ata_pciinit): Use NESTED_FUNC_ATTR.
+	* bus/usb/ohci.c (grub_ohci_pci_iter): Likewise.
+	* bus/usb/uhci.c (grub_uhci_pci_iter): Likewise.
+	* commands/lspci.c (grub_lspci_iter): Likewise.
+
+2009-04-16  Bean  <bean123ch@gmail.com>
+
+	* commands/efi/loadbios.c (grub_cmd_fakebios): Add missing return
+	value.
+
+2009-04-15  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/types.h: Rename ULONG_MAX to GRUB_ULONG_MAX and
+	LONG_MAX to GRUB_LONG_MAX.  Introduce GRUB_LONG_MIN.  Update all
+	users of ULONG_MAX, LONG_MAX and LONG_MIN to use the new
+	definitions.
+
+2009-04-15  Felix Zielcke  <fzielcke@z-51.de>
+
+	* disk/lvm.c (grub_lvm_scan_device): Add `LVM' to the error messages,
+	that no multiple data or metadata areas are supported and `Unknown
+	metadata header'.
+
+2009-04-15  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Move loader out of the kernel
+
+	* kern/loader.c: moved to ...
+	* commands/boot.c: ... moved here
+	* commands/minicmd.c (grub_mini_cmd_boot): moved to ...
+	* commands/boot.c (grub_cmd_boot): moved here. All users updated
+	* include/grub/kernel.h (grub_machine_fini): export
+	* include/grub/loader.h (grub_loader_is_loaded): update declaration
+	(grub_loader_set): likewise
+	(grub_loader_unset): likewise
+	(grub_loader_boot): likewise
+	* conf/common.rmk: new module boot.mod
+	(pkglib_MODULES): add boot.mod
+	* conf/i386-coreboot.rmk (kernel_elf_SOURCES): remove kern/loader.c
+	(grub_emu_SOURCES): likewise
+	* conf/i386-efi.rmk (kernel_elf_SOURCES): likewise
+	(grub_emu_SOURCES): likewise
+	* conf/i386-ieee1275.rmk (kernel_elf_SOURCES): likewise
+	(grub_emu_SOURCES): likewise
+	* conf/i386-pc.rmk (kernel_elf_SOURCES): likewise
+	(grub_emu_SOURCES): likewise
+	* conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): likewise
+	(grub_emu_SOURCES): likewise
+	* conf/sparc64-ieee1275.rmk (kernel_elf_SOURCES): likewise
+	(grub_emu_SOURCES): likewise
+	* conf/x86_64-efi.rmk (kernel_elf_SOURCES): likewise
+	(grub_emu_SOURCES): likewise
+
+2009-04-15  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	use grub_lltoa instead of grub_itoa and grub_ltoa for all purposes
+
+	* kern/misc.c (grub_itoa): Removed function
+	(grub_ltoa): likewise
+	(grub_vsprintf): use grub_lltoa
+
+2009-04-15  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Restore grub-emu
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): add normal/handler.c
+	* conf/i386-coreboot.rmk: likewise
+	* conf/i386-ieee1275.rmk: likewise
+	* conf/powerpc-ieee1275.rmk: likewise
+
+2009-04-15  Felix Zielcke  <fzielcke@z-51.de>
+
+	* INSTALL: Add that `./autogen.sh' needs to be run before
+	`./configure.'.
+
+2009-04-14  Bean  <bean123ch@gmail.com>
+
+	* Makefile.in (pkglib_DATA): Add handler.lst.
+	(handler.lst): New rule.
+
+	* conf/i386-pc.rmk (normal_mod_SOURCES): Add normal/handler.c.
+	* conf/i386-coreboot.rmk: Likewise.
+	* conf/i386-ieee1275.rmk: Likewise.
+	* conf/i386-efi.rmk: Likewise.
+	* conf/x86_64-efi.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	* conf/sparc64-ieee1275.rmk: Likewise.
+
+	* genhandlerlist.sh: New file.
+
+	* genmk.rb: Add rules to generate handler.lst.
+
+	* include/grub/normal.h (grub_file_getline): New function definition.
+	(read_handler_list): Likewise.
+	(free_handler_list): Likewise.
+
+	* include/grub/term.h (grub_term_register_input): Add name parameter
+	for auto generation of handler.lst.
+	(grub_term_register_output): Likewise.
+
+	* normal/handler.c: New file.
+
+	* normal/main.c (get_line): Renamed to grub_file_getline.
+	(read_config_file): Use the newly renamed grub_file_getline.
+	(read_command_list): Likewise.
+	(read_fs_list): Likewise.
+	(grub_normal_execute): Call read_handler_list to parse handler.lst.
+	(GRUB_MOD_FINI): Call free_handler_list to free handler list.
+
+	* term/efi/console.c (grub_console_init): Add name parameter for auto
+	generation of handler.lst.
+	* term/gfxterm.c: Likewise.
+	* term/i386/pc/at_keyboard.c: Likewise.
+	* term/i386/pc/console.c: Likewise.
+	* term/i386/pc/serial.c: Likewise.
+	* term/i386/pc/vesafb.c: Likewise.
+	* term/i386/pc/vga.c: Likewise.
+	* term/i386/pc/vga_text.c: Likewise.
+	* term/ieee1275/ofconsole.c: Likewise.
+	* term/usb_keyboard.c: Likewise.
+
+2009-04-14  Bean  <bean123ch@gmail.com>
+
+	* util/grub-pe2elf.c (write_symbol_table): Terminate short name symbol
+	properly with null character.
+
+2009-04-14  Felix Zielcke  <fzielcke@z-51.de>
+
+	* configure: Remove.
+	* config.h.in: Likewise.
+	* stamp-h.in: Likewise.
+	* DISTLIST: Likewise.
+	* conf/common.mk: Likewise.
+	* conf/i386-coreboot.mk: Likewise.
+	* conf/i386-efi.mk: Likewise.
+	* conf/i386-ieee1275.mk: Likewise.
+	* conf/i386.mk: Likewise.
+	* conf/i386-pc.mk: Likewise.
+	* conf/powerpc-ieee1275.mk: Likewise.
+	* conf/sparc64-ieee1275.mk: Likewise.
+	* conf/x86_64-efi.mk: Likewise.
+
+	* INSTALL: Remove the sentence that Ruby and autoconf are only required if you
+	develop on GRUB.
+
+2009-04-14  John Stanley  <jpsinthemix@verizon.net>
+	    David S. Miller  <davem@davemloft.net>
+
+	* util/hostdisk.c (make_device_name): Fix buffer length
+	calculations.
+
+2009-04-14  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/hostdisk.c [__FreeBSD__ || __FreeBSD_kernel__]: Include
+	<sys/param.h> and <sys/sysctl.h>.
+	(open_device) [__FreeBSD__ || __FreeBSD_kernel_]: Use sysctlgetbyname()
+	to add 0x10 to `kern.geom.debugflags' if it's not already set, before
+	opening the device and reset them afterwards.
+
+2009-04-13  Pavel Roskin  <proski@gnu.org>
+
+	* conf/common.rmk (grub_fstest_SOURCES): Add normal/datetime.c.
+	Reported by John Stanley <jpsinthemix@verizon.net>
+
+2009-04-13  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/10_freebsd.in: Detect Debian GNU/kFreeBSD and use
+	that name for menuentries when appropriate.
+
+2009-04-13  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub.d/10_freebsd.in: Add a missing `fi'.
+
+2009-04-13  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/linux.c (grub_cmd_linux): Don't pass `vga=ask' parameter
+	to Linux, simply abort telling the user it's no longer supported.
+
+2009-04-13  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub.d/10_freebsd.in: Don't exit if /boot/devices.hints
+	doesn't exist.  Check also for /boot/kernel/kernel.gz.  Print
+	`freebsd_loadenv' only when devices.hints exist.
+
+2009-04-13  Pavel Roskin  <proski@gnu.org>
+
+	* term/usb_keyboard.c (grub_usb_keyboard_getkey): Warning fixes.
+
+2009-04-13  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/i386/pc/grub-install.in (install_drive): Remove the BSD
+	partition number.
+	(grub_drive): Likewise.
+
+2009-04-13  David S. Miller  <davem@davemloft.net>
+
+	* kern/sparc64/ieee1275/ieee1275.c: New file.
+	* include/grub/sparc64/ieee1275/ieee1275.h (IEEE1275_MAP_WRITE,
+	IEEE1275_MAP_READ, IEEE1275_MAP_EXEC, IEEE1275_MAP_LOCKED,
+	IEEE1275_MAP_CACHED, IEEE1275_MAP_SE, IEEE1275_MAP_GLOBAL,
+	IEEE1275_MAP_IE, IEEE1275_MAP_DEFAULT): Define.
+	(grub_ieee1275_map_physical, grub_ieee1275_claim_vaddr,
+	grub_ieee1275_alloc_physmem): Declare new exported functions.
+
+	* include/grub/sparc64/ieee1275/loader.h: New file.
+	* include/grub/sparc64/ieee1275/memory.h: Likewise.
+	* include/grub/sparc64/kernel.h: Likewise.
+	* loader/sparc64/ieee1275/linux.c: Likewise.
+
+	* conf/common.rmk (grub_probe_SOURCES): Add Sun partition module.
+	(grub_fstest_SOURCES): Likewise.
+
+	* util/hostdisk.c (make_device_name): Do not make any assumptions
+	about the length of drive names.
+
+	* kern/dl.c (grub_dl_load_file): Close file immediately when
+	we are done using it.
+
+2009-04-12  David S. Miller  <davem@davemloft.net>
+
+	* kern/misc.c (grub_ltoa): Fix cast when handling negative
+	values.  Noticed by Pavel Roskin.
+
+	* configure.ac: Check for __bswapsi2 and__bswapdi2 using
+	target compiler.
+
+	* genmk.rb: Add more flexible image type specification, also
+	pass --strip-unneeded to objcopy.
+	* conf/i386-pc.rmk: Use *_FORMAT.
+	* conf/i386-pc.mk: Rebuilt.
+
+	* disk/ieee1275/ofdisk.c (struct ofdisk_hash_ent): New struct.
+	(OFDISK_HASH_SZ): Define.
+	(ofdisk_hash): New hash table.
+	(ofdisk_hash_fn, ofdisk_hash_find, ofdisk_hash_add): New functions.
+	(grub_ofdisk_open): Use ofdisk_hash_ent address as disk->id
+	instead of device phandle which is not unique.
+
+	* kern/sparc64/ieee1275/init.c: Delete, replace with...
+	* kern/sparc64/ieee1275/crt0.S: assembler implementation.
+	* include/grub/sparc64/ieee1275/kernel.h: Declare grub_prefix[].
+	(GRUB_MOD_ALIGN, GRUB_MOD_GAP, GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE,
+	GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE,
+	GRUB_KERNEL_MACHINE_COMPRESSED_SIZE, GRUB_KERNEL_MACHINE_PREFIX,
+	GRUB_KERNEL_MACHINE_DATA_END): Define.
+	(grub_kernel_image_size, grub_total_module_size): Declare.
+
+2009-04-12  Pavel Roskin  <proski@gnu.org>
+
+	 * configure.ac: Change the logic when we check for target tools.
+	 Do it when the target is specified and it's different from the
+	 specified value of the host.
+
+2009-04-11  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/hostdisk.c [__FreeBSD_kernel__]: Include sys/disk.h.
+	(grub_util_biosdisk_open) [__FreeBSD_kernel__]: Add support for
+	GNU/kFreeBSD. Check if a device is a character device. Use
+	DIOCGMEDIASIZE to get the size.
+	(convert_system_partition_to_system_disk) [__FreeBSD_kernel__]: Add
+	support for GNU/kFreeBSD.
+	(grub_util_biosdisk_get_grub_dev) [__FreeBSD_kernel__]: Check if OS_DEV
+	is a character device instead of a block device. Add support for
+	FreeBSD device names.
+
+	* util/getroot.c (find_root_device) [__FreeBSD_kernel__]: Check if ENT
+	is a character device instead of a block device.
+
+	* util/grub-probe.c (probe) [__FreeBSD_kernel__]: Check if DEVICE_NAME
+	is a character device instead of a block device.
+
+2009-04-11  Andrey Shuvikov  <mr_hyro@yahoo.com>
+
+	* util/hostdisk.c [__FreeBSD__]: Include sys/disk.h.
+	(grub_util_biosdisk_open) [__FreeBSD__]: Add support for
+	FreeBSD. Check if a device is a character device. Use
+	DIOCGMEDIASIZE to get the size.
+	(convert_system_partition_to_system_disk) [__FreeBSD__]: Add
+	support for FreeBSD.
+	(grub_util_biosdisk_get_grub_dev) [__FreeBSD__]: Check if OS_DEV
+	is a character device instead of a block device. Add support for
+	FreeBSD device names.
+
+	* util/getroot.c (find_root_device) [__FreeBSD__]: Check if ENT is
+	a character device instead of a block device.
+	(grub_util_check_char_device): New function.
+
+	* util/grub-probe.c (probe) [__FreeBSD__]: Check if DEVICE_NAME is
+	a character device instead of a block device.
+
+	* include/grub/util/getroot.h (grub_util_check_char_device): New
+	prototype.
+
+2009-04-11  David S. Miller  <davem@davemloft.net>
+
+	* conf/sparc64-ieee1275.rmk (kernel_img_LDFLAGS): Link with
+	static libgcc.
+	* configure.ac: Check for __bswapsi2 and __bswapdi2 presence.
+	* include/grub/sparc64/libgcc.h (__bswapsi2): Export libgcc
+	function, if present.
+	(__bswapdi2): Likewise.
+
+	* include/grub/sparc64/ieee1275/boot.h: New file.
+	* boot/sparc64/ieee1275/boot.S: Likewise.
+	* boot/sparc64/ieee1275/diskboot.S: Likewise.
+
+	* kern/misc.c (grub_ltoa): New function.
+	(grub_vsprintf): Use it to format 'long' integers.
+
+2009-04-10  David S. Miller  <davem@davemloft.net>
+
+	* disk/ieee1275/nand.c (grub_nand_open): All ieee1275 call arg
+	slots are of type grub_ieee1275_cell_t.
+	(grub_nand_read): Likewise.
+	* kern/ieee1275/ieee1275.c (IEEE1275_PHANDLE_INVALID,
+	IEEE1275_IHANDLE_INVALID): Use grub_ieee1275_cell_t since these
+	macros are used to compare values in arg/ret block of the call.
+	(grub_ieee1275_finddevice, grub_ieee1275_get_property,
+	grub_ieee1275_next_property, grub_ieee1275_get_property_length,
+	grub_ieee1275_instance_to_package, grub_ieee1275_package_to_path,
+	grub_ieee1275_instance_to_path, grub_ieee1275_write,
+	grub_ieee1275_read, grub_ieee1275_seek, grub_ieee1275_peer,
+	grub_ieee1275_child, grub_ieee1275_parent, grub_ieee1275_open,
+	grub_ieee1275_close, grub_ieee1275_set_property,
+	grub_ieee1275_set_color): All ieee1275 call arg slots are of type
+	grub_ieee1275_cell_t.
+	* kern/ieee1275/openfw.c (grub_map): Likewise.
+	* include/grub/ieee1275/ieee1275.h (grub_ieee1275_ihandle_t,
+	grub_ieee1275_phandle_t): Define as grub_unit32_t type.
+
+	* kern/ieee1275/init.c (grub_machine_init): Make 'actual' grub_ssize_t.
+	* kern/ieee1275/openfw.c (grub_children_iterate): Likewise.
+	(grub_devalias_iterate): Likewise.
+
+2009-04-10  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	UFS improvements
+
+	* fs/ufs.c (INODE_NBLOCKS): new definition
+	(struct grub_ufs_dirent): added fields for non-BSD dirents
+	(grub_ufs_get_file_block): fixed double indirect handling
+	(grub_ufs_lookup_symlink): use more robust way to determine whether
+	symlink is inline
+	(grub_ufs_find_file): support for non-BSD dirents
+	(grub_ufs_dir): support for non-BSD dirents
+
+2009-04-10  Bean  <bean123ch@gnail.com>
+
+	* include/grub/efi/api.h (grub_efi_configuration_table): Add packed
+	attribute, otherwise the size would be wrong for i386 platform.
+
+	* include/grub/pci.h (grub_pci_read_word): New inline function.
+	(grub_pci_read_byte): Likewise.
+	(grub_pci_write): Likewise.
+	(grub_pci_write_word): Likewise.
+	(grub_pci_write_byte): Likewise.
+
+	* include/grub/pci.h (grub_pci_iteratefunc_t): Add NESTED_FUNC_ATTR.
+
+	* loader/i386/efi/linux.c (fake_bios_data): Moved to loadbios module.
+	(find_framebuf): Scan pci to locate the frame buffer address.
+
+	* commands/efi/fixvideo.c: New file.
+
+	* commands/efi/loadbios.c: Likewise.
+
+	* commands/memrw.c: Likewise.
+
+	* util/grub-dumpbios.in: Likewise.
+
+	* conf/common.rmk (grub-dumpbios): New utility.
+	(pkglib_MODULES): New module memrw.mod.
+	(memrw_mod_SOURCE): New macro.
+	(memrw_mod_CFLAGS): Likewise.
+	(memrw_mod_LDFLAGS): Likewise.
+
+	* conf/i386-efi.rmk (pkglib_MODULES): New module loadbios.mod and
+	fixvideo.mod.
+	(loadbios_mod_SOURCE): New macro.
+	(loadbios_mod_CFLAGS): Likewise.
+	(loadbios_mod_LDFLAGS): Likewise.
+	(fixvideo_mod_SOURCE): Likewise.
+	(fixvideo_mod_CFLAGS): Likewise.
+	(fixvideo_mod_LDFLAGS): Likewise.
+
+	* conf/x86_64.rmk (pkglib_MODULES): New module loadbios.mod and
+	fixvideo.mod.
+	(loadbios_mod_SOURCE): New macro.
+	(loadbios_mod_CFLAGS): Likewise.
+	(loadbios_mod_LDFLAGS): Likewise.
+	(fixvideo_mod_SOURCE): Likewise.
+	(fixvideo_mod_CFLAGS): Likewise.
+	(fixvideo_mod_LDFLAGS): Likewise.
+
+2009-04-08  Felix Zielcke  <fzielcke@z-51.de>
+
+	* disk/lvm.c (grub_lvm_scan_device): Add a missing NULL check.
+
+2009-04-07  David S. Miller  <davem@davemloft.net>
+
+	* kern/sparc64/dl.c (grub_arch_dl_relocate_symbols): Add
+	support for R_SPARC_OLO10 relocations.  Fix compile warning for
+	R_SPARC_WDISP30 case.
+	* kern/sparc64/cache.S: Fix grub_arch_sync_caches implementation.
+
+2009-04-06  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/misc.h (ARRAY_SIZE): New macro.
+	* include/grub/i386/linux.h (GRUB_LINUX_VID_MODE_VESA_START):
+	New macro.
+	* loader/i386/linux.c (allocate_pages): Use free_pages().
+	(grub_linux_unload): Don't use free_pages().
+	(grub_linux_boot): Prevent accessing linux_vesafb_modes with a
+	wrong index.  Treat all other modes as text modes.
+	(grub_cmd_linux): Initialize vid_mode unconditionally to
+	GRUB_LINUX_VID_MODE_NORMAL.  Recognize and support "vga=ask".
+
+	* commands/help.c (print_command_help): Use cmd->prio, not
+	cmd->flags to check for GRUB_PRIO_LIST_FLAG_ACTIVE.
+
+2009-04-06  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Parttool
+
+	* parttool/pcpart.c: new file
+	* commands/parttool.c: likewise
+	* conf/common.rmk (pkglib_MODULES): Added parttool.mod and pcpart.mod
+	(parttool_mod_SOURCES): new variable
+	(parttool_mod_CFLAGS): likewise
+	(parttool_mod_LDFLAGS): likewise
+	(pcpart_mod_SOURCES): likewise
+	(pcpart_mod_CFLAGS): likewise
+	(pcpart_mod_LDFLAGS): likewise
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): added commands/parttool.c
+	and parttool/pcpart.c
+	* conf/i386-efi.rmk: likewise
+	* conf/i386-ieee1275.rmk: likewise
+	* conf/i386-pc.rmk: likewise
+	* conf/powerpc-ieee1275.rmk: likewise
+	* conf/sparc64-ieee1275.rmk: likewise
+	* conf/x86_64-ieee1275.rmk: likewise
+
+2009-04-05  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Support for mtime and further expandability of dir command
+
+	* include/grub/lib/datetime.h: moved to ...
+	* include/grub/datetime.h: ... moved here and added
+	declaration of grub_unixtime2datetime. All users updated
+	* include/grub/fs.h: new syntax for dir and mtime functions in
+	struct grub_fs
+	* include/grub/fshelp.h: new declarations of GRUB_FSHELP_TYPE_MASK
+	and GRUB_FSHELP_FLAGS_MASK
+	* commands/ls.c (grub_ls_list_files): Write mtime in long format
+	* fs/ext2.c (grub_ext2_dir): use new dir syntax and supply mtime
+	(grub_ext2_mtime): new function
+	* fs/hfsplus.c (grub_hfsplus_dir): use new dir syntax and supply mtime
+	(grub_hfsplus_mtime): new function
+	* fs/ufs.c (GRUB_UFS_ATTR_TYPE): new definition
+	(GRUB_UFS_ATTR_FILE): likewise
+	(GRUB_UFS_ATTR_LNK): likewise
+	(struct grub_ufs_sblock): new fields mtime
+	(grub_ufs_read_inode): new parameter to read inode to a separate buffer
+	all users updated
+	(grub_ufs_dir): mtime support
+	(grub_ufs_mtime): new function
+	* fs/affs.c (grub_affs_dir): use new dir syntax
+	* fs/afs.c (grub_afs_dir): likewise
+	* fs/cpio.c (grub_cpio_dir): likewise
+	* fs/fat.c (grub_fat_find_dir): likewise
+	* fs/hfs.c (grub_hfs_dir): likewise
+	* fs/iso9660.c (grub_iso9660_dir): likewise
+	* fs/jfs.c (grub_jfs_dir): likewise
+	* fs/minix.c (grub_minix_dir): likewise
+	* fs/ntfs.c (grub_ntfs_dir): likewise
+	* fs/reiserfs.c (grub_reiserfs_dir): likewise
+	* fs/sfs.c (grub_sfs_dir): likewise
+	* fs/xfs.c (grub_xfs_dir): likewise
+	* util/hostfs.c (grub_hostfs_dir): likewise
+	* lib/datetime.c: moved to ...
+	* normal/datetime.c: ... moved here
+	(grub_unixtime2datetime): new function
+	* kern/rescue.c (grub_rescue_print_files): use new dir syntax
+	* normal/completion.c (iterate_dir): use new dir syntax
+	* normal/misc.c (grub_normal_print_device_info): tell the
+	last modification time of a volume
+	* kern/fs.c (grub_fs_probe): updated dummy function to use new syntax
+	* conf/common.rmk: added lib/datetime.c to ls.mod
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): add normal/datetime.c
+	(normal_mod_SOURCES): likewise
+	(datetime_mod_SOURCES): Removed lib/datetime.c
+	* conf/i386-efi.rmk: likewise
+	* conf/i386-ieee1275.rmk: likewise
+	* conf/i386-pc.rmk: likewise
+	* conf/powerpc-ieee1275.rmk: likewise
+	* conf/sparc64-ieee1275.rmk: likewise
+	* conf/x86_64-efi.rmk: likewise
+
+2009-04-05  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Trim trailing spaces in FAT label and support mtools-like labels
+
+	* fs/fat.c (grub_fat_iterate_dir): New function based
+	on grub_fat_find_dir
+	(grub_fat_find_dir): use grub_fat_iterate_dir
+	(grub_fat_label): likewise
+
+2009-04-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* conf/powerpc-ieee1275.rmk (kernel_elf_HEADERS): add list.h
+	and command.h
+	remove extraneous kernel_elf_HEADERS
+
+2009-04-04  Bean  <bean123ch@gnail.com>
+
+	* include/grub/util/misc.h: Add dummy function fsync for mingw.
+
+	* util/misc.c: Likewise.
+
+2009-04-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* loader/i386/efi/linux.c (fake_bios_data): Use grub_dprintf
+	instead of grub_printf.
+
+2009-04-03  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/linux.c (grub_linux_setup_video): Fill
+	`params->{red,green,blue,reserved}_{mask_size,field_pos}' with
+	values from `mode info' structure instead of hardcoded
+	values.
+
+2009-04-01  Pavel Roskin  <proski@gnu.org>
+
+	* Makefile.in: Remove all references to MODULE_LDFLAGS, it's
+	unused now.
+	* genmk.rb: Likewise.
+	* configure.ac: Likewise.
+
+2009-04-01  Manoel Abranches  <mrabran@linux.vnet.ibm.com>
+
+	* aclocal.m4: Move --build-id=none from MODULE_LDFLAGS to
+	TARGET_LDFLAGS.  This corrects a problem with grub-mkelfimage.
+
+2009-04-01  David S. Miller  <davem@davemloft.net>
+
+	* normal/sparc64/setjmp.S: Fix setjmp implementation.
+	* include/grub/sparc64/setjmp.h (grub_jmp_buf): Update.
+	(grub_setjmp): Mark with 'returns_twice' attribute.
+	* include/grub/i386/setjmp.h (grub_setjmp): Likewise
+	* include/grub/powerpc/setjmp.h (grub_setjmp): Likewise.
+	* include/grub/x86_64/setjmp.h (grub_setjmp): Likewise.
+
+2009-04-01  Robert Millan  <rmh@aybabtu.com>
+
+	Reapply fix from 2008-07-28 which was accidentally reverted; also
+	perform the same fix to a similar check in same function.
+
+	* disk/raid.c (grub_raid_scan_device): Do not abort when two disks
+	with the same number are found, just use issue a warning with
+	grub_dprintf(), as this error has been reported to be non-fatal.
+
+2009-03-31  Pavel Roskin  <proski@gnu.org>
+
+	* aclocal.m4 (grub_I386_CHECK_REGPARM_BUG): Provide safe default
+	for cross-compilation.
+
+2009-03-30  Robert Millan  <rmh@aybabtu.com>
+
+	Fix i386-ieee1275 build.
+
+	* include/grub/i386/ieee1275/loader.h (grub_multiboot2_real_boot):
+	Remove declaration.
+
+2009-03-30  Pavel Roskin  <proski@gnu.org>
+
+	* fs/hfs.c (grub_hfs_strncasecmp): Integrate into ...
+	(grub_hfs_cmp_catkeys): ... this.  Don't assume strings to be
+	zero-terminated, rely only on the strlen value.  Fix comparison
+	of strings differing in length.
+
+2009-03-30  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/linux.c (grub_cmd_linux): Check for zImage before
+	checking for abi version.  Improve error messages on BIOS to notify
+	user about `linux16' command.
+
+2009-03-29  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Leak fixes
+
+	* kern/disk.c (grub_disk_cache_store): Invalidate previous cache
+	in case of collision
+	* disk/scsi.c (grub_scsi_open): free scsi in case of error
+
+2009-03-29  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/linux.c (grub_cmd_linux): Parse "vga=" parameter and
+	set `vid_mode' accordingly.
+	(grub_linux_boot): Process `vid_mode' and set video mode.
+
+2009-03-29  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/10_linux.in (linux_entry): New function.
+	Factorize generation of Linux boot entries.
+
+2009-03-29  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Make the format of Environment Block plain text. The boot loader
+	part is not tested well yet.
+
+	* util/grub-editenv.c (DEFAULT_ENVBLK_SIZE): New macro.
+	(buffer): Removed.
+	(envblk): Likewise.
+	(usage): Remove "info" and "clear". Add "unset". Update the
+	description of "set", as this does not delete variables any
+	longer.
+	(create_envblk_file): Complete rewrite.
+	(open_envblk_file): Likewise.
+	(cmd_info): Removed.
+	(cmd_list): Likewise.
+	(cmd_set): Likewise.
+	(cmd_clear): Likewise.
+	(list_variables): New function.
+	(write_envblk): Likewise.
+	(set_variables): Likewise.
+	(unset_variables): Likewise.
+	(main): Complete rewrite.
+
+	* commands/loadenv.c (buffer): Removed.
+	(envblk): Likewise.
+	(open_envblk_file): New function.
+	(read_envblk_file): Complete rewrite.
+	(grub_cmd_load_env): Likewise.
+	(grub_cmd_list_env): Likewise.
+	(struct blocklist): New struct.
+	(free_blocklists): New function.
+	(check_blocklists): Likewise.
+	(write_blocklists): Likewise.
+	(grub_cmd_save_env): Complete rewrite.
+
+	* include/grub/lib/envblk.h (GRUB_ENVBLK_SIGNATURE): Replaced with
+	a plain text signature.
+	(GRUB_ENVBLK_MAXLEN): Removed.
+	(struct grub_envblk): Complete rewrite.
+	(grub_envblk_find): Removed.
+	(grub_envblk_insert): Likewise.
+	(grub_envblk_open): New prototype.
+	(grub_envblk_set): Likewise.
+	(grub_envblk_delete): Put const to VALUE.
+	(grub_envblk_iterate): Put const to NAME and VALUE.
+	(grub_envblk_close): New prototype.
+	(grub_envblk_buffer): New inline function.
+	(grub_envblk_size): Likewise.
+
+	* lib/envblk.c: Include grub/mm.h.
+	(grub_env_find): Removed.
+	(grub_envblk_open): New function.
+	(grub_envblk_close): Likewise.
+	(escaped_value_len): Likewise.
+	(find_next_line): Likewise.
+	(grub_envblk_insert): Removed.
+	(grub_envblk_set): New function.
+	(grub_envblk_delete): Complete rewrite.
+	(grub_envblk_iterate): Likewise.
+
+2009-03-28  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-pc.rmk (pkglib_MODULES): Add `linux16.mod'.
+	(linux16_mod_SOURCES, linux16_mod_CFLAGS, linux16_mod_LDFLAGS): New
+	variables.  Use 16-bit loader.
+	(linux_mod_SOURCES, linux_mod_CFLAGS, linux_mod_LDFLAGS): Use 32-bit
+	loader.
+	* kern/i386/loader.S (grub_linux_boot): Rename to ...
+	(grub_linux16_boot): ... this.  Update all users.
+	* loader/i386/linux.c (grub_linux32_boot): Rename to ...
+	(grub_linux_boot): ... this.  Update all users.
+
+	* loader/i386/pc/linux.c (GRUB_MOD_INIT(linux)): Rename to ...
+	(GRUB_MOD_INIT(linux16)): ... this.  Rename `linux' and `initrd'
+	commands to `linux16' and `initrd16'.
+	(GRUB_MOD_FINI(linux)): Rename to ...
+	(GRUB_MOD_FINI(linux16)): ... this.
+
+2009-03-24  Pavel Roskin  <proski@gnu.org>
+
+	* genmk.rb: Define ASM_FILE for *.S files for *.lst generation,
+	not just for compilation.
+
+2009-03-22  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Move multiboot helper out of kernel
+
+	* conf/i386-pc.rmk (multiboot_mod_SOURCES): Add
+	`loader/i386/multiboot_helper.S'.
+	* conf/i386-coreboot.rmk: Likewise
+	* conf/i386-ieee1275.rmk: Likewise
+
+	* kern/i386/loader.S: Move multiboot helpers from here...
+	* loader/i386/multiboot_helper.S: ...moved here
+	* include/grub/i386/loader.h: Move declarations of multiboot
+	helpers from here...
+	* include/grub/i386/multiboot.h: ...moved here
+	* loader/i386/multiboot.c: Added include of grub/cpu/multiboot.h
+
+2009-03-22  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/env.c (grub_env_context_open): Added an argument to specify
+	whether a new context inherits exported variables from current
+	one. This is useful when making a sandbox to interpret a config
+	file.
+	All callers updated.
+
+	* include/grub/env.h (grub_env_context_open): Updated the prototype.
+
+2009-03-22  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/env.c (grub_env_context_close): Fix memory leaks.
+
+2009-03-22  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* normal/main.c (grub_normal_execute): Added an argument
+	BATCH to specify if an interactive interface should be provided
+	after reading a config file.
+	All callers updated.
+	(read_command_list): Prevent being executed twice.
+	(read_fs_list): Likewise.
+
+	* include/grub/normal.h (grub_normal_execute): Updated the
+	prototype.
+
+2009-03-22  Pavel Roskin  <proski@gno.org>
+
+	* kern/powerpc/ieee1275/startup.S: Replace EXT_C(start) with
+	_start.
+	* kern/i386/pc/startup.S: Likewise.
+	* kern/i386/efi/startup.S: Likewise.
+	* kern/i386/ieee1275/startup.S: Likewise.
+	* kern/i386/coreboot/startup.S: Likewise.
+	* kern/x86_64/efi/startup.S: Likewise.
+
+	* aclocal.m4 (grub_CHECK_START_SYMBOL): Remove.
+	* configure.ac: Don't call grub_CHECK_START_SYMBOL.
+	* kern/i386/pc/startup.S: Use _start instead of START_SYMBOL.
+
+2009-03-21  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Bugfixes in multiboot for bugs uncovered by solaris kernel.
+
+	* loader/i386/multiboot_elfxx.c (grub_multiboot_load_elf): Corrected
+	limit detection.
+	Use vaddr of correct segment for entry_point.
+
+2009-03-21  Bean  <bean123ch@gmail.com>
+
+	* commands/blocklist.c: Add include file <grub/command.h>, remove
+	<grub/normal.h> and <grub/arg.h>.
+	(grub_cmd_blocklist): Use the new command interface.
+	(GRUB_MOD_INIT): Likewise.
+	(GRUB_MOD_FINI): Likewise.
+	* commands/boot.c: Likewise.
+	* commands/cat.c: Likewise.
+	* commands/cmp.c: Likewise.
+	* commands/configfile.c: Likewise.
+	* commands/crc.c: Likewise.
+	* commands/echo.c: Likewise.
+	* commands/halt.c: Likewise.
+	* commands/handler.c: Likewise.
+	* commands/hdparm.c: Likewise.
+	* commands/help.c: Likewise.
+	* commands/hexdump.c: Likewise.
+	* commands/loadenv.c: Likewise.
+	* commands/ls.c: Likewise.
+	* commands/lsmmap.c: Likewise.
+	* commands/lspci.c: Likewise.
+	* commands/loadenv.c: Likewise.
+	* commands/read.c: Likewise.
+	* commands/reboot.c: Likewise.
+	* commands/search.c: Likewise.
+	* commands/sleep.c: Likewise.
+	* commands/test.c: Likewise.
+	* commands/usbtest.c: Likewise.
+	* commands/videotest.c: Likewise.
+	* commands/i386/cpuid.c: Likewise.
+	* commands/i386/pc/halt.c: Likewise.
+	* commands/i386/pc/play.c: Likewise.
+	* commands/i386/pc/pxecmd.c: Likewise.
+	* commands/i386/pc/vbeinfo.c: Likewise.
+	* commands/i386/pc/vbetest.c: Likewise.
+	* commands/ieee1275/suspend.c: Likewise.
+	* disk/loopback.c: Likewise.
+	* font/font_cmd.c: Likewise.
+	* hello/hello.c: Likewise.
+	* loader/efi/appleloader.c: Likewise.
+	* loader/efi/chainloader.c: Likewise.
+	* loader/i386/bsd.c: Likewise.
+	* loader/i386/efi/linux.c: Likewise.
+	* loader/i386/ieee1275/linux.c: Likewise.
+	* loader/i386/linux.c: Likewise.
+	* loader/i386/pc/chainloader.c: Likewise.
+	* loader/i386/pc/linux.c: Likewise.
+	* loader/powerpc/ieee1275/linux.c: Likewise.
+	* loader/multiboot_loader.c: Likewise.
+	* term/gfxterm.c: Likewise.
+	* term/i386/pc/serial.c: Likewise.
+	* term/terminfo.c: Likewise.
+
+	* term/i386/pc/vesafb.c: Removed <grub/arg.h>.
+	* term/i386/pc/vga.c: Likewise.
+	* video/readers/jpeg.c: Likewise.
+	* video/readers/png.c: Likewise.
+	* video/readers/tga.c: Likewise.
+
+	* util/grub-fstest (cmd_loopback): Removed.
+	(cmd_blocklist): Likewise.
+	(cmd_ls): Likewise.
+	(grub_register_command): Likewise.
+	(grub_unregister_command): Likewise.
+	(execute_command): Use grub_command_find to locate command and execute
+	it.
+
+	* include/grub/efi/chainloader.h: Removed.
+	* loader/efi/chainloader_normal.c: Likewise.
+	* loader/i386/bsd_normal.c: Likewise.
+	* loader/i386/pc/chainloader_normal.c: Likewise.
+	* loader/i386/pc/multiboot_normal.c: Likewise.
+	* loader/linux_normal.c: Likewise.
+	* loader/multiboot_loader_normal.c: Likewise.
+	* loader/powerpc/ieee1275/linux_normal.c: Likewise.
+
+	* gencmdlist.sh: Scan new registration command grub_register_extcmd
+	and grub_register_command_p1.
+
+	* conf/common.rmk (grub_fstest_SOURCES): Add kern/list.c,
+	kern/command.c, lib/arg.c and commands/extcmd.c.
+	(pkglib_MODULES): Remove boot.mod, and minicmd.mod and extcmd.mod.
+	(minicmd_mod_SOURCES): New variable.
+	(minicmd_mod_CFLAGS): Likewise.
+	(minicmd_mod_LDFLAGS): Likewise.
+	(extcmd_mod_SOURCES): Likewise.
+	(extcmd_mod_CFLAGS): Likewise.
+	(extcmd_mod_LDFLAGS): Likewise.
+	(boot_mod_SOURCES): Removed.
+	(boot_mod_CFLAGS): Likewise.
+	(boot_mod_LDFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Add kern/command.c and
+	kern/corecmd.c.
+	(kernel_img_HEADERS): Add command.h.
+	(grub_emu_SOURCES): Remove commands/boot.c and normal/arg.c, add
+	commands/minicmd.c, kern/command.c, kern/corecmd.c, commands/extcmd.c
+	and lib/arg.c.
+	(pkglib_MODULES): Change _linux.mod, _chain.mod, _bsd.mod and
+	_multiboot.mod as linux.mod, chain.mod, bsd.mod and multiboot.mod,
+	remove the corresponding normal mode command.
+	(normal_mod_SOURCES): Remove normal/arg.c.
+	* conf/i386-coreboot.rmk: Likewise.
+	* conf/i386-efi.rmk: Likewise.
+	* conf/i386-ieee1275.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	* conf/x86_64-efi.rmk: Likewise.
+
+	* include/grub/arg.h: Move from here ...
+	* include/grub/lib/arg.h: ... to here.
+
+	* normal/arg.c: Move from here ...
+	* lib/arg.c: ... to here.
+
+	* commands/extcmd.c: New file.
+	* commands/minicmd.c: Likewise.
+	* include/grub/command.h: Likewise.
+	* include/grub/extcmd.h: Likewise.
+	* kern/command.c: Likewise.
+	* kern/corecmd.c: Likewise.
+
+	* kern/list.c (grub_list_iterate): Return int instead of void.
+	(grub_list_insert): New function.
+	(grub_prio_list_insert): Likewise.
+
+	* kern/rescue.c (grub_rescue_command): Removed.
+	(grub_rescue_command_list): Likewise.
+	(grub_rescue_register_command): Likewise.
+	(grub_rescue_unregister_command): Likewise.
+	(grub_rescue_cmd_boot): Move to minicmd.c
+	(grub_rescue_cmd_help): Likewise.
+	(grub_rescue_cmd_info): Likewise.
+	(grub_rescue_cmd_boot): Likewise.
+	(grub_rescue_cmd_testload): Likewise.
+	(grub_rescue_cmd_dump): Likewise.
+	(grub_rescue_cmd_rmmod): Likewise.
+	(grub_rescue_cmd_lsmod): Likewise.
+	(grub_rescue_cmd_exit): Likewise.
+	(grub_rescue_print_devices): Moved to corecmd.c.
+	(grub_rescue_print_files): Likewise.
+	(grub_rescue_cmd_ls): Likewise.
+	(grub_rescue_cmd_insmod): Likewise.
+	(grub_rescue_cmd_set): Likewise.
+	(grub_rescue_cmd_unset): Likewise.
+	(attempt_normal_mode): Use grub_command_find to get normal module.
+	(grub_enter_rescue_mode): Use grub_register_core_commands to register
+	commands, remove grub_rescue_register_command calls.
+
+	* normal/command.c (grub_register_command): Removed.
+	(grub_unregister_command): Likewise.
+	(grub_command_find): Likewise.
+	(grub_iterate_commands): Likewise.
+	(rescue_command): Likewise.
+	(export_command): Moved to corecmd.c.
+	(set_command): Removed.
+	(unset_command): Likewise.
+	(insmod_command): Likewise.
+	(rmmod_command): Likewise.
+	(lsmod_command): Likewise.
+	(grub_command_init): Likewise.
+
+	* normal/completion.c (iterate_command): Use cmd->prio to check for
+	active command.
+	(complete_arguments): Use grub_extcmd_t structure to find options.
+	(grub_normal_do_completion): Change function grub_iterate_commands to
+	grub_command_iterate.
+
+	* normal/execute.c (grub_script_execute_cmd): No need to parse
+	argument here.
+
+	* normal/main.c (grub_dyncmd_dispatcher): New function.
+	(read_command_list): Register unload commands as dyncmd.
+	(grub_cmd_normal): Use new command interface, register rescue,
+	unregister normal at entry, register normal, unregister rescue at exit.
+
+	* include/grub/list.h (grub_list_test_t): New type.
+	(grub_list_iterate): Return int instead of void.
+	(grub_list_insert): New function.
+	(GRUB_AS_NAMED_LIST_P): New macro.
+	(GRUB_AS_PRIO_LIST): Likewise.
+	(GRUB_AS_PRIO_LIST_P): Likewise.
+	(GRUB_PRIO_LIST_PRIO_MASK): New constant.
+	(GRUB_PRIO_LIST_FLAG_ACTIVE): Likewise.
+	(grub_prio_list): New structure.
+	(grub_prio_list_insert): New function.
+	(grub_prio_list_remove): New inline function.
+
+	* include/grub/normal.h: Remove <grub/arg.h>, add <grub/command.h>.
+	(GRUB_COMMAND_FLAG_CMDLINE): Moved to command.h.
+	(GRUB_COMMAND_FLAG_MENU): Likewise.
+	(GRUB_COMMAND_FLAG_BOTH): Likewise.
+	(GRUB_COMMAND_FLAG_TITLE): Likewise.
+	(GRUB_COMMAND_FLAG_NO_ECHO): Likewise.
+	(GRUB_COMMAND_FLAG_NO_ARG_PARSE): Removed.
+	(GRUB_COMMAND_FLAG_NOT_LOADED): Likewise.
+	(grub_command): Likewise.
+	(grub_register_command): Likewise.
+	(grub_command_find): Likewise.
+	(grub_iterate_commands): Likewise.
+	(grub_command_init): Likewise.
+	(grub_arg_parse): Likewise.
+	(grub_arg_show_help): Likewise.
+
+	* include/grub/rescue.h (grub_rescue_register_command): Removed.
+	(grub_rescue_unregister_command): Likewise.
+
+	* include/grub/i386/bsd.h: Remove grub_rescue_cmd_freebsd,
+	grub_rescue_cmd_openbsd, grub_rescue_cmd_netbsd,
+	grub_rescue_cmd_freebsd_loadenv and grub_rescue_cmd_freebsd_module.
+
+	* include/grub/i386/efi/loader.h: Remove grub_rescue_cmd_linux and
+	grub_rescue_cmd_initrd.
+	* include/grub/i386/loader.h: Likewise.
+	* include/grub/x86_64/loader.h: Likewise.
+
+	* include/grub/i386/pc/chainloader.h: Remove grub_chainloader_cmd.
+
+2009-03-21  Bean  <bean123ch@gmail.com>
+
+	* util/hostdisk.c (read_device_map): Use grub_util_get_disk_size
+	instead of stat in mingw environment.
+
+	* util/misc.c (grub_millisleep): Use Sleep in mingw environment.
+
+	* aclocal.m4 (grub_CHECK_LINK_DIR): New function.
+
+	* configure.ac: Use grub_CHECK_LINK_DIR to determine whether to use
+	AC_CONFIG_LINKS.
+
+2009-03-21  Bean  <bean123ch@gmail.com>
+
+	* fs/ext2.c (grub_ext2_mount): Change errno to GRUB_ERR_BAD_FS for
+	out of range error.
+
+2009-03-18  Michel Dänzer  <michel@daenzer.net>
+
+	* fs/ext2.c (grub_ext2_read_block): Take endianness into account when
+	checking inode flags for EXT4_EXTENTS_FLAG.
+
+2009-03-18  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/linux.c: Include `<grub/video.h>' and
+	`<grub/i386/pc/vbe.h>'..
+	(grub_linux_setup_video): New function.  Loosely based on the EFI one.
+	(grub_linux32_boot): Attempt to configure video settings with
+	grub_linux_setup_video().
+	(grub_rescue_cmd_linux): Set noreturn=0 in grub_loader_set, in order
+	to avoid grub_console_fini() which would step out of graphical mode
+	unconditionally.
+
+2009-03-14  Robert Millan  <rmh@aybabtu.com>
+
+	Fix build on powerpc.
+	* conf/powerpc-ieee1275.rmk (kernel_elf_HEADERS): Add `handler.h'.
+
+2009-03-12  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	* term/gfxterm.c (GRUB_MOD_FINI(term_gfxterm)): Correct name of
+	background image command.
+
+2009-03-12  Colin D Bennett  <colin@gibibit.com>
+
+	* term/gfxterm.c (draw_cursor): Ensure character is redrawn.
+	(grub_gfxterm_putchar): Extract pairs of identical calls to
+	draw_cursor out of conditional blocks.
+
+2009-03-11  Pavel Roskin  <proski@gnu.org>
+
+	* fs/hfs.c (grub_hfs_strncasecmp): New function.
+	(grub_hfs_cmp_catkeys): Use HFS specific string comparison.
+
+2009-03-11  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/multiboot_elfxx.c
+	(CONCAT(grub_multiboot_load_elf, XX)): Do not reject ET_DYN files.
+
+2009-03-11  Felix Zielcke  <fzielcke@z-51.de>
+
+	* conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Add `kern/list.c' and
+	`kern/handler.c'.
+
+2009-03-11  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/multiboot.c (code_size): New variable.
+	(grub_multiboot): Define offsets by adding to `code_size' rather
+	than subtracting from `grub_multiboot_payload_size'.  Provide
+	4-byte alignment to MBI and others by increasing
+	`boot_loader_name_length' appropriately.
+
+	* loader/i386/multiboot_elfxx.c
+	(CONCAT(grub_multiboot_load_elf, XX)): Initialize `code_size'.
+
+2009-03-09  Felix Zielcke  <fzielcke@z-51.de>
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Remove duplicated
+	`fs/ext2.c'.
+
+2009-03-08  Robert Millan  <rmh@aybabtu.com>
+
+	Make loader/i386/linux.c usable on i386-pc again.
+
+	* kern/i386/pc/init.c (grub_machine_init): Disable addition of low
+	memory to heap.
+	* loader/i386/linux.c [GRUB_MACHINE_PCBIOS] (allocate_pages): Remove
+	`#error' stanza.
+
+2009-03-07  Bean  <bean123ch@gmail.com>
+
+	* loader/i386/efi/linux.c (grub_rescue_cmd_initrd): Fix a bug in initrd
+	allocation.
+
+2009-03-06  Robert Millan  <rmh@aybabtu.com>
+
+	Fix display issue on terminals with screen size other than 80x25
+	(e.g. gfxterm with resolution higher than 640x480).
+
+	* normal/main.c (grub_normal_init_page): Display title text in a
+	position relative to the center of the terminal instead of relying
+	on a hardcoded offset.
+
+2009-03-04  Robert Millan  <rmh@aybabtu.com>
+
+	Filter /etc/grub.d/10_* so that only add-ons for native kernels are
+	installed.
+
+	* Makefile.in (host_kernel): New variable.
+	* conf/common.rmk (grub-mkconfig_SCRIPTS): Conditionalize all 10_*.in
+	scripts instead of just the windows one.
+	* configure.ac: Initialize and AC_SUBST `host_kernel'.
+
+2009-03-04  Felix Zielcke  <fzielcke@z-51.de>
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add `kern/list.c' and
+	`kern/handler.c'.
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+	* conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+2009-03-04  Felix Zielcke  <fzielcke@z-51.de>
+
+	* partmap/pc.c (pc_partition_map_iterate): Skip over invalid BSD partitions
+	or if there's no space for the disk label and print the partition number on a
+	invalid magic.
+
+2009-03-04  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/misc.c: Include <time.h>.
+	(grub_millisleep): New function.
+
+2009-03-04  Bean  <bean123ch@gmail.com>
+
+	* configure.ac: Only test -mcmodel=large option in x86_64-efi, also add
+	another option -mno-red-zone.
+
+	* commands/handler.c: Change module description.
+
+	* kern/handler.c: Add missing space at the end of description line.
+
+	* kern/list.c: Likewise.
+
+2009-03-03  Robert Millan  <rmh@aybabtu.com>
+
+	Move more components to the relocation area, and fix mbi pointer
+	handling to use the destination rather than the origin (thanks to
+	Vladimir Serbinenko for spotting).
+
+	* loader/i386/multiboot.c (mbi_dest): New variable.
+	(grub_multiboot_boot): Use `mbi_dest' instead of `mbi'.
+	(grub_multiboot): Put cmdline, boot_loader_name and mbi in the
+	relocation area.
+
+2009-03-01  Bean  <bean123ch@gmail.com>
+
+	* include/grub/efi/api.h (GRUB_EFI_MPS_TABLE_GUID): New constant.
+	(GRUB_EFI_ACPI_TABLE_GUID): Likewise.
+	(GRUB_EFI_ACPI_20_TABLE_GUID): Likewise.
+	(GRUB_EFI_SMBIOS_TABLE_GUID): Likewise.
+
+	* loader/i386/efi/linux.c (acpi_guid): New variable.
+	(acpi_guid): Likewise.
+	(EBDA_SEG_ADDR): New constant.
+	(LOW_MEM_ADDR): Likewise.
+	(FAKE_EBDA_SEG): Likewise.
+	(fake_bios_data): New function.
+	(grub_linux_boot): Call fake_bios_data.
+
+2009-03-01  Bean  <bean123ch@gmail.com>
+
+	* commands/terminal.c: Removed.
+
+	* commands/handler.c: New file.
+
+	* include/grub/list.h: Likewise.
+
+	* include/grub/handler.h: Likewise.
+
+	* kern/list.c: Likewise.
+
+	* kern/handler.c: Likewise.
+
+	* kern/term.h: Include header file <grub/handler.h>.
+	(grub_term_input): Move next field to the beginning.
+	(grub_term_output): Likewise.
+	(grub_term_input_class): New variable.
+	(grub_term_output_class): Likewise.
+	(grub_term_register_input): Changed to inline function.
+	(grub_term_register_output): Likewise.
+	(grub_term_unregister_input): Likewise.
+	(grub_term_unregister_output): Likewise.
+	(grub_term_set_current_input): Likewise.
+	(grub_term_set_current_output): Likewise.
+	(grub_term_get_current_input): Likewise.
+	(grub_term_get_current_output): Likewise.
+	(grub_term_iterate_input): Removed.
+	(grub_term_iterate_output): Likewise.
+
+	* kern/term.c (grub_term_list_input): Removed.
+	(grub_term_list_output): Likewise.
+	(grub_term_input_class): New variable.
+	(grub_term_output_class): Likewise.
+	(grub_cur_term_input): Change variable as macro.
+	(grub_cur_term_output): Likewise.
+	(grub_term_register_input): Removed.
+	(grub_term_register_output): Likewise.
+	(grub_term_unregister_input): Likewise.
+	(grub_term_unregister_output): Likewise.
+	(grub_term_set_current_input): Likewise.
+	(grub_term_set_current_output): Likewise.
+	(grub_term_iterate_input): Likewise.
+	(grub_term_iterate_output): Likewise.
+	(grub_term_get_current_input): Likewise.
+	(grub_term_get_current_output): Likewise.
+
+	* util/grub-editenv.c: Include header file <grub/handler.h>.
+	(grub_term_get_current_input): Removed.
+	(grub_term_get_current_output): Likewise.
+	(grub_term_input_class): New variable.
+	(grub_term_output_class): Likewise.
+
+	* util/grub-fstest.c (grub_term_get_current_input): Removed.
+	(grub_term_get_current_output): Likewise.
+	(grub_term_input_class): New variable.
+	(grub_term_output_class): Likewise.
+
+	* util/grub-probe.c (grub_term_get_current_input): Removed.
+	(grub_term_get_current_output): Likewise.
+	(grub_term_input_class): New variable.
+	(grub_term_output_class): Likewise.
+
+	* util/i386/pc/grub-setup.c (grub_term_get_current_input): Removed.
+	(grub_term_get_current_output): Likewise.
+	(grub_term_input_class): New variable.
+	(grub_term_output_class): Likewise.
+
+	* conf/common.rmk (pkglib_MODULES): Replace terminal with handler.
+	(terminal_mod_SOURCES): Likewise.
+	(terminal_mod_CFLAGS): Likewise.
+	(terminal_mod_LDFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Replace terminal.c with
+	handler.c.
+	(kernel_img_SOURCES): Add list.c and handler.c.
+	(kernel_img_HEADERS): Add list.h and handler.h.
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Replace terminal.c with
+	handler.c.
+	(kernel_mod_SOURCES): Add list.c and handler.c.
+	(kernel_mod_HEADERS): Add list.h and handler.h.
+
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Replace terminal.c with
+	handler.c.
+	(kernel_elf_SOURCES): Add list.c and handler.c.
+	(kernel_elf_HEADERS): Add list.h and handler.h.
+
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Replace terminal.c with
+	handler.c.
+	(kernel_elf_SOURCES): Add list.c and handler.c.
+	(kernel_elf_HEADERS): Add list.h and handler.h.
+
+	* conf/x86_64-efi.rmk (grub_emu_SOURCES): Replace terminal.c with
+	handler.c.
+	(kernel_mod_SOURCES): Add list.c and handler.c.
+	(kernel_mod_HEADERS): Add list.h and handler.h.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Replace terminal.c with
+	handler.c.
+	(kernel_elf_SOURCES): Add list.c and handler.c.
+	(kernel_elf_HEADERS): Add list.h and handler.h.
+
+2009-02-27  Robert Millan  <rmh@aybabtu.com>
+
+	Factorize elf32 / elf64 code in Multiboot loader.  This will
+	prevent it from getting out of sync again.
+
+	* loader/i386/multiboot.c (grub_multiboot_is_elf32,
+	grub_multiboot_load_elf32, grub_multiboot_is_elf64,
+	grub_multiboot_load_elf64): Move from here ...
+	* loader/i386/multiboot_elfxx.c (grub_multiboot_is_elf,
+	grub_multiboot_load_elf): ... to here (new file).
+
+2009-02-27  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/10_linux.in: Rename "single-user mode" to
+	"recovery mode".
+
+2009-02-27  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Don't leak in SCSI code.
+	* disk/scsi.c (grub_scsi_close): free `scsi'.
+
+2009-02-27  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/multiboot.c: Move from here ...
+	* loader/i386/multiboot.c: ... to here.  Update all users.
+
+2009-02-27  Robert Millan  <rmh@aybabtu.com>
+
+	Patch from Alexandre Bique <bique.alexandre@gmail.com>
+	* util/i386/pc/grub-setup.c (setup): Fix directory path.
+
+2009-02-27  Krzysztof Smiechowicz  <deadwood@wp.pl>
+
+	* fs/sfs.c (grub_sfs_read_extent): Correction to traversing extent
+	b-tree.
+
+2009-02-27  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/misc.c (grub_strtoull): Fix bug (it mistakenly parsed the
+	`0x' qualifier as 0 when base is specified as parameter).
+
+2009-02-24  Bean  <bean123ch@gmail.com>
+
+	* configure.ac: Check for -mcmodel=large in x86_64 target.
+
+	* include/grub/efi/api.h (efi_call_10): New macro.
+	(efi_wrap_10): New function.
+
+	* include/grub/efi/pe32.h (GRUB_PE32_REL_BASE_HIGH): New macro.
+	(GRUB_PE32_REL_BASED_HIGH): Likewise.
+	(GRUB_PE32_REL_BASED_LOW): Likewise.
+	(GRUB_PE32_REL_BASED_HIGHLOW): Likewise.
+	(GRUB_PE32_REL_BASED_HIGHADJ): Likewise.
+	(GRUB_PE32_REL_BASED_MIPS_JMPADDR): Likewise.
+	(GRUB_PE32_REL_BASED_SECTION): Likewise.
+	(GRUB_PE32_REL_BASED_REL): Likewise.
+	(GRUB_PE32_REL_BASED_IA64_IMM64): Likewise.
+	(GRUB_PE32_REL_BASED_DIR64): Likewise.
+	(GRUB_PE32_REL_BASED_HIGH3ADJ): Likewise.
+
+	* kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Fixed relocation
+	issue.
+
+	* kern/x86_64/efi/callwrap.S (efi_wrap_6): Bug fix.
+	(efi_wrap_10): New function.
+
+	* kern/x86_64/efi/startup.S (codestart): Use relative addressing.
+
+	* loader/efi/appleloader.c (devpath_5): Add support for late 2008
+	MB/MBP model (NV chipset).
+	(devdata_devs): Add devpath_5 to the list.
+
+	* load/i386/efi/linux.c (video_base): Remove variable.
+	(RGB_MASK): New macro.
+	(RGB_MAGIC): Likewise.
+	(LINE_MIN): Likewise.
+	(LINE_MAX): Likewise.
+	(FBTEST_STEP): Likewise.
+	(FBTEST_COUNT): Likewise.
+	(fb_list): New variable.
+	(grub_find_video_card): Remove function.
+	(find_framebuf): New function.
+	(grub_linux_setup_video): Use find_framebuf to get frame buffer and
+	line length.
+
+	* util/i386/efi/grub-mkimage.c (grub_reloc_section): Fix relocation
+	problem for x86_64.
+
+2009-02-22  Vesa Jääskeläinen  <chaac@nic.fi>
+
+	Patch #25624 by Kevin Lacquement <kevin@lacqui>.
+
+	* util/grub-mkconfig.in: Use ${grub_mkdevicemap} instead of hard
+	coding tool name.
+
+2009-02-22  Robert Millan  <rmh@aybabtu.com>
+
+	* include/multiboot.h (MULTIBOOT_INFO_ALIGN): New macro.
+	* loader/i386/pc/multiboot.c (grub_multiboot): Include the MBI
+	in our relocation, instead of using it directly from heap.  Also
+	use `MULTIBOOT_INFO_ALIGN' to ensure it is aligned.
+
+2009-02-21  Robert Millan  <rmh@aybabtu.com>
+
+	Implement USB keyboard support (based on patch by Marco Gerards)
+
+	* conf/i386-pc.rmk (pkglib_MODULES): Add `usb_keyboard.mod'.
+	(usb_keyboard_mod_SOURCES, usb_keyboard_mod_CFLAGS)
+	(usb_keyboard_mod_LDFLAGS): New variables.
+
+	* term/usb_keyboard.c: New file.
+
+2009-02-14  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Corrected wrong declaration
+
+	* kern/disk.c: corrected declaration of grub_disk_ata_pass_through.
+
+2009-02-14  Christian Franke  <franke@computer.org>
+
+	* commands/lspci.c (grub_pci_classes): Add `SATA Controller'.
+	(grub_lspci_iter): Print class code and programming interface byte.
+
+2009-02-14  Christian Franke  <franke@computer.org>
+
+	* gendistlist.sh: Ignore `.svn' directories.
+
+2009-02-14  Felix Zielcke  <fzielcke@z-51.de>
+
+	* fs/fat.c: Add 2009 to Copyright line.
+
+2009-02-14  Christian Franke  <franke@computer.org>
+
+	* commands/hdparm.c: New file.  Provides `hdparm' command
+	which sends ATA commands via grub_disk_ata_pass_through ().
+
+	* conf/i386-pc.rmk: Add ata_pthru.mod and hdparm.mod.
+
+	* disk/ata.c: Include <grub/ata.h>.  Move <grub/misc.h>
+	and <grub/cpu/io.h> to include/grub/ata.h.
+	(enum grub_ata_addressing_t): Move to include/grub/ata.h.
+	(GRUB_CDROM_SECTOR_SIZE): Remove.
+	(GRUB_ATA_*): Move to include/grub/ata.h.
+	(GRUB_ATAPI_*): Likewise.
+	(enum grub_ata_commands): Likewise.
+	(enum grub_ata_timeout_milliseconds): Likewise.
+	(struct grub_ata_device): Likewise.
+	(grub_ata_regset): Likewise.
+	(grub_ata_regget): Likewise.
+	(grub_ata_regset2): Likewise.
+	(grub_ata_regget2): Likewise.
+	(grub_ata_check_ready): Likewise.
+	(grub_ata_wait_not_busy): Remove static, exported in
+	include/grub/ata.h.
+	(grub_ata_wait_drq): Likewise.
+	(grub_ata_pio_read): Likewise.
+
+	* disk/ata_pthru.c: New file.  Provides grub_ata_pass_through ()
+	function for hdparm.mod.
+
+	* include/grub/ata.h: New file, contains declarations from
+	disk/ata.c.
+	(enum grub_ata_commands): Add new commands for commands/hdparm.c.
+
+	* include/grub/disk.h (grub_disk_ata_pass_through_parms): New struct.
+	(grub_disk_ata_pass_through): New exported variable.
+
+	* kern/disk.c (grub_disk_ata_pass_through): New variable.
+
+2009-02-13  Colin D Bennett  <colin@gibibit.com>
+
+	Support multiple fallback entries, and provide an API to support
+	executing default+fallback menu entries.  Renamed the `terminal' menu
+	viewer to `text'.
+
+	* include/grub/normal.h (grub_normal_text_menu_viewer): New global
+	variable declaration.
+	(grub_menu_execute_callback): New structure declaration.
+	(grub_menu_execute_callback_t): New typedef.
+	(grub_menu_execute_with_fallback): New function declaration.
+	(grub_menu_get_entry): Likewise.
+	(grub_menu_get_timeout): Likewise.
+	(grub_menu_set_timeout): Likewise.
+
+	* normal/main.c (GRUB_MOD_INIT(normal)): Refer to new variable name.
+
+	* normal/menu.c (grub_wait_after_message): Moved to
+	`normal/menu_text.c'.
+	(draw_border): Likewise.
+	(print_message): Likewise.
+	(print_entry): Likewise.
+	(print_entries): Likewise.
+	(grub_menu_init_page): Likewise.
+	(get_entry_number): Likewise.
+	(print_timeout): Likewise.
+	(run_menu): Likewise.
+	(grub_menu_execute_entry): Likewise.
+	(show_text_menu): Likewise.
+	(get_and_remove_first_entry_number): New function.
+	(grub_menu_execute_with_fallback): Likewise.
+	(get_entry): Renamed to ...
+	(grub_menu_get_entry): .. this and made it global.
+	(get_timeout): Renamed to ...
+	(grub_menu_get_timeout): ... this and made it global.
+	(set_timeout): Renamed to ...
+	(grub_menu_set_timeout): ... this and made it global.
+	(grub_normal_terminal_menu_viewer): Renamed to ...
+	(grub_normal_text_menu_viewer): ... this.
+
+	* normal/menu_text.c: New file.  Extracted text-menu-specific code
+	from normal/menu.c.
+
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Add `normal/menu_text.c'.
+	(normal_mod_SOURCES): Likewise.
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+	(normal_mod_SOURCES): Likewise.
+
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	(normal_mod_SOURCES): Likewise.
+
+	* conf/i386-pc.rmk, (grub_emu_SOURCES): Likewise.
+	(normal_mod_SOURCES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	(normal_mod_SOURCES): Likewise.
+
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	(normal_mod_SOURCES): Likewise.
+
+	* conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise.
+	(normal_mod_SOURCES): Likewise.
+
+2009-02-11  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/00_header.in: Update old reference to `font' command.
+
+2009-02-10  Felix Zielcke  <fzielcke@z-51.de>
+
+	* fs/fat.c (grub_fat_mount): Fix wrong comparison.
+
+	Based on patch from Javier Martín.
+
+2009-02-09  Felix Zielcke  <fzielcke@z-51.de>
+
+	* conf/common.rmk (grub_probe_SOURCES): Move fs/ext2.c before fs/fat.c
+	to avoid false positives with FAT.
+	(grub_fstest_SOURCES): Likewise.
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Likewise.
+	* conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise.
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+2009-02-09  Felix Zielcke  <fzielcke@z-51.de>
+
+	* fs/fat.c (grub_fat_mount): Try to avoid false positives by checking
+	bpb.version_specific.fat12_or_fat16.fstype and
+	bpb.version_specific.fat32.fstype.
+
+2009-02-08  Robert Millan  <rmh@aybabtu.com>
+
+	* fs/tar.c: Replace "fs/cpio.c" with "cpio.c".
+
+2009-02-08  Robert Millan  <rmh@aybabtu.com>
+
+	* Makefile.in (host_os, host_cpu): New variables.
+	(target_os): Remove.  Update all users.
+
+2009-02-08  Marco Gerards  <marco@gnu.org>
+
+	* Makefile.in (enable_grub_emu_usb): New variable.
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/scsi.c'.
+	(grub_emu_SOURCES) [grub_emu_SOURCES]: Add `disk/usbms.c',
+	`util/usb.c', `bus/usb/usb.c' and `commands/usbtest.c'.
+	(grub_emu_LDFLAGS): Add `$(LIBUSB)'.
+	(pkglib_MODULES): Add `usb.mod', `uhci.mod', `ohci.mod',
+	`usbtest.mod' and `usbms.mod'.
+	(usb_mod_SOURCES, usb_mod_CFLAGS, usb_mod_LDFLAGS)
+	(usbtest_mod_SOURCES, usbtest_mod_CFLAGS, usbtest_mod_LDFLAGS)
+	(uhci_mod_SOURCES, uhci_mod_CFLAGS, uhci_mod_LDFLAGS,
+	(ohci_mod_SOURCES, ohci_mod_CFLAGS, ohci_mod_LDFLAGS)
+	(usbms_mod_SOURCES, usbms_mod_CFLAGS, usbms_mod_LDFLAGS): New
+	variables.
+
+	* disk/usbms.c: New file.
+
+	* include/grub/usb.h: Likewise.
+
+	* include/grub/usbtrans.h: Likewise.
+
+	* include/grub/usbdesc.h: Likewise.
+
+	* bus/usb/usbtrans.c: Likewise.
+
+	* bus/usb/ohci.c: Likewise.
+
+	* bus/usb/uhci.c: Likewise.
+
+	* bus/usb/usbhub.c: Likewise.
+
+	* bus/usb/usb.c: Likewise.
+
+	* commands/usbtest.c: Likewise.
+
+	* util/usb.c: Likewise.
+
+	* include/grub/err.h (grub_err_t): Add `GRUB_ERR_IO'.
+
+	* configure.ac: Test for libusb presence.
+
+	* util/grub-emu.c (main) [HAVE_LIBUSB_H]: Call `grub_libusb_init'.
+
+2009-02-08  Vesa Jääskeläinen  <chaac@nic.fi>
+
+	* kern/mm.c: Add more comments.
+
+2009-02-08  Robert Millan  <rmh@aybabtu.com>
+
+	Patch from Javier Martín.
+	* fs/ext2.c (EXT2_DRIVER_SUPPORTED_INCOMPAT): Add
+	`EXT4_FEATURE_INCOMPAT_FLEX_BG'.
+
+2009-02-08  Robert Millan  <rmh@aybabtu.com>
+
+	* fs/cpio.c: Split tar functionality to ...
+	* fs/tar.c: ... here (new file).  Update all users.
+
+2009-02-07  Robert Millan  <rmh@aybabtu.com>
+
+	* fs/ext2.c (grub_ext2_mount): Avoid mounting filesystems with
+	backward-incompatible features.
+
+	Based on patch from Javier Martín, with some adjustments.
+
+2009-02-07  Michael Scherer  <misc@mandriva.org>
+
+	* fs/hfs.c (grub_hfsplus_iterate_dir): Treat hfs+ as case insensitive.
+
+2009-02-07  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/common.rmk (grub_probe_SOURCES, grub_fstest_SOURCES): Move
+	position of `disk/lvm.c' to ensure grub_init_all() always picks it
+	after the RAID stuff.
+
+2009-02-05  Vesa Jääskeläinen  <chaac@nic.fi>
+
+	Fixes problem when running vbetest command as reported by
+	Vladimir Serbinenko <phcoder@gmail.com>.
+
+	* (grub_vbe_set_video_mode): Fixed problem with text modes.
+
+2009-02-04  Felix Zielcke  <fzielcke@z-51.de>
+
+	util/getroot.c (grub_util_get_grub_dev): Add support for /dev/mdNpN and
+	/dev/md/NpN style mdraid devices.
+
+2009-02-03  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/unifont2pff.rb: Remove.
+
+2009-02-03  Felix Zielcke  <fzielcke@z-51.de>
+
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Add a missing trailing
+	`#'.
+
+2009-02-03  Felix Zielcke  <fzielcke@z-51.de>
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add `normal/menu_viewer.c'.
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+	* conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+2009-02-02  Christian Franke  <franke@computer.org>
+
+	* lib/hexdump.c (hexdump): Print at most 3 lines if data is identical.
+
+2009-02-01  Felix Zielcke  <fzielcke@z-51.de>
+
+	* INSTALL: Note that we now require at least autoconf 2.59 and
+	that LZO is optional.
+
+2009-02-01  Vesa Jääskeläinen  <chaac@nic.fi>
+
+	Base on patch on bug #24154 created by Tomas Tintera
+	<trosos@seznam.cz>.
+
+	* video/i386/pc/vbe.c (grub_video_vbe_scroll): Fix downward scrolling.
+
+2009-02-01  Vesa Jääskeläinen  <chaac@nic.fi>
+
+	Based on patch on bug #25318 created by Bernhard Rosenkraenzer
+	<bero@arklinux.org>.
+
+	* normal/parser.y (script_init): Add missing semicolon.
+
+2009-01-31  Colin D Bennett  <colin@gibibit.com>
+
+	* normal/main.c: Add include to grub/menu_viewer.h.
+	(free_menu_entry_classes): Added.
+	(grub_normal_menu_addentry): Added class property handling.
+	(grub_normal_execute): Changed to use new menu viewer for menu viewing.
+	(GRUB_MOD_INIT(normal)): Added register for text based menu viewer.
+
+	* normal/menu_viewer.c: New file.
+
+	* normal/menu.c (run_menu_entry): Renamed to ...
+	(grub_menu_execute_entry): ... this and	made it as global.
+	(grub_menu_run): Renamed to ...
+	(show_text_menu): ... this and made it local.
+	(show_text_menu): Adapt to new function names.
+	(grub_normal_terminal_menu_viewer): New global variable.
+
+	* include/grub/menu.h: New file.
+
+	* include/grub/menu_viewer.h: New file.
+
+	* include/grub/normal.h: Added include to grub/menu.h.
+	(grub_menu_entry): Moved to include/grub/menu.h.
+	(grub_menu_entry_t): Likewise.
+	(grub_menu): Likewise.
+	(grub_menu_t): Likewise.
+	(grub_normal_terminal_menu_viewer): Added.
+	(grub_menu_execute_entry): Likewise.
+	(grub_menu_run): Removed.
+
+	* DISTLIST: Added include/grub/menu.h.
+	Added include/grub/menu_viewer.h.
+	Added normal/menu_viewer.c.
+
+2009-01-31  Vesa Jääskeläinen  <chaac@nic.fi>
+
+	* normal/execute.c (grub_script_execute_menuentry): Changed to use
+	arglist for menutitle arguments.
+
+	* normal/main.c (grub_normal_menu_addentry): Likewise.
+
+	* normal/parser.y (menuentry): Likewise.
+
+	* normal/script.c (grub_script_create_cmdmenu): Likewise.
+
+	* include/grub/script.h (grub_script_cmd_menuentry): Likewise.
+	(grub_script_create_cmdmenu): Likewise.
+
+	* include/grub/normal.h (grub_normal_menu_addentry): Likewise.
+
+	* conf/i386-pc.rmk (normal_mod_SOURCES): Adapt Colin D Bennett's
+	changes.
+
+	* conf/x86_64-efi.rmk (normal_mod_SOURCES): Likewise.
+
+	* conf/i386-coreboot.rmk (normal_mod_SOURCES): Likewise.
+
+	* conf/i386-efi.rmk (normal_mod_SOURCES): Likewise.
+
+	* conf/i386-ieee1275.rmk (normal_mod_SOURCES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (normal_mod_SOURCES): Likewise.
+
+	* conf/sparc64-ieee1275.rmk (normal_mod_SOURCES): Likewise.
+
+2009-01-30  Christian Franke  <franke@computer.org>
+
+	* normal/arg.c (grub_arg_show_help): Add indentation if '\n' appears
+	in option help text.
+
+2009-01-27  Pavel Roskin  <proski@gnu.org>
+
+	* disk/fs_uuid.c (search_fs_uuid): Ignore case of the UUID.
+
+2009-01-27  Vesa Jääskeläinen  <chaac@nic.fi>
+
+	* commands/lsmmap.c: Add include to grub/machine/memory.h.
+
+	* fs/i386/pc/pxe.c (grub_pxefs_open): Fix sign problem.
+
+	* term/i386/pc/at_keyboard.c (GRUB_MOD_FINI(at_keyboard)): Use proper
+	unregister function.
+
+2009-01-27  Vesa Jääskeläinen  <chaac@nic.fi>
+
+	* disk/scsi.c (grub_scsi_read): Fix sign problem.
+
+	* term/i386/pc/vga_text.c (grub_vga_text_init_fini). Fix declaration.
+
+	* util/grub-mkfont.c (usage): Fix typo.
+
+	* util/elf/grub-mkimage.c (load_modules): Fix warning.
+
+2009-01-26  Daniel Mierswa  <impulze@impulze.org>
+
+	* fs/fat.c (grub_fat_uuid): Fix shift of the first two bytes.
+
+	* commands/search.c (search_fs_uuid): Ignore case of the UUID.
+
+	* kern/misc.c (grub_strcasecmp): New function.
+	(grub_strcasecmp): Use grub_size_t instead of int for length.
+	Fix return value.
+	* include/grub/misc.h: Update function prototypes.
+
+2009-01-26  Robert Millan  <rmh@aybabtu.com>
+
+	* configure.ac: Fix cross-compilation check.
+
+2009-01-22  Christian Franke  <franke@computer.org>
+
+	* kern/misc.c (grub_vsprintf): Fix size and termination of `format2'
+	(precision) digit string.  Allow `.format2' without `format1' (width).
+	Limit input chars for `%s' output to `format2' if specified.  This is
+	compatible with standard printf ().
+
+2009-01-22  Christian Franke  <franke@computer.org>
+
+	* disk/ata.c (grub_ata_wait_status): Replace by ...
+	(grub_ata_wait_not_busy): ... this function.  Checks only BSY bit,
+	other status bits may be invalid while BSY is asserted.
+	(grub_ata_check_ready): New function.
+	(grub_ata_cmd): Removed.
+	(grub_ata_wait_drq): New function.
+	(grub_ata_strncpy): Remove inline.
+	(grub_ata_pio_read): Reduce to actual block transfer.  BSY wait
+	and error check now done by grub_ata_wait_drq ().
+	(grub_ata_pio_write): Likewise.
+	(grub_atapi_identify): Set DEV before check for !BSY.  Use
+	grub_ata_wait_drq () to wait for data.
+	(grub_ata_device_initialize): Add status register check to
+	detect missing SATA slave devices.  Add debug messages.
+	(grub_atapi_wait_drq): Use grub_ata_wait_not_busy ().
+	(grub_atapi_packet): Set DEV before check for !BSY.  Replace
+	transfer loop by grub_ata_pio_write ().
+	(grub_ata_identify): Set DEV before check for !BSY. Use
+	grub_ata_wait_drq () to wait for data.
+	(grub_ata_setaddress): Set DEV before check for !BSY.
+	(grub_ata_readwrite): Remove duplicate code, handle batch/rest and
+	read/write in one loop.  Fix invalid command on write.  Fix incomplete
+	command on (size % batch) == 0.  Add missing error check after write of
+	last block.  Add debug messages.
+	(grub_atapi_read):  Replace transfer loop by grub_ata_pio_read ().
+
+2009-01-19  Christian Franke  <franke@computer.org>
+
+	* disk/ata.c (GRUB_ATAPI_REG_*): New defines.
+	(GRUB_ATAPI_IREASON_*): Likewise.
+	(grub_ata_pio_write): Fix timeout error return.
+	(grub_atapi_identify): Add grub_ata_wait () after cmd.
+	(grub_atapi_wait_drq): New function.
+	(grub_atapi_packet): New parameter `size'.
+	Use grub_atapi_wait_drq () and direct write instead of
+	grub_ata_pio_write ().
+	(grub_atapi_read): Replace grub_ata_pio_read () by a loop which
+	reads the number of bytes requested by the device for each DRQ
+	assertion.
+	(grub_atapi_write): Remove old implementation, return not
+	implemented instead.
+
+2009-01-19  Christian Franke  <franke@computer.org>
+
+	* disk/scsi.c (grub_scsi_read10): Use scsi->blocksize instead
+	of 512 to calculate data size.
+	(grub_scsi_read12): Likewise.
+	(grub_scsi_write10): Likewise.
+	(grub_scsi_write12): Likewise.
+	(grub_scsi_read): Adjust size according to blocksize.
+	Add checks for invalid blocksize and unaligned transfer.
+
+2009-01-19  Vesa Jääskeläinen  <chaac@nic.fi>
+
+	* font/font.c (grub_font_loader_init): Re-position unknown glyph.
+
+	* term/gfxterm.c (write_char): Fix background rendering for wide
+	width glyphs.
+
+2009-01-19  Robert Millan  <rmh@aybabtu.com>
+
+	* config.guess: Update to latest version from config git.
+	* config.sub: Likewise.
+
+2009-01-17  Felix Zielcke  <fzielcke@z-51.de>
+
+	* Makefile.in: Change font compilation to use new grub-mkfont instead
+	of java version.
+
+	* util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java: Remove.
+	* util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java: Likewise.
+	* util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise.
+	* util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise.
+	* util/fonttool/src/org/gnu/grub/fonttool/Converter.java: Likewise.
+	* util/fonttool/src/org/gnu/grub/fonttool/Font.java: Likewise.
+	* util/fonttool/src/org/gnu/grub/fonttool/Glyph.java: Likewise.
+	* util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java: Likewise.
+	* util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java: Likewise.
+
+2009-01-16  Christian Franke  <franke@computer.org>
+
+	* disk/ata.c (enum grub_ata_commands): Remove EXEC_DEV_DIAGNOSTICS.
+	(enum grub_ata_timeout_milliseconds): New enum.
+	(grub_ata_wait_status): Add parameter milliseconds.
+	(grub_ata_cmd): Remove variable `err'.  Remove wait for !DRQ to allow
+	recovery from timed-out commands.
+	(grub_ata_pio_read): Add parameter milliseconds.  Fix error return,
+	return grub_errno instead of REG_ERROR.
+	(grub_ata_pio_write): Add parameter milliseconds.
+	(grub_atapi_identify): Fix size of ATAPI IDENTIFY sector.
+	Pass milliseconds to grub_ata_wait_status () and
+	grub_ata_pio_read ().
+	(grub_atapi_packet): Pass milliseconds to grub_ata_pio_write ().
+	(grub_ata_identify): Remove variable `ataerr'.  Pass milliseconds to
+	grub_ata_wait_status ().  Fix IDENTIFY timeout check.
+	(grub_ata_device_initialize): Remove EXECUTE DEVICE DIAGNOSTICS.
+	It is not suitable for device detection, because DEV bit is ignored,
+	the command may run too long, and not all devices set the signature
+	properly.
+	(grub_ata_pciinit): Clear grub_errno before grub_ata_device_initialize ().
+	(grub_ata_setaddress): Pass milliseconds to grub_ata_wait_status ().
+	Fix device selection, DEV bit must be set first to address the registers
+	of the correct device.
+	(grub_ata_readwrite): Pass milliseconds to grub_ata_wait_status () and
+	grub_ata_pio_read/write ().
+	(grub_atapi_read): Pass milliseconds to grub_ata_pio_read ().
+	(grub_atapi_write): Pass milliseconds to grub_ata_pio_write ().
+
+2009-01-13  Carles Pina i Estany  <carles@pina.cat>
+
+	* util/grub-editenv.c (main): Use fseeko(), not fseek().
+
+2009-01-13  Bean  <bean123ch@gmail.com>
+
+	* util/grub-mkfont.c (write_font): forget to remove some debug code.
+
+2009-01-13  Bean  <bean123ch@gmail.com>
+
+	* Makefile.in: (enable_grub_mkfont): New variable.
+	(freetype_cflags): Likewise.
+	(freetype_libs): Likewise.
+
+	* common.rmk (bin_UTILITIES): Add `grub-mkfont' if requested.
+	(grub_mkfont_SOURCES): New variable.
+	(grub_mkfont_CFLAGS): Likewise.
+	(grub_mkfont_LDFLAGS): Likewise.
+
+	* configure.ac (--enable-grub-mkfont): New option. Check for freetype2
+	library if `--enable-grub-mkfont' is requested.
+	(enable_grub_mkfont): New variable.
+	(freetype_cflags): Likewise.
+	(freetype_libs): Likewise.
+
+	* util/grub-mkfont.c: New file.
+
+2009-01-12  Christian Franke  <franke@computer.org>
+
+	* disk/ata.c (grub_ata_pciinit): Fix bit numbers of compatibility
+	mode check.  Fix setting of compat_use[].
+
+2009-01-10  Robert Millan  <rmh@aybabtu.com>
+
+	Update a few copyright years which we forgot to do in 2008 (only for
+	files whose changes made in 2008 were copyright-significant)
+
+	* Makefile.in: Add 2008 to Copyright line.
+	* disk/ieee1275/ofdisk.c: Likewise.
+	* disk/efi/efidisk.c: Likewise.
+	* kern/dl.c: Likewise.
+	* kern/sparc64/ieee1275/init.c: Likewise.
+	* kern/mm.c: Likewise.
+	* kern/efi/mm.c: Likewise.
+	* boot/i386/pc/boot.S: Likewise.
+	* genfslist.sh: Likewise.
+	* fs/iso9660.c: Likewise.
+	* fs/hfs.c: Likewise.
+	* fs/jfs.c: Likewise.
+	* fs/minix.c: Likewise.
+	* fs/ufs.c: Likewise.
+	* gensymlist.sh.in: Likewise.
+	* genkernsyms.sh.in: Likewise.
+	* include/grub/misc.h: Likewise.
+	* include/grub/types.h: Likewise.
+	* include/grub/symbol.h: Likewise.
+	* include/grub/elf.h: Likewise.
+	* include/grub/kernel.h: Likewise.
+	* include/grub/disk.h: Likewise.
+	* include/grub/dl.h: Likewise.
+	* include/grub/i386/linux.h: Likewise.
+	* include/grub/i386/pc/biosdisk.h: Likewise.
+	* include/grub/efi/api.h: Likewise.
+	* include/grub/efi/pe32.h: Likewise.
+	* include/grub/util/misc.h: Likewise.
+	* normal/execute.c: Likewise.
+	* normal/arg.c: Likewise.
+	* normal/completion.c: Likewise.
+	* normal/lexer.c: Likewise.
+	* normal/parser.y: Likewise.
+	* normal/misc.c: Likewise.
+	* commands/i386/pc/vbeinfo.c: Likewise.
+	* commands/hexdump.c: Likewise.
+	* commands/terminal.c: Likewise.
+	* commands/ls.c: Likewise.
+	* commands/help.c: Likewise.
+	* partmap/pc.c: Likewise.
+	* loader/efi/chainloader.c: Likewise.
+	* loader/multiboot_loader.c: Likewise.
+	* loader/i386/pc/multiboot2.c: Likewise.
+	* term/efi/console.c: Likewise.
+	* term/i386/pc/serial.c: Likewise.
+	* util/lvm.c: Likewise.
+	* util/console.c: Likewise.
+	* util/i386/efi/grub-mkimage.c: Likewise.
+	* util/raid.c: Likewise.
+
+2009-01-06  Vesa Jääskeläinen  <chaac@nic.fi>
+
+	* commands/videotest.c: Removed include to grub/machine/memory.h.
+
+	* conf/i386-pc.rmk (pkglib_MODULES): Removed video.mod, gfxterm.mod,
+	videotest.mod, bitmap.mod, tga.mod, jpeg.mod, png.mod.
+	(video_mod_SOURCES): Removed.
+	(video_mod_CFLAGS): Likewise.
+	(video_mod_LDFLAGS): Likewise.
+	(gfxterm_mod_SOURCES): Likewise.
+	(gfxterm_mod_CFLAGS): Likewise.
+	(gfxterm_mod_LDFLAGS): Likewise.
+	(videotest_mod_SOURCES): Likewise.
+	(videotest_mod_CFLAGS): Likewise.
+	(videotest_mod_LDFLAGS): Likewise.
+	(bitmap_mod_SOURCES): Likewise.
+	(bitmap_mod_CFLAGS): Likewise.
+	(bitmap_mod_LDFLAGS): Likewise.
+	(tga_mod_SOURCES): Likewise.
+	(tga_mod_CFLAGS): Likewise.
+	(tga_mod_LDFLAGS): Likewise.
+	(jpeg_mod_SOURCES): Likewise.
+	(jpeg_mod_CFLAGS): Likewise.
+	(jpeg_mod_LDFLAGS): Likewise.
+	(png_mod_SOURCES): Likewise.
+	(png_mod_CFLAGS): Likewise.
+	(png_mod_LDFLAGS): Likewise.
+
+	* conf/common.rmk (pkglib_MODULES): Added video.mod, videotest.mod,
+	bitmap.mod, tga.mod, jpeg.mod, png.mod, font.mod, gfxterm.mod
+	(video_mod_SOURCES): Added.
+	(video_mod_CFLAGS): Likewise.
+	(video_mod_LDFLAGS): Likewise.
+	(videotest_mod_SOURCES): Likewise.
+	(videotest_mod_CFLAGS): Likewise.
+	(videotest_mod_LDFLAGS): Likewise.
+	(bitmap_mod_SOURCES): Likewise.
+	(bitmap_mod_CFLAGS): Likewise.
+	(bitmap_mod_LDFLAGS): Likewise.
+	(tga_mod_SOURCES): Likewise.
+	(tga_mod_CFLAGS): Likewise.
+	(tga_mod_LDFLAGS): Likewise.
+	(jpeg_mod_SOURCES): Likewise.
+	(jpeg_mod_CFLAGS): Likewise.
+	(jpeg_mod_LDFLAGS): Likewise.
+	(png_mod_SOURCES): Likewise.
+	(png_mod_CFLAGS): Likewise.
+	(png_mod_LDFLAGS): Likewise.
+	(gfxterm_mod_SOURCES): Likewise.
+	(gfxterm_mod_CFLAGS): Likewise.
+	(gfxterm_mod_LDFLAGS): Likewise.
+
+	* term/gfxterm.c: Removed include to grub/machine/memory.h,
+	grub/machine/console.h.
+
+2009-01-04  Jerone Young  <jerone@gmail.com>
+
+	Make on screen instructions clearer
+
+	Based on patch created by Jidanni <jidanni@jidanni.org>
+
+	* normal/menu.c: print clearer instructions on the screen
+
+2009-01-02  Colin D Bennett  <colin@gibibit.com>
+
+	New font engine.
+
+	Additional changes by Vesa Jääskeläinen <chaac@nic.fi> to adapt to
+	build system and fixed gfxterm.c to work with different	sized fonts.
+
+	* configure.ac: Changed UNIFONT_HEX to UNIFONT_BDF.
+
+	* configure: Re-generated.
+
+	* DISTLIST: Removed font/manager.c.
+	Added font/font.c.
+	Added font/font_cmd.c.
+
+	* Makefile.in: Changed UNIFONT_HEX to UNIFONT_BDF.  Added Font tool
+	compilation.
+
+	* include/grub/misc.h (grub_utf8_to_ucs4): Changed prototype.  Changed users.
+
+	* kern/misc.c (grub_utf8_to_ucs4): Changed prototype.
+
+	* kern/term.c: Changed users of grub_utf8_to_ucs4.
+
+	* normal/menu.c: Likewise.
+
+	* conf/common.rmk (font_mod_SOURCES): Removed font/manager.c.
+	(font_mod_SOURCES): Added font/font_cmd.c, font/font.c.
+
+	* include/grub/font.h: Replaced with new file.
+
+	* include/grub/video.h (GRUB_VIDEO_MODE_TYPE_ALPHA): Changed value.
+	(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED): Likewise.
+	(GRUB_VIDEO_MODE_TYPE_COLOR_MASK): Likewise.
+	(GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP): Added.
+	(grub_video_blit_format): Added GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED.
+	(grub_video_mode_info): Added bg_red, bg_green, bg_blue, bg_alpha,
+	fg_red, fg_green, fg_blue, fg_alpha.
+	(grub_video_adapter): Removed blit_glyph.
+	(grub_video_blit_glyph): Removed.
+
+	* font/manager.c: Removed file.
+
+	* font/font.c: New file.
+
+	* font/font_cmd.c: Likewise.
+
+	* video/video.c (grub_video_blit_glyph): Removed.
+
+	* video/i386/pc/vbe.c (grub_video_vbe_map_rgb): Added 1-bit support.
+	(grub_video_vbe_map_rgba): Likewise.
+	(grub_video_vbe_unmap_color_int): Likewise.
+	(grub_video_vbe_blit_glyph): Removed.
+	(grub_video_vbe_adapter): Removed blit_glyph.
+
+	* video/i386/pc/vbeutil.c (get_data_ptr): Added 1-bit support.
+	(get_pixel): Likewise.
+	(set_pixel): Likewise.
+
+	* commands/videotest.c (grub_cmd_videotest): Added more tests for fonts.
+
+	* term/gfxterm.c: Adapted to new font engine.
+
+	* term/i386/pc/vesafb.c: Marked as deprecated.  Made it compile.
+
+	* term/i386/pc/vga.c: Likewise.
+
+	* util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java: New file.
+
+	* util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java: Likewise.
+
+	* util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise.
+
+	* util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise.
+
+	* util/fonttool/src/org/gnu/grub/fonttool/Converter.java: Likewise.
+
+	* util/fonttool/src/org/gnu/grub/fonttool/Font.java: Likewise.
+
+	* util/fonttool/src/org/gnu/grub/fonttool/Glyph.java: Likewise.
+
+	* util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java: Likewise.
+
+	* util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java: Likewise.
+
+	* util/grub.d/00_header.in: Changed to use new loadfont command.
+
+	* util/grub-mkconfig_lib.in: Changed font extension.
+
+2008-12-28  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/getroot.c (grub_util_get_grub_dev): Add support for
+	/dev/md/dNNpNN style partitionable mdraid devices.
+
+2008-12-12  Alex Smith  <alex@alex-smith.me.uk>
+
+	* fs/i386/pc/pxe.c (grub_pxefs_open): Handle the one open connection
+	at a time limit of the PXE TFTP API correctly.
+	(grub_pxefs_close): Likewise.
+
+2008-11-29  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/ata.c (grub_ata_pciinit): Handle errors raised by
+	grub_ata_device_initialize() calls.
+
+2008-11-28  Krzysztof Smiechowicz  <deadwood@wp.pl>
+
+	* fs/affs.c (grub_affs_iterate_dir): Return failure when directory
+	iteration failed.
+	* fs/sfs.c (grub_sfs_iterate_dir): Likewise.
+
+2008-11-28  Robert Millan  <rmh@aybabtu.com>
+
+	Fix build on powerpc-ieee1275.  Based on patch created by
+	Manoel Abranches <mrabran@linux.vnet.ibm.com>.
+	* conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Add
+	`kern/ieee1275/mmap.c'.
+	* include/grub/powerpc/ieee1275/memory.h: New file.
+
+	Provide grub-install on coreboot.
+	* conf/i386-coreboot.rmk (sbin_SCRIPTS): Add `grub-install'.
+	(grub_install_SOURCES): New variable.
+	* util/i386/pc/grub-install.in: Add a few condition checks to make it
+	usable on coreboot.
+
+2008-11-25  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/grub-fstest.c (grub_term_get_current_input): Change return type
+	to `grub_term_input_t'.
+	(grub_term_get_current_output): Change return type to
+	`grub_term_output_t'.
+
+2008-11-22  Robert Millan  <rmh@aybabtu.com>
+
+	Fix breakage on coreboot due to declaration mismatch.
+	* term/i386/pc/vga_text.c (grub_vga_text_init_fini): New function.
+	(grub_vga_text_term): Use grub_vga_text_init_fini() instead of
+	grub_vga_text_cls().
+
+	* kern/i386/loader.S (grub_multiboot_backward_relocator): Improve
+	comments.  Avoid copying one more byte than necessary (just in case).
+
+	* conf/powerpc-ieee1275.rmk (kernel_elf_LDFLAGS): Change link address
+	to 0x200000 (avoids trouble with some OFW implementations, and matches
+	with the one in Yaboot).
+	Reported by Manoel Abranches
+
+2008-11-20  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/i386/coreboot/init.c (grub_time_tics): Remove variable.
+	(grub_get_rtc, grub_exit): Abort with grub_fatal() if called.
+
+	* util/grub-mkconfig_lib.in (grub_warn): New function.
+	(convert_system_path_to_grub_path): Use grub_warn() when issuing
+	warnings, to obtain consistent formatting.
+	* util/grub.d/00_header.in: Likewise.
+	* util/update-grub_lib.in: Likewise.
+
+	* loader/i386/linux.c (allocate_pages): Fix a warning.
+	Move comment text to `#error' stanza.
+
+	Harmonize ieee1275's grub_available_iterate() with the generic
+	grub_machine_mmap_iterate() interface (fixes a recently-introduced
+	build problem on i386-ieee1275):
+	* kern/ieee1275/openfw.c (grub_available_iterate): Moved from here ...
+	* kern/ieee1275/mmap.c (grub_machine_mmap_iterate): ... here.  Add third
+	parameter `type'.  Update all users of this function.
+	* conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add
+	`kern/ieee1275/mmap.c'.
+	* kern/ieee1275/init.c
+	* include/grub/ieee1275/ieee1275.h (grub_available_iterate): Replace
+	with ...
+	(grub_machine_mmap_iterate): ... this.
+	* include/grub/i386/pc/memory.h (grub_machine_mmap_iterate): Change
+	return type to `grub_err_t'.  Update all implementations of this
+	function prototype.
+	* include/grub/i386/coreboot/memory.h (grub_machine_mmap_iterate):
+	Likewise.
+
+	Add `lsmmap' command (lists firmware-provided memory map):
+	* commands/lsmmap.c: New file.
+	* conf/i386-pc.rmk (pkglib_MODULES): Add `lsmmap.mod'.
+	(lsmmap_mod_SOURCES, lsmmap_mod_CFLAGS, lsmmap_mod_LDFLAGS): New
+	variables.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	* conf/i386-coreboot.rmk: Likewise.
+	* conf/i386-ieee1275.rmk: Likewise.
+
+2008-11-19  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/linux.c (grub_rescue_cmd_initrd): Fix a typo.
+	* loader/i386/linux.c (grub_rescue_cmd_initrd): Implement a few needed
+	constraints to initrd allocation (based on code from
+	loader/i386/pc/linux.c).  Without them, initrd was allocated too high
+	for Linux to find it.
+
+2008-11-14  Robert Millan  <rmh@aybabtu.com>
+
+	* fs/cpio.c (grub_cpio_open): Compare `name' and `fn' by hand in
+	order to cope with duplicate slashes.
+
+2008-11-14  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/coreboot/memory.h (GRUB_MEMORY_MACHINE_LOWER_SIZE):
+	Redefine to match with GRUB_MEMORY_MACHINE_UPPER_START (0x100000).  We
+	don't want to mess with lower memory, because it is used in the Linux
+	loader.
+
+	* loader/i386/linux.c (allocate_pages): Allocate `real_mode_mem' in
+	an appropriate place in lower memory, between 0x10000 and 0x90000,
+	like loader/i386/efi/linux.c does.  Linux often panics if real_mode_mem
+	is in our heap (probably as a result of it being corrupted during
+	decompression).  Add #error instance with comment to explain why this
+	loader isn't currently usable on PC/BIOS.
+
+2008-11-14  Robert Millan  <rmh@aybabtu.com>
+
+	* term/i386/pc/serial.c [! GRUB_MACHINE_PCBIOS]
+	(GRUB_SERIAL_PORT_NUM): Fix miscalculation.
+
+2008-11-12  Robert Millan  <rmh@aybabtu.com>
+
+	Make loader/i386/linux.c buildable on i386-pc (although disabled).
+
+	* include/grub/i386/pc/init.h: Include `<grub/machine/memory.h>'.
+	(struct grub_machine_mmap_entry, grub_machine_mmap_iterate): Move
+	from here ...
+	* include/grub/i386/pc/memory.h: ... to here.
+
+2008-11-12  Robert Millan  <rmh@aybabtu.com>
+
+	Fix build problems on i386-ieee1275 and *-efi (introduced by vga_text
+	split).
+
+	* include/grub/i386/pc/console.h: Include `<grub/i386/vga_common.h>'.
+	(grub_console_cur_color, grub_console_real_putchar)
+	(grub_console_putchar, grub_console_getcharwidth, grub_console_getwh)
+	(grub_console_setcolorstate, grub_console_setcolor)
+	(grub_console_getcolor): Move from here ...
+	* include/grub/i386/vga_common.h: ... to here (new file).
+
+	* term/i386/pc/vga_text.c: Replace `<grub/machine/console.h>' with
+	`<grub/i386/vga_common.h>' and `<grub/cpu/io.h>' with
+	`<grub/i386/io.h>'.
+	* term/i386/vga_common.c: Replace `<grub/machine/console.h>' with
+	`<grub/i386/vga_common.h>'.
+
+2008-11-12  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Add `term/i386/vga_common.c'.
+	* conf/i386.rmk (pkglib_MODULES): Add `vga_text.mod'.
+	(vga_text_mod_SOURCES, vga_text_mod_CFLAGS, vga_text_mod_LDFLAGS): New
+	variables.
+	* conf/i386-coreboot.rmk (kernel_elf_SOURCES): Replace
+	`term/i386/pc/console.c' with `term/i386/vga_common.c'.
+
+	* kern/i386/coreboot/init.c (grub_machine_init): Replace call to
+	grub_console_init() with call to grub_vga_text_init().
+	(grub_machine_fini): Replace call to
+	grub_console_fini() with call to grub_vga_text_fini() and
+	grub_at_keyboard_fini().
+
+	* include/grub/i386/pc/console.h: Include `<grub/term.h>'.
+	(grub_console_putchar, grub_console_getcharwidth, grub_console_getwh)
+	(grub_console_setcolorstate, grub_console_setcolor)
+	(grub_console_getcolor): New function prototypes.
+
+	* term/i386/pc/vga_text.c: Include `<grub/dl.h>'.
+	(grub_vga_text_getxy, grub_vga_text_gotoxy, grub_vga_text_cls)
+	(grub_vga_text_setcursor): Static-ize.
+	(grub_vga_text_term): New structure.
+	(GRUB_MOD_INIT(vga_text), GRUB_MOD_FINI(vga_text)): New functions.
+
+	* term/i386/pc/console.c: Remove `<grub/machine/machine.h>'.
+	(grub_console_cur_color, grub_console_standard_color)
+	(grub_console_normal_color, grub_console_highlight_color)
+	(map_char, grub_console_putchar, grub_console_getcharwidth)
+	(grub_console_getwh, grub_console_setcolorstate, grub_console_setcolor)
+	(grub_console_getcolor): Move from here ...
+	* term/i386/vga_common.c: ... to here (same function names).
+
+2008-11-12  Robert Millan  <rmh@aybabtu.com>
+
+	Use newly-added Multiboot support in coreboot.
+
+	* conf/i386-coreboot.rmk (kernel_elf_SOURCES): Replace
+	`kern/i386/coreboot/mmap.c' with `kern/i386/multiboot_mmap.c'.
+
+	* kern/i386/coreboot/startup.S: Enable Multiboot header, fix its
+	alignment, set `MULTIBOOT_MEMORY_INFO' flag.
+	(codestart): Store the MBI in `startup_multiboot_info' when we're
+	being loaded using Multiboot.
+
+	* kern/i386/coreboot/init.c (grub_machine_init): Move
+	grub_at_keyboard_init() call to beginning of function (useful for
+	debugging).  Call grub_machine_mmap_init() before attempting to use
+	grub_machine_mmap_iterate().
+	(grub_lower_mem, grub_upper_mem): Move from here ...
+	* kern/i386/multiboot_mmap.c (grub_lower_mem, grub_upper_mem): ... to
+	here (new file).
+
+	* include/grub/i386/coreboot/memory.h (grub_machine_mmap_init): New
+	function prototype.
+
+2008-11-12  Robert Millan  <rmh@aybabtu.com>
+
+	Fix a regression introduced by the at_keyboard.mod split.  Because
+	some terminals are default on some platforms and non-default on
+	others, the first terminal being registered determines which is
+	going to be default.
+
+	* kern/term.c (grub_term_register_input): If this is the first
+	terminal being registered, set it as the current one.
+	(grub_term_register_output): Likewise.
+
+	* term/efi/console.c (grub_console_init): Do not call
+	grub_term_set_current_output() or grub_term_set_current_input().
+	* term/ieee1275/ofconsole.c (grub_console_init): Likewise.
+	* term/i386/pc/console.c (grub_console_init): Likewise.
+	(grub_console_fini): Do not call grub_term_set_current_input()
+	(but leave grub_term_set_current_output() to restore text mode).
+
+2008-11-10  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/00_header.in: Add backward compatibility check for
+	versions of terminal.mod that don't understand `terminal_input' or
+	`terminal_output'.
+
+2008-11-09  Robert Millan  <rmh@aybabtu.com>
+
+	* commands/terminal.c (GRUB_MOD_FINI(terminal)): Unregister
+	`terminal_input' / `terminal_output', not `terminal'.
+
+2008-11-08  Robert Millan  <rmh@aybabtu.com>
+
+	* Makefile.in (include_DATA): Fix srcdir=. assumption.
+	(DISTCLEANFILES): Add `build_env.mk'.
+
+2008-11-08  Robert Millan  <rmh@aybabtu.com>
+
+	* term/i386/pc/vesafb.c (grub_vesafb_term): Change type to
+	`struct grub_term_output'.  Remove `.checkkey' and `.getkey'
+	members.  Update all users.
+	* util/console.c (grub_ncurses_term): Split in ...
+	(grub_ncurses_term_input): ... this, and ...
+	(grub_ncurses_term_output): ... this.  Update all users.
+	* term/ieee1275/ofconsole.c: Remove stale `#endif'.
+
+2008-11-08  Robert Millan  <rmh@aybabtu.com>
+
+	* Makefile.in (PKGLIB): Add $(pkglib_BUILDDIR).
+	(PKGDATA): Add $(pkgdata_SRCDIR).
+	(pkglib_BUILDDIR): New variable.
+	(pkgdata_SRCDIR): New variable.
+	(build_env.mk): New target.
+	(include_DATA): New variable.
+	(install-local): Install $(include_DATA) files in $(includedir).
+
+2008-11-07  Pavel Roskin  <proski@gnu.org>
+
+	* gendistlist.sh: Use C locale for sorting to ensure consistent
+	output on all systems.
+
+	* util/grub.d/00_header.in: Remove incorrect space before
+	"serial".
+
+2008-11-07  Robert Millan  <rmh@aybabtu.com>
+
+	* include/multiboot2.h (struct multiboot_header): Add `flags' member as
+	per specification.
+	* loader/multiboot2.c (grub_multiboot2): Fix Multiboot2 header check.
+	* loader/multiboot_loader.c (find_multi_boot2_header): New function
+	(based on find_multi_boot1_header).
+	(grub_rescue_cmd_multiboot_loader): Check for Multiboot2 header,
+	using find_multi_boot2_header(), and abort if neither Multiboot or
+	Multiboot headers were found.
+
+2008-11-07  Robert Millan  <rmh@aybabtu.com>
+
+	Modularize at_keyboard.mod:
+
+	* conf/i386.rmk (pkglib_MODULES): Add `at_keyboard.mod'.
+	(at_keyboard_mod_SOURCES, at_keyboard_mod_CFLAGS)
+	(at_keyboard_mod_LDFLAGS): New variables.
+
+	Actual terminal split:
+
+	* include/grub/term.h (struct grub_term): Split in ...
+	(struct grub_term_input): ... this, and ...
+	(struct grub_term_output): ... this.  Update all users.
+	(grub_term_set_current): Split in ...
+	(grub_term_set_current_input): ... this, and ...
+	(grub_term_set_current_output): ... this.
+	(grub_term_get_current): Split in ...
+	(grub_term_get_current_input): ... this, and ...
+	(grub_term_get_current_output): ... this.
+	(grub_term_register): Split in ...
+	(grub_term_register_input): ... this, and ...
+	(grub_term_register_output): ... this.
+	(grub_term_unregister): Split in ...
+	(grub_term_unregister_input): ... this, and ...
+	(grub_term_unregister_output): ... this.
+	(grub_term_iterate): Split in ...
+	(grub_term_iterate_input): ... this, and ...
+	(grub_term_iterate_output): ... this.
+
+	* kern/term.c (grub_term_list): Split in ...
+	(grub_term_list_input): ... this, and ...
+	(grub_term_list_output): ... this.  Update all users.
+	(grub_cur_term): Split in ...
+	(grub_cur_term_input): ... this, and ...
+	(grub_cur_term_output): ... this.  Update all users.
+	(grub_term_set_current): Split in ...
+	(grub_term_set_current_input): ... this, and ...
+	(grub_term_set_current_output): ... this.
+	(grub_term_get_current): Split in ...
+	(grub_term_get_current_input): ... this, and ...
+	(grub_term_get_current_output): ... this.
+	(grub_term_register): Split in ...
+	(grub_term_register_input): ... this, and ...
+	(grub_term_register_output): ... this.
+	(grub_term_unregister): Split in ...
+	(grub_term_unregister_input): ... this, and ...
+	(grub_term_unregister_output): ... this.
+	(grub_term_iterate): Split in ...
+	(grub_term_iterate_input): ... this, and ...
+	(grub_term_iterate_output): ... this.
+
+	* kern/misc.c (grub_abort): Split use of grub_term_get_current() into
+	a check for input and one for output (and only attempt to get keys
+	from user when input works).
+
+	* util/grub-probe.c (grub_term_get_current): Split in ...
+	(grub_term_get_current_input): ... this, and ...
+	(grub_term_get_current_output): ... this.
+	* util/grub-fstest.c: Likewise.
+	* util/i386/pc/grub-setup.c: Likewise.
+	* util/grub-editenv.c: Likewise.
+
+	Portability adjustments:
+
+	* conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Remove
+	`term/i386/pc/at_keyboard.c'.
+	* kern/ieee1275/init.c [__i386__] (grub_machine_init): Remove call to
+	grub_keyboard_controller_init() (now handled by terminal .init).
+	* kern/i386/coreboot/init.c (grub_machine_init): Add call to
+	grub_at_keyboard_init().
+	* include/grub/i386/ieee1275/console.h (grub_keyboard_controller_init)
+	(grub_console_checkkey, grub_console_getkey): Remove (now provided by
+	at_keyboard.mod via input terminal interface).
+	* include/grub/i386/coreboot/console.h: Convert into a stub for
+	`<grub/i386/pc/console.h>'.
+
+	Migrate full terminals to new API:
+
+	* term/efi/console.c (grub_console_term): Split into ...
+	(grub_console_term_input): ... this, and ...
+	(grub_console_term_output): ... this.  Update all users.
+	* term/ieee1275/ofconsole.c: Remove __i386__ hack.
+	(grub_ofconsole_init): Split into ...
+	(grub_ofconsole_init_input): ... this, and ...
+	(grub_ofconsole_init_output): ... this.
+	(grub_ofconsole_term): Split into ...
+	(grub_ofconsole_term_input): ... this, and ...
+	(grub_ofconsole_term_output): ... this.  Update all users.
+	* term/i386/pc/serial.c (grub_serial_term): Split into ...
+	(grub_serial_term_input): ... this, and ...
+	(grub_serial_term_output): ... this.  Update all users.
+	* term/i386/pc/console.c (grub_console_term): Split into ...
+	(grub_console_term_input): ... this, and ...
+	(grub_console_term_output): ... this.  Update all users.
+	(grub_console_term_input): Only enable it on PC/BIOS platform.
+	(grub_console_init): Remove grub_keyboard_controller_init() call.
+
+	Migrate input terminals to new API:
+
+	* term/i386/pc/at_keyboard.c: Replace `cpu' and `machine' with
+	`i386' and `i386/pc' to enable build on x86_64 (this driver is
+	i386-specific anyway).
+	(grub_console_checkkey): Rename to ...
+	(grub_at_keyboard_checkkey): ... this.  Static-ize.  Update all
+	users.
+	(grub_keyboard_controller_orig): New variable.
+	(grub_console_getkey): Rename to ...
+	(grub_at_keyboard_getkey): ... this.  Static-ize.  Update all
+	users.
+	(grub_keyboard_controller_init): Static-ize.  Save original
+	controller value so that it can be restored ...
+	(grub_keyboard_controller_fini): ... here (new function).
+	(grub_at_keyboard_term): New structure.
+	(GRUB_MOD_INIT(at_keyboard), GRUB_MOD_FINI(at_keyboard)): New
+	functions.
+
+	Migrate output terminals to new API:
+
+	* term/i386/pc/vga.c (grub_vga_term): Change type to
+	`struct  grub_term_output'.  Remove `.checkkey' and `.getkey'
+	members.  Update all users.
+	* term/gfxterm.c (grub_video_term): Change type to
+	`struct  grub_term_output'.  Remove `.checkkey' and `.getkey'
+	members.  Update all users.
+	* include/grub/i386/pc/console.h (grub_console_checkkey)
+	(grub_console_getkey): Do not export (no longer needed by gfxterm,
+	etc).
+
+	Migrate `terminal' command and userland tools to new API:
+
+	* commands/terminal.c (grub_cmd_terminal): Split into ...
+	(grub_cmd_terminal_input): ... this, and ...
+	(grub_cmd_terminal_output): ... this.
+	(GRUB_MOD_INIT(terminal)): Split `terminal' command in two commands:
+	`terminal_input' and `terminal_output'.
+	* util/grub.d/00_header.in: Adjust `terminal' calls to new
+	`terminal_input' / `terminal_output' API.
+	* util/grub-mkconfig.in: Export ${GRUB_TERMINAL_INPUT} and
+	${GRUB_TERMINAL_OUTPUT} instead of ${GRUB_TERMINAL} (and if user
+	provided ${GRUB_TERMINAL}, convert it).
+
+2008-11-04  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/10_freebsd.in: New file.  Generate grub configuration
+	for FreeBSD.
+	* conf/common.rmk (grub-mkconfig_SCRIPTS): Add 10_freebsd.
+
+2008-11-03  Bean  <bean123ch@gmail.com>
+
+	* kern/elf.c (grub_elf32_load): Revert to previous code.
+	(grub_elf64_load): Likewise.
+
+	* loader/i386/bsd.c (grub_bsd_elf32_hook): Change return address.
+
+2008-11-01  Robert Millan  <rmh@aybabtu.com>
+
+	* Makefile.in (CPPFLAGS): Fix builddir=. assumption.
+	(TARGET_CPPFLAGS): Likewise.
+	* genmk.rb (mod_src): Fix builddir=. and srcdir=. assumptions.
+
+2008-11-01  Carles Pina i Estany  <carles@pina.cat>
+
+	* normal/menu.c (run_menu): Add Previous and Next Page keys in menu.
+
+2008-10-29  Guillem Jover  <guillem.jover@nokia.com>
+
+	* disk/lvm.c (grub_lvm_scan_device): Fix error recovery by delaying the
+	addition of objects until the code is not going to be able to fail.
+
+2008-10-29  Guillem Jover  <guillem.jover@nokia.com>
+
+	* disk/lvm.c (grub_lvm_scan_device): Fix possible NULL value handling
+	(add a missing NULL check, and correct them by moving the pointer
+	operations after the actual check).
+
+2008-10-29  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-install.in: Handle empty string as output from
+	make_system_path_relative_to_its_root().
+
+2008-10-05  Hans Lambermont  <hans@lambermont.dyndns.org>
+
+	* disk/lvm.c (grub_lvm_scan_device): Allocate buffer space for the
+	circular metadata worst case scenario. If the metadata is circular
+	then copy the wrap in place.
+	* include/grub/lvm.h: Add GRUB_LVM_MDA_HEADER_SIZE, from the LVM2
+	project lib/format_text/layout.h
+	Circular metadata bug found and patch debugged by Jan Derk Gerlings.
+
+2008-10-03  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/i386/pc/grub-install.in: Source grub-mkconfig_lib instead of update-grub_lib.
+
+2008-10-03  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/update-grub_lib.in: Mention filename in warning message.
+
+2008-09-29  Felix Zielcke  <fzielcke@z-51.de>
+
+	* NEWS: Update for rename of update-grub to grub-mkconfig.
+
+2008-09-29  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/update-grub_lib.in: Copy to ...
+	* util/grub-mkconfig_lib.in: ... this.  Update all users.
+	* util/update-grub_lib.in: Make it a stub to `grub-mkconfig_lib.in'.
+	* util/update-grub.in: Rename to ...
+	* util/grub-mkconfig.in: ... this.  Update all users.  Remove `-y'
+	option. Add `--output' option to allow users to specify the generated
+	configuration file.  Default to stdout.
+	(update_grub_dir): Rename to ...
+	(grub_mkconfig_dir): ... this.
+	(grub_cfg): Default to an empty string.
+	* conf/common.rmk (update-grub): Rename to ...
+	(grub-mkconfig): ... this.
+	(update-grub_lib): Copy to ...
+	(grub-mkconfig_lib): ... this.
+	(update-grub_SCRIPTS): Copy to ...
+	(grub-mkconfig_SCRIPTS): ... this. Update all users.
+	(update-grub_DATA): Rename to ...
+	(grub-mkconfig_DATA): ... this.
+
+2008-09-28  Robert Millan  <rmh@aybabtu.com>
+
+	* fs/iso9660.c (struct grub_iso9660_primary_voldesc): Rename `created'
+	to `modified'.  Add the real `created' field.
+	(grub_iso9660_uuid): Use `modified' rather than `created' for
+	constructing the UUID.
+
+2008-09-28  Felix Zielcke  <fzielcke@z-51.de>
+
+	fs/jfs.c (grub_jfs_find_file): Treat multiple slashes like one.
+	Based on code from Tomas Ebenlendr <ebik@ucw.cz>.
+
+2008-09-28  Bean  <bean123ch@gmail.com>
+
+	* fs/ntfs.c (grub_ntfs_iterate_dir): Fix a bug in the previous patch.
+	Thanks to Christian Franke for finding this bug.
+
+2008-09-25  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub-mkdevicemap.c (make_device_map): Actually replace all
+	instances of grub_util_get_disk_name() (see previous commit).
+
+2008-09-25  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-pc.rmk (grub_mkdevicemap_SOURCES): Remove
+	`util/i386/get_disk_name.c'.
+	* conf/i386-efi.rmk: Likewise.
+	* conf/x86_64-efi.rmk: Likewise.
+	* conf/i386-coreboot.rmk: Likewise.
+	* conf/i386-ieee1275.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_mkdevicemap_SOURCES): Remove
+	`util/ieee1275/get_disk_name.c'.
+	* include/grub/util/misc.h (grub_util_get_disk_name): Remove.
+	* util/ieee1275/get_disk_name.c: Remove file.
+	* util/i386/get_disk_name.c: Remove file.
+	* util/grub-mkdevicemap.c (make_device_map): Back to hardcoding
+	"hd%d" for device.map entries, rather than using
+	grub_util_get_disk_name().
+
+2008-09-24  Carles Pina i Estany  <carles@pina.cat>
+
+	* disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Fix `unused parameter'
+	warning.
+	* commands/i386/pc/pxecmd.c (dmraid_nvidia): Likewise.
+
+2008-09-24  Carles Pina i Estany  <carles@pina.cat>
+
+	* include/grub/i386/pc/console.h (GRUB_TERM_NPAGE):
+	Changed to 0x5100.
+	(GRUB_TERM_PPAGE): Changed to 0x4900.
+
+2008-09-24  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/powerpc/ieee1275/console.h (GRUB_CONSOLE_KEY_*): Remove
+	macros (they were i386-pc specific).
+	* include/grub/sparc64/ieee1275/console.h: Likewise.
+	* include/grub/efi/console.h: Likewise.
+
+2008-09-22  Bean  <bean123ch@gmail.com>
+
+	* fs/ntfs.c (grub_ntfs_iterate_dir): Fix a rare case where $BITMAP is
+	resident and in attribute list.
+
+	* include/grub/ntfs.h (BMP_LEN): Removed.
+
+2008-09-22  Bean  <bean123ch@gmail.com>
+
+	* disk/ata.c (grub_atapi_open): Initialize devfnd, no need to set
+	scsi->name and scsi->luns, as they will be set in grub_scsi_open.
+
+	* disk/scsi.c (grub_scsi_open): Don't call p->close (scsi) here when
+	error occurs, as grub_disk_open will call grub_disk_close, which will
+	call p->close (scsi).
+
+2008-09-21  Felix Zielcke  <fzielcke@z-51.de>
+
+	* configure.ac (AC_INIT): Quote `GRUB' string and version number.
+	(AC_PREREQ): Bumped to 2.59.
+	(AC_TRY_COMPILE): Replace obsolete macro with ...
+	(AC_COMPILE_IFELSE): ... this.
+	* aclocal.m4 (AC_TRY_LINK): Replace obsolete macro with ...
+	(AC_LINK_IFELSE): ... this.
+
+2008-09-21  Felix Zielcke  <fzielcke@z-51.de>
+
+	* autogen.sh: Add a call to `gendistlist.sh'.
+
+2008-09-19  Christian Franke  <franke@computer.org>
+
+	* aclocal.m4 (grub_CHECK_ENABLE_EXECUTE_STACK): New function.
+	* configure.ac: Call grub_CHECK_ENABLE_EXECUTE_STACK.
+	* include/grub/misc.h [NEED_ENABLE_EXECUTE_STACK]:
+	Export __enable_execute_stack() to modules.
+	* kern/misc.c [NEED_ENABLE_EXECUTE_STACK] (__enable_execute_stack):
+	New function.
+
+2008-09-09  Felix Zielcke  <fzielcke@z-51.de>
+
+	* Makefile.in (RMKFILES): Add `i386.rmk' and `x86_64-efi.rmk'.
+	Sort the list.
+
+2008-09-09  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/hostdisk.c: Replace #include <grub/util/biosdisk.h> with
+	#include <grub/util/hostdisk.h>.
+
+2008-09-08  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Skip
+	segments when their filesz is zero (grub_file_read() interprets
+	zero-size as "read until EOF", which results in memory corruption).
+	Use `lowest_segment' rather than 0 for calculating the current
+	segment load address.
+
+2008-09-08  Robert Millan  <rmh@aybabtu.com>
+
+	* util/hostdisk.c (open_device): Replace a grub_util_info() call
+	with grub_dprintf("hostdisk", ...), as it was so verbose that it
+	clobbered useful information.
+
+2008-09-08  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/util/biosdisk.h: Move to ...
+	* include/grub/util/hostdisk.h: ... here.  Update all users.
+	* util/biosdisk.c: Move to ...
+	* util/hostdisk.c: ... here.  Update all users.
+
+2008-09-07  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/multiboot.c (mmap_addr, mmap_length): Remove
+	variables.
+	(grub_multiboot): Move `mbi' allocation upwards, so that mmap address
+	and length can be stored directly in the `mbi->mmap_addr' and
+	`mbi->mmap_length' struct fields.
+
+2008-09-07  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386.rmk: New file.  Provides declaration for building
+	`cpuid.mod'.
+	* conf/i386-pc.rmk (pkglib_MODULES): Remove `cpuid.mod'.
+	(cpuid_mod_SOURCES, cpuid_mod_CFLAGS, cpuid_mod_LDFLAGS): Remove
+	variables.
+	Include `conf/i386.mk'.
+	* conf/i386-efi.rmk: Likewise.
+	* conf/x86_64-efi.rmk: Likewise.
+	* conf/i386-coreboot.rmk: Likewise.
+	* conf/i386-ieee1275.rmk: Likewise.
+
+2008-09-07  Vesa Jääskeläinen  <chaac@nic.fi>
+
+	Based on patch created by Colin D Bennett <colin@gibibit.com>.
+	Adds optimization support for BGR based modes.
+
+	* include/grub/i386/pc/vbeblit.h (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8) Removed.
+	(grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8_R8G8B8A8): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8_R8G8B8X8): Likewise.
+	(grub_video_i386_vbeblit_index_R8G8B8A8): Likewise.
+	(grub_video_i386_vbeblit_index_R8G8B8X8): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8A8_R8G8B8): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8_R8G8B8): Likewise.
+	(grub_video_i386_vbeblit_index_R8G8B8): Likewise.
+	(grub_video_i386_vbeblit_index_index): Likewise.
+	(grub_video_i386_vbeblit_replace_directN): Added.
+	(grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888): Likewise.
+	(grub_video_i386_vbeblit_replace_BGRX8888_RGB888): Likewise.
+	(grub_video_i386_vbeblit_replace_BGR888_RGBX8888): Likewise.
+	(grub_video_i386_vbeblit_replace_BGR888_RGB888): Likewise.
+	(grub_video_i386_vbeblit_replace_RGBX8888_RGB888): Likewise.
+	(grub_video_i386_vbeblit_replace_RGB888_RGBX8888): Likewise.
+	(grub_video_i386_vbeblit_replace_index_RGBX8888): Likewise.
+	(grub_video_i386_vbeblit_replace_index_RGB888): Likewise.
+	(grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888): Likewise.
+	(grub_video_i386_vbeblit_blend_BGR888_RGBA8888): Likewise.
+	(grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888): Likewise.
+	(grub_video_i386_vbeblit_blend_RGB888_RGBA8888): Likewise.
+	(grub_video_i386_vbeblit_blend_index_RGBA8888): Likewise.
+
+	* include/grub/i386/pc/vbefill.h (grub_video_i386_vbefill_R8G8B8A8) Removed.
+	(grub_video_i386_vbefill_R8G8B8): Likewise.
+	(grub_video_i386_vbefill_index): Likewise.
+	(grub_video_i386_vbefill_direct32): Added.
+	(grub_video_i386_vbefill_direct24): Likewise.
+	(grub_video_i386_vbefill_direct16): Likewise.
+	(grub_video_i386_vbefill_direct8): Likewise.
+
+	* include/grub/video.h (grub_video_blit_format): Removed
+	GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8, GRUB_VIDEO_BLIT_FORMAT_R8G8B8.
+	(grub_video_blit_format): Added GRUB_VIDEO_BLIT_FORMAT_RGBA_8888,
+	GRUB_VIDEO_BLIT_FORMAT_BGRA_8888, GRUB_VIDEO_BLIT_FORMAT_RGB_888,
+	GRUB_VIDEO_BLIT_FORMAT_BGR_888, GRUB_VIDEO_BLIT_FORMAT_RGB_565,
+	GRUB_VIDEO_BLIT_FORMAT_BGR_565.
+
+	* video/video.c (grub_video_get_blit_format): Updated to use new
+	blit formats.  Added handling for 16 bit color modes.
+
+	* video/i386/pc/vbe.c (grub_video_vbe_fill_rect): Updated to use new
+	fillers.
+	(common_blitter): Updated to use new blitters.
+
+	* video/i386/pc/vbeblit.c (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8):
+	Removed.
+	(grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8_R8G8B8A8): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8_R8G8B8X8): Likewise.
+	(grub_video_i386_vbeblit_index_R8G8B8A8): Likewise.
+	(grub_video_i386_vbeblit_index_R8G8B8X8): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8A8_R8G8B8): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8_R8G8B8): Likewise.
+	(grub_video_i386_vbeblit_index_R8G8B8): Likewise.
+	(grub_video_i386_vbeblit_index_index): Likewise.
+	(grub_video_i386_vbeblit_replace_directN): Added.
+	(grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888): Likewise.
+	(grub_video_i386_vbeblit_replace_BGRX8888_RGB888): Likewise.
+	(grub_video_i386_vbeblit_replace_BGR888_RGBX8888): Likewise.
+	(grub_video_i386_vbeblit_replace_BGR888_RGB888): Likewise.
+	(grub_video_i386_vbeblit_replace_RGBX8888_RGB888): Likewise.
+	(grub_video_i386_vbeblit_replace_RGB888_RGBX8888): Likewise.
+	(grub_video_i386_vbeblit_replace_index_RGBX8888): Likewise.
+	(grub_video_i386_vbeblit_replace_index_RGB888): Likewise.
+	(grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888): Likewise.
+	(grub_video_i386_vbeblit_blend_BGR888_RGBA8888): Likewise.
+	(grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888): Likewise.
+	(grub_video_i386_vbeblit_blend_RGB888_RGBA8888): Likewise.
+	(grub_video_i386_vbeblit_blend_index_RGBA8888): Likewise.
+
+	* video/i386/pc/vbefill.c (grub_video_i386_vbefill_R8G8B8A8): Removed.
+	(grub_video_i386_vbefill_R8G8B8): Likewise.
+	(grub_video_i386_vbefill_index): Likewise.
+	(grub_video_i386_vbefill_direct32): Added.
+	(grub_video_i386_vbefill_direct24): Likewise.
+	(grub_video_i386_vbefill_direct16): Likewise.
+	(grub_video_i386_vbefill_direct8): Likewise.
+
+	* video/readers/jpeg.c (grub_jpeg_decode_sos): Adapt to new blitter
+	types.
+
+	* video/readers/tga.c (grub_video_reader_tga): Adapt to new blitter
+	types.
+
+	* video/readers/png.c (grub_png_decode_image_header): Adapt to new
+	blitter types.
+
+	* video/bitmap.c (grub_video_bitmap_create): Adapt to new blitter
+	types.
+
+2008-09-06  Felix Zielcke  <fzielcke@z-51.de>
+
+	* disk/raid.c (insert_array): Set `array->chunk_size' to 64 for
+	RAID level 1.
+
+2008-09-06  Felix Zielcke  <fzielcke@z-51.de>
+
+	* fs/iso9660.c (grub_iso9660_date): New structure.
+	(grub_iso9660_primary_voldesc): Add `grub_iso9660_date' member.
+	(grub_iso9660_uuid): New function.
+
+2008-09-05  Bean  <bean123ch@gmail.com>
+
+	* fs/fshelp.c (grub_fshelp_find_file): Handle case insensitive names.
+
+	* fs/ntfs.c (list_file): Ignore names in DOS namespace, set the case
+	insensitive bit for names in Win32 and Win32 & DOS namespace.
+
+	* include/grub/fshelp.h (GRUB_FSHELP_CASE_INSENSITIVE): New macro.
+
+	* include/grub/types.h (LONG_MAX): Likewise.
+
+2008-09-04  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/getroot.c: Include <config.h>.
+	(grub_util_get_grub_dev): Rewrite to use asprintf for mdraid devices,
+	add support for /dev/md/N devices and handle LVM double dash escaping.
+
+2008-09-04  Felix Zielcke  <fzielcke@z-51.de>
+
+	* config.guess: Update to latest version from config git.
+	* config.sub: Likewise.
+
+2008-09-03  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/scsi.c (grub_scsi_open): Remove size limit when printing
+	`disk->total_sectors'.
+
+2008-09-01  Colin D Bennett  <colin@gibibit.com>
+
+	* include/grub/normal.h: Fixed incorrect comment for
+	GRUB_COMMAND_FLAG_NO_ARG_PARSE.
+
+2008-09-01  Colin D Bennett  <colin@gibibit.com>
+
+	* commands/i386/pc/vbeinfo.c (grub_cmd_vbeinfo): Replaced constant
+	values with defines.
+
+	* include/grub/i386/pc/vbe.h (GRUB_VBE_MODEATTR_SUPPORTED): Added.
+	(GRUB_VBE_MODEATTR_RESERVED_1): Likewise.
+	(GRUB_VBE_MODEATTR_BIOS_TTY_OUTPUT_SUPPORT): Likewise.
+	(GRUB_VBE_MODEATTR_COLOR): Likewise.
+	(GRUB_VBE_MODEATTR_GRAPHICS): Likewise.
+	(GRUB_VBE_MODEATTR_VGA_COMPATIBLE): Likewise.
+	(GRUB_VBE_MODEATTR_VGA_WINDOWED_AVAIL): Likewise.
+	(GRUB_VBE_MODEATTR_LFB_AVAIL): Likewise.
+	(GRUB_VBE_MODEATTR_DOUBLE_SCAN_AVAIL): Likewise.
+	(GRUB_VBE_MODEATTR_INTERLACED_AVAIL): Likewise.
+	(GRUB_VBE_MODEATTR_TRIPLE_BUF_AVAIL): Likewise.
+	(GRUB_VBE_MODEATTR_STEREO_AVAIL): Likewise.
+	(GRUB_VBE_MODEATTR_DUAL_DISPLAY_START): Likewise.
+	(GRUB_VBE_MEMORY_MODEL_TEXT): Likewise.
+	(GRUB_VBE_MEMORY_MODEL_CGA): Likewise.
+	(GRUB_VBE_MEMORY_MODEL_HERCULES): Likewise.
+	(GRUB_VBE_MEMORY_MODEL_PLANAR): Likewise.
+	(GRUB_VBE_MEMORY_MODEL_NONCHAIN4_256): Likewise.
+	(GRUB_VBE_MEMORY_MODEL_YUV): Likewise.
+
+2008-08-31  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/multiboot.c (grub_get_multiboot_mmap_len): Fix
+	declaration.
+	(grub_multiboot): Fix a few warnings.
+
+2008-08-31  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/multiboot.c: Update comment not to say that
+	boot_device support is unimplemented.
+
+2008-08-31  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/multiboot.c: Update comment not to say that a.out
+	or memory map support are unimplemented.
+
+2008-08-31  Colin D Bennett  <colin@gibibit.com>
+
+	* util/i386/pc/grub-mkrescue.in: Support multiple overlay directories.
+
+2008-08-31  Colin D Bennett  <colin@gibibit.com>
+
+	* commands/i386/pc/vbeinfo.c (grub_cmd_vbeinfo): Show VBE version and
+	total video memory in 'vbeinfo' output; show color format details for
+	each video mode.
+
+2008-08-30  Pavel Roskin  <proski@gnu.org>
+
+	* util/genmoddep.c: Remove for real this time.
+	* DISTLIST: Remove util/genmoddep.c.
+
+2008-08-30  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/i386/pc/startup.S (multiboot_header): Force 4-byte alignment
+	as required by Multiboot spec (it was already 4-byte aligned, but
+	only by chance).
+
+2008-08-29  Pavel Roskin  <proski@gnu.org>
+
+	* kern/powerpc/ieee1275/crt0.S: Rename to ...
+	* kern/powerpc/ieee1275/startup.S: ... this.
+	* conf/powerpc-ieee1275.rmk: Adjust for the above.
+	* DISTLIST: Likewise.
+
+	* kern/powerpc/ieee1275/crt0.S: Include grub/symbol.h and
+	grub/cpu/kernel.h.  Add start label for consistency with other
+	platforms.  Add grub_prefix immediately after start.  Add jump
+	to the code after grub_prefix.
+	* include/grub/powerpc/kernel.h: Provide valid values for
+	GRUB_KERNEL_CPU_PREFIX and GRUB_KERNEL_CPU_DATA_END.
+
+2008-08-29  Bean  <bean123ch@gmail.com>
+
+	* configure.ac: Change host_os to cygwin for mingw.
+	(asprintf): New check for function.
+
+	* include/grub/symbol.h: Replace #ifndef __CYGWIN__ with
+	#if ! defined (__CYGWIN__) && ! defined (__MINGW32__).
+
+	* include/grub/util/misc.h: #include <config.h> and <grub/types.h>,
+	declare asprintf if HAVE_ASPRINTF is not set, declare fseeko, ftello,
+	sync, sleep and grub_util_get_disk_size for mingw.
+
+	* util/biosdisk.c (grub_util_biosdisk_open): Use grub_util_get_disk_size
+	to get size in mingw.
+	(open_device): Use flag O_BINARY if it's defined.
+	(find_root_device): Add dummy code for mingw.
+
+	* util/grub-mkdevicemap.c (get_floppy_disk_name): Return 0 for mingw.
+	(get_ide_disk_name): Return //./PHYSICALDRIVE%d for mingw.
+	(get_scsi_disk_name): Return 0 for mingw.
+
+	* util/hostfs.c: #include <grub/util/misc.h>.
+	(grub_hostfs_open): Use "rb" flag to open file, use
+	grub_util_get_disk_size to get disk size for mingw.
+
+	* util/misc.c: #include <windows.h> and <winioctl.h> in mingw.
+	(asprintf): New function if HAVE_ASPRINTF is not set.
+	(sync): New function for mingw.
+	(sleep): Likewise.
+	(grub_util_get_disk_size): Likewise.
+
+2008-08-28  Pavel Roskin  <proski@gnu.org>
+
+	* conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Add
+	kern/time.c.
+
+2008-08-28  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (find_grub_drive): Declare missing `i' variable.
+
+2008-08-28  Robert Millan  <rmh@aybabtu.com>
+
+	Change find_grub_drive() syntax so it doesn't prevent it from
+	detecting NULL names as errors.
+
+	* util/biosdisk.c (find_grub_drive): Move free slot search code
+	from here ...
+	(find_free_slot): ... to here.
+	(read_device_map): Use find_free_slot() to search for free slots.
+
+2008-08-27  Marco Gerards  <marco@gnu.org>
+
+	* conf/common.rmk (pkglib_MODULES): Add scsi.mod.
+	(scsi_mod_SOURCES): New variable.
+	(scsi_mod_CFLAGS): Likewise
+	(scsi_mod_LDFLAGS): Likewise.
+
+	* disk/scsi.c: New file.
+
+	* include/grub/scsi.h: Likewise.
+
+	* include/grub/scsicmd.h: Likewise.
+
+	* disk/ata.c: Include <grub/scsi.h>.
+	(grub_atapi_packet): Do not use grub_ata_cmd, use registers
+	instead.
+	(grub_ata_iterate): Skip ATAPI devices.
+	(grub_ata_open): Only handle ATAPI devices.
+	(struct grub_atapi_read): Removed.
+	(grub_atapi_readsector): Likewise.
+	(grub_ata_read): No longer handle ATAPI devices.
+	(grub_ata_write): Likewise.
+	(grub_atapi_iterate): New function.
+	(grub_atapi_read): Likewise.
+	(grub_atapi_write): Likewise.
+	(grub_atapi_open): Likewise.
+	(grub_atapi_close): Likewise.
+	(grub_atapi_dev): New variable.
+	(GRUB_MOD_INIT(ata)): Register ATAPI as SCSI device.
+	(GRUB_MOD_FINI(ata)): Unregister ATAPI.
+
+	* include/grub/disk.h (enum grub_disk_dev_id): Add
+	`GRUB_DISK_DEVICE_SCSI_ID'.
+
+2008-08-26  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (grub_util_biosdisk_open, open_device)
+	(grub_util_biosdisk_get_grub_dev): Make error messages a bit more
+	descriptive.
+
+2008-08-23  Bean  <bean123ch@gmail.com>
+
+	* conf/common.rmk (grub_probe_SOURCES): Add disk/mdraid_linux.c.
+	(grub_fstest_SOURCES): Add disk/raid5_recover.c, disk/raid6_recover.c,
+	disk/mdraid_linux.c and disk/dmraid_nvidia.c and lib/crc.c.
+	(pkglib_MODULES): Add raid5rec.mod, raid6rec.mod, mdraid.mod and
+	dm_nv.mod.
+	(raid5rec_mod_SOURCES): New macro.
+	(raid5rec_mod_CFLAGS): Likewise.
+	(raid5rec_mod_LDFLAGS): Likewise.
+	(raid6rec_mod_SOURCES): Likewise.
+	(raid6rec_mod_CFLAGS): Likewise.
+	(raid6rec_mod_LDFLAGS): Likewise.
+	(mdraid_mod_SOURCES): Likewise.
+	(mdraid_mod_CFLAGS): Likewise.
+	(mdraid_mod_LDFLAGS): Likewise.
+	(dm_nv_mod_SOURCES): Likewise.
+	(dm_nv_mod_CFLAGS): Likewise.
+	(dm_nv_mod_LDFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add disk/mdraid_linux.c.
+	(grub_emu_SOURCES):  Add disk/raid5_recover.c, disk/raid6_recover.c,
+	disk/mdraid_linux.c and disk/dmraid_nvidia.c.
+
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Add disk/raid5_recover.c,
+	disk/raid6_recover.c, disk/mdraid_linux.c and disk/dmraid_nvidia.c.
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+	* disk/raid5_recover.c: New file.
+
+	* disk/raid6_recover.c: Likewise.
+
+	* disk/mdraid_linux.c: Likewise.
+
+	* disk/dmraid_nvidia.c: Likewise.
+
+	* disk/i386/pc/biosdisk.c: Set total_sectors of cdrom device to
+	ULONG_MAX.
+
+	* disk/raid.c (grub_raid_open): Use the size of the smallest disk to
+	calculate the size of raid device.
+	(grub_raid_read): Simplify raid0 code. Support raid4, raid6 and four
+	different layout of raid5.
+	(grub_raid_scan_device): Remove code specific to mdraid.
+	(grub_raid_list): New variable.
+	(free_array): New function.
+	(grub_raid_register): Likewise.
+	(grub_raid_unregister): Likewise.
+	(grub_raid_rescan): Likewise.
+	(GRUB_MOD_INIT): Don't iterate device here.
+	(GRUB_MOD_FINI): Use free_array to release resource.
+
+	* include/grub/raid.h: Remove macro and structure specific to mdraid.
+	(grub_raid5_recover_func_t): New function variable type.
+	(grub_raid6_recover_func_t): Likewise.
+	(grub_raid5_recover_func): New variable.
+	(grub_raid6_recover_func): Likewise.
+	(grub_raid_register): New function.
+	(grub_raid_unregister): Likewise.
+	(grub_raid_rescan): Likewise.
+	(grub_raid_block_xor): Likewise.
+
+	* util/grub-fstest.c: Add #include <grub/raid.h> and <grub/lib/crc.h>.
+	(CMD_CRC): New macro.
+	(part): Removed.
+	(read_file): Handle device as well as file.
+	(cmd_crc): New function.
+	(fstest): Handle multiple disks.
+	(options): Remove part, raw and long, add root and diskcount.
+	(usage): Add crc, remove -p, -r, -l, add -r and -c.
+	(main): Find the first non option entry and ignore subsequent options,
+	add handling for the new options, support multiple disks.
+
+	* util/grub-probe.c (probe): Add mdraid to abstraction_name.
+
+2008-08-23  Bean  <bean123ch@gmail.com>
+
+	* normal/x86_64/setjmp.S (grub_longjmp): Return 1 when val = 0.
+
+	* genfslist.sh: Ignore kernel.mod.
+
+	* genpartmaplist.sh: Likewise.
+
+2008-08-23  Robert Millan  <rmh@aybabtu.com>
+
+	* util/getroot.c (find_root_device): Skip anything that starts with
+	a dot, not just directories.  This avoids things like /dev/.tmp.md0.
+
+2008-08-22  Felix Zielcke  <fzielcke@z-51.de>
+
+	* util/update-grub.in (GRUB_GFXMODE): Export variable.
+	* util/grub.d/00_header.in: Allow the administrator to change default
+	gfxmode via ${GRUB_GFXMODE}.
+
+2008-08-21  Felix Zielcke  <fzielcke@z-51.de>
+
+	* fs/ntfs.c (grub_ntfs_mount): Fix a memory leak.
+
+2008-08-21  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/linux.c: New file.  Implements generic 32-bit Linux
+	loader.
+	* conf/i386-coreboot.rmk (_linux_mod_SOURCES): Replace
+	`loader/i386/pc/linux.c' with `loader/i386/linux.c'.
+
+2008-08-20  Carles Pina i Estany  <carles@pina.cat>
+
+	* menu/normal.c (run_menu): Replace hardcoded numbers with macros
+	(16 for GRUB_TERM_UP and 14 for GRUB_TERM_DOWN)
+
+2008-08-19  Robert Millan  <rmh@aybabtu.com>
+
+	* term/gfxterm.c (DEFAULT_CURSOR_COLOR): Remove.
+	(struct grub_virtual_screen): Remove `cursor_color'.
+	(grub_virtual_screen_setup): Remove `virtual_screen.cursor_color'
+	initialization.
+	(write_cursor): Use `virtual_screen.fg_color' to draw cursor.
+
+2008-08-18  Robert Millan  <rmh@aybabtu.com>
+
+	Unify (identical) linux_normal.c files.
+	* loader/i386/efi/linux_normal.c: Move from here ...
+	* loader/linux_normal.c: ... to here.  Update all users.
+	* loader/i386/pc/linux_normal.c: Delete.  Update all users.
+	* loader/i386/ieee1275/linux_normal.c: Likewise.
+
+2008-08-18  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/linux.h (LINUX_LOADER_ID_LILO)
+	(LINUX_LOADER_ID_LOADLIN, LINUX_LOADER_ID_BOOTSECT)
+	(LINUX_LOADER_ID_SYSLINUX, LINUX_LOADER_ID_ETHERBOOT)
+	(LINUX_LOADER_ID_ELILO, LINUX_LOADER_ID_GRUB, LINUX_LOADER_ID_UBOOT)
+	(LINUX_LOADER_ID_XEN, LINUX_LOADER_ID_GUJIN, LINUX_LOADER_ID_QEMU):
+	New macros.
+	(GRUB_LINUX_CL_OFFSET, GRUB_LINUX_CL_END_OFFSET): Move from here ...
+	* loader/i386/pc/linux.c (GRUB_LINUX_CL_OFFSET)
+	(GRUB_LINUX_CL_END_OFFSET): ... to here.
+	* loader/i386/efi/linux.c (GRUB_EFI_CL_OFFSET): Rename to ...
+	(GRUB_LINUX_CL_OFFSET): ... this.  Update all users.
+	(GRUB_EFI_CL_END_OFFSET): Rename to ...
+	(GRUB_LINUX_CL_END_OFFSET): ... this.  Update all users.
+	(grub_rescue_cmd_linux): Macroify `type_of_loader' initialization.
+	Initialize `params->video_cursor_x' and `params->video_cursor_y'
+	portably using grub_getxy().
+	Replace `-EFI' with `-bzImage' in boot message.
+
+2008-08-17  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/x86_64/kernel.h: New file (<grub/i386/kernel.h> stub).
+
+2008-08-17  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/i386/pc/mmap.c'.
+
+	* include/grub/i386/pc/init.h (GRUB_MACHINE_MEMORY_AVAILABLE)
+	(GRUB_MACHINE_MEMORY_RESERVED): New macros.
+	(grub_machine_mmap_iterate): New function declaration.
+	* include/grub/multiboot.h (struct grub_multiboot_mmap_entry): New
+	structure.
+	(GRUB_MMAP_MEMORY_AVAILABLE, GRUB_MMAP_MEMORY_RESERVED): New
+	macros.
+
+	* kern/i386/pc/init.c (grub_machine_init): Replace hardcoded region
+	type check value with `GRUB_MACHINE_MEMORY_AVAILABLE'.
+	Move e820 parsing from here ...
+	* kern/i386/pc/mmap.c: New file.
+	(grub_machine_mmap_iterate): ... to here.
+
+	* include/grub/i386/coreboot/memory.h: Remove `<grub/err.h>'.
+	(GRUB_LINUXBIOS_MEMORY_AVAILABLE): Rename (for consistency) to ...
+	(GRUB_MACHINE_MEMORY_AVAILABLE): ... this.  Update all users.
+	(grub_available_iterate): Redeclare to return `void', and redeclare
+	its hook to use grub_uint64_t as addr and size parameters, and rename
+	to ...
+	(grub_machine_mmap_iterate): ... this.  Update all users.
+
+	* kern/i386/coreboot/mmap.c (grub_mmap_iterate): Simplify parser loop
+	to make it more readable.  Rename to ...
+	(grub_machine_mmap_iterate): ... this.
+
+	* loader/i386/pc/multiboot.c (mmap_addr, mmap_length): New variables.
+	(grub_get_multiboot_mmap_len, grub_fill_multiboot_mmap): New functions.
+	(grub_multiboot): Allocate an extra region after the payload, and fill
+	it with a Multiboot memory map.  Adjust a.out loader to calculate size
+	with the extra space.
+	(grub_multiboot_load_elf32): Adjust elf32 loader to calculate size
+	with the extra space.
+
+2008-08-17  Carles Pina i Estany  <carles@pina.cat>
+
+	* menu/normal.c (run_menu): Add Home and End keys in grub-menu.
+
+2008-08-17  Felix Zielcke  <fzielcke@z-51.de>
+
+	* gendistlist.sh: Add *.y, *.tex, *.texi, grub.cfg, README, *.sc,
+	mdate-sh to the list `find' searches for.
+	* DISTLIST: Regenerated.
+
+2008-08-16  Felix Zielcke  <fzielcke@z-51.de>
+
+	* gendistlist.sh (EXTRA_DISTFILES): Remove gensymlist.sh,
+	genkernsyms.sh.  Add geninit.sh, geninitheader.sh, genkernsyms.sh.in,
+	genmoddep.awk, gensymlist.sh.in.
+	(DISTDIRS): Add bus, docs, hook, lib.
+	* DISTLIST: Regenerated.
+	* NEWS: Add cygwin support and change the `os-prober' entry a bit.
+
+2008-08-16  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/raid.c (grub_raid_init): Handle/report errors set by
+	grub_device_iterate().
+	* disk/lvm.c (grub_lvm_init): Likewise.
+
+2008-08-15  Bean  <bean123ch@gmail.com>
+
+	* conf/i386-pc.rmk (pkglib_MODULES): Add datetime.mod, date.mod
+	and datehook.mod.
+	(datetime_mod_SOURCES): New macro.
+	(datetime_mod_CFLAGS): Likewise.
+	(datetime_mod_LDFLAGS): Likewise.
+	(date_mod_SOURCES): Likewise.
+	(date_mod_CFLAGS): Likewise.
+	(date_mod_LDFLAGS): Likewise.
+	(datehook_mod_SOURCES): Likewise.
+	(datehook_mod_CFLAGS): Likewise.
+	(datehook_mod_LDFLAGS): Likewise.
+
+	* conf/i386-coreboot.rmk (pkglib_MODULES): Add datetime.mod, date.mod
+	and datehook.mod.
+	(datetime_mod_SOURCES): New macro.
+	(datetime_mod_CFLAGS): Likewise.
+	(datetime_mod_LDFLAGS): Likewise.
+	(date_mod_SOURCES): Likewise.
+	(date_mod_CFLAGS): Likewise.
+	(date_mod_LDFLAGS): Likewise.
+	(datehook_mod_SOURCES): Likewise.
+	(datehook_mod_CFLAGS): Likewise.
+	(datehook_mod_LDFLAGS): Likewise.
+
+	* conf/i386-ieee1275.rmk (pkglib_MODULES): Add datetime.mod, date.mod
+	and datehook.mod.
+	(datetime_mod_SOURCES): New macro.
+	(datetime_mod_CFLAGS): Likewise.
+	(datetime_mod_LDFLAGS): Likewise.
+	(date_mod_SOURCES): Likewise.
+	(date_mod_CFLAGS): Likewise.
+	(date_mod_LDFLAGS): Likewise.
+	(datehook_mod_SOURCES): Likewise.
+	(datehook_mod_CFLAGS): Likewise.
+	(datehook_mod_LDFLAGS): Likewise.
+
+	* conf/i386-efi.rmk (pkglib_MODULES): Add datetime.mod, date.mod
+	and datehook.mod.
+	(datetime_mod_SOURCES): New macro.
+	(datetime_mod_CFLAGS): Likewise.
+	(datetime_mod_LDFLAGS): Likewise.
+	(date_mod_SOURCES): Likewise.
+	(date_mod_CFLAGS): Likewise.
+	(date_mod_LDFLAGS): Likewise.
+	(datehook_mod_SOURCES): Likewise.
+	(datehook_mod_CFLAGS): Likewise.
+	(datehook_mod_LDFLAGS): Likewise.
+
+	* conf/x86_64-efi.rmk (pkglib_MODULES): Add datetime.mod, date.mod
+	and datehook.mod.
+	(datetime_mod_SOURCES): New macro.
+	(datetime_mod_CFLAGS): Likewise.
+	(datetime_mod_LDFLAGS): Likewise.
+	(date_mod_SOURCES): Likewise.
+	(date_mod_CFLAGS): Likewise.
+	(date_mod_LDFLAGS): Likewise.
+	(datehook_mod_SOURCES): Likewise.
+	(datehook_mod_CFLAGS): Likewise.
+	(datehook_mod_LDFLAGS): Likewise.
+
+	* kern/env.c (grub_env_insert): Fix a bug in prevp pointer.
+
+	* commands/date.c: New file.
+
+	* hook/datehook.c: Likewise.
+
+	* include/grub/lib/datetime.h: Likewise.
+
+	* include/grub/i386/cmos.h: Likewise.
+
+	* lib/datetime.c: Likewise.
+
+	* lib/i386/datetime.c: Likewise.
+
+	* lib/efi/datetime.c: Likewise.
+
+2008-08-14  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/common.rmk (bin_UTILITIES): Add `grub-mkelfimage'.
+	(grub_mkelfimage_SOURCES): New variable.
+	(util/elf/grub-mkimage.c_DEPENDENCIES): Likewise.
+
+	* conf/i386-coreboot.rmk (bin_UTILITIES, grub_mkimage_SOURCES)
+	(grub_mkimage_LDFLAGS, util/elf/grub-mkimage.c_DEPENDENCIES): Remove.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	* conf/i386-ieee1275.rmk: Likewise.
+
+	* kern/ieee1275/init.c: Include `<grub/cpu/kernel.h>'.
+	* kern/i386/coreboot/init.c: Likewise.
+
+	* kern/i386/ieee1275/startup.S: Replace `<grub/machine/kernel.h>'
+	with `<grub/cpu/kernel.h>'.
+	(GRUB_KERNEL_MACHINE_PREFIX, GRUB_KERNEL_MACHINE_DATA_END): Renamed
+	to ...
+	(GRUB_KERNEL_CPU_PREFIX, GRUB_KERNEL_CPU_DATA_END): ... this.
+	* kern/i386/coreboot/startup.S: Likewise.
+
+	* include/grub/powerpc/ieee1275/kernel.h (GRUB_MOD_ALIGN)
+	(GRUB_MOD_GAP): Remove.
+	* include/grub/powerpc/kernel.h: New file.
+	* include/grub/i386/ieee1275/kernel.h (GRUB_KERNEL_MACHINE_PREFIX)
+	(GRUB_KERNEL_MACHINE_DATA_END): Remove.
+	* include/grub/i386/kernel.h: New file.
+	* include/grub/i386/coreboot/kernel.h (GRUB_MOD_ALIGN)
+	(GRUB_MOD_GAP, GRUB_KERNEL_MACHINE_PREFIX)
+	(GRUB_KERNEL_MACHINE_DATA_END): Remove.
+
+	* util/ieee1275/grub-install.in (grub_mkimage): Initialize to use
+	`grub-mkelfimage'.
+	Use --directory when invoking grub_mkimage.
+
+	* util/elf/grub-mkimage.c: Include `<grub/cpu/kernel.h>'.
+	(add_segments): Replace GRUB_KERNEL_MACHINE_DATA_END and
+	GRUB_KERNEL_MACHINE_PREFIX with GRUB_KERNEL_CPU_DATA_END
+	and GRUB_KERNEL_CPU_PREFIX.
+
+2008-08-14  Felix Zielcke  <fzielcke@z-51.de>
+
+	* include/grub/err.h (grub_err_printf): New function prototype.
+	* util/misc.c (grub_err_printf): New function.
+	* kern/misc.c [! GRUB_UTIL] (grub_err_printf): New alias for
+	grub_printf.
+	* kern/err.c (grub_print_error): Use grub_err_printf.
+
+2008-08-13  Robert Millan  <rmh@aybabtu.com>
+
+	* docs/grub.cfg: Remove `/dev/' prefix in GNU/Hurd boot entry.
+
+2008-08-13  Robert Millan  <rmh@aybabtu.com>
+
+	* docs/grub.cfg: Use the native device name for the example GNU/Hurd
+	boot entry.
+
+2008-08-12  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Move part
+	of the relocation code from here ...
+	(grub_multiboot): ... to here.
+	(forward_relocator, backward_relocator): Move from here ...
+	* kern/i386/loader.S (grub_multiboot_forward_relocator)
+	(grub_multiboot_backward_relocator): ... to here.
+	(grub_multiboot_real_boot): Use %edx for entry offset.  Put Multiboot
+	magic in %eax.  Use %ebp for jumping (so %edx is not trashed).
+	* include/grub/i386/loader.h (grub_multiboot_forward_relocator)
+	(grub_multiboot_forward_relocator_end)
+	(grub_multiboot_backward_relocator)
+	(grub_multiboot_backward_relocator_end): New variables.
+
+2008-08-12  Bean  <bean123ch@gmail.com>
+
+	* disk/raid.c (grub_raid_read): Fix a bug in raid0 code.
+
+2008-08-11  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/i386/linuxbios/startup.S: Move from here ...
+	* kern/i386/coreboot/startup.S: ... to here.
+
+	* kern/i386/linuxbios/init.c: Move from here ...
+	* kern/i386/coreboot/init.c: ... to here.
+
+	* kern/i386/linuxbios/table.c: Move from here ...
+	* kern/i386/coreboot/mmap.c: ... to here.
+
+	* conf/i386-coreboot.rmk (kernel_elf_SOURCES): Update moved files.
+
+2008-08-11  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/device.c (grub_device_open): Do not handle grub_disk_open()
+	errors.  Leave it to the upper layer to handle them.
+
+2008-08-09  Christian Franke  <franke@computer.org>
+
+	* Makefile.in: Add `target_os' and `enable_grub_pe2elf'.
+	* conf/common.rmk: Install `grub-pe2elf' only if requested.
+	Install `grub.d/10_windows' only on Cygwin.
+	* configure.ac: Add subst of `target_os'.
+	Check `target_os' also before setting TARGET_OBJ2ELF.
+	Add `--enable-grub-pe2elf'.
+
+2008-08-08  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/disk.c: Replace `<grub/machine/time.h>' with `<grub/time.h>'.
+	(grub_last_time): Change type to grub_uint64_t.
+	(grub_disk_open): Migrate code from to using grub_get_time_ms().
+	(grub_disk_close): Likewise.
+
+	* normal/menu.c: Replace `<grub/machine/time.h>' with `<grub/time.h>'.
+	(run_menu): Migrate code from to using grub_get_time_ms().
+
+	* util/misc.c (grub_get_time_ms): New function.
+
+2008-08-08  Marco Gerards  <marco@gnu.org>
+
+	* disk/ata.c (grub_ata_regget): Change return type to
+	`grub_uint8_t'.
+	(grub_ata_regget2): Likewise.
+	(grub_ata_wait_status): New function.
+	(grub_ata_wait_busy): Removed function, updated all users to use
+	`grub_ata_wait_status'.
+	(grub_ata_wait_drq): Likewise.
+	(grub_ata_cmd): New function.
+	(grub_ata_pio_read): Change return type to `grub_uint8_t'.  Add
+	error handling.
+	(grub_ata_pio_write): Add error handling.
+	(grub_atapi_identify): Likewise.
+	(grub_atapi_packet): Use `grub_ata_cmd' and improve error
+	handling.
+	(grub_ata_identify): Use `grub_ata_cmd' and improve error
+	handling.  Actually use the detected registers.  Reorder the
+	detection logic such that it is easier to read.
+	(grub_ata_pciinit): Do not assign the same ID to each controller.
+	(grub_ata_setaddress): Use `grub_ata_cmd' and improve error
+	handling.
+	(grub_atapi_readsector): Check the result of `grub_ata_pio_read'.
+
+	* include/grub/err.h (grub_err_t): Add `GRUB_ERR_TIMEOUT'.
+
+2008-08-08  Marco Gerards  <marco@gnu.org>
+
+	* NEWS: Update.
+
+2008-08-07  Bean  <bean123ch@gmail.com>
+
+	* include/grub/x86_64/pci.h: New file.
+
+2008-08-07  Christian Franke  <franke@computer.org>
+
+	* kern/i386/pit.c (TIMER2_SPEAKER): New define.
+	(TIMER2_GATE): Likewise.
+	(grub_pit_wait): Add enable/disable of the timer2 gate
+	bit of port 0x61.  This fixes a possible infinite loop.
+
+2008-08-07  Bean  <bean123ch@gmail.com>
+
+	* conf/x86_64-efi.rmk (kernel_mod_SOURCES): Add kern/time.c,
+	kern/i386/tsc.c and kern/i386/pit.c.
+
+	* include/grub/i386/tsc.h (grub_cpu_is_cpuid_supported): Handle
+	x86_64 platform.
+
+	* kern/i386/efi/init.c: Replace <grub/cpu/tsc.h> with
+	<grub/i386/tsc.h>.
+
+	* kern/i386/pit.c: Replace <grub/cpu/io.h> with <grub/i386/io.h>.
+
+2008-08-07  Bean  <bean123ch@gmail.com>
+
+	* conf/i386-efi.rmk (kernel_mod_SOURCES): Add kern/time.c.
+
+	* conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add kern/time.c,
+
+	* include/grub/i386/pit.h: Use macro KERNEL_CPU_PIT_HEADER to avoid
+	multiple inclusion. Add #include <grub/types.h>.
+
+2008-08-06  Christian Franke  <franke@computer.org>
+
+	* conf/common.rmk: Build and install `10_windows'.
+	* util/grub.d/10_windows.in: New script.
+
+2008-08-06  Pavel Roskin  <proski@gnu.org>
+
+	* kern/i386/pit.c: Include `<grub/i386/pit.h>'.
+
+2008-08-06  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-coreboot.rmk (kernel_elf_ASFLAGS): New variable.
+	* kern/i386/tsc.c: Include `<grub/i386/pit.h>'.
+
+2008-08-06  Bean  <bean123ch@gmail.com>
+
+	* fs/i386/pc/pxe.c (grub_pxe_data): New member block_size.
+	(grub_pxefs_fs_int): Remove dummy definition.
+	(grub_pxefs_open): Use data->block_size to store the current block
+	size setting.
+	(grub_pxefs_read): Use block size stored in data->block_size. As the
+	value of grub_pxe_blksize can be changed after the file is opened.
+
+2008-08-06  Bean  <bean123ch@gmail.com>
+
+	* fs/i386/pc/pxe.c (curr_file): new variable.
+	(grub_pxefs_open): Simply the handling of pxe file system. Don't
+	require the dummy internal file system anymore.
+	(grub_pxefs_read): Removed.
+	(grub_pxefs_close): Likewise.
+	(grub_pxefs_fs_int): Likewise.
+	(grub_pxefs_read_int): Renamed to grub_pxefs_read. Reinitialize tftp
+	connection when we switch file.
+	(grub_pxefs_close_int): Renamed to grub_pxefs_close.
+
+2008-08-06  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-coreboot.rmk (pkglib_MODULES): Add `reboot.mod' and
+	`halt.mod'.
+	(reboot_mod_SOURCES, reboot_mod_CFLAGS, reboot_mod_LDFLAGS)
+	(halt_mod_SOURCES, halt_mod_CFLAGS, halt_mod_LDFLAGS): New variables.
+
+	* kern/i386/halt.c: New file.
+	* kern/i386/reboot.c: Likewise.
+	* include/grub/i386/reboot.h: Likewise.
+	* include/grub/i386/halt.h: Likewise.
+
+	* commands/halt.c [! GRUB_MACHINE_IEEE1275 ! GRUB_MACHINE_EFI]:
+	Include `<grub/cpu/halt.h>'.
+	* commands/reboot.c [! GRUB_MACHINE_IEEE1275 ! GRUB_MACHINE_EFI]
+	[! GRUB_MACHINE_PCBIOS]: Include `<grub/cpu/reboot.h>'.
+
+	* term/i386/pc/at_keyboard.c: Include `<grub/cpu/at_keyboard.h>'.
+	(SHIFT_L, SHIFT_R, CTRL, ALT, CAPS_LOCK, KEYBOARD_REG_DATA)
+	(KEYBOARD_REG_STATUS, KEYBOARD_COMMAND_ISREADY, KEYBOARD_COMMAND_READ)
+	(KEYBOARD_COMMAND_WRITE, KEYBOARD_COMMAND_REBOOT)
+	(KEYBOARD_SCANCODE_SET1, KEYBOARD_ISMAKE, KEYBOARD_ISREADY)
+	(KEYBOARD_SCANCODE, OLPC_UP, OLPC_DOWN, OLPC_LEFT, OLPC_RIGHT): Move
+	from here ...
+	* include/grub/i386/at_keyboard.h: ... to here.
+
+2008-08-05  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/i386/pit.c'.
+	* conf/i386-efi.rmk (kernel_mod_SOURCES): Likewise.
+	* conf/i386-coreboot.rmk (kernel_elf_SOURCES): Likewise. Also add
+	`kern/i386/tsc.c', `kern/generic/rtc_get_time_ms.c' and
+	`kern/generic/millisleep.c'.
+
+	* kern/i386/tsc.c (calibrate_tsc): Rewrite using grub_pit_wait()
+	instead of grub_get_rtc().
+	(grub_tsc_init): Initialize `tsc_boot_time'.
+
+	* kern/i386/linuxbios/init.c (grub_millisleep): Remove stub.
+	(grub_machine_init): Use grub_tsc_init() rather than
+	installing an RTC-based handler via grub_install_get_time_ms().
+
+	* kern/i386/pit.c: New file.
+	* include/grub/i386/pit.h: Likewise.
+
+2008-08-05  Bean  <bean123ch@gmail.com>
+
+	* boot/i386/pc/pxeboot.S (_start): Use drive number 0x7F for pxe.
+
+	* conf/i386-pc.rmk (kernel_img_HEADERS): Add machine/pxe.h.
+	(pkglib_MODULES): Add pxe.mod and pxecmd.mod.
+	(pxe_mod_SOURCES): New macro.
+	(pxe_mod_CFLAGS): Likewise.
+	(pxe_mod_LDFLAGS): Likewise.
+	(pxecmd_mod_SOURCES): Likewise.
+	(pxecmd_mod_CFLAGS): Likewise.
+	(pxecmd_mod_LDFLAGS): Likewise.
+
+	* kern/i386/pc/startup.S (grub_pxe_scan): New function.
+	(grub_pxe_call): Likewise.
+
+	* include/grub/disk.h (grub_disk_dev_id): Add GRUB_DISK_DEVICE_PXE_ID.
+
+	* commands/i386/pc/pxecmd.c: New file.
+
+	* fs/i386/pc/pxe.c: Likewise.
+
+	* include/grub/i386/pc/pxe.h: Likewise.
+
+2008-08-05  Bean  <bean123ch@gmail.com>
+
+	* util/console.c (grub_console_cur_color): New variable.
+	(grub_console_standard_color): Likewise.
+	(grub_console_normal_color): Likewise.
+	(grub_console_highlight_color): Likewise.
+	(color_map): Likewise.
+	(use_color): Likewise.
+	(NUM_COLORS): New macro.
+	(grub_ncurses_setcolorstate): Handle color properly.
+	(grub_ncurses_setcolor): Don't change color here, just remember the
+	settings, color will be set in grub_ncurses_setcolorstate.
+	(grub_ncurses_getcolor): New function.
+	(grub_ncurses_init): Initialize color pairs.
+	(grub_ncurses_term): New member grub_ncurses_getcolor.
+
+2008-08-05  Colin D Bennett  <colin@gibibit.com>
+
+	High resolution timer support.  Implemented for x86 CPUs using TSC.
+	Extracted generic grub_millisleep() so it's linked in only as needed.
+	This requires a Pentium compatible CPU; if the RDTSC instruction is
+	not supported, then it falls back on the generic grub_get_time_ms()
+	implementation that uses the machine's RTC.
+
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/time.c',
+	`kern/i386/tsc.c', `kern/generic/rtc_get_time_ms.c' and
+	`kern/generic/millisleep.c'.
+
+	* conf/i386-efi.rmk (kernel_mod_SOURCES): Add `kern/i386/tsc.c',
+	`kern/generic/rtc_get_time_ms.c' and `kern/generic/millisleep.c'.
+
+	* conf/x86_64-efi.rml (kernel_mod_SOURCES): Add
+	`kern/generic/millisleep.c' and `kern/generic/rtc_get_time_ms.c'.
+
+	* conf/sparc64-ieee1275.rmk (kernel_elf_SOURCES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Add
+	`kern/generic/millisleep.c'.
+
+	* conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Likewise.
+
+	* conf/i386-coreboot.rmk (kernel_elf_SOURCES): Add `kern/time.c'.
+
+	* kern/generic/rtc_get_time_ms.c: New file.
+
+	* kern/generic/millisleep.c: New file.
+
+	* kern/misc.c: Don't include
+	<kern/time.h> anymore.
+	(grub_millisleep_generic): Removed.
+
+	* commands/sleep.c (grub_interruptible_millisleep): Uses
+	grub_get_time_ms() instead of grub_get_rtc().
+
+	* include/grub/i386/tsc.h (grub_get_tsc): New file.  New inline
+	function.
+	(grub_cpu_is_cpuid_supported): New inline function.
+	(grub_cpu_is_tsc_supported): New inline function.
+	(grub_tsc_init): New function prototype.
+	(grub_tsc_get_time_ms): New function prototype.
+
+	* kern/i386/tsc.c (grub_get_time_ms): New file.
+
+	* include/grub/time.h: Include <grub/types.h.
+	(grub_millisleep_generic): Removed.
+	(grub_get_time_ms): New prototype.
+	(grub_install_get_time_ms): New prototype.
+	(grub_rtc_get_time_ms): New prototype.
+
+	* kern/time.c (grub_get_time_ms): New function.
+	(grub_install_get_time_ms): New function.
+
+	* kern/i386/efi/init.c: Include <grub/cpu/tsc.h>.  Don't include
+	<grub/time.h> anymore.
+	(grub_millisleep): Removed.
+	(grub_machine_init): Call grub_tsc_init.
+
+	* kern/i386/linuxbios/init.c (grub_machine_init): Install the RTC
+	get_time_ms() implementation.
+
+	* kern/sparc64/ieee1275/init.c (grub_millisleep): Removed.
+	(ieee1275_get_time_ms): New function.
+	(grub_machine_init): Install get_time_ms() implementation.
+
+	* kern/i386/pc/init.c: Include <grub/cpu/tsc.h>.
+	(grub_machine_init): Call grub_tsc_init().
+	(grub_millisleep): Removed.
+
+	* kern/ieee1275/init.c (grub_millisleep): Removed.
+	(grub_machine_init): Install ieee1275_get_time_ms()
+	implementation.
+	(ieee1275_get_time_ms): New function.
+	(grub_get_rtc): Now calls ieee1275_get_time_ms(), which does the
+	real work.
+
+2008-08-05  Marco Gerards  <marco@gnu.org>
+
+	* disk/ata.c: Include <grub/pci.h>.
+	(enum grub_ata_commands): Add `GRUB_ATA_CMD_EXEC_DEV_DIAGNOSTICS'.
+	(grub_ata_initialize): Rewritten.
+	(grub_ata_device_initialize): New function.
+
+2008-08-04  Pavel Roskin  <proski@gnu.org>
+
+	* kern/main.c: Include grub/mm.h.
+
+2008-08-04  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-coreboot.rmk (COMMON_ASFLAGS, COMMON_CFLAGS)
+	(COMMON_LDFLAGS): Harmonize with i386-pc version (fixes a code
+	corruption problem).
+
+2008-08-04  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Fix misc
+	warnings introduced in my last commit.
+
+2008-08-03  Robert Millan  <rmh@aybabtu.com>
+
+	Make PCI available on all i386 architectures.
+
+	* include/grub/i386/pc/pci.h: Move from here ...
+	* include/grub/i386/pci.h: ... to here.
+
+	* include/grub/i386/pc/pci.h: Remove.
+	* include/grub/i386/efi/pci.h: Remove.
+	* include/grub/x86_64/efi/pci.h: Remove.
+
+	* include/grub/pci.h: Replace `<grub/machine/pci.h>' with
+	`<grub/cpu/pci.h>'.
+
+	* conf/i386-coreboot.rmk (pkglib_MODULES): Add `pci' and `lspci'.
+	(pci_mod_SOURCES, pci_mod_CFLAGS, pci_mod_LDFLAGS, lspci_mod_SOURCES)
+	(lspci_mod_CFLAGS, lspci_mod_LDFLAGS): New variables.
+
+	* conf/i386-ieee1275.rmk: Likewise.
+
+2008-08-03  Robert Millan  <rmh@aybabtu.com>
+
+	* term/i386/pc/vga_text.c (CRTC_CURSOR_DISABLE): New macro.
+	(grub_console_setcursor): Make it possible to set cursor off.
+
+2008-08-03  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/00_header.in: Be platform-agnostic.  Probe for existence
+	of modules instead of assuming which platform provides what.
+	* util/update-grub.in: Likewise.
+
+2008-08-03  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/i386/pc/init.c (make_install_device): Check for `grub_prefix'
+	instead of `grub_install_dos_part' to determine whether a drive needs
+	to be prepended to prefix (`grub_install_dos_part' is not reliable,
+	because it can be overridden when loading GRUB via Multiboot).
+
+2008-08-02  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-install.in: Remove trailing slash from prefix.
+
+2008-08-02  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Add a pair
+	of informational grub_dprintf() calls.
+
+2008-08-02  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/memdisk.c (memdisk_size): Don't initialize.
+	(GRUB_MOD_INIT(memdisk)): Find memdisk using grub_module_iterate().
+
+	* include/grub/i386/pc/kernel.h
+	(GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE): Remove macro.
+	(GRUB_KERNEL_MACHINE_PREFIX, GRUB_KERNEL_MACHINE_DATA_END): Shift.
+	(grub_memdisk_image_size, grub_arch_memdisk_addr)
+	(grub_arch_memdisk_size): Remove.
+
+	* include/grub/kernel.h (struct grub_module_header): Remove `offset'
+	field (was only used to transfer a constant).  Add `type' field to
+	support multiple module types.
+	(grub_module_iterate): New function.
+
+	* kern/device.c (grub_device_open): Do not hide error messages
+	when grub_disk_open() fails.  Use grub_print_error() instead.
+
+	* kern/i386/pc/init.c (grub_arch_modules_addr)
+	(grub_arch_memdisk_size): Remove functions.
+	(grub_arch_modules_addr): Return the module address in high memory
+	(now that it isn't copied anymore).
+
+	* kern/i386/pc/startup.S (grub_memdisk_image_size): Remove variable.
+	(codestart): Don't add grub_memdisk_image_size to %ecx in LZMA
+	decompression routine (grub_total_module_size already includes that
+	now).  Don't copy modules back to low memory.
+
+	* kern/main.c: Include `<grub/mm.h>'.
+	(grub_load_modules): Split out (and use) ...
+	(grub_module_iterate): ... this function, which iterates through
+	module objects and runs a hook.
+	Comment out grub_mm_init_region() call, as it would cause non-ELF
+	modules to be overwritten.
+
+	* util/i386/pc/grub-mkimage.c (generate_image): Instead of appending
+	the memdisk image in its own region, make it part of the module list.
+	* util/elf/grub-mkimage.c (options): Add "memdisk"|'m' option.
+	(main): Parse --memdisk|-m option, and pass user-provided path as
+	parameter to generate_image().
+	(add_segments): Pass `memdisk_path' down to load_modules().
+	(load_modules): Embed memdisk image in module section when requested.
+	* util/i386/efi/grub-mkimage.c (make_mods_section): Initialize
+	`header.type' instead of `header.offset'.
+
+	* conf/powerpc-ieee1275.rmk (pkglib_MODULES): Add `memdisk.mod'.
+	(memdisk_mod_SOURCES, memdisk_mod_CFLAGS)
+	(memdisk_mod_LDFLAGS): New variables.
+	* conf/i386-coreboot.rmk: Likewise.
+	* conf/i386-ieee1275.rmk: Likewise.
+
+2008-08-02  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/multiboot.c (playground, forward_relocator)
+	(backward_relocator): New variables.  Used to allocate and relocate
+	the payload, respectively.
+	(grub_multiboot_load_elf32): Load into heap instead of requested
+	address, install the appropriate relocator code in each bound of
+	the payload, and set the entry point such that
+	grub_multiboot_real_boot() will jump to one of them.
+
+	* kern/i386/loader.S (grub_multiboot_payload_size)
+	(grub_multiboot_payload_orig, grub_multiboot_payload_dest)
+	(grub_multiboot_payload_entry_offset): New variables.
+	(grub_multiboot_real_boot): Set cpu context to what the relocator
+	expects, and jump to the relocator instead of the payload.
+
+	* include/grub/i386/loader.h (grub_multiboot_payload_size)
+	(grub_multiboot_payload_orig, grub_multiboot_payload_dest)
+	(grub_multiboot_payload_entry_offset): Export.
+
+2008-08-01  Bean  <bean123ch@gmail.com>
+
+	* normal/menu_entry.c (editor_getline): Don't return the original
+	string as result, as it will be released by lexer once it has done
+	using it.
+
+2008-08-01  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/10_linux.in: Use prepare_grub_to_access_device() from
+	within menuentries, not before them.
+	util/grub.d/10_hurd.in: Likewise.
+
+2008-08-01  Bean  <bean123ch@gmail.com>
+
+	* conf/common.rmk (pkglib_MODULES): Add bufio.mod.
+	(bufio_mod_SOURCES): New macro.
+	(bufio_mod_CFLAGS): Likewise.
+	(bufio_mod_LDFLAGS): Likewise.
+
+	* include/grub/bufio.h: New file.
+
+	* io/bufio.c: Likewise.
+
+	* video/png.c: Replace <grub/file.h> with <grub/bufio.h>.
+	(grub_video_reader_png): Use grub_buffile_open to open file.
+
+	* video/jpeg.c: Replace <grub/file.h> with <grub/bufio.h>.
+	(grub_video_reader_jpeg): Use grub_buffile_open to open file.
+
+	* video/tga.c: Replace <grub/file.h> with <grub/bufio.h>.
+	(grub_video_reader_tga): Use grub_buffile_open to open file.
+
+	* font/manager.c: Include <grub/bufio.h>.
+	(add_font): Use grub_buffile_open to open file.
+
+2008-07-31  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): When loading
+	ELF segments, use a macro for arbitrarily accessing any of them instead
+	of preparing a pointer that allows access to one at a time.
+	(grub_multiboot_load_elf64): Likewise.
+
+2008-07-31  Bean  <bean123ch@gmail.com>
+
+	* boot/i386/pc/lnxboot.S (real_code_2): Replace 0x50 with
+	GRUB_KERNEL_MACHINE_DATA_END.
+
+2008-07-30  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_DATA_END):
+	Increase from 0x50 to 0x60.
+	* util/i386/pc/grub-install.in: Detect cross-disk installs, and
+	use UUIDs to identify the root drive for them.  If that's not
+	possible, abort.
+	* util/i386/pc/grub-setup.c (setup): Do not special-case, or even
+	check, for cross-disk installs.
+
+2008-07-30  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/ieee1275/init.c (grub_machine_set_prefix): If `grub_prefix'
+	is non-empty, use it to set the `prefix' environment variable instead
+	of the usual approach.
+	* kern/i386/linuxbios/init.c (make_install_device): Remove function.
+	(grub_machine_set_prefix): Use `grub_prefix' to set the `prefix'
+	environment variable instead of dummy make_install_device().
+
+	* kern/i386/ieee1275/startup.S: Include `<grub/machine/kernel.h>'.
+	(start): Insert a data section, with `grub_prefix' variable.
+	* kern/i386/linuxbios/startup.S: Likewise.
+
+	* include/grub/powerpc/ieee1275/kernel.h [!ASM_FILE] (grub_prefix):
+	New variable reference.
+	* include/grub/i386/ieee1275/kernel.h (GRUB_KERNEL_MACHINE_PREFIX):
+	New macro.  Defines offset of `grub_prefix' within startup.S (relative
+	to `start').
+	(GRUB_KERNEL_MACHINE_DATA_END): New macro.  Defines the end of data
+	section within startup.S (relative to `start').
+	* include/grub/i386/coreboot/kernel.h: Likewise.
+
+	* util/elf/grub-mkimage.c (add_segments): Receive `prefix' parameter.
+	Overwrite grub_prefix with its contents, at the beginning of the
+	first segment.
+	(main): Understand -p|--prefix.
+
+2008-07-30  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/10_hurd.in: Source ${libdir}/grub/update-grub_lib.
+
+2008-07-30  Robert Millan  <rmh@aybabtu.com>
+
+	* term/i386/pc/vga_text.c (grub_console_cls): Use
+	grub_console_gotoxy() to go back to beginning of the screen.
+	Found by Patrick Georgi <patrick.georgi@coresystems.de>
+
+2008-07-29  Christian Franke  <franke@computer.org>
+
+	* util/update-grub_lib.in (make_system_path_relative_to_its_root):
+	Add conversion of emulated mount points on Cygwin.
+
+2008-07-29  Christian Franke  <franke@computer.org>
+
+	* util/update-grub.in: Add a check for admin
+	group on Cygwin.
+	Remove old `grub.cfg.new' before creation.
+	Add `-f' to `mv' to handle the different filesystem
+	semantics of Windows.
+
+2008-07-29  Bean  <bean123ch@gmail.com>
+
+	* normal/main.c (get_line): Fix buffer overflow bug.
+
+2008-07-28  Robert Millan  <rmh@aybabtu.com>
+
+	* partmap/apple.c (GRUB_APPLE_HEADER_MAGIC): New macro.
+	(struct grub_apple_header): New struct.  Describes the layout of
+	the partmap header.
+	(apple_partition_map_iterate): Check the header magic as well as the
+	partition magic (which was already being checked).
+
+2008-07-28  Pavel Roskin  <proski@gnu.org>
+
+	* genmk.rb: Add a warning to the beginning of the output that
+	it's a generated file and should not be edited.
+
+2008-07-28  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/raid.c (grub_raid_scan_device): Do not abort when two disks
+	with the same number are found, just use issue a warning with
+	grub_dprintf(), as this error has been reported to be non-fatal.
+
+2008-07-27  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/ata.c (grub_ata_dumpinfo): Use grub_dprintf() for debugging
+	information.
+
+2008-07-27  Bean  <bean123ch@gmail.com>
+
+	* fs/fat.c (GRUB_FAT_MAXFILE): New constant.
+	(grub_fat_find_dir): Ignore case when comparing filename.
+
+2008-07-27  Bean  <bean123ch@gmail.com>
+
+	* fs/xfs.c (grub_xfs_dir_header): Change field i8count back to
+	smallino, as it's more descriptive, and i8count can be confused with
+	the other field count.
+	(grub_xfs_iterate_dir): Adjust grub_xfs_dir_entry pointer for small
+	inode type.
+
+2008-07-27  Bean  <bean123ch@gmail.com>
+
+	* commands/crc.c: New file.
+
+	* lib/crc.c: Likewise.
+
+	* include/grub/lib/crc.h: Likewise.
+
+	* util/grub-fstest.c: grub/hexdump.h => grub/lib/hexdump.h.
+
+	* commands/hexdump.c: grub/hexdump.h => grub/lib/hexdump.h.
+	(hexdump): Move this function to ...
+
+	* lib/hexdump.c: ... here.
+
+	* include/grub/hexdump.h: Renamed to ...
+
+	* include/grub/lib/hexdump.h: ... this.
+
+	* commands/loadenv.c: grub/envblk.h => grub/lib/envblk.h
+
+	* util/grub-editenv.c: Likewise.
+
+	* include/envblk.h: Renamed to ...
+
+	* include/lib/envblk.h: ... this.
+
+	* util/envblk.c: Renamed to ...
+
+	* lib/envblk.c: ... this.
+
+	* conf/common.rmk (grub_fstest_SOURCES): commands/hexdump.c =>
+	lib/hexdump.c.
+	(grub_editenv_SOURCES): util/envblk.c => lib/envblk.c
+	(pkglib_MODULES): Add crc.mod.
+	(hexdump_mod_SOURCES): Add lib/hexdump.c.
+	(loadenv_mod_SOURCES): util/envblk.c => lib/envblk.c.
+	(crc_mod_SOURCES): New macro.
+	(crc_mod_CFLAGS): Likewise.
+	(crc_mod_LDFLAGS): Likewise.
+
+	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Add lib/hexdump.c.
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise.
+
+2008-07-27  Felix Zielcke  <fzielcke@z-51.de>
+
+	* commands/help.c: Include <grub/term.h>.
+	(TERM_WIDTH): Removed.  Updated all users.
+
+2008-07-27  Pavel Roskin  <proski@gnu.org>
+
+	* util/getroot.c (find_root_device): Rephrase a comment to avoid
+	spurious warnings about a comment within a comment.
+
+2008-07-25  Robert Millan  <rmh@aybabtu.com>
+
+	* util/getroot.c (find_root_device): Skip devices that match
+	/dev/dm-[0-9].  This lets the real device be found for any type of
+	abstraction (LVM, EVMS, RAID..).
+	(grub_guess_root_device): Do not traverse /dev/mapper (for LVM)
+	and /dev/evms (for EVMS) before traversing /dev.  If a /dev/dm-[0-9]
+	device is found first, find_root_device() will now skip it.
+
+2008-07-24  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/types.h: Use __builtin_bswap32() and
+	__builtin_bswap64() with gcc 4.3 and newer.
+
+2008-07-24  Christian Franke  <franke@computer.org>
+
+	* util/i386/pc/grub-install.in: If `--debug' is specified,
+	pass `--verbose' to grub-setup.
+	Abort script if make_system_path_relative_to_its_root() fails.
+
+2008-07-24  Bean  <bean123ch@gmail.com>
+
+	* configure.ac: Fixed a bug caused by the previous cygwin patch,
+	variable `target_platform' should be `platform'.
+
+2008-07-24  Bean  <bean123ch@gmail.com>
+
+	* video/reader/png.c (DEFLATE_HLIT_MAX): Change value.
+	(grub_png_init_fixed_block): New function.
+	(grub_png_decode_image_data): Handle fixed huffman code compression.
+
+2008-07-24  Bean  <bean123ch@gmail.com>
+
+	* common.rmk (bin_UTILITIES): Add grub-pe2elf.
+	(grub_pe2elf_SOURCES): New macro.
+	(CLEANFILES): Add grub-pe2elf.
+
+	* include/grub/efi/pe32.h (GRUB_PE32_SCN_ALIGN_1BYTES): New constant.
+	(GRUB_PE32_SCN_ALIGN_2BYTES): Likewise.
+	(GRUB_PE32_SCN_ALIGN_4BYTES): Likewise.
+	(GRUB_PE32_SCN_ALIGN_8BYTES): Likewise.
+	(GRUB_PE32_SCN_ALIGN_16BYTES): Likewise.
+	(GRUB_PE32_SCN_ALIGN_32BYTES): Likewise.
+	(GRUB_PE32_SCN_ALIGN_64BYTES): Likewise.
+	(GRUB_PE32_SCN_ALIGN_SHIFT): Likewise.
+	(GRUB_PE32_SCN_ALIGN_MASK): Likewise.
+	(GRUB_PE32_SYM_CLASS_EXTERNAL): Likewise.
+	(GRUB_PE32_SYM_CLASS_STATIC): Likewise.
+	(GRUB_PE32_SYM_CLASS_FILE): Likewise.
+	(GRUB_PE32_DT_FUNCTION): Likewise.
+	(GRUB_PE32_REL_I386_DIR32): Likewise.
+	(GRUB_PE32_REL_I386_REL32): Likewise.
+	(grub_pe32_symbol): New structure.
+	(grub_pe32_reloc): Likewise.
+
+	* util/grub-pe2elf.c: New file.
+
+	* configure.ac: Set TARGET_OBJ2ELF if host os is cygwin. Don't test for
+	start symbol in non pc platform.
+
+	* genmk.rb: Use TARGET_OBJ2ELF to convert native object format to elf.
+
+	The following patches are from Christian Franke.
+
+	* include/grub/dl.h: Remove .previous, gas supports this only
+	for ELF format.
+
+	* include/grub/symbol.h [__CYGWIN__] (#define FUNCTION/VARIABLE):
+	Remove .type, gas supports this only for ELF format.
+
+	* kern/dl.c (grub_dl_resolve_dependencies): Add check for trailing
+	nullbytes in symbol table. This fixes an infinite loop if table is
+	zero filled.
+
+	* Makefile.in: Add autoconf replacements TARGET_IMG_LDSCRIPT,
+	TARGET_IMG_LDFLAGS and EXEEXT.
+
+	* aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): Replace -Wl,-N by
+	TARGET_IMG_LDFLAGS_AC.
+	(grub_CHECK_STACK_ARG_PROBE): New function.
+
+	* conf/i386-pc.rmk: Replace -Wl,-N by TARGET_IMG_LDFLAGS.
+
+	* conf/i386-pc-cygwin-ld-img.sc: New linker script.
+
+	* configure.ac: Add check for linker script "conf/${target}-img-ld.c"
+	to set TARGET_IMG_LD* accordingly.
+	Add check for Cygwin to set TARGET_MOD_OBJCOPY accordingly.
+	Add call to grub_CHECK_STACK_ARG_PROBE.
+	Use TARGET_IMG_LDFLAGS to check start, bss_start, end symbols.
+
+	* genkernsyms.sh.in: Handle HAVE_ASM_USCORE case.
+
+	* genmk.rb: Add EXEEXT to CLEANFILES.
+
+2008-07-23  Robert Millan  <rmh@aybabtu.com>
+
+	* Makefile.in (UNICODE_ARROWS, UNICODE_LINES): New variables (they
+	define the codes for arrows and lines used for the menu).
+	(ascii.pff): Generate fonts for $(UNICODE_ARROWS) and $(UNICODE_LINES)
+	as well.
+
+	* util/update-grub_lib.in (font_path): Prefer ascii.pff over complete
+	fonts, because the latter are too slow.
+
+2008-07-21  Bean  <bean123ch@gmail.com>
+
+	* kern/i386/pc/startup.S (gate_a20_try_bios): Change test order for
+	a20. Run keyboard test last, as it will cause macbook to halt.
+
+2008-07-18  Pavel Roskin  <proski@gnu.org>
+
+	* kern/dl.c: Go back to using GRUB_CPU_SIZEOF_VOID_P.  We cannot
+	load foreign architecture modules correctly anyway.  Keep
+	support for loading host architecture modules, whether we
+	compile them or not.
+
+2008-07-17  Pavel Roskin  <proski@gnu.org>
+
+	* configure.ac: Use -m32 or -m64 regardless of whether we had to
+	change target_cpu.  The compiler default can mismatch target_cpu
+	in any case.
+
+	* disk/efi/efidisk.c: Fix format warnings on x86_64.
+	* kern/efi/efi.c: Likewise.
+
+	* aclocal.m4 (grub_PROG_TARGET_CC): New macro.  Check if the
+	target compiler is functional.
+	* configure.ac: Call grub_PROG_TARGET_CC once all target flags
+	are set up.
+
+	* configure.ac: Default to efi platform for x86_64-apple.  Allow
+	powerpc64 CPU, default to ieee1275 platform for it.  Split CPU
+	adjustments from the rest, only do them if target is not
+	explicitly given.  Merge other adjustments with the final sanity
+	check.  Remove an extraneous check for supported CPU.  Be
+	specific which CPU and which platform is not supported.
+
+	* configure.ac: Default to pc platform for x86_64.
+
+2008-07-17  Robert Millan  <rmh@aybabtu.com>
+
+	Partial LinuxBIOS -> Coreboot rename.
+
+	* conf/i386-linuxbios.rmk: Renamed to ...
+	* conf/i386-coreboot.rmk: ... this.
+	* Makefile.in (RMKFILES): s/i386-linuxbios.rmk/i386-coreboot.rmk/g.
+	* configure.ac: Accept "coreboot" as input platform (but maintain
+	compatibility with "linuxbios").
+	* include/grub/i386/linuxbios: Renamed to ...
+	* include/grub/i386/coreboot: ... this.
+
+2008-07-17  Bean  <bean123ch@gmail.com>
+
+	* conf/i386/efi.rmk (pkglib_MODULES): add pci.mod and lspci.mod.
+	(appleldr_mod_SOURCE): New variable.
+	(appleldr_mod_CFLAGS): Likewise.
+	(appleldr_mod_LDFLAGS): Likewise.
+	(pci_mod_SOURCES): Likewise.
+	(pci_mod_CFLAGS): Likewise.
+	(pci_mod_LDFLAGS): Likewise.
+	(lspci_mod_SOURCES): Likewise.
+	(lspci_mod_CFLAGS): Likewise.
+	(lspci_mod_LDFLAGS): Likewise.
+
+	* conf/x86_64-efi.rmk: New file.
+
+	* disk/efi/efidisk.c (grub_efidisk_read): Wrap efi calls with efi_call_N
+	macro.
+	(grub_efidisk_write): Likewise.
+
+	* include/efi/api.h (efi_call_0): New macro.
+	(efi_call_1): Likewise.
+	(efi_call_2): Likewise.
+	(efi_call_3): Likewise.
+	(efi_call_4): Likewise.
+	(efi_call_5): Likewise.
+	(efi_call_6): Likewise.
+
+	* include/grub/efi/chainloader.h (grub_chainloader_cmd): Rename to
+	grub_rescue_cmd_chainloader.
+
+	* include/grub/efi/pe32.h (GRUB_PE32_MACHINE_X86_64): New macro.
+	(grub_pe32_optional_header): Change some fields based on i386 or
+	x86_64 platform.
+	(GRUB_PE32_PE32_MAGIC): Likewise.
+
+	* include/grub/efi/uga_draw.h: New file.
+
+	* include/grub/elf.h (STN_ABS): New constant.
+	(R_X86_64_NONE): Relocation constant for x86_64.
+	(R_X86_64_64): Likewise.
+	(R_X86_64_PC32): Likewise.
+	(R_X86_64_GOT32): Likewise.
+	(R_X86_64_PLT32): Likewise.
+	(R_X86_64_COPY): Likewise.
+	(R_X86_64_GLOB_DAT): Likewise.
+	(R_X86_64_JUMP_SLOT): Likewise.
+	(R_X86_64_RELATIVE): Likewise.
+	(R_X86_64_GOTPCREL): Likewise.
+	(R_X86_64_32): Likewise.
+	(R_X86_64_32S): Likewise.
+	(R_X86_64_16): Likewise.
+	(R_X86_64_PC16): Likewise.
+	(R_X86_64_8): Likewise.
+	(R_X86_64_PC8): Likewise.
+
+	* include/grub/i386/efi/pci.h: New file.
+
+	* include/grub/i386/linux.h (GRUB_LINUX_EFI_SIGNATURE):
+	Change it value based on platform.
+	(GRUB_LINUX_EFI_SIGNATURE_0204): New constant.
+	(GRUB_E820_RAM): Likewise.
+	(GRUB_E820_RESERVED): Likewise.
+	(GRUB_E820_ACPI): Likewise.
+	(GRUB_E820_NVS): Likewise.
+	(GRUB_E820_EXEC_CODE): Likewise.
+	(GRUB_E820_MAX_ENTRY): Likewise.
+	(grub_e820_mmap): New structure.
+	(linux_kernel_header): Change the efi field according to different
+	kernel version, also field from linux_kernel_header.
+
+	* include/grub/kernel.h (grub_module_info): Add padding for x86_64.
+
+	* include/grub/pci.h (GRUB_PCI_ADDR_SPACE_MASK): New constant.
+	(GRUB_PCI_ADDR_SPACE_MEMORY): Likewise.
+	(GRUB_PCI_ADDR_SPACE_IO): Likewise.
+	(GRUB_PCI_ADDR_MEM_TYPE_MASK): Likewise.
+	(GRUB_PCI_ADDR_MEM_TYPE_32): Likewise.
+	(GRUB_PCI_ADDR_MEM_TYPE_1M): Likewise.
+	(GRUB_PCI_ADDR_MEM_TYPE_64): Likewise.
+	(GRUB_PCI_ADDR_MEM_PREFETCH): Likewise.
+	(GRUB_PCI_ADDR_MEM_MASK): Likewise.
+	(GRUB_PCI_ADDR_IO_MASK): Likewise.
+
+	* include/grub/x86_64/efi/kernel.h: New file.
+
+	* include/grub/x86_64/efi/loader.h: Likewise.
+
+	* include/grub/x86_64/efi/machine.h: Likewise.
+
+	* include/grub/x86_64/efi/pci.h: Likewise.
+
+	* include/grub/x86_64/efi/time.h: Likewise.
+
+	* include/grub/x86_64/linux.h: Likewise.
+
+	* include/grub/x86_64/setjmp.h: Likewise.
+
+	* include/grub/x86_64/time.h: Likewise.
+
+	* include/grub/x86_64/types.h: Likewise.
+
+	* kern/dl.c (GRUB_CPU_SIZEOF_VOID_P): Changed to
+	 GRUB_TARGET_SIZEOF_VOID_P.
+
+	* kern/efi/efi.c (grub_efi_locate_protocol): Wrap efi calls.
+	(grub_efi_locate_handle): Likewise.
+	(grub_efi_open_protocol): Likewise.
+	(grub_efi_set_text_mode): Likewise.
+	(grub_efi_stall): Likewise.
+	(grub_exit): Likewise.
+	(grub_reboot): Likewise.
+	(grub_halt): Likewise.
+	(grub_efi_exit_boot_services): Likewise.
+	(grub_get_rtc): Likewise.
+
+	* kern/efi/mm.c (MEMORY_MAP_SIZE): Change to 0x3000 for new models.
+	(GRUB_CPU_SIZEOF_VOID_P): Changed to GRUB_TARGET_SIZEOF_VOID_P.
+	(grub_efi_allocate_pages): Wrap efi calls.
+	(grub_efi_free_pages): Wrap efi calls.
+	(grub_efi_get_memory_map): Wrap efi calls.
+
+	* kern/x86_64/dl.c: New file.
+
+	* kern/x86_64/efi/callwrap.S: Likewise.
+
+	* kern/x86_64/efi/startup.S: Likewise.
+
+	* loader/efi/appleloader.c: Likewise.
+
+	* loader/efi/chainloader.c (cmdline): New variable.
+	(grub_chainloader_unload): Wrap efi calls.
+	(grub_chainloader_boot): Likewise.
+	(grub_rescue_cmd_chainloader): Wrap efi calls, handle
+	command line.
+
+	* loader/efi/chainloader_normal.c (chainloader_command):
+	Change grub_chainloader_cmd to grub_rescue_cmd_chainloader, pass
+	command line.
+
+	* loader/i386/efi/linux.c (allocate_pages): Change allocation
+	method.
+	(grub_e820_add_region): New function.
+	(grub_linux_boot): Construct e820 map from efi map, handle x86_64
+	booting.
+	(grub_find_video_card): New function.
+	(grub_linux_setup_video): New function.
+	(grub_rescue_cmd_linux): Probe for video information.
+
+	* normal/x86_64/setjmp.S: New file.
+
+	* term/efi/console.c (map_char): New function.
+	(grub_console_putchar): Map unicode char.
+	(grub_console_checkkey): Wrap efi calls.
+	(grub_console_getkey): Likewise.
+	(grub_console_getwh): Likewise.
+	(grub_console_gotoxy): Likewise.
+	(grub_console_cls): Likewise.
+	(grub_console_setcolorstate): Likewise.
+	(grub_console_setcursor): Likewise.
+
+	* util/i386/efi/grub-mkimage.c: Add support for x86_64.
+
+2008-07-16  Pavel Roskin  <proski@gnu.org>
+
+	* loader/i386/efi/linux.c (allocate_pages): Fix warnings in
+	format strings.
+
+	* util/i386/efi/grub-mkimage.c (get_target_address): Return a
+	pointer, not an integer.  This fixes a warning and prevents
+	precision loss on 64-bit systems.
+	(relocate_addresses): Remove unneeded cast.
+
+2008-07-15  Pavel Roskin  <proski@gnu.org>
+
+	* kern/i386/ieee1275/init.c: Include grub/cache.h.
+
+	* term/ieee1275/ofconsole.c: Disable code unused on i386.
+
+	* kern/ieee1275/ieee1275.c (grub_ieee1275_get_integer_property):
+	Fix comparison between signed and unsigned.
+
+	* include/grub/i386/ieee1275/console.h: Declare
+	grub_console_init() and grub_console_fini().
+
+	* loader/i386/ieee1275/linux.c (grub_set_bootpath): Remove.
+	It's empty and unused.
+
+	* fs/ext2.c (grub_ext2_read_block): Initialize blknr in the
+	beginning to avoid warnings with some compilers.
+
+	* loader/ieee1275/multiboot2.c: Include grub/machine/loader.h.
+	[__i386__] (grub_mb2_arch_boot): Avoid unnecessary cast.
+
+2008-07-14  Pavel Roskin  <proski@gnu.org>
+
+	* kern/env.c (grub_register_variable_hook): Don't copy empty
+	string, it leaks memory.  Pass "" to grub_env_set(), it should
+	handle constant strings.
+
+	* commands/blocklist.c (grub_cmd_blocklist): Fix format warning.
+	* commands/cmp.c (grub_cmd_cmp): Likewise.
+	* kern/dl.c (grub_dl_flush_cache): Likewise.
+	(grub_dl_load_core): Likewise.
+	* kern/elf.c (grub_elf32_load_phdrs): Likewise.
+	(grub_elf64_load_phdrs): Likewise.
+
+2008-07-13  Pavel Roskin  <proski@gnu.org>
+
+	* lib/LzmaEnc.c (LzmaEnc_SetProps): Fix warning about comparison
+	between signed and unsigned.
+	(LzmaEnc_Finish): Fix warning about an unused parameter.
+
+2008-07-13  Bean  <bean123ch@gmail.com>
+
+	* Makefile.in (enable_lzo): New rule.
+
+	* conf/i386-pc.rmk (grub_mkimage_SOURCES): New test with enable_lzo.
+
+	* configure.ac (ENABLE_LZO): New option --enable-lzo.
+
+	* boot/i386/pc/lnxboot.S: #include <config.h>.
+
+	* include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): Change
+	its value according to the compression algorithm used, lzo or lzma.
+
+	* util/i386/pc/grub-mkimage.c (compress_kernel): Use different
+	compression algorithm according to configure macro.
+
+	* kern/i386/pc/startup.S (codestart): Likewise.
+
+	* kern/i386/pc/lzma_decode.S: New file.
+
+	* include/grub/lib/LzFind.h: Likewise.
+
+	* include/grub/lib/LzHash.h: Likewise.
+
+	* include/grub/lib/LzmaDec.h: Likewise.
+
+	* include/grub/lib/LzmaEnc.h: Likewise.
+
+	* include/grub/lib/LzmaTypes.h: Likewise.
+
+	* lib/LzFind.c: Likewise.
+
+	* lib/LzmaDec.c: Likewise.
+
+	* lib/LzmaEnc.c: Likewise.
+
+2008-07-13  Bean  <bean123ch@gmail.com>
+
+	* fs/ext2.c (EXT4_EXTENTS_FLAG): New macro.
+	(grub_ext4_extent_header): New structure.
+	(grub_ext4_extent): Likewise.
+	(grub_ext4_extent_idx): Likewise.
+	(grub_ext4_find_leaf): New function.
+	(grub_ext2_read_block): Handle extents.
+
+2008-07-12  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-mkrescue.in: s/grub-install/grub-mkrescue/g.
+
+2008-07-11  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/40_custom.in: New file. Example on how to add custom
+	entries to /etc/grub.d.
+	* conf/common.rmk (%, update-grub_SCRIPTS, CLEANFILES): Install
+	40_custom (implicitly, by merging all the grub.d rules).
+
+2008-07-11  Pavel Roskin  <proski@gnu.org>
+
+	* commands/read.c (grub_getline): Fix invalid memory access.
+	Don't add newline to the variable value.
+
+	* term/i386/pc/serial.c (GRUB_SERIAL_PORT_NUM): New constant.
+	[!GRUB_MACHINE_PCBIOS] (serial_hw_io_addr): Add COM2 and COM3.
+	(serial_hw_get_port): Check validity of the port number.
+	(grub_cmd_serial): Check return value of serial_hw_get_port().
+
+2008-07-07  Pavel Roskin  <proski@gnu.org>
+
+	* boot/i386/pc/diskboot.S (notification_string): Replace
+	"Loading kernel" with just "loading".  This is shorter, less
+	confusing and saves a few bytes for possible future changes.
+
+2008-07-05  Pavel Roskin  <proski@gnu.org>
+
+	* disk/ata.c (grub_ata_dumpinfo): Don't output addressing and
+	size for ATAPI devices, they are undefined.  Output sector
+	number in decimal form.
+
+	* disk/ata.c: Use named constants for status bits.
+
+2008-07-04  Pavel Roskin  <proski@gnu.org>
+
+	* kern/i386/linuxbios/init.c (grub_machine_init): Cast addr to
+	grub_addr_t before casting it to the void pointer to fix a
+	warning.  Non-addressable regions are discarded earlier.
+	(grub_arch_modules_addr): Cast _end to grub_addr_t.
+	* kern/i386/linuxbios/table.c: Include grub/misc.h.
+	(check_signature): Don't shadow table_header.
+	(grub_linuxbios_table_iterate): Cast numeric constants to
+	grub_linuxbios_table_header_t.
+	* include/grub/i386/linuxbios/init.h: Add noreturn attribute to
+	grub_stop().
+
+	* kern/ieee1275/init.c: Cast _start and _end to grub_addr_t to
+	prevent warnings.
+
+	* include/grub/misc.h (ALIGN_UP): Avoid unnecessary cast to a
+	pointer, which can cause warnings.  Support 64-bit addresses.
+
+	* util/elf/grub-mkimage.c: Use GRUB_TARGET_SIZEOF_LONG instead
+	of sizeof(long).  This fixes PowerPC image generation on x86_64.
+
+2008-07-04  Robert Millan  <rmh@aybabtu.com>
+
+	This fixes a performance issue when pc & gpt partmap iterators
+	didn't abort iteration even after our hook found what it was
+	looking for (often causing expensive probes of non-existent drives).
+
+	Some callers relied on previous buggy behaviour, since they would
+	raise an error when their own hooks caused early abortion of its
+	iteration.
+
+	* kern/device.c (grub_device_open): Improve error message.
+	* disk/lvm.c (grub_lvm_open): Likewise.
+	* disk/raid.c (grub_raid_open): Likewise.
+
+	* partmap/pc.c (pc_partition_map_iterate): Abort parent iteration
+	when hook requests it, independently of grub_errno.
+	(pc_partition_map_probe): Do not fail when find_func() caused
+	early abortion of pc_partition_map_iterate().
+
+	* partmap/gpt.c (gpt_partition_map_iterate): Abort parent iteration
+	when hook requests it, independently of grub_errno.
+	(gpt_partition_map_probe): Do not fail when find_func() caused
+	early abortion of gpt_partition_map_iterate().
+
+	* kern/partition.c (grub_partition_iterate): Abort parent iteration
+	when hook requests it, independently of grub_errno.  Do not fail when
+	part_map_iterate_hook() caused early abortion of p->iterate().
+
+	* util/biosdisk.c (grub_util_biosdisk_get_grub_dev): Do not fail
+	when grub_partition_iterate() returned with non-zero.
+
+2008-07-03  Pavel Roskin  <proski@gnu.org>
+
+	* disk/ata.c (grub_ata_pio_write): Check status before writing,
+	like we do in grub_ata_pio_read().
+	(grub_ata_readwrite): Always write individual sectors.  Fix the
+	sector count for the remainder.
+	(grub_ata_write): Enable writing to ATA devices.  Correctly
+	report error for ATAPI devices.
+
+2008-07-02  Pavel Roskin  <proski@gnu.org>
+
+	* boot/i386/pc/cdboot.S: Add _start entry to fix a linker
+	warning.
+
+	* disk/ata.c (grub_ata_readwrite): Don't increment sector number
+	for every read sector, we already increment it for the whole
+	batch.  This fixes reading more than 256 sectors at once.
+
+	* util/grub-editenv.c (cmd_info): Cast argument to long
+	explicitly.  ptrdiff_t reduces to int on i386.
+
+	* util/grub-editenv.c (main): Be specific which parameter is
+	missing.
+
+	* disk/memdisk.c (memdisk_addr): Make a pointer to fix warnings.
+	(memdisk): Make memdisk_orig_addr a pointer.
+
+	* fs/reiserfs.c (grub_reiserfs_read): Fix misuse of grub_size_t
+	for file offsets, use grub_off_t instead.  Fix printf format
+	warnings.
+
+	* fs/reiserfs.c: Remove #warning, TODO list items don't belong
+	there.  Real unexpected warnings should not drown in the noise
+	about known problems.
+
+	* commands/hexdump.c (grub_cmd_hexdump): Fix misuse of
+	grub_disk_addr_t for memory addresses.
+
+	* loader/aout.c (grub_aout_load): Cast load_addr to pointer
+	explicitly to fix a warning.
+
+	* util/grub-editenv.c (cmd_info): Fix warning in printf format.
+
+	* Makefile.in (MODULE_LDFLAGS): New variable.
+	* aclocal.m4 (grub_PROG_LD_BUILD_ID_NONE): New macro.  Check if
+	the linker accepts --build-id=none.
+	* configure.ac: Call grub_PROG_LD_BUILD_ID_NONE.  Substitute
+	MODULE_LDFLAGS.
+	* genmk.rb: Use MODULE_LDFLAGS when linking modules.
+
+	* fs/xfs.c (struct grub_xfs_dir_header): Use names similar to
+	those in Linux XFS code.  Provide a way to access 64-bit parent
+	inode.
+	(grub_xfs_iterate_dir): Use the new names.  Avoid reading past
+	the end of struct grub_xfs_dir_header.
+
+2008-07-02  Bean  <bean123ch@gmail.com>
+
+	* include/grub/ieee1275.h (grub_ieee1275_flag): New constant
+	GRUB_IEEE1275_FLAG_CANNOT_INTERPRET, GRUB_IEEE1275_FLAG_FORCE_CLAIM
+	and GRUB_IEEE1275_FLAG_NO_ANSI.
+
+	* kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set flag
+	GRUB_IEEE1275_FLAG_CANNOT_INTERPRET, GRUB_IEEE1275_FLAG_FORCE_CLAIM
+	and GRUB_IEEE1275_FLAG_NO_ANSI for Open Hackware.
+
+	* kern/ieee1275/ieee1275.c (grub_ieee1275_interpret): Return
+	immediately if GRUB_IEEE1275_FLAG_CANNOT_INTERPRET is set.
+
+	* kern/ieee1275/init.c (grub_claim_heap): Claim memory directly if
+	GRUB_IEEE1275_FLAG_FORCE_CLAIM is set.
+
+	* term/ieee1275/ofconsole.c (grub_ofconsole_writeesc): Don't output
+	esc sequence on non ANSI terminal.
+	(grub_ofconsole_gotoxy): Emulate backspace key on non ANSI terminal.
+
+	* util/elf/grub-mkimage.c (add_segments): Move ELF header to the
+	beginning of file.
+
+2008-07-02  Bean  <bean123ch@gmail.com>
+
+	* conf/common.rmk (bin_UTILITIES): Add grub-editenv.
+	(grub_editenv_SOURCES): New variable.
+	(pkglib_MODULES): Add loadenv.mod.
+	(loadenv_mod_SOURCES): New variable.
+	(loadenv_mod_CFLAGS): Likewise.
+	(loadenv_mod_LDFLAGS): Likewise.
+
+	* include/grub/envblk.h: New file.
+
+	* util/envblk.c: New file.
+
+	* util/grub-editenv.c: New file.
+
+	* commands/loadenv.c: New file.
+
+2008-07-01  Pavel Roskin  <proski@gnu.org>
+
+	* include/multiboot2.h (struct multiboot_tag_module): Use char,
+	not unsigned char.  This fixes warnings and is consistent with
+	other tags.
+
+	* disk/fs_uuid.c (search_fs_uuid): Correctly increment count.
+
+	* normal/parser.y: Define YYENABLE_NLS as 0 to fix warnings.
+
+	* term/tparm.c (analyze): Always set *popcount.
+
+	* loader/i386/pc/linux.c (grub_rescue_cmd_linux): Remove useless
+	cast to fix a warning.
+
+	* loader/i386/pc/multiboot2.c (grub_mb2_arch_module_alloc): Use
+	cast to suppress a warning.
+
+	* fs/afs.c (grub_afs_read_block): Return grub_disk_addr_t, as
+	grub_fshelp_read_file() expects.
+
+	* fs/fat.c: Fix UUID calculation on big-endian systems.  We
+	write uuid as a 32-bit value in CPU byte order, so declare and
+	use it as such.
+
+	* disk/raid.c: Cast grub_dprintf() arguments to unsigned long
+	long if the format specifier expects it.
+	* partmap/gpt.c (gpt_partition_map_iterate): Likewise.
+	* partmap/pc.c (pc_partition_map_iterate): Likewise.
+	* fs/ntfs.c (grub_ntfs_uuid): Cast data->uuid to unsigned long
+	long to fix a warning.
+	* fs/reiserfs.c (grub_reiserfs_read): Change casts in
+	grub_dprintf() arguments to fix warnings.
+
+2008-06-30  Pavel Roskin  <proski@gnu.org>
+
+	* util/i386/pc/grub-setup.c (setup): Write install_dos_part and
+	install_bsd_part immediately before core.img is embedded or
+	modified on disk.  This fixes core.img verification if core.img
+	cannot be embedded.
+
+	* util/i386/pc/grub-setup.c (setup): Use core_path_dev, not
+	core_path to calculate the blocklist.
+	Patch from Javier Martín <lordhabbit@gmail.com>
+
+2008-06-29  Robert Millan  <rmh@aybabtu.com>
+
+	* fs/xfs.c (GRUB_XFS_FSB_TO_BLOCK): New macro.  Maps filesystem
+	block to disk block.
+	(grub_xfs_read_block): Use GRUB_XFS_FSB_TO_BLOCK() on result.
+	Patch from Niels Böhm <bitbucket@arcor.de>
+
+2008-06-29  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in (font_path): Search for fonts in
+	/boot/grub first, which is more likely to be readable (we aren't
+	deciding where fonts live, just looking for them).
+
+2008-06-26  Pavel Roskin  <proski@gnu.org>
+
+	* util/biosdisk.c (read_device_map): Don't leave dead map
+	entries for devices failing stat() check.
+
+	* util/i386/pc/grub-setup.c (setup): Don't reuse core_path, use
+	core_path_dev for the core.img path on the target device.
+
+2008-06-26  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/fs_uuid.c: New file.
+	* conf/common.rmk (pkglib_MODULES): Add `fs_uuid.mod'.
+	(fs_uuid_mod_SOURCES, fs_uuid_mod_CFLAGS)
+	(fs_uuid_mod_LDFLAGS): New variables.
+	* include/grub/disk.h (grub_disk_dev_id): Add
+	`GRUB_DISK_DEVICE_UUID_ID'.
+	* kern/disk.c (grub_disk_dev_iterate): Allow disk devices not to
+	implement iterate().
+
+2008-06-26  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/10_linux.in: Avoid passing UUIDs to Linux when either
+	"/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" does not exist, or when a
+	Linux image includes no initrd.
+
+2008-06-21  Javier Martín  <lordhabbit@gmail.com>
+
+	* util/i386/pc/grub-setup.c (setup): Remove literal "core.img" in a
+	call to resolve the core image location that effectively appended the
+	name twice.
+
+2008-06-21  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/00_header.in: Move last prepare_grub_to_access_device()
+	call from here ...
+
+	* util/grub.d/10_hurd.in: ... to here ...
+	* util/grub.d/10_linux.in: ... and here.
+
+2008-06-19  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/main.c (grub_main): Export `prefix' variable immediately
+	after it has been set by grub_machine_set_prefix().
+
+2008-06-19  Robert Millan  <rmh@aybabtu.com>
+
+	* commands/search.c (search_label, search_fs_uuid, search_file): Print
+	search result when not saving to variable, not the other way around.
+	When saving to variable, abort iteration as soon as a match is found.
+
+2008-06-19  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in (prepare_grub_to_access_device): Remove
+	check for partition that provides /boot/grub.  Its logic is flawed,
+	as it prevents prepare_grub_to_access_device() from being called
+	multiple times.
+
+2008-06-19  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in (prepare_grub_to_access_device): Issue
+	"insmod" command directly when abstraction modules are needed,
+	instead of relying on GRUB_PRELOAD_MODULES (which had no effect
+	since it had already been processed).
+
+2008-06-19  Pavel Roskin  <proski@gnu.org>
+
+	* conf/i386-efi.rmk: Recompile grub-mkimage.c if Makefile has
+	changed.  This is needed in case GRUB_LIBDIR changes.
+	* conf/i386-ieee1275.rmk: Likewise.
+	* conf/i386-linuxbios.rmk: Likewise.
+	* conf/i386-pc.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+
+2008-06-18  Pavel Roskin  <proski@gnu.org>
+
+	* conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Rename
+	kernel_elf_symlist.c to symlist.c for consistency with other
+	architectures.  Update all users.
+	* conf/sparc64-ieee1275.rmk (kernel_elf_SOURCES): Likewise.
+
+2008-06-18  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-install.in: If the drive is LVM or RAID, prepend
+	it in prefix.
+
+	* util/i386/pc/grub-setup.c (main): Don't handle prefix at all.  Set
+	`must_embed' to 1 when root_dev is a RAID device.  When dest_dev is
+	a RAID device, run setup() for all members independently on whether
+	LVM abstraction is being used.
+	(setup): Don't handle prefix at all; let grub-mkimage take care of it.
+	If grub-mkimage has set `*install_dos_part == -2', don't override this
+	value.
+	Perform *install_dos_part adjustments independently on whether
+	we're embedding or not.
+	Clarify error message when image is too big for embedding.
+	Remove duplicate *install_dos_part stanza.
+
+2008-06-17  Robert Millan  <rmh@aybabtu.com>
+
+	* term/ieee1275/ofconsole.c (fgcolor, bgcolor): Remove variables.
+	(grub_ofconsole_normal_color, grub_ofconsole_highlight_color): New
+	variables.
+	(grub_ofconsole_setcolor, grub_ofconsole_getcolor): Load/store
+	values in grub_ofconsole_normal_color and
+	grub_ofconsole_highlight_color (they're not directly related to
+	background and foreground).
+	(grub_ofconsole_setcolorstate): Extract background and foreground
+	from grub_ofconsole_normal_color and grub_ofconsole_highlight_color.
+
+2008-06-17  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in (prepare_grub_to_access_device): Use
+	/boot/grub for the check in last commit, not /boot (they could be
+	different partitions).
+
+2008-06-16  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in (prepare_grub_to_access_device): If we were
+	asked to setup access for the same partition that provides /boot,
+	don't bother using UUIDs since our root already has the value we
+	want.
+
+2008-06-16  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (convert_system_partition_to_system_disk): Detect
+	I2O devices.
+	Patch from Sven Mueller <sven@debian.org>.
+
+2008-06-16  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub.in: Check for $EUID instead of $UID.
+	Reported by Vincent Zweije.
+
+2008-06-16  Bean  <bean123ch@gmail.com>
+
+	* fs/ext2.c (grub_ext2_blockgroup): Revert to pre-journal state.
+	(grub_ext2_read_block): Likewise.
+	(grub_ext2_read_inode): Likewise.
+	(grub_ext2_mount): Likewise.
+	(grub_ext2_close): Likewise.
+	(grub_ext3_get_journal): Removed.
+
+	* fs/reiserfs.c (grub_reiserfs_get_item): Revert to pre-journal state.
+	(grub_reiserfs_read_symlink): Likewise.
+	(grub_reiserfs_mount): Likewise.
+	(grub_reiserfs_open): Likewise.
+	(grub_reiserfs_read): Likewise.
+	(grub_reiserfs_close): Likewise.
+	(grub_reiserfs_get_journal): Removed.
+
+	* fs/fshelp.c (grub_fshelp_read): Removed.
+	(grub_fshelp_map_block): Likewise.
+
+	* include/grub/fshelp.h (grub_fshelp_journal_type): Removed.
+	(grub_fshelp_journal): Likewise.
+	(grub_fshelp_read): Likewise.
+	(grub_fshelp_map_block): Likewise.
+
+2008-06-16  Pavel Roskin  <proski@gnu.org>
+
+	* conf/powerpc-ieee1275.rmk: Remove -msoft-float, we don't use
+	floating point anymore.
+	* include/grub/powerpc/libgcc.h: Leave only necessary exports.
+
+2008-06-15  Pavel Roskin  <proski@gnu.org>
+
+	* commands/ls.c (grub_ls_list_files): Use integer calculations
+	for human readable format, avoid floating point use.
+	* kern/misc.c (grub_ftoa): Remove.
+	(grub_vsprintf): Remove floating point support.
+
+2008-06-15  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/10_linux.in: Use the underlying device for loop-AES
+	devices.
+	Reported by Max Vozeler.
+
+2008-06-15  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-mkimage.c (generate_image): If we included a drive
+	in our prefix, set install_{dos,bsd}_part = -2 to indicate this can be
+	skipped later.
+	(main): If a memdisk was requested, add "(memdisk)" drive explicitly to
+	the beginning of the prefix.
+
+	* kern/i386/pc/init.c (make_install_device): Remove memdisk check.
+	It is assumed that if we have a memdisk, grub-mkimage has set
+	grub_prefix to include the "(memdisk)" drive in it.
+
+2008-06-15  Robert Millan  <rmh@aybabtu.com>
+
+	* term/i386/pc/console.c [GRUB_MACHINE_LINUXBIOS] (grub_console_init):
+	Initialize keyboard controller after registering the terminal, so that
+	grub_printf() can be called from grub_keyboard_controller_init().
+
+2008-06-15  Robert Millan  <rmh@aybabtu.com>
+
+	* fs/sfs.c (grub_sfs_read_extent): Fix the count of nodes in
+	extent-btree which is written as big endian on disk.
+	Reported by Alain Greppin  <al@chilibi.org>.
+
+2008-06-14  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/efi/grub-install.in (modules): Remove `_chain'.
+	* util/i386/pc/grub-install.in (modules): Likewise.
+
+2008-06-13  Pavel Roskin  <proski@gnu.org>
+
+	* commands/ls.c (grub_ls_list_files): Fix format warnings.
+
+2008-06-13  Bean  <bean123ch@gmail.com>
+
+	* commands/hexdump.c (grub_cmd_hexdump): Adjust offset for partition.
+
+	* fs/ext2.c (grub_ext3_get_journal): Fix revoke block handling.
+
+	* fs/fshelp.c (grub_fshelp_map_block): Don't map block 0 as it's used
+	to indicate sparse block.
+
+2008-06-12  Pavel Roskin  <proski@gnu.org>
+
+	* fs/ext2.c (grub_ext2_read_inode): Don't normalize block
+	number, grub_fshelp_read() does it for us.
+
+	* fs/fshelp.c (grub_fshelp_read): New function.  Implement
+	linear disk read with journal translation.
+	* fs/ext2.c: Use grub_fshelp_read() instead of grub_disk_read().
+	* include/grub/fshelp.h: Declare grub_fshelp_read().
+
+2008-06-09  Pavel Roskin  <proski@gnu.org>
+
+	* fs/minix.c (grub_minix_mount): Handle error reading
+	superblock.
+
+2008-06-08  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-setup.c (main): If install drive is an LVM,
+	don't append the RAID prefix afterwards.
+	Reported by Clint Adams.
+
+2008-06-08  Robert Millan  <rmh@aybabtu.com>
+
+	Based on description from Pavel:
+	* kern/disk.c (grub_disk_check_range): Rename to ...
+	(grub_disk_adjust_range): ... this.  Add a comment explaining the
+	tasks performed by this function.
+
+2008-06-08  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/ntfs.h (struct grub_ntfs_bpb): Rename `serial_number' to
+	`num_serial' (for consistency with other variables).
+	(struct grub_ntfs_data): Add `uuid' member.
+	* fs/ntfs.c (grub_ntfs_mount): Initialize `data->uuid'.
+	(grub_ntfs_uuid): New function.
+	(grub_ntfs_fs): Reference grub_ntfs_uuid() in `uuid' struct member.
+
+2008-06-07  Pavel Roskin  <proski@gnu.org>
+
+	* util/biosdisk.c (open_device): Revert last change to the
+	function, it broke installation.  The sector needs to be
+	different dependent on which device is opened.
+
+2008-06-06  Robert Millan  <rmh@aybabtu.com>
+
+	Ensure GRUB_KERNEL_MACHINE_DATA_END is always consistent with the
+	rest of GRUB, and breakage doesn't happen if its value were modified.
+
+	* include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE):
+	Redefine as an offset from `GRUB_KERNEL_MACHINE_DATA_END' instead of
+	a constant (same value).
+	* kern/i386/pc/startup.S: Replace hardcoded `0x50' with
+	`GRUB_KERNEL_MACHINE_DATA_END' (same value).
+
+2008-06-06  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (open_device): Do not modify sector offset when
+	accessing a partition.  kern/disk.c already handles this for us.
+
+2008-06-06  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub-emu.c (grub_machine_init): Move code in this function from
+	here ...
+	(main): ... to here (before grub_util_biosdisk_init() call, to prevent
+	segfault in case grub_printf() is called).
+
+	* util/i386/pc/grub-install.in: Append `--device-map=${device_map}' to
+	grub_probe.  Update all users not to explicitly add it again.
+	(grub_device): New variable; contains corresponding device for grubdir.
+	(fs_module, partmap_module, devabstraction_module): Pass
+	`--device ${grub_device}' to grub_probe to avoid traversing /dev
+	every time.
+
+2008-06-05  Robert Millan  <rmh@aybabtu.com>
+
+	* normal/misc.c (grub_normal_print_device_info): When a filesystem UUID
+	is found, print it (same layout as with labels).
+
+2008-06-04  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (get_drive): Rename to ...
+	(find_grub_drive): ... this.  Update all users.
+
+	(get_os_disk): Rename to ...
+	(convert_system_partition_to_system_disk): ... this.  Update all users.
+
+	(find_drive): Rename to ...
+	(find_system_device): ... this.  Update all users.
+
+2008-06-04  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (get_os_disk): Handle IDA devices.
+	* util/grub-mkdevicemap.c (get_mmc_disk_name)
+	(make_device_map): Likewise.
+
+2008-06-01  Robert Millan  <rmh@aybabtu.com>
+
+	*  util/biosdisk.c (get_drive): Verify that `map[i].drive' is non-NULL
+	before dereferencing it.
+
+	* fs/fat.c (struct grub_fat_bpb): Move fat32-specific fields into a
+	union with fat12/fat16-specific ones.  Add some new fields, including
+	`num_serial' for both versions.
+	(struct grub_fat_data): Add `uuid' member.
+	(grub_fat_mount): Refer to fat32-specific fields in `bpb' by their new
+	names.  Initialize `data->uuid' using `num_serial'.
+	(grub_fat_uuid): New function.
+	(grub_fat_fs): Reference grub_fat_uuid() in `uuid' struct member.
+
+	* fs/reiserfs.c (grub_reiserfs_superblock): Add `uuid' field.
+	(grub_reiserfs_uuid): New function.
+	(grub_reiserfs_fs): Reference grub_reiserfs_uuid() in `uuid' struct
+	member.
+
+	* fs/xfs.c (grub_xfs_sblock): Add `uuid' field.
+	(grub_xfs_uuid): New function.
+	(grub_xfs_fs): Reference grub_reiserfs_uuid() in `uuid' struct member.
+
+2008-06-01  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in (prepare_grub_to_access_device): Generate
+	code that is backward compatible with pre-uuid search command.
+
+2008-05-31  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/i386/pc/biosdisk.c (grub_biosdisk_iterate): Iterate through
+	floppies after everything else, to ensure floppy drive isn't accessed
+	unnecessarily (patch from Bean).
+
+2008-05-31  Robert Millan  <rmh@aybabtu.com>
+
+	* commands/search.c (search_label, search_fs_uuid, search_file): Do
+	not print device names when we were asked to set a variable.
+
+2008-05-31  Robert Millan  <rmh@aybabtu.com>
+
+	* term/ieee1275/ofconsole.c (grub_ofconsole_setcursor): Implement
+	using "cursor-on" and "cursor-off" commands (understood at least by
+	the Open Firmware flavour on OLPC).
+
+2008-05-31  Michael Gorven  <michael@gorven.za.net>
+
+	* term/terminfo.c (grub_terminfo_set_current): Correct vt100 cursor
+	on and off sequences.
+
+2008-05-31  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in: Replace `grub-probe' with `${grub_probe}'.
+	* util/update-grub.in: Likewise.
+
+2008-05-30  Pavel Roskin  <proski@gnu.org>
+
+	* util/biosdisk.c (linux_find_partition): Simplify logic and
+	make the code more universal.  Keep special processing for
+	devfs, but use a simple rule for all other devices.  If the
+	device ends with a number, append 'p' and the partition number.
+	Otherwise, append only the partition number.
+
+2008-05-30  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub.in (GRUB_DISABLE_LINUX_UUID): Export variable.
+	* util/grub.d/10_linux.in: If GRUB_DEVICE_UUID is set, and
+	GRUB_DISABLE_LINUX_UUID isn't true, use the filesystem UUIDs as
+	the `root' parameter to Linux.
+
+2008-05-30  Robert Millan  <rmh@aybabtu.com>
+
+	* commands/search.c (options): Rename --fs_uuid to --fs-uuid.
+	* util/update-grub_lib.in (prepare_grub_to_access_device): Replace
+	--fs_uuid with --fs-uuid.
+	* util/update-grub.in: Allow filesystem UUID probes to fail (since not
+	all filesystems support them).
+
+2008-05-30  Robert Millan  <rmh@aybabtu.com>
+
+	* fs/ext2.c (grub_ext2_uuid): Use `04x' instead of '02x' as
+	grub_printf() flags, since we're printing in units of 2 bytes.
+
+2008-05-30  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/00_header.in: Remove obsolete comment referencing
+	convert_system_path_to_grub_path().
+	* util/update-grub.in: Likewise.
+	* util/update-grub_lib.in (is_path_readable_by_grub): New function.
+	(convert_system_path_to_grub_path): Add a warning message explaining
+	that this function is deprecated.  Rely on is_path_readable_by_grub()
+	for the readability checks.
+	(font_path): Use is_path_readable_by_grub() for the readability
+	check rather than convert_system_path_to_grub_path().
+
+2008-05-30  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in (prepare_grub_to_access_device): New function.
+	* util/update-grub.in: Set `GRUB_FONT_PATH' to the system path, without
+	converting it first.
+	* util/grub.d/00_header.in: Use prepare_grub_to_access_device() to setup
+	grub.cfg for access to font file, and afterwards call it again to set
+	the root device.
+
+2008-05-30  Robert Millan  <rmh@aybabtu.com>
+
+	* commands/search.c (options): Add --fs_uuid option.
+	(search_fs_uuid): New function.
+	(grub_cmd_search): Fix --set argument passing.
+	Use search_fs_uuid() when requested via --fs_uuid.
+	(grub_search_init): Update help message.
+	* fs/ext2.c (struct grub_ext2_sblock): Rename `unique_id' to `uuid'
+	and redeclare it as an array of 16-bit words.
+	(grub_ext2_uuid): New function.
+	(grub_ext2_fs): Reference grub_ext2_uuid() in `uuid' struct member.
+	* include/grub/fs.h (struct grub_fs): Add `uuid' struct member.
+	* util/update-grub.in (GRUB_DEVICE_UUID, GRUB_DEVICE_BOOT)
+	(GRUB_DEVICE_BOOT_UUID): New variables.
+	(GRUB_DRIVE. GRUB_DRIVE_BOOT. GRUB_DRIVE_BOOT_GRUB): Remove.
+	* util/grub.d/00_header.in: Set root using `search --fs_uuid' command
+	whenever possible.
+	* util/grub.d/10_hurd.in: Avoid explicit use of root drive.  Instead,
+	just assume `root' variable has the right value.
+	* util/grub.d/10_linux.in: Likewise.
+	* util/grub-probe.c (probe): Probe for filesystem UUID when requested
+	via PRINT_FS_UUID.
+	(main): Recognise `-t fs_uuid' argument.
+
+2008-05-30  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (map): Redefine structure to hold information
+	about GRUB drive name.
+	(get_drive): Reimplement without assuming (and verifying) BIOS-like
+	drive names.
+	(call_hook): Remove.
+	(grub_util_biosdisk_iterate): Access drive names via `.drive' struct
+	member.  Assume drive has partitions.
+	(grub_util_biosdisk_open): Access device names via `.device' struct
+	member.
+	(open_device): Likewise.
+	(find_drive): Likewise.
+	(read_device_map): Adjust map[] usage to match the new struct
+	definition.  Don't check for duplicates (still possible, but not cheap
+	anymore).
+	(grub_util_biosdisk_fini): Free malloced buffers referenced by map[].
+	(make_device_name): Remove assumption of BIOS-like drive names.
+
+2008-05-30  Pavel Roskin  <proski@gnu.org>
+
+	* conf/i386-efi.rmk (normal/execute.c_DEPENDENCIES): Remove, as
+	compiling execute.c doesn't need grub_script.tab.h anymore.
+	(normal/command.c_DEPENDENCIES): Likewise.
+	(normal/function.c_DEPENDENCIES): Likewise.
+	* conf/i386-ieee1275.rmk: Likewise.
+	* conf/i386-linuxbios.rmk: Likewise.
+	* conf/i386-pc.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	* conf/sparc64-ieee1275.rmk: Likewise.
+
+2008-05-29  Pavel Roskin  <proski@gnu.org>
+
+	* disk/lvm.c (grub_lvm_scan_device): Check for the buffer end
+	when scanning metadata for volume group name.
+
+	* include/grub/script.h: Don't include grub_script.tab.h.  It's
+	a generated file, which may only be included from the files with
+	DEPENDENCIES rules in the makefile.  Don't use typedef YYSTYPE,
+	use union YYSTYPE, as the later allows forward declaration.
+	* normal/lexer.c: Don't use typedef YYSTYPE, use union YYSTYPE.
+
+2008-05-29  Robert Millan  <rmh@aybabtu.com>
+
+	* term/i386/pc/at_keyboard.c: Include `grub/machine/machine.h'.
+	(OLPC_UP, OLPC_DOWN, OLPC_LEFT, OLPC_RIGHT): New macros.
+	[GRUB_MACHINE_IEEE1275] (keyboard_map): Add OLPC scan codes
+	(grub_console_checkkey): Add grub_dprintf() call to report unknown
+	scan codes.
+
+2008-05-29  Robert Millan  <rmh@aybabtu.com>
+
+	* term/i386/pc/at_keyboard.c (grub_console_checkkey): Add support for
+	control key combinations.
+
+2008-05-29  Robert Millan  <rmh@aybabtu.com>
+
+	* util/powerpc/ieee1275/grub-install.in: Move from here ...
+	* util/ieee1275/grub-install.in: ... to here.
+	* powerpc-ieee1275.rmk (grub_install_SOURCES): Update location.
+	* i386-ieee1275.rmk (sbin_SCRIPTS): New variable.
+	(grub_install_SOURCES): Likewise.
+
+2008-05-29  Robert Millan  <rmh@aybabtu.com>
+
+	* fs/affs.c: Update copyright year.
+	* fs/ext2.c: Likewise.
+	* fs/fshelp.c: Likewise.
+	* fs/hfsplus.c: Likewise.
+	* fs/ntfs.c: Likewise.
+	* fs/xfs.c: Likewise.
+	* include/grub/fshelp.h: Likewise.
+	* util/grub-mkdevicemap.c: Likewise.
+
+2008-05-28  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub.in: Allow chmod call to fail, since /boot/grub/
+	might need to be fatfs to support some firmware implementations
+	(e.g. OFW or EFI).
+
+2008-05-28  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (linux_find_partition, get_os_disk): Handle MMC
+	devices.
+	* util/grub-mkdevicemap.c (get_mmc_disk_name)
+	(make_device_map): Likewise.
+
+2008-05-20  Bean  <bean123ch@gmail.com>
+
+	* fs/fshelp.c (grub_fshelp_map_block): New function.
+	(grub_fshelp_find_file): Use 64-bit type for pos and block address.
+	Use `>>' and `&' operator to avoid 64-bit divide and modulo.
+
+	* include/grub/fshelp.h (grub_fshelp_journal_type): New enum.
+	(GRUB_FSHELP_JOURNAL_UNUSED_MAPPING): New macro.
+	(grub_fshelp_journal): New structure.
+	(grub_fshelp_map_block): New function prototype.
+	(grub_fshelp_read_file): Use grub_disk_addr_t as block type.
+	(grub_fshelp_map_block): Likewise.
+
+	* fs/ext2.c (EXT3_FEATURE_COMPAT_HAS_JOURNAL): New macro.
+	(EXT3_JOURNAL_MAGIC_NUMBER): Likewise.
+	(EXT3_JOURNAL_DESCRIPTOR_BLOCK): Likewise.
+	(EXT3_JOURNAL_COMMIT_BLOCK): Likewise.
+	(EXT3_JOURNAL_SUPERBLOCK_V1): Likewise.
+	(EXT3_JOURNAL_SUPERBLOCK_V2): Likewise.
+	(EXT3_JOURNAL_REVOKE_BLOCK): Likewise.
+	(EXT3_JOURNAL_FLAG_ESCAPE): Likewise.
+	(EXT3_JOURNAL_FLAG_SAME_UUID): Likewise.
+	(EXT3_JOURNAL_FLAG_DELETED): Likewise.
+	(EXT3_JOURNAL_FLAG_LAST_TAG): Likewise.
+	(grub_ext2_sblock): New members for journal support.
+	(grub_ext3_journal_header): New structure.
+	(grub_ext3_journal_revoke_header): Likewise.
+	(grub_ext3_journal_block_tag): Likewise.
+	(grub_ext3_journal_sblock): Likewise.
+	(grub_fshelp_node): New members logfile and journal.
+	(grub_ext2_read_block): Change block type to grub_disk_addr_t. Use
+	grub_fshelp_map_block to get real block number.
+	(grub_ext2_blockgroup): Use grub_fshelp_map_block to get real block
+	number.
+	(grub_ext2_read_inode): Likewise.
+	(grub_ext3_get_journal): New function.
+	(grub_read_inode): Initialize journal using grub_ext3_get_journal.
+	(grub_ext2_close): Release memory used by journal.
+
+	* fs/reiserfs.c (REISERFS_MAGIC_STRING): Changed to "ReIsEr".
+	(REISERFS_MAGIC_DESC_BLOCK): New macro.
+	(grub_reiserfs_transaction_header): Renamed to
+	grub_reiserfs_description_block, replace field data with real_blocks.
+	(grub_reiserfs_commit_block): New structure.
+	(grub_reiserfs_data): New member journal.
+	(grub_reiserfs_get_item): Use grub_fshelp_map_block to get real block
+	number.
+	(grub_reiserfs_read_symlink): Likewise.
+	(grub_reiserfs_iterate_dir): Likewise.
+	(grub_reiserfs_open): Likewise.
+	(grub_reiserfs_read): Likewise.
+	(grub_reiserfs_get_journal): New function.
+	(grub_reiserfs_mount): Use "ReIsEr" as super block magic, as there are
+	three varieties ReIsErFs, ReIsEr2Fs and ReIsEr3Fs. Initialize journal
+	using grub_reiserfs_get_journal.
+	(grub_reiserfs_close): Release memory used by journal.
+
+	* fs/affs.c (grub_affs_read_block): Change block type to
+	grub_disk_addr_t. Use grub_divmod64 to do 64-bit division.
+
+	* fs/afs.c (grub_afs_read_block): Change block type to grub_disk_addr_t.
+
+	* fs/hfsplus.c (grub_hfsplus_read_block): Likewise.
+
+	* fs/ntfs.c (grub_ntfs_read_block): Likewise.
+
+	* fs/udf.c (grub_udf_read_block): Change block type to
+	grub_disk_addr_t. Use type cast to avoid warning.
+
+	* fs/xfs.c (grub_xfs_read_block): Likewise.
+
+2008-05-16  Christian Franke  <franke@computer.org>
+
+	* commands/cat.c (grub_cmd_cat): Remove non-ESC keys from keyboard queue
+	to ensure that break with ESC will always work.
+	* commands/sleep.c (grub_interruptible_millisleep): Likewise.
+	Remove ESC from keyboard queue.
+
+2008-05-16  Christian Franke  <franke@computer.org>
+
+	* util/biosdisk.c: [__CYGWIN__] Add includes.
+	(grub_util_biosdisk_open): Use Linux code also for Cygwin.
+	(get_os_disk): Move variable declarations to OS specific
+	parts to avoid warning.
+	[__GNU__] (get_os_disk): Fix /dev/sdXsN case.
+	[__CYGWIN__] (get_os_disk): Add Cygwin /dev/sdXN device names.
+	(grub_util_biosdisk_get_grub_dev): Use Linux code also for
+	Cygwin.
+	* util/getroot.c: [__CYGWIN__] Add includes.
+	(strip_extra_slashes): Fix "/" case.
+	[__CYGWIN__] (get_win32_path): New function.
+	[__CYGWIN__] (grub_get_prefix): Add conversion to win32 path.
+	[__CYGWIN__] (find_root_device): Disable.
+	[__CYGWIN__] (get_bootsec_serial): New function.
+	[__CYGWIN__] (find_cygwin_root_device): Likewise.
+	[__linux__] (grub_guess_root_device): Add early returns to simplify
+	structure.
+	[__CYGWIN__] (grub_guess_root_device): Call find_cygwin_root_device.
+	[__linux__] (grub_util_get_dev_abstraction): Enable LVM and RAID
+	check for Linux only.
+
+2008-05-15  Bean  <bean123ch@gmail.com>
+
+	* kern/i386/pc/startup.S (grub_console_getkey): Workaround for the
+	keyboard hang problem in apple's intel mac.
+
+2008-05-09  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (linux_find_partition, get_os_disk): Handle Virtio
+	devices.
+	* util/grub-mkdevicemap.c (get_virtio_disk_name)
+	(make_device_map): Likewise.
+	Reported by Aurelien Jarno <aurel32@debian.org>
+
+2008-05-07  Ian Campbell  <ijc@hellion.org.uk>
+
+	* util/biosdisk.c (get_os_disk): Recognise xvd type disks.
+	* util/grub-mkdevicemap.c (get_xvd_disk_name): New function.
+	(make_device_map): Output entries for xvd type disks.
+
+2008-05-07  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (linux_find_partition, get_os_disk): Handle CCISS
+	devices.
+	* util/grub-mkdevicemap.c (get_cciss_disk_name)
+	(make_device_map): Likewise.
+	Reported by Roland Dreier <rdreier@cisco.com>
+
+2008-05-07  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/lvm.c (grub_lvm_scan_device): Detect errors in an additional
+	grub_strstr() call.  Correct a few mistakes in failure path handling.
+
+2008-05-06  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in (make_system_path_relative_to_its_root):
+	Do not print a trailing slash (therefore, the root directory is an
+	empty string).
+	(convert_system_path_to_grub_path): Do not remove trailing slash
+	from make_system_path_relative_to_its_root() output.
+
+	* util/i386/pc/grub-install.in: Add trailing slash to output from
+	make_system_path_relative_to_its_root().
+
+2008-05-06  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub-fstest.c (grub_refresh): Call `fflush (stdout)'.  This
+	ensures that output lines aren't intermangled with those sent to
+	stderr (via grub_util_info()).
+	* util/grub-probe.c (grub_refresh): Likewise.
+	* util/i386/pc/grub-setup.c (grub_refresh): Likewise.
+
+2008-05-05  Christian Franke  <franke@computer.org>
+
+	* util/grub-mkdevicemap.c (get_floppy_disk_name) [__CYGWIN__]:
+	Add Cygwin device names.
+	(get_ide_disk_name) [__CYGWIN__]: Likewise.
+	(get_scsi_disk_name) [__CYGWIN__]: Likewise.
+	(check_device): Return error instead of success on empty name.
+	(make_device_map): Move label inside linux specific code to
+	prevent compiler warning.
+
+2008-04-30  Robert Millan  <rmh@aybabtu.com>
+
+	Based on patch from Fabian Greffrath <greffrath@leat.rub.de>
+	* util/grub.d/10_linux.in: Add ${GRUB_CMDLINE_LINUX_DEFAULT} to the
+	first boot option.
+	* util/update-grub.in: Export GRUB_CMDLINE_LINUX_DEFAULT.
+
+2008-04-29  Robert Millan  <rmh@aybabtu.com>
+
+	* docs/grub.cfg: New file (example GRUB configuration).
+
+2008-04-26  Robert Millan  <rmh@aybabtu.com>
+
+	* DISTLIST: Sort (sort -u < DISTLIST | sponge DISTLIST).  Add
+	`loader/i386/ieee1275/linux.c', `loader/i386/ieee1275/linux_normal.c'
+	and `disk/ieee1275/nand.c'.
+
+2008-04-25  Bean  <bean123ch@gmail.com>
+
+	* Makefile.in (RMKFILES): Add missing arch i386-ieee1275 and
+	i386-linuxbios.
+
+	* commands/hexdump.c (grub_cmd_hexdump): Support dumping of device,
+	change the buffer size to 4096 for cdrom device.
+
+	* conf/i386-ieee1275.rmk (pkglib_MODULES): Add _linux.mod, linux.mod
+	and nand.mod.
+	(_linux_mod_SOURCES): New variable.
+	(_linux_mod_CFLAGS): Likewise.
+	(_linux_mod_LDFLAGS): Likewise.
+	(linux_mod_SOURCES): Likewise.
+	(linux_mod_CFLAGS): Likewise.
+	(linux_mod_LDFLAGS): Likewise.
+	(nand_mod_SOURCES): Likewise.
+	(nand_mod_CFLAGS): Likewise.
+	(nand_mod_LDFLAGS): Likewise.
+
+	* disk/ieee1275/ofdisk.c (grub_ofdisk_open): Return
+	GRUB_ERR_UNKNOWN_DEVICE instead of GRUB_ERR_BAD_DEVICE if no device
+	type property. (nand device in olpc don't have this property)
+
+	* include/grub/disk.h (grub_disk_dev_id): New macro
+	GRUB_DISK_DEVICE_NAND_ID.
+
+	* include/grub/i386/ieee1275/loader.h (grub_rescue_cmd_linux): New
+	function prototype.
+	(grub_rescue_cmd_initrd): Likewise.
+
+	* include/grub/i386/linux.h (GRUB_LINUX_OFW_SIGNATURE): New macro.
+	(linux_kernel_params): Add new member ofw_signature, ofw_num_items,
+	ofw_cif_handler and ofw_idt, adjust padding number.
+
+	* include/grub/i386/pc/memory.h (grub_upper_mem): Export it if
+	GRUB_MACHINE_IEEE1275 is defined.
+
+	* include/grub/ieee1275/ieee1275.h (grub_available_iterate):
+	Use NESTED_FUNC_ATTR attribute on the hook parameter.
+
+	* kern/powerpc/ieee1275/init.c (grub_claim_heap): Use NESTED_FUNC_ATTR
+	on nested function heap_init.
+	(grub_upper_mem): New variable for i386-ieee1275.
+	(grub_get_extended_memory): New function for i386-ieee1275.
+	(grub_machine_init): Call grub_get_extended_memory for i386-ieee1275.
+
+	* kern/powerpc/ieee1275/openfw.c (grub_available_iterate): Use
+	NESTED_FUNC_ATTR on the hook parameter. Don't quit if no device type
+	property.
+
+	* loader/i386/ieee1275/linux.c: New file.
+
+	* loader/i386/ieee1275/linux_normal.c: New file.
+
+	* disk/ieee1275/nand.c: New file.
+
+2008-04-18  Thomas Schwinge  <tschwinge@gnu.org>
+
+	* util/i386/pc/grub-mkrescue.in (grub_mkimage): Don't overwrite correct
+	value.
+	* util/powerpc/ieee1275/grub-mkrescue.in (grub_mkimage): Likewise.
+
+2008-04-18  Robert Millan  <rmh@aybabtu.com>
+
+	Restructures early code path on ieee1275 to unify grub_main() as
+	the first C function that is executed in every platform.
+
+	* include/grub/ieee1275/ieee1275.h (grub_ieee1275_init): New prototype.
+	* kern/i386/ieee1275/startup.S (_start): Jump to grub_main() instead of
+	cmain().
+	* kern/powerpc/ieee1275/crt0.S (_start): Likewise.
+	* kern/ieee1275/cmain.c (cmain): Rename to ...
+	* kern/ieee1275/cmain.c (grub_ieee1275_init): ... this.
+	* kern/ieee1275/init.c (grub_machine_init): Call grub_ieee1275_init()
+	at the beginning.
+
+2008-04-18  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub.in: Fix syntax error when setting
+	`GRUB_PRELOAD_MODULES'.
+	Reported by Stephane Chazelas <stephane@artesyncp.com>
+
+2008-04-17  Lubomir Kundrak  <lkundrak@redhat.com>
+
+	* aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): take only .text
+	section into account, newer toolchains generate unique build ids
+	* configure.ac: remove the test for --build-id=none acceptance,
+	we want build ids to be preserved
+	* genmk.rb: add -R .note.gnu.build-id to objcopy, so build id
+	far from other sections don't cause the raw binary images grow
+	size
+
+2008-04-15  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/lvm.c: Update copyright year.
+	* kern/misc.c: Likewise.
+
+2008-04-14  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* disk/lvm.c (grub_lvm_scan_device): Add forgotten failure path when
+	there is no memory left for physical volume name.
+
+2008-04-14  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* disk/lvm.c (grub_lvm_scan_device): Fix logical volume's physical
+	volume name mapping to support bigger than 9 character names properly.
+
+2008-04-13  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/i386/pc/biosdisk.c (grub_biosdisk_rw): Fix CHS limit check,
+	as per http://www.allensmith.net/Storage/HDDlimit/Int13h.htm
+
+2008-04-13  Christian Franke  <franke@computer.org>
+
+	* util/i386/pc/grub-mkrescue.in: Add --emulation=floppy
+	to create a floppy emulation boot CD when non emulation mode
+	does not work.
+	Enable Joliet CD filesystem extension.
+
+2008-04-13  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/misc.c (grub_strncat): Fix off-by-one error.
+	Reported by Zhang Huan <zhanghuan@nrchpc.ac.cn>
+
+	* kern/env.c (grub_env_context_close): Clear current context, not
+	previous one.
+	Patch from Zhang Huan <zhanghuan@nrchpc.ac.cn>
+
+	* kern/misc.c (grub_strcat): Minor speed optimization (same code size).
+
+2008-04-13  Robert Millan  <rmh@aybabtu.com>
+
+	Improve robustness when handling LVM.
+
+	* disk/lvm.c (grub_lvm_getvalue): Return 0 when `*p' is NULL
+	(and leave `*p' unmodified).
+	(grub_lvm_iterate): Don't assume `vg->lvs != NULL' when iterating
+	through it.
+	(grub_lvm_memberlist): Don't assume `lv->vg->pvs != NULL' when
+	iterating through it.
+	(grub_lvm_open): Don't assume `vg->lvs != NULL' when iterating
+	through it.
+	(grub_lvm_scan_device): Check the return value (and fail gracefully
+	when due) on each grub_lvm_getvalue() or grub_strstr() call.
+	Don't assume `vg->pvs != NULL' when iterating through it.
+
+2008-04-13  Robert Millan  <rmh@aybabtu.com>
+
+	* gendistlist.sh (EXTRA_DISTFILES): Add `genpartmaplist.sh'.
+	* genmk.rb (partmap): New variable.
+	(CLEANFILES, PARTMAPFILES): Add #{partmap}.
+	(#{partmap}): New target rule.
+	* genpartmaplist.sh: New file.
+	* Makefile.in (pkglib_DATA): Add partmap.lst.
+	(partmap.lst): New target rule.
+	* util/i386/pc/grub-mkrescue.in: Generate grub.cfg that loads needed
+	modules (including all partition maps), instead of preloading them.
+
+2007-04-13  Fabian Greffrath  <fabian.greffrath@web.de>
+
+	* util/grub.d/30_os-prober.in: New script. Use `os-prober' and
+	`linux-boot-prober' (if installed) to detect other operating
+	systems which are installed on the computer and add them to
+	the boot menu.
+	* conf/common.rmk: Build and install 30_os-prober.
+
+2008-04-12  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/powerpc/ieee1275/init.c: Move from here ...
+	* kern/ieee1275/init.c: ... to here.  Update all users.
+
+	* kern/powerpc/ieee1275/cmain.c: Move from here ...
+	* kern/ieee1275/cmain.c: ... to here.  Update all users.
+
+	* kern/powerpc/ieee1275/openfw.c: Move from here ...
+	* kern/ieee1275/openfw.c: ... to here.  Update all users.
+
+	* loader/powerpc/ieee1275/multiboot2.c: Move from here ...
+	* loader/ieee1275/multiboot2.c: ... to here.  Update all users.
+
+2008-04-10  Pavel Roskin  <proski@gnu.org>
+
+	* configure.ac: Always use "_cv_" in cache variables for
+	compatibility with Autoconf 2.62.
+
+2008-04-07  Robert Millan  <rmh@aybabtu.com>
+
+	Revert grub/machine/init.h addition by Pavel (since it breaks on
+	i386-ieee1275 and others):
+	* util/i386/pc/misc.c: Remove grub/machine/init.h.
+	* util/powerpc/ieee1275/misc.c: Likewise.
+
+2008-04-07  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub-probe.c (probe): Improve error message.
+
+2008-04-07  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (read_device_map): Skip devices that don't exist
+	(this prevents the presence of a bogus entry from ruining the whole
+	thing).
+
+2008-04-06  Pavel Roskin  <proski@gnu.org>
+
+	* util/biosdisk.c: Include grub/util/biosdisk.h.
+	* util/grub-fstest.c (execute_command): Make static.
+	* util/grub-mkdevicemap.c (check_device): Likewise.
+	* util/i386/pc/misc.c: Include grub/machine/init.h.
+	* util/powerpc/ieee1275/misc.c: Likewise.
+	* util/lvm.c: Include grub/util/lvm.h.
+	* util/misc.c: Include grub/kernel.h, grub/misc.h and
+	grub/cache.h.
+	* util/raid.c: Include grub/util/raid.h.
+	(grub_util_getdiskname): Make static.
+
+	* util/grub-emu.c (main): Remove calls to grub_hostfs_init() and
+	grub_hostfs_fini(), as they are called from grub_init_all() and
+	grub_fini_all() respectively.  This fixes an infinite loop in
+	grub-fstest due to double registration of hostfs.
+	Reported by Christian Franke <Christian.Franke@t-online.de>
+
+2008-04-05  Pavel Roskin  <proski@gnu.org>
+
+	* bus/pci.c (grub_pci_iterate): For multifunction devices, probe
+	all 8 functions.  Otherwise, probe function 0 only.
+
+2008-04-04  Pavel Roskin  <proski@gnu.org>
+
+	* commands/lspci.c (grub_lspci_iter): Print the bus number
+	correctly.
+
+	* commands/lspci.c (grub_pci_classes): Fix typos.
+	(grub_lspci_iter): Don't print func twice.  Print vendor ID
+	before device ID, as it's normally done.
+
+	* kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options):
+	Fix signedness warnings.
+	* kern/powerpc/ieee1275/openfw.c (grub_available_iterate):
+	Likewise.
+	* util/ieee1275/get_disk_name.c: Include config.h so that
+	_GNU_SOURCE is defined and getline() is declared.  Mark an
+	unused argument as such.  Fix a signedness warning.
+
+2008-04-02  Pavel Roskin  <proski@gnu.org>
+
+	* genkernsyms.sh.in: Use more robust assignments for CC and
+	srcdir.  Quote srcdir.
+	* gensymlist.sh.in: Likewise.  Assert at the compile time that
+	the symbol table is not empty.
+
+	* disk/raid.c (grub_raid_memberlist): Fix a signedness warning.
+	* fs/cpio.c (grub_cpio_read): Likewise.
+
+2008-04-01  Pavel Roskin  <proski@gnu.org>
+
+	* disk/ata.c (grub_ata_open): Don't lose precision in disk->id.
+	* disk/host.c (grub_host_open): Likewise.
+	* disk/loopback.c (grub_loopback_open): Likewise.
+	* disk/memdisk.c (grub_memdisk_open): Use a string pointer for
+	disk->id as in disk/host.c, not a multi-character constant.
+
+	* util/grub-fstest.c (cmd_cmp): Use fseeko(), not fseek().  The
+	later is obsolete, potentially dangerous and sets a bad example.
+	* util/i386/efi/grub-mkimage.c (make_header): Likewise.
+	* util/misc.c (grub_util_get_image_size): Likewise.
+
+	* disk/loopback.c (options): Improve help for "--partitions".
+
+	* normal/arg.c (grub_arg_show_help): Fix spacing of the long
+	options to align them with the short options, e.g. "echo -e".
+
+2008-03-31  Bean  <bean123ch@gmail.com>
+
+	* video/reader/png.c (grub_png_data): New member is_16bit and
+	image_data.
+	(grub_png_decode_image_header): Detect 16 bit png image.
+	(grub_png_convert_image): New function to convert 16 bit image to 8 bit.
+	(grub_png_decode_png): Call grub_png_convert_image for 16 bit image.
+	(grub_video_reader_png): Release memory occupied by image_data.
+
+	* fs/ntfs.c (find_attr): Handle non-resident attribute list larger than
+	4096 bytes.
+	(grub_nfs_mount): Skip the test for sector per cluster.
+
+	* include/grub/ntfs.h (MAX_SPC): Removed.
+
+2008-03-31  Bean  <bean123ch@gmail.com>
+
+	* conf/common.rmk (pkgdata_MODULES): Add afs.mod.
+	(grub_probe_SOURCES): Add fs/afs.c.
+	(grub_fstest_SOURCES): Likewise.
+	(afs_mod_SOURCES): New variable.
+	(afs_mod_CFLAGS): Likewise.
+	(afs_mod_LDFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/afs.c.
+	(grub_emu_SOURCES): Likewise.
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+	* fs/afs.c: New file.
+
+2008-03-30  Pavel Roskin  <proski@gnu.org>
+
+	* disk/host.c: Include grub/misc.h to fix a warning.
+	* util/hostfs.c: Use GRUB_MOD_INIT and GRUB_MOD_FINI to fix
+	warnings about implicit declarations.
+
+	* fs/udf.c (grub_udf_mount): Fix warning about a shadowing a
+	variable.
+	* include/grub/i386/loader.h: Change declaration of
+	grub_linux_boot() to match what grub_loader_set() expects.
+	* util/getroot.c (grub_guess_root_device): Return const char* to
+	fix a warning.
+	* util/grub-probe.c (probe): Fix a warning about uninitialized
+	abstraction_name variable.
+	* util/i386/get_disk_name.c (grub_util_get_disk_name): Mark
+	second argument as unused to fix a warning.
+
+	* loader/i386/pc/multiboot2.c (grub_mb2_arch_elf64_hook): Add
+	missing grub_error() call.
+
+	* util/update-grub_lib.in: Define datarootdir, since Autoconf
+	2.60 and newer uses it to define datadir.
+
+	* commands/sleep.c: Fix warning about implicit declaration.
+	* disk/memdisk.c: Likewise.
+	* loader/aout.c: Likewise.
+	* loader/i386/bsd_normal.c: Likewise.
+	* util/grub-probe.c: Likewise.
+
+	* commands/i386/cpuid.c (has_longmode): Make static.
+	* disk/i386/pc/biosdisk.c (cd_drive): Likewise.
+	* include/grub/i386/bsd.h (bios_memmap_t): Remove, it's unused.
+
+	* kern/i386/pc/startup.S (real_to_prot): Use %cs prefix to load
+	GDT.  This is more robust, as %ds can change.
+	(grub_biosdisk_rw_int13_extensions): Don't clear %ds before
+	calling real_to_prot().
+	(grub_biosdisk_get_diskinfo_int13_extensions): Likewise.
+
+2008-03-28  Pavel Roskin  <proski@gnu.org>
+
+	* kern/i386/pc/startup.S: Assert that uncompressed functions
+	don't spill beyond GRUB_KERNEL_MACHINE_RAW_SIZE.
+	* kern/i386/pc/lzo1x.S: Remove all .align directives in the
+	code, as they push parts of the code (error handlers) beyond
+	GRUB_KERNEL_MACHINE_RAW_SIZE.  Speed is not as important in this
+	code as correctness and size.
+
+2008-03-28  Pavel Roskin  <proski@gnu.org>
+
+	* kern/i386/pc/startup.S
+	(grub_biosdisk_get_diskinfo_int13_extensions): When converting
+	data block address to the real mode, keep offset minimal.  This
+	works around a bug in AWARD BIOS on old Athlon systems, which
+	makes CD detection hang.
+
+2008-03-26  Pavel Roskin  <proski@gnu.org>
+
+	* normal/color.c (grub_parse_color_name_pair): Make `name' a
+	const.
+	* include/grub/normal.h: Add grub_parse_color_name_pair()
+	declaration.
+
+2008-03-24  Bean  <bean123ch@gmail.com>
+
+	* disk/i386/pc/biosdisk.c (cd_start): Removed.
+	(cd_count): Removed.
+	(cd_drive): New variable.
+	(grub_biosdisk_get_drive): Don't check for (cdN) device.
+	(grub_biosdisk_call_hook): Likewise.
+	(grub_biosdisk_iterate): Change cdrom detection method.
+	(grub_biosdisk_open): Replace cd_start with cd_drive.
+	(GRUB_MOD_INIT): Use grub_biosdisk_get_cdinfo_int13_extension to
+	detect cdrom device.
+
+	* include/grub/i386/pc/biosdisk.h (GRUB_BIOSDISK_MACHINE_CDROM_START):
+	Removed.
+	(GRUB_BIOSDISK_MACHINE_CDROM_END): Removed.
+	(GRUB_BIOSDISK_CDTYPE_NO_EMUL): New macro.
+	(GRUB_BIOSDISK_CDTYPE_1_2_M): Likewise.
+	(GRUB_BIOSDISK_CDTYPE_1_44_M): Likewise.
+	(GRUB_BIOSDISK_CDTYPE_2_88_M): Likewise.
+	(GRUB_BIOSDISK_CDTYPE_HARDDISK): Likewise.
+	(GRUB_BIOSDISK_CDTYPE_MASK): Likewise.
+	(grub_biosdisk_cdrp): New structure.
+	(grub_biosdisk_get_cdinfo_int13_extensions): New function.
+
+	* include/grub/i386/pc/kernel.h (grub_boot_drive): Export this variable.
+
+	* kern/i386/pc/init.c (make_install_device): Don't use (cdN) as root
+	device.
+
+	* kern/i386/pc/startup.S (grub_biosdisk_get_cdinfo_int13_extensions):
+	New function.
+
+2008-03-20  Robert Millan  <rmh@aybabtu.com>
+
+	Remove 2 TiB limit in ata.mod.
+	* disk/ata.c (grub_ata_device): Promote `size' to grub_uint64_t.
+	(grub_ata_dumpinfo): Print sector count with 0x%llx.
+	(grub_ata_identify): Interpret `&info16[100]' as a pointer to
+	grub_uint64_t instead of grub_uint32_t.
+
+2008-03-05  Bean  <bean123ch@gmail.com>
+
+	* loader/i386/pc/multiboot.c (grub_multiboot_get_bootdev): New function.
+	(grub_multiboot): Set boot device.
+
+	* boot/i386/pc/lnxboot.S (real_code_2): Set %dh to 0xFF.
+
+2008-03-02  Bean  <bean123ch@gmail.com>
+
+	* fs/reiserfs.c (grub_reiserfs_read_symlink): Add 0 at the end of
+	symlink_buffer.
+
+2008-03-01  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Added docs/fdl.texi, docs/grub.texi, docs/mdate-sh and
+	texinfo.tex.
+
+	* docs/grub.texi: New file. Copied from GRUB Legacy, and slightly
+	modified.
+
+	* docs/fdl.texi: New file.
+
+	* docs/mdate-sh: New file. Copied from gnulib.
+	* docs/texinfo.tex: Likewise.
+
+	* config.guess: Updated from gnulib.
+	* install-sh: Likewise.
+
+2008-02-28  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-linuxbios.rmk (pkglib_MODULES): Add aout.mod.
+	(aout_mod_SOURCES): New variable.
+	(aout_mod_CFLAGS): Likewise.
+	(aout_mod_LDFLAGS): Likewise.
+
+	* conf/i386-ieee1275.rmk: Likewise.
+
+2008-02-28  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub.in: Reorganise terminal validity check.  Accept
+	`ieee1275:console' (OLPC) and `*:gfxterm' as valid too.
+	Based on suggestion by Franklin PIAT.
+
+2008-02-28  Fabian Greffrath  <greffrath@leat.rub.de>
+
+	* include/grub/util/getroot.h (grub_util_check_block_device): Export new
+	function.
+	* util/getroot.c (grub_util_check_block_device): New function that
+	returns the given argument if it is a block device and returns NULL else.
+	* util/grub-probe.c (argument_is_device): New variable.
+	(probe): Promote device_name from a variable to an argument. Receive
+	device_name from grub_util_check_block_device() if path is NULL and from
+	grub_guess_root_device() else. Do not free() device_name anymore.
+	(options): Introduce new parameter '-d, --device'.
+	(main): Add description of the new parameter to the help screen.
+	Rename path variable to argument. Set argument_is_device if the '-d'
+	option is given. Pass argument to probe() depending on
+	argument_is_device.
+
+2008-02-24  Bean  <bean123ch@gmail.com>
+
+	* fs/iso9660.c (GRUB_ISO9660_VOLDESC_BOOT): New macro.
+	(GRUB_ISO9660_VOLDESC_PRIMARY): Likewise.
+	(GRUB_ISO9660_VOLDESC_SUPP): Likewise.
+	(GRUB_ISO9660_VOLDESC_PART): Likewise.
+	(GRUB_ISO9660_VOLDESC_END): Likewise.
+	(grub_iso9660_primary_voldesc): New member escape.
+	(grub_iso9660_data): New member joliet.
+	(grub_iso9660_convert_string): New function.
+	(grub_iso9660_mount): Detect joliet extension.
+	(grub_iso9660_iterate_dir): Convert filename when joliet is detected.
+	(grub_iso9660_iso9660_label): Likewise.
+
+	* conf/common.rmk (pkgdata_MODULES): Add udf.mod.
+	(grub_setup_SOURCES): Add fs/udf.c.
+	(grub_fstest_SOURCES): Likewise.
+	(udf_mod_SOURCES): New variable.
+	(udf_mod_CFLAGS): Likewise.
+	(udf_mod_LDFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/udf.c.
+	(grub_emu_SOURCES): Likewise.
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+	* fs/udf.c: New file.
+
+2008-02-24  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-efi.rmk (normal/function.c_DEPENDENCIES)
+	(normal/lexer.c_DEPENDENCIES): New variables.
+	* conf/i386-ieee1275.rmk (normal/function.c_DEPENDENCIES)
+	(normal/lexer.c_DEPENDENCIES): Likewise.
+	* conf/i386-linuxbios.rmk (normal/function.c_DEPENDENCIES)
+	(normal/lexer.c_DEPENDENCIES): Likewise.
+	* conf/i386-pc.rmk (normal/function.c_DEPENDENCIES)
+	(normal/lexer.c_DEPENDENCIES): Likewise.
+	* conf/powerpc-ieee1275.rmk (normal/function.c_DEPENDENCIES)
+	(normal/lexer.c_DEPENDENCIES): Likewise.
+	* conf/sparc64-ieee1275.rmk (normal/function.c_DEPENDENCIES)
+	(normal/lexer.c_DEPENDENCIES): Likewise.
+
+2008-02-23  Robert Millan  <rmh@aybabtu.com>
+
+	* partmap/gpt.c (grub_gpt_magic): Add `0x' qualifier to each member,
+	since they were intended to be in hex.  This didn't break previously
+	because of a bug in gpt_partition_map_iterate() (see below).
+
+	(gpt_partition_map_iterate): Replace `grub_memcmp' with `! grub_memcmp'
+	when checking the validity of GPT header.
+	Remove `partno', since it always provides the same information as `i'.
+
+2008-02-21  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* include/grub/efi/time.h: Fix a wrong comment.
+
+2008-02-19  Pavel Roskin  <proski@gnu.org>
+
+	* kern/rescue.c (grub_enter_rescue_mode): Improve initial
+	message.
+
+2008-02-19  Bean  <bean123ch@gmail.com>
+
+	* conf/i386-pc.rmk (pkglib_MODULES): Add aout.mod _bsd.mod and bsd.mod.
+	(aout_mod_SOURCES): New variable.
+	(aout_mod_CFLAGS): Likewise.
+	(aout_mod_LDFLAGS): Likewise.
+	(_bsd_mod_SOURCES): New variable.
+	(_bsd_mod_CFLAGS): Likewise.
+	(_bsd_mod_LDFLAGS): Likewise.
+	(bsd_mod_SOURCES): New variable.
+	(bsd_mod_CFLAGS): Likewise.
+	(bsd_mod_LDFLAGS): Likewise.
+
+	* include/grub/aout.h: New file.
+
+	* include/grub/i386/loader.h (grub_unix_real_boot): New function.
+
+	* include/grub/i386/bsd.h: New file.
+
+	* include/grub/i386/pc/init.h (grub_get_mmap_entry): Use EXPORT_FUNC
+	to make it public.
+
+	* kern/elf.c (grub_elf32_load): Get the physical address after the hook
+	function is called, so that it's possible to change it inside the hook.
+	(grub_elf64_load): Likewise.
+	(grub_elf_file): Don't close the file if elf header is not found.
+	(grub_elf_close): Close the file if grub_elf_file fails (The new
+	grub_elf_file won't close it).
+	(grub_elf32_size): Use NESTED_FUNC_ATTR for nested function calcsize.
+	(grub_elf64_size): Likewise.
+
+	* kern/i386/loader.S (grub_unix_real_boot): New function.
+
+	* loader/aout.c: New file.
+
+	* loader/i386/bsd.c: New file.
+
+	* loader/i386/bsd_normal.c: New file.
+
+	* loader/i386/pc/multiboot.c (grub_multiboot): Handle a.out format.
+
+	* loader/multiboot2.c (grub_multiboot2): Reset grub_errno so that it
+	can test other formats.
+
+2008-02-19  Robert Millan  <rmh@aybabtu.com>
+
+	* partmap/gpt.c: Include `<grub/gpt_partition.h>'.
+	(grub_gpt_partition_type_empty): Redefine with macro from
+	`<grub/gpt_partition.h>'.
+	(gpt_partition_map_iterate): Adjust partition type comparison.
+
+	Export `entry' as partmap-specific `part.data' struct.
+	(grub_gpt_header, grub_gpt_partentry): Move from here ...
+
+	* include/grub/gpt_partition.h (grub_gpt_header)
+	(grub_gpt_partentry): ... to here (new file).
+
+	* util/i386/pc/grub-setup.c: Include `<grub/gpt_partition.h>'.
+
+	(grub_gpt_partition_type_bios_boot): New const variable, defined
+	with macro from `<grub/gpt_partition.h>'.
+
+	(setup): Replace `first_start' with `embed_region', which keeps
+	track of the embed region (and is partmap-agnostic).
+
+	Replace find_first_partition_start() with find_usable_region(),
+	which finds a usable region for embedding using partmap-specific
+	knowledge (supports PC/MSDOS and GPT).
+
+	Fix all assumptions that the embed region start at sector 1, using
+	`embed_region.start' from now on.  Similarly, use `embed_region.end'
+	rather than `first_start' to calculate available size.
+
+	In grub_util_info() message, replace "into after the MBR" with an
+	indication of the specific sector our embed region starts at.
+
+2008-02-19  Robert Millan  <rmh@aybabtu.com>
+
+	* DISTLIST: Replace `commands/ieee1275/halt.c' and
+	`commands/ieee1275/reboot.c' with `commands/halt.c' and
+	`commands/reboot.c'.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES, reboot_mod_SOURCES)
+	(halt_mod_SOURCES): Likewise.
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES, reboot_mod_SOURCES)
+	(halt_mod_SOURCES): Likewise.
+
+2008-02-17  Christian Franke  <franke@computer.org>
+
+	* commands/cat.c (grub_cmd_cat): Add break on GRUB_TERM_ESC key.
+
+2008-02-17  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-setup.c (setup): In find_first_partition_start(),
+	set `first_start' to 0 for non-PC/MSDOS partition maps.
+
+2008-02-16  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-setup.c (setup): In find_first_partition_start(),
+	do not assume partition map is PC/MSDOS before performing checks that
+	are specific to that layout.
+
+2008-02-13  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-linuxbios.rmk (grub_emu_SOURCES): Remove
+	`commands/i386/pc/halt.c' and `commands/i386/pc/reboot.c'.
+	* kern/i386/linuxbios/init.c (grub_halt, grub_reboot): Remove stubs.
+
+2008-02-13  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.ac: Only a cosmetic change on the handling of
+	-fno-stack-protector.
+
+2008-02-12  Alexandre Boeglin  <alex@boeglin.org>
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Replace
+	commands/i386/pc/halt.c and reboot.c by commands/halt.c and
+	reboot.c.
+	(grub_install_SOURCES): Add halt.mod and reboot.mod.
+	(halt_mod_SOURCES): New variable.
+	(halt_mod_CFLAGS): Likewise.
+	(halt_mod_LDFLAGS): Likewise.
+	(reboot_mod_SOURCES): Likewise.
+	(reboot_mod_CFLAGS): Likewise.
+	(reboot_mod_LDFLAGS): Likewise.
+
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Replace
+	commands/ieee1275/halt.c and reboot.c by commands/halt.c and
+	reboot.c.
+	(halt_mod_SOURCES): Likewise.
+	(reboot_mod_SOURCES): Likewise.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Replace
+	commands/i386/pc/reboot.c by commands/reboot.c.
+	(reboot_mod_SOURCES): Likewise.
+
+	* commands/i386/pc/reboot.c: merge this file ...
+
+	* commands/ieee1275/reboot.c: ... and this file ...
+
+	* commands/reboot.c: ... to this file.
+	Add some precompiler directive to include the correct header for
+	each machine.
+
+	* commands/ieee1275/halt.c: move this file ...
+
+	* commands/halt.c: ... to here.
+	Add some precompiler directive to include the correct header for
+	each machine.
+
+	* include/grub/efi/efi.h (grub_reboot): New function declaration.
+	(grub_halt): Likewise.
+
+	* kern/efi/efi.c (grub_reboot): New function.
+	(grub_halt): Likewise.
+
+2008-02-12  Robert Millan  <rmh@aybabtu.com>
+
+	* util/getroot.c (grub_guess_root_device): Inspect /dev/evms before
+	/dev (like it is done for /dev/mapper).  This doesn't provide support
+	for EVMS, but at least it is now easy to identify the problem when it
+	arises.
+
+2008-02-11  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (grub_util_biosdisk_open, linux_find_partition)
+	(grub_util_biosdisk_get_grub_dev): Check open() exit status by
+	comparing it with -1, not 0.
+
+2008-02-10  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Add `disk/raid.c' and
+	`disk/lvm.c'.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Likewise.
+
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Move `disk/raid.c' and
+	`disk/lvm.c' to the end of the list.
+	* conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Likewise.
+
+2008-02-10  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/main.c (grub_load_normal_mode): Do not reset `grub_errno'.  Call
+	grub_print_error() instead.  This will let user know why we're entering
+	rescue mode.
+	Based on suggestions from Sam Morris.
+
+2008-02-10  Alexandre Boeglin  <alex@boeglin.org>
+
+	* normal/arg.c (grub_arg_parse): If one of the args is "--", call add_arg()
+	on remaining N args, instead of "--" arg N times.
+
+2008-02-09  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* font/manager.c (unknown_glyph): Added variable for unknown glyph.
+	(fill_with_default_glyph): Changed to use unknown_glyph for fill
+	pattern for unknown glyphs.
+
+2008-02-09  Robert Millan  <rmh@aybabtu.com>
+
+	* configure.ac: Probe for `help2man'.
+	* Makefile.in (builddir): New variable.
+	(HELP2MAN): Likewise.  Set to `true' when @HELP2MAN@ doesn't provide it,
+	or otherwise add a few flags/options to it.
+	(install-local): For every executable utility or script that is
+	installed, invoke $(HELP2MAN) to install a manpage based on --help
+	output.
+
+	* util/i386/pc/grub-install.in: Move down `update-grub_lib' sourcing, so
+	that it doesn't prevent --help from working in build tree.
+
+	* util/i386/pc/grub-mkrescue.in (usage): Replace `grub-devel@gnu.org'
+	with `bug-grub@gnu.org'.
+	* util/powerpc/ieee1275/grub-mkrescue.in (usage): Likewise.
+	* util/update-grub.in (usage): New function.
+	Implement proper argument check, with support for --help and --version
+	(as well as existing -y).
+
+2008-02-09  Christian Franke  <franke@computer.org>
+
+	* commands/cat.c (grub_cmd_cat): Print '\r' as hex to
+	avoid overwriting previous output.
+	* kern/rescue.c (grub_rescue_cmd_cat): Likewise.
+
+2008-02-09  Robert Millan  <rmh@aybabtu.com>
+
+	* normal/menu.c (run_menu): If timeout is set to zero, don't bother
+	drawing the menu.
+
+2008-02-09  Robert Millan  <rmh@aybabtu.com>
+
+	* commands/sleep.c: New file.
+	* conf/common.rmk (pkglib_MODULES): Add `commands/sleep.c'.
+	(sleep_mod_SOURCES): New variable.
+	(sleep_mod_CFLAGS): Likewise.
+	(sleep_mod_LDFLAGS): Likewise.
+
+2008-02-09  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/raid.c (grub_raid_scan_device): Add a pair of sanity checks for
+	situations in which we can deduce the RAID size and the superblock
+	doesn't match it.
+
+2008-02-09  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/lvm.c [GRUB_UTIL] (grub_lvm_memberlist): New function.  Construct
+	and return a grub_diskmemberlist_t composed of LVM physical volumes.
+	[GRUB_UTIL] (grub_lvm_dev): Add `memberlist' member.
+
+	* disk/raid.c [GRUB_UTIL] (grub_raid_memberlist): New function.  Construct
+	and return a grub_diskmemberlist_t composed of physical array members.
+	[GRUB_UTIL] (grub_raid_dev): Add `memberlist' member.
+
+	* include/grub/disk.h [GRUB_UTIL] (grub_disk_memberlist): New struct
+	prototype.
+	[GRUB_UTIL] (struct grub_disk_dev): Add `memberlist' function pointer.
+	[GRUB_UTIL] (struct grub_disk_memberlist): New struct declaration.
+	[GRUB_UTIL] (grub_disk_memberlist_t): New typedef.
+
+	* util/grub-probe.c (probe): Move partmap probing code from here ...
+	(probe_partmap): ... to here.
+	(probe): Use probe_partmap() once for the disk we're probing, and
+	additionally, when such disk contains a memberlist() struct member,
+	once for each disk that is contained in the structure returned by
+	memberlist().
+
+2008-02-09  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub-probe.c (main): When `verbosity > 1', set `debug'
+	environment variable to 'all' in order to obtain debug output from
+	non-util/ code.
+	* util/i386/pc/grub-setup.c (main): Likewise.
+
+2008-02-08  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/raid.c (grub_raid_scan_device): Check for
+	`array->device[sb.this_disk.number]' rather than for
+	`array->device[sb.this_disk.number]->name', since the latter is not
+	guaranteed to be accessible.
+
+2008-02-08  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/raid.c: Update copyright.
+	* fs/cpio.c: Likewise.
+	* include/grub/raid.h: Likewise.
+	* loader/i386/pc/multiboot.c: Likewise.
+	* util/hostfs.c: Likewise.
+
+2008-02-08  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/raid.h (struct grub_raid_array): Change type of `device'
+	to a grub_disk_t array.
+	* disk/raid.c (grub_raid_read): Replace `device[x].disk' accesses with
+	`device[x]'.
+	(grub_raid_scan_device): Replace `device[x].name' accesses with
+	`device[x]->name'.  Simplify initialization of `array->device[x]'.
+
+2008-02-08  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/raid.c (grub_raid_open, grub_raid_scan_device): Add a few
+	grub_dprintf() calls.
+	* kern/disk.c (grub_disk_read): Include grub_errmsg in out of range
+	error message.
+
+2008-02-07  Christian Franke  <franke@computer.org>
+
+	* util/hostfs.c (grub_hostfs_open): Use fseeko and ftello
+	instead of fseek and ftell to support large files.
+	(grub_hostfs_read): Likewise.
+
+2008-02-07  Robert Millan  <rmh@aybabtu.com>
+
+	Patch from Jeroen Dekkers.
+	* disk/raid.c (grub_raid_scan_device): Reset `grub_errno' on disk
+	failure, since successfully reading all array members might not be
+	required.
+
+2008-02-06  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub-probe.c (probe): Simplify partmap probing (with the
+	assumption that the first word up to the underscore equals to
+	the module name).
+
+2008-02-06  Christian Franke  <franke@computer.org>
+
+	* fs/cpio.c (grub_cpio_find_file): Return GRUB_ERR_NONE
+	(and set *ofs = 0) instead of GRUB_ERR_FILE_NOT_FOUND on
+	last block of a cpio or tar stream.
+	Check for "TRAILER!!!" instead of any empty data
+	block to detect last block of a cpio stream.
+	(grub_cpio_dir): Fix constness of variable np.
+	(grub_cpio_open): Return GRUB_ERR_FILE_NOT_FOUND if
+	cpio or tar trailer is detected.  This fixes a crash
+	on open of a non existing file.
+
+2008-02-05  Bean  <bean123ch@gmail.com>
+
+	* loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Get physical
+	address of entry.
+	(grub_multiboot_load_elf64): Likewise.
+	(grub_multiboot): Initialize mbi structure.
+
+	* util/grub-fstest.c: Don't include unused header file script.h.
+
+	* conf/common.rmk (grub-fstest.c_DEPENDENCIES): Move to the beginning
+	of file.
+	(grub_fstest_SOURCES): Likewise.
+
+2008-02-05  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/term.h (GRUB_TERM_LEFT, GRUB_TERM_RIGHT)
+	(GRUB_TERM_UP, GRUB_TERM_DOWN, GRUB_TERM_HOME, GRUB_TERM_END)
+	(GRUB_TERM_DC, GRUB_TERM_PPAGE, GRUB_TERM_NPAGE, GRUB_TERM_ESC)
+	(GRUB_TERM_TAB, GRUB_TERM_BACKSPACE): New macros.
+
+	* kern/i386/pc/startup.S: Include `<grub/term.h>'.
+	(translation_table): Replace hardcoded values with macros
+	provided by `<grub/term.h>'.
+
+	* term/i386/pc/at_keyboard.c: Include `<grub/term.h>'.
+	(keyboard_map): Correct/add a few values, with macros provided
+	by `<grub/term.h>'.
+	(keyboard_map_shift): Zero values that don't differ from their
+	`keyboard_map' equivalents.
+	(grub_console_checkkey): Optimize KEYBOARD_STATUS_CAPS_LOCK toggling.
+	Discard the second scan code that is always sent by Caps lock.
+	Only use `keyboard_map_shift' when it provides a non-zero value,
+	otherwise fallback to `keyboard_map'.
+
+2008-02-04  Bean  <bean123ch@gmail.com>
+
+	* Makefile.in (enable_grub_fstest): New variable.
+
+	* conf/common.rmk (grub_fstest_init.lst): New rule.
+	(grub_fstest_init.h): Likewise.
+	(grub_fstest_init.c): Likewise.
+	(util/grub-fstest.c_DEPENDENCIES): New variable.
+	(grub_fstest_SOURCES): Likewise.
+
+	* configure.ac (enable_grub_fstest): Check for --enable-grub-fstest.
+
+	* util/grub-fstest.c: New file.
+
+2008-02-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Make grub-setup handle a separate root device.
+
+	* util/i386/pc/grub-setup.c (setup): Always open the root device,
+	so that the root device can be compared with the destination
+	device.
+	When embedding the core image, if the root and destination devices
+	are different, set ROOT_DRIVE to ROOT_DEV->DISK->ID. Otherwise, to
+	0xFF.
+	When not embedding, set ROOT_DRIVE to 0xFF.
+
+2008-02-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Add support for having a grub directory in a different drive. This
+	is still only the data handling part.
+
+	* kern/i386/pc/startup.S (multiboot_trampoline): Set %dh to 0xFF.
+	(codestart): Save %dh in GRUB_ROOT_DRIVE.
+	(grub_root_drive): New variable.
+
+	* kern/i386/pc/init.c (make_install_device): Use GRUB_ROOT_DRIVE
+	instead of GRUB_BOOT_DRIVE to construct a device name. Set
+	GRUB_ROOT_DRIVE to GRUB_BOOT_DRIVE if it is 0xFF, otherwise use it
+	as it was.
+
+	* include/grub/i386/pc/kernel.h (grub_root_drive): New prototype.
+
+	* include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_ROOT_DRIVE): New
+	macro.
+	(GRUB_BOOT_MACHINE_DRIVE_CHECK): Set to 0x4f.
+
+	* boot/i386/pc/pxeboot.S (_start): Set %dh to 0xFF. For now, this
+	is bogus, because PXE booting does not specify any drive
+	correctly.
+
+	* boot/i386/pc/lnxboot.S (reg_edx): Set the second byte to 0xFF. I
+	am not sure if this is really correct.
+
+	* boot/i386/pc/cdboot.S: Set %dh to 0xFF, because the root drive
+	is always identical to the boot drive when booting from a CD.
+
+	* boot/i386/pc/boot.S (MOV_MEM_TO_AL): Removed. Not needed any
+	longer.
+	(root_drive): New variable.
+	(real_start): Unconditionally set %dh to ROOT_DRIVE.
+	(setup_sectors): Push %dx right after popping it, because %dh will
+	be modified later.
+	(copy_buffer): Restore %dx.
+
+2008-02-03  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-mkrescue.in: Rewrite most of image generation to
+	use `cdboot.img' for cdrom images.
+
+2008-02-03  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/00_header.in: Issue scripting commands for GRUB to
+	only setup gfxterm when `font' command has succeeded.
+
+2008-02-03  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/multiboot_loader.c [GRUB_MACHINE_LINUXBIOS]
+	(grub_rescue_cmd_multiboot_loader)
+	(grub_rescue_cmd_module_loader): Enable multiboot1 calls.
+
+2008-02-03  Pavel Roskin  <proski@gnu.org>
+
+	* kern/i386/pc/startup.S (grub_chainloader_real_boot): Pop
+	%edx and %esi from stack only after grub_gate_a20() is called.
+	grub_gate_a20() clobbers %edx.
+
+2008-02-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.ac (AC_INIT): Bumped to 1.96.
+
+	* DISTLIST: Added boot/i386/pc/cdboot.S, bus/pci.c,
+	commands/lspci.c,disk/memdisk.c, include/grub/pci.h,
+	include/grub/i386/pc/pci.h, video/readers/jpeg.c, and
+	video/readers/png.c.
+
+2008-02-03  Bean  <bean123ch@gmail.com>
+
+	* conf/i386-pc.rmk (pkglib_IMAGES): Add cdboot.img.
+	(cdboot_img_SOURCES): New variable.
+	(cdboot_img_ASFLAGS): New variable.
+	(cdboot_img_LDFLAGS): New variable.
+
+	* boot/i386/pc/cdboot.S: New file.
+
+	* disk/i386/pc/biosdisk.c (cd_start): New variable.
+	(cd_count): Likewise.
+	(grub_biosdisk_get_drive): Add support for cd device.
+	(grub_biosdisk_call_hook): Likewise.
+	(grub_biosdisk_iterate): Likewise.
+	(grub_biosdisk_open): Likewise.
+	(GRUB_BIOSDISK_CDROM_RETRY_COUNT): New macro.
+	(grub_biosdisk_rw): Support reading from cd device.
+	(GRUB_MOD_INIT): Iterate cd devices.
+
+	* include/grub/i386/pc/biosdisk.h (GRUB_BIOSDISK_FLAG_CDROM): New macro.
+	(GRUB_BIOSDISK_MACHINE_CDROM_START): Likewise.
+	(GRUB_BIOSDISK_MACHINE_CDROM_END): Likewise.
+
+	* kern/i386/pc/init.c (make_install_device): Check for cd device.
+
+2008-02-02  Robert Millan  <rmh@aybabtu.com>
+
+	* commands/read.c: New file.
+	* conf/common.rmk (pkglib_MODULES): Add `commands/read.c'.
+	(read_mod_SOURCES): New variable.
+	(read_mod_CFLAGS): Likewise.
+	(read_mod_LDFLAGS): Likewise.
+
+2008-02-02  Robert Millan  <rmh@aybabtu.com>
+
+	* normal/main.c (grub_normal_execute): Check for `menu->size' when
+	determining whether menu has to be displayed.
+
+2008-02-02  Marco Gerards  <marco@gnu.org>
+
+	* bus/pci.c: New file.
+
+	* include/grub/pci.h: Likewise.
+
+	* include/grub/i386/pc/pci.h: Likewise.
+
+	* commands/lspci.c: Likewise.
+
+	* conf/i386-pc.rmk (pkglib_MODULES): Add `pci.mod' and
+	`lspci.mod'.
+	(pci_mod_SOURCES): New variable.
+	(pci_mod_CFLAGS): Likewise.
+	(pci_mod_LDFLAGS): Likewise.
+	(lspci_mod_SOURCES): Likewise.
+	(lspci_mod_CFLAGS): Likewise.
+	(lspci_mod_LDFLAGS): Likewise.
+
+2008-02-02  Bean  <bean123ch@gmail.com>
+
+	* fs/ufs.c (INODE_BLKSZ): Fix incorrect value.
+	(grub_ufs_get_file_block): Fix indirect block calculation problem.
+
+	* fs/xfs.c (grub_xfs_sblock): New member log2_dirblk.
+	(grub_xfs_btree_node): New structure.
+	(grub_xfs_btree_root): New structure.
+	(grub_xfs_inode): New members nblocks, extsize, nextents and btree.
+	(GRUB_XFS_EXTENT_OFFSET): Use exts instead of inode->data.extents.
+	(GRUB_XFS_EXTENT_BLOCK): Likewise.
+	(GRUB_XFS_EXTENT_SIZE): Likewise.
+	(grub_xfs_read_block): Support btree format type.
+	(grub_xfs_iterate_dir): Use NESTED_FUNC_ATTR in call_hook.
+	Use directory block as basic unit.
+
+	* fs/fshelp.c (grub_fshelp_read_file): Bug fix for sparse block.
+
+	* aclocal.m4 (grub_i386_CHECK_REGPARM_BUG): Define NESTED_FUNC_ATTR as
+	__attribute__ ((__regparm__ (1))).
+
+2008-02-01  Robert Millan  <rmh@aybabtu.com>
+
+	Correct a mistake in previous commit.
+
+	* conf/i386-pc.rmk (normal/execute.c_DEPENDENCIES): Move to the
+	top.
+	(normal/command.c_DEPENDENCIES): New variable.
+
+2008-02-01  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-efi.rmk (normal/execute.c_DEPENDENCIES): Move to the
+	top.
+	(normal/command.c_DEPENDENCIES): New variable.
+	(grub-emu_DEPENDENCIES, normal_mod_DEPENDENCIES): Remove variables.
+	* conf/i386-ieee1275.rmk: Likewise.
+	* conf/i386-linuxbios.rmk: Likewise.
+	* conf/i386-pc.rmk: Likewise.
+	* conf/sparc64-ieee1275.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	(grub_emu_SOURCES): Add `fs/fshelp.c'.
+
+	* genmk.rb: Add `$(#{src}_DEPENDENCIES)' in targets that require it.
+
+2008-02-01  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/disk.c (grub_disk_read, grub_disk_write): Add grub_dprintf()
+	call at beginning of function.
+
+2008-01-31  Pavel Roskin  <proski@gnu.org>
+
+	* util/powerpc/ieee1275/grub-mkrescue.in: New file.
+	* conf/powerpc-ieee1275.rmk (bin_SCRIPTS): New variable.
+	(grub_mkrescue_SOURCES): Likewise.
+	* DISTLIST: Add util/powerpc/ieee1275/grub-mkrescue.in.
+
+2008-01-30  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-pc.rmk (sbin_UTILITIES): Remove `grub-probe'.
+	(util/grub-probe.c_DEPENDENCIES, grub_probe_SOURCES): Moved from here ...
+	* conf/common.rmk (util/grub-probe.c_DEPENDENCIES)
+	(grub_probe_SOURCES): ... to here.
+
+	* conf/i386-efi.rmk (sbin_UTILITIES): Remove `grub-probe'.
+	(util/grub-probe.c_DEPENDENCIES, grub_probe_SOURCES): Remove.
+	* conf/i386-ieee1275.rmk: Likewise.
+	* conf/i386-linuxbios.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+
+2008-01-30  Tristan Gingold  <gingold@free.fr>
+
+	* kern/rescue.c: Silently accept empty lines.
+
+2008-01-29  Bean  <bean123ch@gmail.com>
+
+	* boot/i386/pc/lnxboot.S (data_start): Code cleanup.
+	(real_code_2): Code cleanup and change comment style.
+	(move_memory): Avoid using 32-bit address mode.
+
+2008-01-29  Bean  <bean123ch@gmail.com>
+
+	* conf/i386-pc.rmk (pkglib_MODULES): Add `png.mod'.
+	(png_mod_SOURCES): New variable.
+	(png_mod_CFLAGS): Likewise.
+	(png_mod_LDFLAGS): Likewise.
+
+	* video/readers/png.c: New file.
+
+2008-01-28  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/linuxbios/kernel.h (GRUB_MOD_GAP): New macro.
+	* kern/powerpc/ieee1275/init.c (grub_arch_modules_addr): Remove
+	`ifndef GRUB_MOD_GAP' hack.
+	* util/elf/grub-mkimage.c (add_segments): Likewise.
+
+2008-01-27  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/powerpc/ieee1275/init.c (grub_arch_modules_addr): Skip
+	`GRUB_MOD_GAP' for platforms in which it's not defined.
+	* util/elf/grub-mkimage.c (add_segments): Likewise.
+
+2008-01-27  Robert Millan  <rmh@aybabtu.com>
+
+	Get grub-emu to build again (including parallel builds).
+
+	* conf/i386-pc.rmk (util/grub-emu.c_DEPENDENCIES): Remove variable.
+	Split into ...
+	(util/grub-emu.c_DEPENDENCIES): ... this, ...
+	(normal/execute.c_DEPENDENCIES): ... this, ...
+	(grub-emu_DEPENDENCIES): ... and this.
+
+	* conf/i386-efi.rmk: Likewise.
+	* conf/i386-linuxbios.rmk: Likewise.
+	* conf/i386-ieee1275.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	(grub_emu_SOURCES): Remove duplicated `kern/file.c'.
+
+2008-01-27  Robert Millan  <rmh@aybabtu.com>
+
+	* NEWS: Add a few items.
+
+2008-01-27  Robert Millan  <rmh@aybabtu.com>
+
+	Fix parallel builds with grub-emu.  Based on earlier commit for
+	grub-probe and grub-setup.
+
+	* conf/i386-pc.rmk (grub-emu_DEPENDENCIES): Renamed to ...
+	(util/grub-emu.c_DEPENDENCIES): ... this.
+	* conf/i386-efi.rmk (grub-emu_DEPENDENCIES): Renamed to ...
+	(util/grub-emu.c_DEPENDENCIES): ... this.
+	* conf/i386-linuxbios.rmk (grub-emu_DEPENDENCIES): Renamed to ...
+	(util/grub-emu.c_DEPENDENCIES): ... this.
+	* conf/i386-ieee1275.rmk (grub-emu_DEPENDENCIES): Renamed to ...
+	(util/grub-emu.c_DEPENDENCIES): ... this.
+	* conf/powerpc-ieee1275.rmk (grub-emu_DEPENDENCIES): Renamed to ...
+	(util/grub-emu.c_DEPENDENCIES): ... this.
+
+2008-01-27  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/powerpc/ieee1275/kernel.h: Introduce GRUB_MOD_GAP
+	to create a gap between _end and the modules added to the image
+	with grub-mkrescue.  That fixes "CLAIM failed" on PowerMAC.
+	* kern/powerpc/ieee1275/init.c: Use GRUB_MOD_GAP.
+	* util/elf/grub-mkimage.c (add_segments): Likewise.
+
+2008-01-26  Pavel Roskin  <proski@gnu.org>
+
+	* kern/dl.c (grub_dl_load): Don't abort if prefix is not set,
+	just return an error.
+
+2008-01-26  Bean  <bean123ch@gmail.com>
+
+	* fs/reiserfs.c (grub_fshelp_node): New member next_offset.
+	(grub_reiserfs_get_item): Save offset of the next item.
+	(grub_reiserfs_iterate_dir): Use next_offset to find next item.
+
+2008-01-25  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-pc.rmk (grub_setup_SOURCES, grub_emu_SOURCES): Regroup to
+	make all filesystem sources appear together (possibly fixing omissions
+	while at it).
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	* conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/i386-pc.rmk (grub_probe_SOURCES): Likewise.  Additionally,
+	add `kern/file.c'.
+	* conf/i386-efi.rmk (grub_probe_SOURCES): Likewise.
+	* conf/i386-ieee1275.rmk (grub_probe_SOURCES): Likewise.
+	* conf/i386-linuxbios.rmk (grub_probe_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_probe_SOURCES): Likewise.
+
+	* util/grub-probe.c: Include `<grub/file.h>' and `<sys/stat.h>'.
+	(probe): Add a sanity check to make sure of our ability to read
+	requested files when probing for filesystem type.
+
+	* genmk.rb: Update copyright year (2007).
+
+	* include/grub/fs.h (grub_fat_init, grub_fat_fini, grub_ext2_init)
+	(grub_ext2_fini, grub_ufs_init, grub_ufs_fini, grub_minix_init)
+	(grub_minix_fini, grub_hfs_init, grub_hfs_fini, grub_jfs_init)
+	(grub_jfs_fini, grub_xfs_init, grub_xfs_fini, grub_affs_init)
+	(grub_affs_fini, grub_sfs_init, grub_sfs_fini, grub_iso9660_init)
+	: Remove function prototypes.
+
+2008-01-25  Robert Millan  <rmh@aybabtu.com>
+
+	Revert my previous commits (based on wrong assumption of how grub_errno
+	works).
+
+	* kern/disk.c (grub_disk_open): Stop resetting grub_errno.
+	* kern/file.c (grub_file_open): Likewise.
+
+2008-01-24  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/ieee1275/ieee1275.h: Introduce flag for firmwares
+	that hang if GRUB tries to setup colors.
+	* term/ieee1275/ofconsole.c (grub_ofconsole_init): Don't set
+	colors for firmwares that don't support it.
+	* kern/powerpc/ieee1275/cmain.c (grub_ieee1275_set_flag):
+	Recognize Open Hack'Ware, set flags to work around its
+	limitations.
+
+2008-01-24  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/file.c (grub_file_open): Do not account previous failures of
+	unrelated functions when grub_errno is checked for.
+	Reported by Oleg Strikov.
+
+2008-01-24  Bean  <bean123ch@gmail.com>
+
+	* fs/ufs.c (GRUB_UFS_VOLNAME_LEN): New macro.
+	(grub_ufs_sblock): New member volume name.
+	(grub_ufs_find_file): Fix string copy bug.
+	(grub_ufs_label): Implement this function properly.
+
+	* fs/hfs.c (grub_hfs_cnid_type): New enum.
+	(grub_hfs_iterate_records): Use the correct file number for extents
+	and catalog file. Fix problem in next index calculation.
+	(grub_hfs_find_node): Replace recursive function call with loop.
+	(grub_hfs_iterate_dir): Replace recursive function call with loop.
+
+2008-01-23  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/ieee1275/loader.h: Include `<grub/types.h>',
+	`<grub/symbol.h>' and `<grub/multiboot.h>'.
+	(grub_multiboot2_real_boot): New function prototype.
+
+	* include/grub/i386/pc/memory.h: Include `<grub/machine/machine.h>'.
+	[!GRUB_MACHINE_IEEE1275] (grub_lower_mem, grub_upper_mem): Disable.
+
+	* kern/i386/ieee1275/init.c (grub_os_area_addr)
+	(grub_os_area_size, grub_lower_mem, grub_upper_mem): Remove variables.
+
+2008-01-23  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/mm.c (grub_mm_init_region): Replace grub_dprintf() call with
+	#ifdef'ed out grub_printf().
+
+2008-01-23  Robert Millan  <rmh@aybabtu.com>
+
+	* term/i386/pc/at_keyboard.c (grub_keyboard_isr): #ifdef out
+	grub_dprintf calls, since they make "debug=all" mode unusable.
+	(grub_console_checkkey): Likewise.
+
+2008-01-23  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add
+	`term/i386/pc/at_keyboard.c'.
+	(pkglib_MODULES): Add `serial.mod'.
+	(serial_mod_SOURCES): New variable.
+	(serial_mod_CFLAGS): Likewise.
+	(serial_mod_LDFLAGS): Likewise.
+
+	* include/grub/i386/ieee1275/console.h: Add `<grub/symbol.h>'.  Remove
+	`<grub/powerpc/ieee1275/console.h>'.
+	(grub_keyboard_controller_init): New function prototype.
+	(grub_console_checkkey): Likewise.
+	(grub_console_getkey): Likewise.
+
+	* kern/powerpc/ieee1275/init.c (grub_machine_init): Initialize AT
+	keyboard on i386.
+
+	* term/ieee1275/ofconsole.c (grub_ofconsole_term): On i386, use
+	grub_ofconsole_checkkey() and grub_ofconsole_getkey() for input.
+
+2008-01-23  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/i386/pc/init.c (make_install_device): When memdisk image is
+	present, "(memdisk)/boot/grub" becomes the default prefix.
+
+	* util/i386/pc/grub-mkrescue.in: Switch to a minimal core.img plus
+	a memdisk tarball with all the modules.  Add --overlay=DIR option that
+	allows users to overlay additional files into the image.
+
+2008-01-23  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add `machine/loader.h'
+	and `machine/memory.h'.
+	(pkglib_MODULES): Add `multiboot.mod' and `_multiboot.mod'.
+	(_multiboot_mod_SOURCES): New variable.
+	(_multiboot_mod_CFLAGS): Likewise.
+	(_multiboot_mod_LDFLAGS): Likewise.
+	(multiboot_mod_SOURCES): Likewise.
+	(multiboot_mod_CFLAGS): Likewise.
+	(multiboot_mod_LDFLAGS): Likewise.
+
+	* include/grub/i386/ieee1275/loader.h: New file.
+
+	* include/grub/i386/ieee1275/machine.h: Likewise.
+
+	* include/grub/i386/ieee1275/memory.h: Likewise.
+
+	* include/grub/i386/pc/init.h (grub_os_area_addr): Remove (redundant)
+	variable declaration.
+	(grub_os_area_size): Likewise.
+
+	* kern/i386/ieee1275/init.c (grub_os_area_addr, grub_os_area_size)
+	(grub_lower_mem, grub_upper_mem): New variables.
+	(grub_stop_floppy): New function (just to make
+	grub_multiboot2_real_boot() happy).
+
+	* kern/i386/ieee1275/startup.S: Include `<grub/machine/memory.h>',
+	`<grub/cpu/linux.h>', `<multiboot.h>' and `<multiboot2.h>'.
+	(grub_stop): New function.
+	Include `"../realmode.S"' and `"../loader.S"'.
+
+	* loader/multiboot_loader.c: Include `<grub/machine/machine.h>'.
+	Replace `__i386__' #ifdefs with `GRUB_MACHINE_PCBIOS'.
+
+	* loader/powerpc/ieee1275/multiboot2.c (grub_mb2_arch_boot): On i386,
+	rely on grub_multiboot2_real_boot() for final boot.
+
+2008-01-22  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): When
+	`GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' flag is set, skip any
+	device that doesn't look like an SD card.
+	* include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): Add
+	`GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' flag.
+	* kern/powerpc/ieee1275/cmain.c (grub_ieee1275_set_flag): Detect
+	OLPC laptop, and set `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' when
+	found.
+
+2008-01-22  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/powerpc/ieee1275/init.c (grub_claim_heap): Add sanity check to
+	avoid claiming over our own code.
+
+2008-01-22  Bean  <bean123ch@gmail.com>
+
+	* conf/i386-pc.rmk (pkglib_MODULES): Add `jpeg.mod'.
+	(jpeg_mod_SOURCES): New variable.
+	(jpeg_mod_CFLAGS): Likewise.
+	(jpeg_mod_LDFLAGS): Likewise.
+
+	* video/readers/jpeg.c : New file.
+
+2008-01-22  Bean  <bean123ch@gmail.com>
+
+	* fs/cpio.c (grub_cpio_find_file): Return GRUB_ERR_FILE_NOT_FOUND when
+	there are no more items.
+
+2008-01-21  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/mm.c (grub_mm_init_region): Improve debug message.
+
+2008-01-21  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-pc.rmk (GRUB_MEMORY_MACHINE_LINK_ADDR): New variable.
+	(kernel_img_LDFLAGS): Use `GRUB_MEMORY_MACHINE_LINK_ADDR' as link
+	address.
+	(grub_mkimage_CFLAGS): Propagate `GRUB_MEMORY_MACHINE_LINK_ADDR' as
+	a C macro.
+	* include/grub/i386/pc/memory.h (GRUB_MEMORY_MACHINE_UPPER): New macro.
+	Indicates start of upper memory.
+	* util/i386/pc/grub-mkimage.c: Include `<grub/machine/memory.h>'.
+	(generate_image): Abort when image size is big enough to corrupt
+	upper memory.
+
+	* include/grub/i386/pc/vga.h: Include `<grub/machine/memory.h>'.
+	(GRUB_MEMORY_MACHINE_VGA_ADDR): Alias for `GRUB_MEMORY_MACHINE_UPPER'.
+	* term/i386/pc/vga.c (VGA_MEM): Use `GRUB_MEMORY_MACHINE_VGA_ADDR'
+	instead of hardcoding 0xA0000.
+	* video/i386/pc/vbe.c: Include `<grub/machine/vga.h>'.
+	(grub_vbe_set_video_mode): Use `GRUB_MEMORY_MACHINE_VGA_ADDR'
+	instead of hardcoding 0xA0000.
+
+2008-01-21  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/memdisk.c (memdisk_size): New variable.
+	(grub_memdisk_open): Replace grub_arch_memdisk_size() call with
+	`memdisk_size'.
+	(grub_memdisk_init): Initialize `memdisk_size'.  Reallocate memdisk
+	image to dynamic memory.
+	(grub_memdisk_fini): Replace grub_arch_memdisk_size() call with
+	`memdisk_size'.  Free memdisk block.
+
+2008-01-21  Robert Millan  <rmh@aybabtu.com>
+
+	Fix detection of very small filesystems (like tar).
+
+	* fs/reiserfs.c (grub_reiserfs_mount): When disk is too small to
+	contain a ReiserFS, abort with GRUB_ERR_BAD_FS rather than
+	GRUB_ERR_OUT_OF_RANGE (which made the upper layer think there's
+	a problem with this disk).
+
+2008-01-21  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/i386/pc/biosdisk.c (grub_biosdisk_iterate): Add debug message
+	on grub_biosdisk_rw_standard() error.
+
+2008-01-21  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/ieee1275/ieee1275.h: Add 2008 to Copyright line for
+	recent changes.
+	* kern/elf.c: Likewise.
+	* kern/ieee1275/ieee1275.c: Likewise.
+	* kern/powerpc/ieee1275/openfw.c: Likewise.
+	* term/ieee1275/ofconsole.c: Likewise.
+
+2008-01-21  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/pc/kernel.h: Include `<grub/symbol.h>'.
+
+	* include/grub/kernel.h (grub_arch_memdisk_addr)
+	(grub_arch_memdisk_size): Moved from here ...
+
+	* include/grub/i386/pc/kernel.h (grub_arch_memdisk_addr)
+	(grub_arch_memdisk_size): ... to here.
+
+2008-01-21  Robert Millan  <rmh@aybabtu.com>
+
+	Mostly based on bugfix from Bean.
+
+	* kern/elf.c (grub_elf32_phdr_iterate): Use `NESTED_FUNC_ATTR'
+	attribute with hook() parameter.
+	(grub_elf32_load): Use `NESTED_FUNC_ATTR' with grub_elf32_load_segment()
+	declaration.
+	(grub_elf64_phdr_iterate): Use `NESTED_FUNC_ATTR'
+	attribute with hook() parameter.
+	(grub_elf64_load): Use `NESTED_FUNC_ATTR' with grub_elf64_load_segment()
+	declaration.
+
+2008-01-21  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-pc.rmk (kernel_img_HEADERS): Add `machine/kernel.h'.
+	(pkglib_MODULES): Add `memdisk.mod'.
+	(memdisk_mod_SOURCES): New variable.
+	(memdisk_mod_CFLAGS): Likewise.
+	(memdisk_mod_LDFLAGS): Likewise.
+
+	* disk/memdisk.c: New file.
+
+	* include/grub/disk.h (grub_disk_dev_id): Add
+	`GRUB_DISK_DEVICE_MEMDISK_ID'.
+
+	* include/grub/i386/pc/kernel.h
+	(GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE): New macro.
+	(GRUB_KERNEL_MACHINE_PREFIX): Increment by 4.
+	(grub_kernel_image_size): New variable declaration.
+	(grub_total_module_size): Likewise.
+	(grub_memdisk_image_size): Likewise.
+
+	* include/grub/i386/pc/memory.h
+	(GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR): New macro.
+
+	* include/grub/kernel.h: Include `<grub/symbol.h>'.
+	(grub_arch_memdisk_addr): New variable declaration.
+	(grub_arch_memdisk_size): Likewise.
+
+	* kern/i386/pc/init.c (grub_arch_memdisk_addr): New function.
+	(grub_arch_memdisk_size): Likewise.
+
+	* kern/i386/pc/startup.S (grub_memdisk_image_size): New variable.
+	(codestart): Replace hardcoded `0x100000' with
+	`GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR' macro.
+
+	* util/i386/pc/grub-mkimage.c: Include `<grub/misc.h>'.
+	(generate_image): Add `memdisk_path' parameter.  When `memdisk_path' is
+	not NULL, append the contents of the file it refers to, at the end of
+	the compressed kernel image.  Initialize `grub_memdisk_image_size'
+	variable (at `GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE' offset).
+	(options): Add "memdisk"|'m' option.
+	(main): Parse --memdisk|-m option, and pass user-provided path as
+	parameter to generate_image().
+
+2008-01-20  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/sparc64/ieee1275/openfw.c (grub_devalias_iterate): Copy debug
+	grub_dprintf() calls from here ...
+	* kern/powerpc/ieee1275/openfw.c (grub_devalias_iterate): ... to here.
+
+2008-01-20  Robert Millan  <rmh@aybabtu.com>
+
+	Fix detection of "real mode" when /options/real-mode? doesn't exist.
+
+	* include/grub/ieee1275/ieee1275.h (grub_ieee1275_mmu): New variable
+	declaration.
+	* kern/powerpc/ieee1275/cmain.c (grub_ieee1275_mmu): New variable.
+	(grub_ieee1275_find_options): If `grub_ieee1275_mmu' is 0, set
+	`GRUB_IEEE1275_FLAG_REAL_MODE'.
+	(cmain): Initialize `grub_ieee1275_mmu' (using /chosen/mmu integer
+	property).
+	* kern/powerpc/ieee1275/openfw.c (grub_map): Rely on pre-initialized
+	`grub_ieee1275_mmu' rather than obtaining a handler on every call.
+
+2008-01-19  Robert Millan  <rmh@aybabtu.com>
+
+	Get rid of confusing function (superseded by
+	`grub_ieee1275_get_integer_property')
+	* include/grub/ieee1275/ieee1275.h (grub_ieee1275_decode_int_4): Remove
+	prototype.
+	* kern/ieee1275/ieee1275.c (grub_ieee1275_decode_int_4): Remove
+	function.
+	* term/ieee1275/ofconsole.c (grub_ofconsole_init): Avoid use of
+	grub_ieee1275_decode_int_4(), by obtaining integer properties directly
+	in native endianness from grub_ieee1275_get_integer_property().
+
+2008-01-19  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/powerpc/ieee1275/openfw.c (grub_halt): Issue "power-off"
+	command after "shut-down", since implementations differ on which
+	the command for halt is.
+
+2008-01-19  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/linuxbios/console.h: Add header protection.
+	(grub_keyboard_controller_init): New function prototype.
+	* term/i386/pc/at_keyboard.c (KEYBOARD_COMMAND_ISREADY): New macro.
+	(KEYBOARD_COMMAND_READ): Likewise.
+	(KEYBOARD_COMMAND_WRITE): Likewise.
+	(KEYBOARD_SCANCODE_SET1): Likewise.
+	(grub_keyboard_controller_write): New function.
+	(grub_keyboard_controller_read): Likewise.
+	(grub_keyboard_controller_init): Likewise.
+
+	* term/i386/pc/console.c: Include `<grub/machine/machine.h>'.
+	(grub_console_init): On coreboot/LinuxBIOS, call
+	grub_keyboard_controller_init().
+
+2008-01-19  Robert Millan  <rmh@aybabtu.com>
+
+	PowerPC changes provided by Pavel Roskin.
+
+	* kern/powerpc/ieee1275/cmain.c (cmain): Don't take any arguments.
+	* kern/powerpc/ieee1275/crt0.S: Store r5 in grub_ieee1275_entry_fn,
+	don't rely on cmain() doing it.
+	* kern/i386/ieee1275/startup.S (_start): Store %eax in
+	grub_ieee1275_entry_fn, don't rely on cmain() doing it.
+
+2008-01-16  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/linuxbios/memory.h
+	(GRUB_MEMORY_MACHINE_LINUXBIOS_TABLE_ADDR): Remove macro.
+	* kern/i386/linuxbios/table.c (grub_linuxbios_table_iterate): Do not
+	receive `table_header' as argument.  Instead, probe for it in the
+	known memory ranges where it can be present.
+	(grub_available_iterate): Do not pass a fixed `table_header' address
+	to grub_linuxbios_table_iterate().
+
+2008-01-15  Robert Millan  <rmh@aybabtu.com>
+
+	* configure.ac: Add `i386-ieee1275' to the list of supported targets.
+	* conf/i386-ieee1275.rmk: New file.
+	* include/grub/i386/ieee1275/console.h: Likewise.
+	* include/grub/i386/ieee1275/ieee1275.h: Likewise.
+	* include/grub/i386/ieee1275/kernel.h: Likewise.
+	* include/grub/i386/ieee1275/time.h: Likewise.
+	* kern/i386/ieee1275/init.c: Likewise.
+	* kern/i386/ieee1275/startup.S: Likewise.
+
+2008-01-15  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/misc.c (grub_vsprintf): Do not reset `longlongfmt' to zero
+	when pointers are 32-bit (but still do set it to one when they are
+	64-bit).
+
+2008-01-15  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/ieee1275/ieee1275.h
+	(grub_ieee1275_get_integer_property): New function prototype.
+
+	* kern/ieee1275/ieee1275.c: Include `<grub/types.h>'.
+	(grub_ieee1275_get_integer_property): New function.  Wraps around
+	grub_ieee1275_get_property() to handle endianness.
+
+	* kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): Replace
+	grub_ieee1275_get_property() with grub_ieee1275_get_integer_property()
+	where appropriate.
+	* kern/powerpc/ieee1275/openfw.c (grub_available_iterate): Likewise.
+	(grub_map): Likewise.
+	* kern/sparc64/ieee1275/openfw.c (grub_map): Likewise.
+
+2008-01-15  Bean  <bean123ch@gmail.com>
+
+	* normal/execute.c (grub_script_exec_argument_to_string): Check for undefined variable.
+	(grub_script_execute_cmdline): Reset grub_errno.
+
+	* normal/main.c (read_config_file): Reset grub_errno.
+
+	* normal/parse.y (script_init): New.
+	(script): Move function and menuentry here.
+	(delimiter): New.
+	(command): Add delimiter at the end of command.
+	(commands): Adjust to match the new command.
+	(commandblock): Remove grub_script_lexer_record_start.
+	(menuentry): Add grub_script_lexer_record_start, use the new commands.
+	(if): Use the new commands.
+
+	* conf/common.rmk (pkgdata_MODULES): Add echo.mod.
+
+2008-01-15  Robert Millan  <rmh@aybabtu.com>
+
+	* normal/menu.c (run_menu): Move timeout message from here ...
+	(print_timeout): ... to here.
+	(run_menu): Use print_timeout() once during initial draw to print
+	the whole message, and again in every clock tick to update only
+	the number of seconds.
+
+2008-01-15  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/powerpc/ieee1275/openfw.c (grub_available_iterate): Obtain
+	actual size of `available' from grub_ieee1275_get_property(), and
+	restrict parsing to that bound.
+
+2008-01-15  Christian Franke  <franke@computer.org>
+
+	* util/grub-emu.c: Replace <argp.h> by <getopt.h>.
+	(argp_program_version): Remove variable.
+	(argp_program_bug_address): Likewise.
+	(options): Convert from struct argp_option to struct option.
+	(struct arguments): Remove.
+	(parse_opt): Remove.
+	(usage): New function.
+	(main): Replace struct args members by simple variables.
+	Replace argp_parse() by getopt_long().
+	Add switch to evaluate options.
+	Add missing "(...)" around root_dev in prefix string.
+
+2008-01-14  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/powerpc/ieee1275/init.c (grub_exit): Reimplement as a wrapper
+	for grub_ieee1275_exit(), in order to improve portability.
+
+2008-01-14  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/10_linux.in (prefix): Define.
+	(exec_prefix): Likewise.  Both definitions are later used by `libdir'.
+
+2008-01-13  Pavel Roskin  <proski@gnu.org>
+
+	* disk/ieee1275/ofdisk.c (grub_ofdisk_open): Don't use
+	grub_errno if no errors have been detected.
+
+2008-01-12  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/util/getroot.h (grub_dev_abstraction_types): New enum.
+	(grub_util_get_dev_abstraction): New function prototype.
+
+	* util/getroot.c: Include `<grub/util/getroot.h>'
+	(grub_util_get_grub_dev): Move detection of abstraction type to ...
+	(grub_util_get_dev_abstraction): ... here (new function).
+
+	* util/grub-probe.c: Convert PRINT_* to an enum.  Add
+	`PRINT_ABSTRACTION'.
+	(probe): Probe for abstraction type when requested.
+	(main): Understand `--target=abstraction'.
+
+	* util/i386/efi/grub-install.in: Add abstraction module to core
+	image when it is found to be necessary.
+	* util/i386/pc/grub-install.in: Likewise.
+	* util/powerpc/ieee1275/grub-install.in: Likewise.
+
+	* util/update-grub_lib.in (font_path): Return system path without
+	converting to GRUB path.
+	* util/update-grub.in: Convert system path returned by font_path()
+	to a GRUB path.  Use `grub-probe -t abstraction' to determine what
+	abstraction module is needed for loading fonts (if any).  Export
+	that as `GRUB_PRELOAD_MODULES'.
+	* util/grub.d/00_header.in: Process `GRUB_PRELOAD_MODULES' (print
+	insmod commands).
+
+2008-01-12  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Remove some unused code from reiserfs.
+
+	* fs/reiserfs.c (struct grub_reiserfs_key)
+	[GRUB_REISERFS_KEYV2_BITFIELD]: Removed offset and type.
+	(struct grub_reiserfs_node_body): Removed.
+	(grub_reiserfs_get_key_v2_type) [GRUB_REISERFS_KEYV2_BITFIELD]:
+	Likewise.
+	(grub_reiserfs_get_key_offset) [GRUB_REISERFS_KEYV2_BITFIELD]:
+	Likewise.
+	(grub_reiserfs_set_key_offset) [GRUB_REISERFS_KEYV2_BITFIELD]:
+	Likewise.
+	(grub_reiserfs_set_key_offset) [GRUB_REISERFS_KEYV2_BITFIELD]:
+	Likewise.
+	(grub_reiserfs_set_key_type) [GRUB_REISERFS_KEYV2_BITFIELD]:
+	Likewise.
+	(grub_reiserfs_iterate_dir) [GRUB_REISERFS_KEYV2_BITFIELD]:
+	Likewise.
+	(grub_reiserfs_open) [GRUB_REISERFS_KEYV2_BITFIELD]: Likewise.
+	(grub_reiserfs_read) [GRUB_REISERFS_KEYV2_BITFIELD]: Likewise.
+	(grub_reiserfs_dir) [GRUB_REISERFS_KEYV2_BITFIELD]: Likewise.
+
+2008-01-10  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in (grub_file_is_not_garbage): New function.
+	Determines if a file is garbage left by packaging systems, etc.
+	* util/update-grub.in: Use grub_file_is_not_garbage() as a condition
+	for processing /etc/grub.d scripts.
+	* util/grub.d/10_hurd.in: Fix `GRUB_DISTRIBUTOR' comparison.
+	* util/grub.d/10_linux.in: Likewise.  Use grub_file_is_not_garbage()
+	as a condition for processing Linux images.
+
+2008-01-10  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/powerpc/libgcc.h (__ucmpdi2): New export.  Needed
+	to compile reiserfs.c on PowerPC.
+
+2008-01-10  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/device.c (grub_device_iterate): Do not abort device iteration
+	when one of the devices cannot be opened.
+	* kern/disk.c (grub_disk_open): Do not account previous failures of
+	unrelated functions when grub_errno is checked for.
+
+2008-01-08  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/linux.c (grub_rescue_cmd_linux): For
+	`! grub_linux_is_bzimage', change order of address comparison to make
+	it more intuitive, and improve "too big zImage" error message.
+
+2008-01-08  Robert Millan  <rmh@aybabtu.com>
+
+	* Makefile.in (uninstall): Handle `$(update-grub_SCRIPTS)' and
+	`$(update-grub_DATA)'.
+	(distcheck): Fix race condition when invoking `$(MAKE)' on multiple
+	targets.
+
+2008-01-07  Robert Millan  <rmh@aybabtu.com>
+
+	* boot/i386/pc/boot.S (boot_drive_check): Add a comment indicating
+	which instruction is modified by grub-setup during installation
+	(since it wasn't obvious by only looking at this file).
+
+2008-01-07  Robert Millan  <rmh@aybabtu.com>
+
+	* TODO: Rewrite.  Just refer to the wiki and the BTS instead of
+	listing actual TODO items.
+
+2008-01-06  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* fs/reiserfs.c (grub_reiserfs_get_key_v2_type): Handle endianness
+	correctly.
+	(grub_reiserfs_get_key_offset): Likewise.
+	(grub_reiserfs_set_key_offset): Likewise.
+	(grub_reiserfs_set_key_type): Likewise.
+	(grub_reiserfs_iterate_dir): Return 1 if found, otherwise 0.
+
+	(GRUB_REISERFS_KEYV2_BITFIELD): Undefined. Probably it would be
+	better to remove the bitfield version completely.
+
+2008-01-06  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* fs/reiserfs.c (grub_reiserfs_iterate_dir): ENTRY_ITEM must be
+	allocated from the heap, due to the fshelp implementation.
+	(grub_reiserfs_dir): Free NODE, due to the same reason.
+
+2008-01-06  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Mostly from Vincent Pelletier:
+
+	* fs/reiserfs.c: New file.
+
+	* conf/common.rmk (pkglib_MODULES): Added reiserfs.mod.
+	(reiserfs_mod_SOURCES): New variable.
+	(reiserfs_mod_CFLAGS): Likewise.
+	(reiserfs_mod_LDFLAGS): Likewise.
+
+	* DISTLIST: Added boot/i386/pc/lnxboot.S, commands/hexdump.c,
+	disk/ata.c, fs/cpio.c, fs/ntfscomp.c, fs/reiserfs.c,
+	include/grub/ntfs.h, include/grub/i386/pc/machine.h, and
+	normal/color.c.
+
+2008-01-06  Robert Millan  <rmh@aybabtu.com>
+
+	* normal/color.c: Remove `<grub/env.h>'.
+
+2008-01-05  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* include/grub/normal.h: Include <grub/env.h>.
+
+2008-01-05  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-setup.c (usage): Replace obsolete `(hd0,0)' in
+	usage example with `(hd0,1)'.
+	Reported by Samuel Thibault.
+
+2008-01-05  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/i386/loader.S (grub_linux_is_bzimage): New variable.
+	(grub_linux_boot_zimage): Rename to ...
+	(grub_linux_boot): ... this.
+	(grub_linux_boot_bzimage): Merge with `grub_linux_boot_zimage'.
+	(grub_linux_boot_zimage): Conditionalize zImage copy.
+
+	* include/grub/i386/loader.h (grub_linux_is_bzimage): Add prototype.
+	(grub_linux_boot_bzimage): Remove prototype.
+	(grub_linux_boot_zimage): Rename to ...
+	(grub_linux_boot): ... this.
+
+	* loader/i386/pc/linux.c (big_linux): Replace with `grub_linux_is_bzimage'.
+	(grub_linux_boot): Remove function.
+
+2008-01-05  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/normal.h (grub_env_write_color_normal): New prototype.
+	(grub_env_write_color_highlight): Likewise.
+	(grub_wait_after_message): Likewise.
+
+	* normal/color.c: New file.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add `normal/color.c'.
+	(normal_mod_DEPENDENCIES): Likewise.
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Add `normal/color.c'.
+	(normal_mod_DEPENDENCIES): Likewise.
+
+	* conf/i386-linuxbios.rmk (grub_emu_SOURCES): Add `normal/color.c'.
+	(normal_mod_DEPENDENCIES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `normal/color.c'.
+	(normal_mod_DEPENDENCIES): Likewise.
+
+	* normal/menu_entry.c (run): Rely on grub_wait_after_message()
+	for waiting after a message is printed.
+	* normal/main.c (read_config_file): Likewise.
+	(grub_normal_init): Register grub_env_write_color_normal() and
+	grub_env_write_color_highlight() hooks.  Mark `color_normal' and
+	`color_highlight' variables as global.
+
+	* normal/menu.c (grub_wait_after_message): New function.
+	(grub_color_menu_normal): New variable.  Replaces ...
+	(GRUB_COLOR_MENU_NORMAL): ... this macro.
+	(grub_color_menu_highlight): New variable.  Replaces ...
+	(GRUB_COLOR_MENU_HIGHLIGHT): ... this macro.
+	(draw_border): Set color state to `GRUB_TERM_COLOR_NORMAL' instead of
+	`GRUB_TERM_COLOR_STANDARD'.
+	(print_message): Use `grub_setcolorstate' to reload colors.  Rename
+	`normal_code' and `highlight_code' to `old_color_normal' and
+	`old_color_highlight', respectively.
+	(grub_menu_init_page): Update colors when drawing the menu, based on
+	`menu_color_normal' and `menu_color_highlight' variables.
+	(grub_menu_run): Rely on grub_wait_after_message() for waiting after
+	a message is printed.
+
+2008-01-05  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/env.c (grub_env_context_open): Propagate hooks for global
+	variables to new context.
+
+	* kern/main.c (grub_set_root_dev): Export `root' variable.
+
+2008-01-05  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (get_os_disk): Check for devfs-style IDE and SCSI
+	discs unconditionally, since udev and others have options to provide
+	them.
+
+2008-01-05  Robert Millan  <rmh@aybabtu.com>
+
+	* normal/completion.c (iterate_dir): Skip `.' and `..' directories.
+
+2008-01-04  Christian Franke  <franke@computer.org>
+
+	* kern/i386/pc/init.c (grub_machine_init): Fix evaluation
+	of eisa_mmap.
+
+2008-01-03  Pavel Roskin  <proski@gnu.org>
+
+	* kern/i386/linuxbios/init.c: Put "void" to all function
+	declarations with no arguments.
+	* kern/powerpc/ieee1275/init.c: Likewise.
+	* term/i386/pc/at_keyboard.c: Likewise.
+	* term/i386/pc/vga_text.c: Likewise.
+	* util/grub-mkdevicemap.c: Likewise.
+
+2008-01-02  Robert Millan  <rmh@aybabtu.com>
+
+	* loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Improve error
+	message when loaded image is out of bounds.
+	(grub_multiboot_load_elf64): Likewise.
+
+2008-01-02  Pavel Roskin  <proski@gnu.org>
+
+	* util/grub.d/10_linux.in: Try version without ".old" when
+	looking for initrd.  It's better to use initrd from the newer
+	kernel of the same version than no initrd at all.
+
+2008-01-01  Robert Millan  <rmh@aybabtu.com>
+
+	* util/biosdisk.c (get_os_disk): Fix check for IDE or SCSI discs.
+
+2008-01-01  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* include/grub/video.h: Added grub_video_unmap_color and
+	grub_video_get_active_render_target.
+	(grub_video_adapter): Added unmap_color and get_active_render_target.
+
+	* video/video.c: Added grub_video_unmap_color and
+	grub_video_get_active_render_target.
+	(grub_video_get_info): Changed method to accept NULL pointer as an
+	argument to allow detection of active video adapter.
+
+	* video/i386/pc/vbe.c: Renamed grub_video_vbe_unmap_color as
+	grub_video_vbe_unmap_color_int.
+	Added grub_video_vbe_unmap_color and
+	grub_video_vbe_get_active_render_target.
+	(grub_video_vbe_adapter): Added unmap_color and
+	get_active_render_target.
+
+	* video/i386/pc/vbeblit.c: Replaced grub_video_vbe_unmap_color usage
+	with grub_video_vbe_unmap_color_int.
+
+	* term/gfxterm.c (DEFAULT_STANDARD_COLOR): Added.
+	(DEFAULT_NORMAL_COLOR): Likewise.
+	(DEFAULT_HIGHLIGHT_COLOR) Likewise.
+	(DEFAULT_FG_COLOR): Removed.
+	(DEFAULT_BG_COLOR): Likewise.
+	(DEFAULT_CURSOR_COLOR): Changed value.
+	(grub_virtual_screen): Added standard_color_setting,
+	normal_color_setting, highlight_color_setting and term_color.
+	(grub_virtual_screen): Removed fg_color_setting and bg_color_setting.
+	(bitmap_width): Added.
+	(bitmap_height): Likewise.
+	(bitmap): Likewise.
+	(set_term_color): Likewise.
+	(grub_virtual_screen_setup): Changed to use new terminal coloring
+	settings.
+	(grub_gfxterm_init): Added init for bitmap.
+	(grub_gfxterm_fini): Added destroy for bitmap.
+	(redraw_screen_rect): Updated to use background bitmap and new
+	terminal coloring.
+	(scroll_up): Added optimization for case when there is no bitmap.
+	(grub_gfxterm_cls): Fixed to use correct background color.
+	(grub_virtual_screen_setcolorstate): Changed to use new terminal
+	coloring.
+	(grub_virtual_screen_setcolor): Likewise.
+	(grub_virtual_screen_getcolor): Added.
+	(grub_gfxterm_background_image_cmd): Likewise.
+	(grub_video_term): Added setcolor and getcolor.
+	(MOD_INIT): Added registration of background_image command.
+	(MOD_TERM): Added unregistration for background_image command.
+
+2007-12-30  Pavel Roskin  <proski@gnu.org>
+
+	* loader/multiboot_loader.c: Fix multiboot command
+	unregistration.  Fix all typos in the word "multiboot".
+
+2007-12-29  Pavel Roskin  <proski@gnu.org>
+
+	* util/grub.d/10_linux.in: Refactor search for initrd.  Add
+	support for initrd names used in Fedora.
+
+2007-12-26  Bean  <bean123ch@gmail.com>
+
+	* conf/common.rmk (pkgdata_MODULES): Add cpio.mod.
+	(cpio_mod_SOURCES): New variable.
+	(cpio_mod_CFLAGS): Likewise.
+	(cpio_mod_LDFLAGS): Likewise.
+
+	* fs/cpio.c: New file.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add cpio.c.
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+2007-12-25  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/term.h (struct grub_term): Add `getcolor' function.
+	(grub_getcolor): New function.
+
+	* kern/term.c (grub_getcolor): New function.
+	* normal/menu.c (GRUB_COLOR_MENU_NORMAL): New macro.
+	(GRUB_COLOR_MENU_HIGHLIGHT): New macro.
+	(print_entry): Set normal and highlight colors to
+	`GRUB_COLOR_MENU_NORMAL' and `GRUB_COLOR_MENU_HIGHLIGHT',
+	respectively, before printing and restore them to old
+	values afterwards.
+	(grub_menu_init_page): Likewise.  Fill an additional colored space
+	that would otherwise be left blank.
+
+	* term/efi/console.c (grub_console_getcolor): New function.
+	(struct grub_console_term.getcolor): New variable.
+	* term/i386/pc/console.c (grub_console_getcolor): New function.
+	(struct grub_console_term.getcolor): New variable.
+	* term/ieee1275/ofconsole.c (grub_ofconsole_getcolor): New function.
+	(struct grub_console_term.getcolor): New variable.
+
+	* term/i386/pc/serial.c (grub_serial_setcolor): Remove function.
+	(struct grub_console_term.setcolor): Remove variable.
+	* term/i386/pc/vesafb.c (grub_virtual_screen_setcolor): Remove function.
+	(struct grub_console_term.setcolor): Remove variable.
+	* term/i386/pc/vga.c (grub_vga_setcolor): Remove function.
+	(struct grub_console_term.setcolor): Remove variable.
+	* term/gfxterm.c (grub_virtual_screen_setcolor): Remove function.
+	(struct grub_console_term.setcolor): Remove variable.
+
+2007-12-25  Robert Millan  <rmh@aybabtu.com>
+
+	* configure.ac: Search for possible unifont.hex locations, and
+	define UNIFONT_HEX if found.
+
+	* Makefile.in (UNIFONT_HEX): Define variable.
+	(DATA): Rename to ...
+	(PKGLIB): ... this.  Update all users.
+	(PKGDATA): New variable.
+	(pkgdata_IMAGES): Rename to ...
+	(pkglib_IMAGES): ... this. Update all users.
+	(pkgdata_MODULES): Rename to ...
+	(pkglib_MODULES): ... this. Update all users.
+	(pkgdata_PROGRAMS): Rename to ...
+	(pkglib_PROGRAMS): ... this. Update all users.
+	(pkgdata_DATA): Rename to ...
+	(pkglib_DATA): ... this. Update all users.
+	(CLEANFILES): Redefine to `$(pkglib_DATA) $(pkgdata_DATA)'.
+	(unicode.pff, ascii.pff): New rules.
+	(all-local): Add `$(PKGDATA)' dependency.
+	(install-local): Process `$(PKGDATA)'.
+
+	* util/update-grub_lib.in (font_path): Search for *.pff files in
+	a few more locations, including `${pkgdata}'.
+
+2007-12-23  Robert Millan  <rmh@aybabtu.com>
+
+	Patch from Bean  <bean123ch@gmail.com>:
+	* disk/loopback.c (grub_loopback_read): Add missing bit shift to
+	`size'.
+
+2007-12-21  Bean  <bean123ch@gmail.com>
+
+	* conf/common.rmk (pkgdata_MODULES): Add ntfscomp.mod.
+	(ntfscomp_mod_SOURCES): New variable.
+	(ntfscomp_mod_CFLAGS): Likewise.
+	(ntfscomp_mod_LDFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/ntfscomp.c.
+	(grub_probe_SOURCES): Likewise.
+	(grub_emu_SOURCES): Likewise.
+
+	* conf/i386-efi.rmk (grub_probe_SOURCES): Add fs/ntfscomp.c.
+	(grub_emu_SOURCES): Likewise.
+
+	* conf/i386-linuxbios.rmk (grub_probe_SOURCES): Add fs/ntfscomp.c.
+	(grub_emu_SOURCES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_probe_SOURCES): Add fs/ntfscomp.c.
+	(grub_emu_SOURCES): Likewise.
+
+	* fs/ntfs.c (grub_ntfscomp_func): New variable.
+	(read_run_list): Renamed to grub_ntfs_read_run_list.
+	(decomp_nextvcn): Moved to ntfscomp.c.
+	(decomp_getch): Likewise.
+	(decomp_get16): Likewise.
+	(decomp_block): Likewise.
+	(read_block): Likewise.
+	(read_data): Partially moved to ntfscomp.c.
+	(fixup): Change unsigned to grub_uint16_t.
+	(read_mft): Change unsigned long to grub_uint32_t.
+	(read_attr): Likewise.
+	(read_data): Likewise.
+	(read_run_data): Likewise.
+	(read_run_list): Likewise.
+	(read_mft): Likewise.
+
+	* fs/ntfscomp.c: New file.
+
+	* include/grub/ntfs.h: New file.
+
+2007-12-16  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub-mkdevicemap.c (make_device_map): Iterate up to 20 for
+	IDE disk check, since Linux is known to support 20 IDE disks.
+	Reported by Colin Watson.
+
+2007-12-15  Bean  <bean123ch@gmail.com>
+
+	* conf/i386-pc.rmk (pkgdata_IMAGES): Add lnxboot.img.
+	(lnxboot_img_SOURCES): New variable.
+	(lnxboot_img_ASFLAGS): Likewise.
+	(lnxboot_img_LDFLAGS): Likewise.
+
+	* boot/i386/pc/lnxboot.S: New file.
+
+2007-11-24  Pavel Roskin  <proski@gnu.org>
+
+	* configure.ac: Test if '--build-id=none' is supported by the
+	linker.  If yes, add it to TARGET_LDFLAGS.  Build ID causes
+	objcopy to generate incorrect binary files (binutils
+	2.17.50.0.18-1 as shipped by Fedora 8).
+	* aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): Use LDFLAGS when
+	linking, so that build ID doesn't break the test.
+
+2007-11-24  Pavel Roskin  <proski@gnu.org>
+
+	* include/grub/i386/time.h: use "void" in the argument list
+	of grub_cpu_idle().
+	* include/grub/powerpc/time.h: Likewise.
+	* include/grub/sparc64/time.h: Likewise.
+
+2007-11-18  Christian Franke  <franke@computer.org>
+
+	* util/console.c (grub_ncurses_getkey): Change curses KEY_* mapping,
+	now return control chars instead of GRUB_CONSOLE_KEY_* constants.
+	This fixes the problem that function keys did not work in grub-emu.
+
+2007-11-18  Christian Franke  <franke@computer.org>
+
+	* disk/host.c (grub_host_open): Remove attribute unused from
+	name parameter. Add check for "host". This fixes the problem
+	that grub-emu does not find partitions.
+
+2007-11-18  Christian Franke  <franke@computer.org>
+
+	* util/hostfs.c (is_dir): New function.
+	(grub_hostfs_dir):  Handle missing dirent.d_type case.
+	(grub_hostfs_read): Add missing fseek().
+	(grub_hostfs_label): Clear label pointer.  This fixes a crash
+	of grub-emu on "ls (host)".
+
+2007-11-18  Christian Franke  <franke@computer.org>
+
+	* include/grub/i386/pc/init.h (struct grub_machine_mmap_entry):
+	Add attribute packed, gcc 3.4.4 on Cygwin aligns this
+	to 64 bit boundary by default.
+
+2007-11-18  Bean  <bean123ch@gmail.com>
+
+	* conf/common.rmk (pkgdata_MODULES): Add hexdump.mod.
+	(hexdump_mod_SOURCES): New variable.
+	(hexdump_mod_CFLAGS): Likewise.
+	(hexdump_mod_LDFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add command/hexdump.c.
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Add command/hexdump.c.
+
+	* conf/i386-linuxbios.rmk (grub_emu_SOURCES): Add command/hexdump.c.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add command/hexdump.c.
+
+	* include/grub/hexdump.h: New file.
+
+	* commands/hexdump.c: New file.
+
+2007-11-10  Robert Millan  <rmh@aybabtu.com>
+
+	* commands/i386/pc/play.c (beep_off): Switch order of arguments
+	in grub_outb() calls.
+	(beep_on): Likewise.
+
+2007-11-10  Christian Franke  <franke@computer.org>
+
+	* normal/menu.c (run_menu): Check for empty menu to avoid crash.
+	(grub_menu_run): Likewise.
+
+2007-11-10  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/efi/machine.h: New file.
+	* include/grub/i386/linuxbios/machine.h: Likewise.
+	* include/grub/i386/pc/machine.h: Likewise.
+	* include/grub/powerpc/ieee1275/machine.h: Likewise.
+	* include/grub/sparc64/ieee1275/machine.h: Likewise.
+
+	* term/i386/pc/serial.c: Include <grub/machine/machine.h>.
+	(serial_hw_io_addr): New variable.
+	(serial_hw_get_port): Obtain port address from `serial_hw_io_addr'
+	instead of `(unsigned short *) 0x400'.
+
+2007-11-10  Bean  <bean123ch@gmail.com>
+
+	* fs/ntfs.c (read_block): Fix a bug caused by adjacent blocks.
+
+2007-11-10  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* conf/i386-pc.rmk (pkgdata_MODULES): Added vga.mod.
+	(vga_mod_SOURCES): Added.
+	(vga_mod_CFLAGS): Likewise.
+	(vga_mod_LDFLAGS): Likewise.
+
+	* term/i386/pc/vga.c (get_map_mask): Switch order of arguments in
+	grub_outb() calls.
+	(set_map_mask): Likewise.
+	(set_read_map): Likewise.
+	(set_read_address): Likewise.
+	(vga_font): Removed variable.
+	(get_vga_glyph): Removed function.
+	(invalidate_char): Likewise.
+	(write_char): Changed to use grub_font_get_glyph() for font
+	information.
+	(grub_vga_putchar): Likewise.
+	(grub_vga_getcharwidth): Likewise.
+
+2007-11-10  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* conf/i386-pc.rmk (boot_img_LDFLAGS): Use COMMON_LDFLAGS for target
+	flags.
+	(pxeboot_img_LDFLAGS): Likewise.
+	(diskboot_img_LDFLAGS): Likewise.
+	(kernel_img_LDFLAGS): Likewise.
+
+2007-11-06  Robert Millan  <rmh@aybabtu.com>
+
+	* term/i386/pc/serial.c (serial_hw_put): Switch order of arguments
+	in grub_outb() calls.
+	(serial_hw_init): Likewise.
+
+2007-11-05  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub.in: Allow files in ${update_grub_dir} to contain
+	spaces.  Skip non-regular files.
+
+2007-11-05  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/disk.c (grub_disk_firmware_fini)
+	(grub_disk_firmware_is_tainted): New variables.
+
+	* include/grub/disk.h (grub_disk_firmware_fini)
+	(grub_disk_firmware_is_tainted): Likewise.
+
+	* disk/i386/pc/biosdisk.c (GRUB_MOD_FINI(biosdisk)): Moved from here ...
+	(grub_disk_biosdisk_fini): ... to here.
+	(GRUB_MOD_FINI(biosdisk)): Implement using grub_disk_biosdisk_fini().
+	(GRUB_MOD_INIT(biosdisk)): Abort when `grub_disk_firmware_is_tainted'
+	is set.  Register grub_disk_biosdisk_fini() in
+	`grub_disk_firmware_fini'.
+
+	* disk/ata.c: Remove `<grub/machine/biosdisk.h>'.
+	(GRUB_MOD_INIT(ata)): Remove grub_biosdisk_fini() call.
+	Use `grub_disk_firmware_is_tainted' and `grub_disk_firmware_fini'
+	to finish existing firmware disk interface.
+
+	* conf/i386-linuxbios.rmk (pkgdata_MODULES): Add `ata.mod'.
+	(ata_mod_SOURCES): New variable.
+	(ata_mod_CFLAGS): Likewise.
+	(ata_mod_LDFLAGS): Likewise.
+
+2007-11-05  Robert Millan  <rmh@aybabtu.com>
+
+	* disk/ata.c: Remove `<grub/machine/time.h>'.  Include `<grub/time.h>'.
+	(grub_ata_wait): Reimplement using grub_millisleep().
+
+	* include/grub/misc.h (grub_div_roundup): Fix parenthesization.
+	* include/grub/i386/time.h (grub_cpu_idle): Disable `hlt' instruction.
+
+2007-11-03  Marco Gerards  <marco@gnu.org>
+
+	* term/i386/pc/vga_text.c: Include <grub/cpu/io.h>.
+	(CRTC_ADDR_PORT): New macro.
+	(CRTC_DATA_PORT): Likewise.
+	(CRTC_CURSOR): Likewise.
+	(CRTC_CURSOR_ADDR_HIGH): Likewise.
+	(CRTC_CURSOR_ADDR_LOW): Likewise.
+	(update_cursor): New function.
+	(grub_console_real_putchar): Call `update_cursor'.
+	(grub_console_gotoxy): Likewise.
+	(grub_console_cls): Set the default color when clearing the
+	screen.
+	(grub_console_setcursor): Implemented.
+
+2007-11-03  Marco Gerards  <marco@gnu.org>
+
+	* disk/ata.c (grub_ata_pio_read): Don't wait for the command to
+	become activate.
+	(grub_ata_pio_write): Likewise.
+
+	(grub_atapi_identify): Wait after issuing an ATA command.
+	(grub_atapi_packet): Likewise.
+	(grub_ata_identify): Likewise.
+	(grub_ata_readwrite): Likewise.
+
+2007-11-03  Marco Gerards  <marco@gnu.org>
+
+	* disk/ata.c (grub_ata_pio_read): Detect and return the error code.
+	(grub_ata_pio_write): Likewise.
+	(grub_ata_readwrite): Use `grub_error', instead of
+	returning `grub_errno'.
+
+2007-11-03  Marco Gerards  <marco@gnu.org>
+
+	* disk/ata.c (grub_ata_readwrite): Call grub_ata_pio_read and
+	grub_ata_pio_write once for every single sector, instead of for
+	multiple sectors.
+
+2007-10-31  Robert Millan  <rmh@aybabtu.com>
+
+	* configure.ac: Add `i386-linuxbios' to the list of supported targets.
+
+	* conf/i386-linuxbios.rmk: New file.
+
+	* kern/i386/pc/hardware.c: Likewise.
+	* term/i386/pc/at_keyboard.c: Likewise.
+	* term/i386/pc/vga_text.c: Likewise.
+
+	* include/grub/i386/linuxbios/boot.h: Likewise.
+	* include/grub/i386/linuxbios/console.h: Likewise.
+	* include/grub/i386/linuxbios/init.h: Likewise.
+	* include/grub/i386/linuxbios/kernel.h: Likewise.
+	* include/grub/i386/linuxbios/loader.h: Likewise.
+	* include/grub/i386/linuxbios/memory.h: Likewise.
+	* include/grub/i386/linuxbios/serial.h: Likewise.
+	* include/grub/i386/linuxbios/time.h: Likewise.
+
+	* kern/i386/linuxbios/init.c: Likewise.
+	* kern/i386/linuxbios/startup.S: Likewise.
+	* kern/i386/linuxbios/table.c: Likewise.
+
+2007-10-31  Marco Gerards  <marco@gnu.org>
+
+	* conf/i386-pc.rmk (pkgdata_MODULES): Add `ata.mod'.
+	(ata_mod_SOURCES): New variable.
+	(ata_mod_CFLAGS): Likewise.
+	(ata_mod_LDFLAGS): Likewise.
+
+	* disk/ata.c: New file.
+
+	* include/grub/disk.h (grub_disk_dev_id): Add
+	`GRUB_DISK_DEV_ATA_ID'.
+
+2007-10-31  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/pc/init.h (grub_lower_mem): Moved from here ...
+	* include/grub/i386/pc/memory.h (grub_lower_mem): ... to here.
+
+	* include/grub/i386/pc/init.h (grub_upper_mem): Moved from here ...
+	* include/grub/i386/pc/memory.h (grub_upper_mem): ... to here.
+
+	* include/grub/i386/pc/memory.h: Include `<grub/symbol.h>' and
+	`<grub/types.h>'.
+
+	* loader/i386/pc/multiboot.c: Include `<grub/machine/memory.h>'.
+
+2007-10-27  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/types.h (ULONG_MAX): Define macro.
+
+2007-10-22  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/i386/pc/startup.S: Remove `"kern/i386/realmode.S"'.  Include
+	`"../realmode.S"'.
+	Remove `"kern/i386/loader.S"'.  Include `"../loader.S"'.
+
+2007-10-22  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Remove `disk/i386/pc/biosdisk.c'.
+	(pkgdata_MODULES): Add `biosdisk.mod'.
+	(biosdisk_mod_SOURCES, biosdisk_mod_CFLAGS, biosdisk_mod_LDFLAGS): New
+	variables.
+
+	* disk/i386/pc/biosdisk.c: Include `<grub/dl.h>'.
+	(grub_biosdisk_init): Replace with ...
+	(GRUB_MOD_INIT(biosdisk)): ... this.
+	(grub_biosdisk_fini): Replace with ...
+	(GRUB_MOD_FINI(biosdisk)): ... this.
+
+	* kern/i386/pc/init.c: Remove `<grub/machine/biosdisk.h>'.
+	(grub_machine_init): Remove call to grub_biosdisk_init().
+	(grub_machine_fini): Remove call to grub_machine_fini().
+
+	* util/i386/pc/grub-install.in (modules): Add `biosdisk'.
+
+2007-10-22  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/time.h: New file.
+	* include/grub/i386/time.h: Likewise.
+	* include/grub/powerpc/time.h: Likewise.
+	* include/grub/sparc64/time.h: Likewise.
+
+	* include/grub/i386/pc/time.h (KERNEL_TIME_HEADER): Rename all
+	instances to ...
+	(KERNEL_MACHINE_TIME_HEADER): ... this.
+	* include/grub/powerpc/ieee1275/time.h (KERNEL_TIME_HEADER): Rename all
+	instances to ...
+	(KERNEL_MACHINE_TIME_HEADER): ... this.
+	* include/grub/sparc64/ieee1275/time.h (KERNEL_TIME_HEADER): Rename all
+	instances to ...
+	(KERNEL_MACHINE_TIME_HEADER): ... this.
+
+	* kern/i386/efi/init.c: Include `<grub/time.h>'.
+	(grub_millisleep): New function.
+	* kern/i386/pc/init.c: Include `<grub/time.h>'.
+	(grub_millisleep): New function.
+	* kern/powerpc/ieee1275/init.c: Include `<grub/time.h>'.
+	Remove `grub/machine/time.h' include.
+	(grub_millisleep): New function.
+	* kern/sparc64/ieee1275/init.c: Include `<grub/time.h>'.
+	Remove `grub/machine/time.h' include.
+	(grub_millisleep): New function.
+
+	* include/grub/misc.h (grub_div_roundup): New function.
+
+	* kern/misc.c: Include `<grub/time.h>'.
+	(grub_millisleep_generic): New function.
+
+	* conf/i386-efi.rmk (kernel_mod_HEADERS): Remove `i386/efi/time.h'.
+	Add `time.h'.
+	* conf/i386-pc.rmk (kernel_img_HEADERS): Remove `machine/time.h'.
+	Add `time.h'.
+	* conf/powerpc-ieee1275.rmk (kernel_elf_HEADERS): Remove
+	`machine/time.h'.  Add `time.h'.
+	* conf/sparc64-ieee1275.rmk (kernel_elf_HEADERS): Likewise.
+
+2007-10-21  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/misc.h (grub_max): New function.
+
+2007-10-21  Robert Millan  <rmh@aybabtu.com>
+
+	* util/misc.c (grub_util_info): Call fflush() before returning.
+
+2007-10-20  Robert Millan  <rmh@aybabtu.com>
+
+	* genmk.rb (Image): Copy `extra_flags' from here ...
+	(PModule): ... to here.  Use it in `#{obj}: #{src}' rule.
+
+	* commands/i386/cpuid.c (grub_cmd_cpuid): Add __attribute__ ((unused))
+	to `argc' and `args' arguments.
+
+2007-10-17  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/i386/loader.S: New file.
+
+	* kern/i386/pc/startup.S (grub_linux_prot_size): Moved from here ...
+	* kern/i386/loader.S (grub_linux_prot_size)... to here.
+	* kern/i386/pc/startup.S (grub_linux_tmp_addr): Moved from here ...
+	* kern/i386/loader.S (grub_linux_tmp_addr)... to here.
+	* kern/i386/pc/startup.S (grub_linux_real_addr): Moved from here ...
+	* kern/i386/loader.S (grub_linux_real_addr)... to here.
+	* kern/i386/pc/startup.S (grub_linux_boot_zimage): Moved from here ...
+	* kern/i386/loader.S (grub_linux_boot_zimage)... to here.
+	* kern/i386/pc/startup.S (grub_linux_boot_bzimage): Moved from here ...
+	* kern/i386/loader.S (grub_linux_boot_bzimage)... to here.
+	* kern/i386/pc/startup.S (grub_multiboot_real_boot): Moved from here ...
+	* kern/i386/loader.S (grub_multiboot_real_boot)... to here.
+	* kern/i386/pc/startup.S (grub_multiboot2_real_boot): Moved from here ...
+	* kern/i386/loader.S (grub_multiboot2_real_boot)... to here.
+
+	* kern/i386/realmode.S: New file.
+
+	* kern/i386/pc/startup.S (protstack): Moved from here ...
+	* kern/i386/realmode.S (protstack)... to here.
+	* kern/i386/pc/startup.S (gdt): Moved from here ...
+	* kern/i386/realmode.S (gdt)... to here.
+	* kern/i386/pc/startup.S (prot_to_real): Moved from here ...
+	* kern/i386/realmode.S (prot_to_real)... to here.
+
+	* kern/i386/pc/startup.S: Include `kern/i386/loader.S' and
+	`kern/i386/realmode.S'.
+
+2007-10-17  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/loader.h: New file.
+
+	* include/grub/i386/pc/loader.h (grub_linux_prot_size)
+	(grub_linux_tmp_addr, grub_linux_real_addr, grub_os_area_addr)
+	(grub_os_area_size, grub_linux_boot_zimage, grub_linux_boot_bzimage)
+	(grub_multiboot_real_boot, grub_multiboot2_real_boot)
+	(grub_rescue_cmd_linux, grub_rescue_cmd_initrd): Moved from here ...
+	* include/grub/i386/loader.h (grub_linux_prot_size)
+	(grub_linux_tmp_addr, grub_linux_real_addr, grub_os_area_addr)
+	(grub_os_area_size, grub_linux_boot_zimage, grub_linux_boot_bzimage)
+	(grub_multiboot_real_boot, grub_multiboot2_real_boot)
+	(grub_rescue_cmd_linux, grub_rescue_cmd_initrd): ... to here.
+
+	* include/grub/i386/pc/loader.h: Include `grub/cpu/loader.h'.
+
+2007-10-15  Robert Millan  <rmh@aybabtu.com>
+
+	* normal/misc.c (grub_normal_print_device_info): Do not probe for
+	filesystem when dev->disk is unset.
+	Do probe for filesystem even when dev->disk->has_partitions is set.
+	In case a filesystem is found, always report it.
+	In case it isn't, if dev->disk->has_partitions is set, report that
+	a partition table was found instead of reporting that no filesystem
+	could be identified.
+
+2007-10-12  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/powerpc-ieee1275.rmk (grub_mkimage_SOURCES): Replace reference
+	to util/powerpc/ieee1275/grub-mkimage.c with util/elf/grub-mkimage.c.
+
+	* include/grub/types.h (grub_host_to_target16): New macro.
+	(grub_host_to_target32): Likewise.
+	(grub_host_to_target64): Likewise.
+	(grub_target_to_host16): Likewise.
+	(grub_target_to_host32): Likewise.
+	(grub_target_to_host64): Likewise.
+
+	* include/grub/powerpc/ieee1275/kernel.h (GRUB_IEEE1275_MOD_ALIGN):
+	Renamed from to ...
+	(GRUB_MOD_ALIGN): ...this.  Update all users.
+
+	* util/elf/grub-mkimage.c (load_note): Replace grub_cpu_to_be32 with
+	grub_host_to_target32.
+	Replace grub_be_to_cpu32 with grub_target_to_host32.
+	(load_modules): Likewise.
+	(add_segments): Replace grub_be_to_cpu16 with grub_target_to_host16.
+	Replace grub_be_to_cpu32 with grub_target_to_host32.
+	Replace grub_cpu_to_be16 with grub_host_to_target16.
+	Replace grub_cpu_to_be32 grub_host_to_target32.
+
+2007-10-12  Robert Millan  <rmh@aybabtu.com>
+
+	* util/powerpc/ieee1275/grub-mkimage.c: Moved to ...
+	* util/elf/grub-mkimage.c: ... here.
+
+	* DISTLIST: Add `util/elf/grub-mkimage.c'.  Remove
+	`util/powerpc/ieee1275/grub-mkimage.c'.
+
+2007-10-07  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/powerpc/ieee1275/init.c: Rename HEAP_LIMIT to HEAP_MAX_ADDR,
+	and make it easier to figure out.
+	Add HEAP_MIN_SIZE and HEAP_MAX_ADDR definitions.
+	(grub_claim_heap): Use HEAP_MAX_ADDR rather than taking a parameter.
+	Do not avoid claiming a region above HEAP_MAX_ADDR if that would
+	leave us with less than HEAP_MIN_SIZE total heap.
+	Avoid our total amount of heap to surpass HEAP_MAX_SIZE.
+
+2007-10-03  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/io.h: New file.
+	* commands/i386/pc/play.c (inb): Removed.
+	(outb): Removed.
+	Include grub/cpu/io.h.  Replace inb() with grub_inb() and outb()
+	with grub_outb().
+	* term/i386/pc/serial.c  (inb): Removed.
+	(outb): Removed.
+	Include grub/cpu/io.h.  Replace inb() with grub_inb() and outb()
+	with grub_outb().
+	* term/i386/pc/vga.c  (inb): Removed.
+	(outb): Removed.
+	Include grub/cpu/io.h.  Replace inb() with grub_inb() and outb()
+	with grub_outb().
+
+2007-10-02  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Add util/hostfs.c.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	Reported by Marcin Kurek.
+
+2007-09-07  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/powerpc/ieee1275/cmain.c (grub_ieee1275_test_flag): Detect
+	SmartFirmware version updates (as released by Sven Luther), and avoid
+	setting GRUB_IEEE1275_FLAG_NO_PARTITION_0 or
+	GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS unless the running version is
+	known broken.
+
+2007-09-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Hitoshi Ozeki:
+	* kern/i386/pc/init.c (compact_mem_regions): Decrease NUM_REGIONS
+	when merging two regions.
+
+2007-09-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/rescue.c (grub_enter_rescue_mode): Free ARGS.
+	* normal/completion.c (grub_normal_do_completion): Likewise.
+	Reported by Hitoshi Ozeki.
+
+2007-09-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Do not use devices at boot in chainloading.
+
+	* loader/i386/pc/chainloader.c (boot_drive): New variable.
+	(boot_part_addr): Likewise.
+	(grub_chainloader_boot): Simply call grub_chainloader_real_boot
+	with BOOT_DRIVE and BOOT_PART_ADDR.
+	(grub_chainloader_cmd): Set BOOT_DRIVE and BOOT_PART_ADDR.
+	Reported by Hitoshi Ozeki <h-ozeki@ck2.so-net.ne.jp>.
+
+2007-08-29  Robert Millan  <rmh@aybabtu.com>
+
+	Patch from Simon Peter <dn.tlp@gmx.net>:
+	* genmk.rb (Utility): Append $(#{src}_DEPENDENCIES) to #{obj} targets.
+	* conf/i386-pc.rmk: Replace grub-probe_DEPENDENCIES with
+	util/grub-probe.c_DEPENDENCIES.  Replace grub-setup_DEPENDENCIES with
+	util/i386/pc/grub-setup.c_DEPENDENCIES.
+	* conf/i386-efi.rmk: Replace grub-probe_DEPENDENCIES with
+	util/grub-probe.c_DEPENDENCIES.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+
+2007-08-28  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/get_disk_name.c: New.  Implement grub_util_get_disk_name()
+	to tell grub-mkdevicemap how to name devices.
+	* util/ieee1275/get_disk_name.c: Likewise (using "ofpathname -a"
+	feature).
+
+	* conf/i386-efi.rmk (grub_mkdevicemap_SOURCES): Add
+	util/i386/get_disk_name.c.
+	* conf/i386-pc.rmk (grub_mkdevicemap_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_mkdevicemap_SOURCES): Add
+	util/ieee1275/get_disk_name.c.
+
+	* include/grub/util/misc.h: grub_util_get_disk_name() declaration.
+
+	* DISTLIST: Add util/i386/get_disk_name.c and
+	util/ieee1275/get_disk_name.c.
+
+	* util/grub-mkdevicemap.c: Replace device naming logic with
+	grub_util_get_disk_name() calls.
+
+2007-08-20  Robert Millan  <rmh@aybabtu.com>
+
+	* normal/menu.c (run_menu): Refer to seconds as "s" not "seconds"
+	(so that it works for both plural and singular quantities).
+
+2007-08-05  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/10_linux.in (test_gt): Strip out vmlinu[xz]- prefix
+	so that [xz] isn't taken into account when determining order.
+
+2007-08-02  Marco Gerards  <marco@gnu.org>
+
+	* DISTLIST: Add `disk/host.c', `fs/ntfs.c', `include/multiboot.h',
+	`include/multiboot2.h', `include/grub/elfload.h',
+	`include/multiboot.h', `include/grub/multiboot.h',
+	`include/grub/multiboot_loader.h', `include/grub/multiboot2.h',
+	`include/grub/i386/pc/biosdisk.h', `include/grub/util/biosdisk.h',
+	`kern/elf.c', `loader/multiboot_loader.c',
+	`loader/multiboot_loader_normal.c', `loader/multiboot2.c',
+	`loader/i386/pc/multiboot2.c',
+	`loader/powerpc/ieee1275/multiboot2.c', `util/hostfs.c' and
+	`util/i386/pc/grub-mkrescue.in'.  Remove
+	`include/grub/biosdisk.h', `include/grub/i386/pc/multiboot.h',
+	`include/grub/i386/pc/util/biosdisk.h' and
+	`include/grub/powerpc/ieee1275/multiboot.h'.
+
+2007-08-02  Bean  <bean123ch@gmail.com>
+
+	* conf/common.rmk (pkgdata_MODULES): Add ntfs.mod.
+	(ntfs_mod_SOURCES): New variable.
+	(ntfs_mod_CFLAGS): Likewise.
+	(ntfs_mod_LDFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/ntfs.c.
+	(grub_probe_SOURCES): Likewise.
+	(grub_emu_SOURCES): Likewise.
+
+	* conf/i386-efi.rmk (grub_probe_SOURCES): Add fs/ntfs.c.
+	(grub_emu_SOURCES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_probe_SOURCES): Add fs/ntfs.c.
+	(grub_emu_SOURCES): Likewise.
+
+	* conf/misc.c (grub_utf16_to_utf8): Fix unicode conversion bug.
+
+	* fs/ntfs.c: New file.
+
+2007-08-02  Bean  <bean123ch@gmail.com>
+
+	* disk.h (grub_disk): Use NESTED_FUNC_ATTR.
+
+	* file.h (grub_file): Likewise.
+
+	* fshelp.h (grub_fshelp_read_file): Likewise.
+
+	* util/i386/pc/grub-setup.c (setup): Likewise.
+	(save_first_sector): Likewise.
+	(save_blocklists): Likewise.
+
+	* fs/affs.c (grub_affs_read_file): Likewise.
+
+	* fs/ext2.c (grub_ext2_read_file): Likewise.
+
+	* fs/fat.c (grub_fat_read_data): Likewise.
+
+	* fs/fshelp.c (grub_fshelp_read_file): Likewise.
+
+	* fs/hfs.c (grub_hfs_read_file): Likewise.
+
+	* fs/hfsplus.c (grub_hfsplus_read_file): Likewise.
+
+	* fs/jfs.c (grub_jfs_read_file): Likewise.
+
+	* fs/minix.c (grub_minix_read_file): Likewise.
+
+	* fs/sfs.c (grub_sfs_read_file): Likewise.
+
+	* fs/ufs.c (grub_ufs_read_file): Likewise.
+
+	* fs/xfs.c (grub_xfs_read_file): Likewise.
+
+	* command/blocklist.c (read_blocklist): Likewise.
+	(print_blocklist): Likewise.
+
+2007-08-02  Marco Gerards  <marco@gnu.org>
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/host.c' and
+	`util/hostfs.c'.
+
+	* disk/host.c: New file.
+
+	* util/hostfs.c: Likewise.
+
+	* fs/hfsplus.c (grub_hfsplus_mount): When reading out of disk,
+	return `GRUB_ERR_BAD_FS'.
+	* fs/sfs.c (grub_sfs_mount): Likewise.
+	* fs/xfs.c (grub_xfs_mount): Likewise.
+
+	* include/grub/disk.h (enum grub_disk_dev_id): Add
+	`GRUB_DISK_DEVICE_HOST_ID'.
+
+	* util/grub-emu.c (main): Initialize and de-initialize hostfs.
+
+2007-07-24  Jerone Young  <jerone@gmail.com>
+
+	* conf/i386-pc.rmk: Add Multiboot loader and multiboot 2 to multiboot
+	modules for compilation.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+
+	* include/multiboot.h: Move multiboot definitions to one file. Rename
+	many definitions to not get grub specific.
+	* include/multiboot2.h: Create header with multiboot 2 definitions.
+	* include/grub/multiboot.h: Header for grub specific function
+	prototypes and definitions.
+	* include/grub/multiboot2.h: Likewise.
+	* include/grub/multiboot_loader.h: Likewise.
+	* include/grub/i386/pc/multiboot.h: Removed.
+	* include/grub/powerpc/ieee1275/multiboot.h: Removed.
+
+	* loader/multiboot_loader.c: Created to act as a proxy for multiboot 1
+	and 2 to allow for one multiboot and module commands.
+	* loader/multiboot2.c: Add multiboot2 functionality.
+	* loader/i386/pc/multiboot.c: Modify for new multiboot header location
+	and definition names.
+	* loader/i386/pc/multiboot2.c: Created to add i386 specific multiboot
+	2 functions.
+	* loader/powerpc/ieee1275/multiboot2.c: Created to add powerpc
+	ieee1275 specific multiboot2 code.
+
+	* kern/i386/pc/startup.S: Change headers and definition names for
+	multiboot. Add function grub_multiboot2_real_boot for multiboot 2.
+
+2007-07-22  Robert Millan  <rmh@aybabtu.com>
+
+	* geninitheader.sh: Process file specified in first parameter rather
+	than hardcoding grub_modules_init.lst.
+	* geninit.sh: Likewise.  Also, construct header name dynamically rather
+	than hardcoding grub_modules_init.h.
+
+	* conf/common.rmk: Rename grub_modules_init.[ch] files associated with
+	grub-emu to grub_emu_init.[ch].  Add rules to build analogous
+	grub_probe_init.[ch] and grub_setup_init.[ch].
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_DEPENDENCIES): Replace
+	grub_modules_init.h with grub_emu_init.h.
+	(grub_probe_DEPENDENCIES, grub_probe_SOURCES): Add new
+	grub_probe_init.[ch] files.
+	* conf/i386-efi.rmk: Likewise.
+	* conf/i386-pc.rmk: Likewise.
+	(grub_setup_DEPENDENCIES, grub_setup_SOURCES): Add new
+	grub_setup_init.[ch] files.
+
+	* util/grub-emu.c: Replace grub_modules_init.h with grub_emu_init.h.
+	* util/grub-probe.c: Include grub_probe_init.h.  Use grub_init_all()
+	to initialize modules rather than a list of hardcoded functions.
+	* util/i386/pc/grub-setup.c: Include grub_setup_init.h.  Use
+	grub_init_all() to initialize modules rather than a list of hardcoded
+	functions.
+
+2007-07-22  Robert Millan  <rmh@aybabtu.com>
+
+	* kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): Set
+	GRUB_IEEE1275_FLAG_NO_PARTITION_0 flag when running on SmartFirmware.
+
+2007-07-22  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): Add
+	GRUB_IEEE1275_FLAG_BROKEN_OUTPUT flag.
+	* kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): Set this
+	flag when running on SmartFirmware.
+	* term/ieee1275/ofconsole.c (grub_ofconsole_init): Avoid running
+	"output-device output" command when GRUB_IEEE1275_FLAG_BROKEN_OUTPUT
+	was set.
+
+	* kern/powerpc/ieee1275/openfw.c (grub_ieee1275_encode_devname):
+	Increase partno when GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS flag is set,
+	rather than decreasing it.
+
+	* util/i386/pc/grub-setup.c (setup): When embedding is required, but
+	there's not enough space to do it, fail in the same way as when it
+	can't be done because there are no partitions.
+
+	* util/powerpc/ieee1275/grub-install.in: Improve error message shown
+	when nvsetenv failed.
+
+2007-07-22  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* conf/i386-pc.rmk (CLEANFILES): Removed for grub-mkrescue,
+	because this rule is automatically generated.
+	(grub-mkrescue): Removed for the same reason as above.
+
+2007-07-22  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Migrate to GNU General Public License Version 3.
+
+	* COPYING: Replaced with the plain text version of GPLv3.
+
+	* config.guess: Updated from gnulib.
+	* config.sub: Likewise.
+
+	* geninit.sh: Output a GPLv3 copyright notice.
+	* geninitheader.sh: Likewise.
+	* genmodsrc.sh: Likewise.
+	* gensymlist.sh.in: Likewise.
+
+	* boot/i386/pc/boot.S: Upgraded to GPLv3.
+	* boot/i386/pc/diskboot.S: Likewise.
+	* boot/i386/pc/pxeboot.S: Likewise.
+	* commands/blocklist.c: Likewise.
+	* commands/boot.c: Likewise.
+	* commands/cat.c: Likewise.
+	* commands/cmp.c: Likewise.
+	* commands/configfile.c: Likewise.
+	* commands/echo.c: Likewise.
+	* commands/help.c: Likewise.
+	* commands/ls.c: Likewise.
+	* commands/search.c: Likewise.
+	* commands/terminal.c: Likewise.
+	* commands/test.c: Likewise.
+	* commands/videotest.c: Likewise.
+	* commands/i386/cpuid.c: Likewise.
+	* commands/i386/pc/halt.c: Likewise.
+	* commands/i386/pc/play.c: Likewise.
+	* commands/i386/pc/reboot.c: Likewise.
+	* commands/i386/pc/vbeinfo.c: Likewise.
+	* commands/i386/pc/vbetest.c: Likewise.
+	* commands/ieee1275/halt.c: Likewise.
+	* commands/ieee1275/reboot.c: Likewise.
+	* commands/ieee1275/suspend.c: Likewise.
+	* disk/loopback.c: Likewise.
+	* disk/lvm.c: Likewise.
+	* disk/raid.c: Likewise.
+	* disk/efi/efidisk.c: Likewise.
+	* disk/i386/pc/biosdisk.c: Likewise.
+	* disk/ieee1275/ofdisk.c: Likewise.
+	* font/manager.c: Likewise.
+	* fs/affs.c: Likewise.
+	* fs/ext2.c: Likewise.
+	* fs/fat.c: Likewise.
+	* fs/fshelp.c: Likewise.
+	* fs/hfs.c: Likewise.
+	* fs/hfsplus.c: Likewise.
+	* fs/iso9660.c: Likewise.
+	* fs/jfs.c: Likewise.
+	* fs/minix.c: Likewise.
+	* fs/sfs.c: Likewise.
+	* fs/ufs.c: Likewise.
+	* fs/xfs.c: Likewise.
+	* hello/hello.c: Likewise.
+	* include/grub/acorn_filecore.h: Likewise.
+	* include/grub/arg.h: Likewise.
+	* include/grub/bitmap.h: Likewise.
+	* include/grub/boot.h: Likewise.
+	* include/grub/cache.h: Likewise.
+	* include/grub/device.h: Likewise.
+	* include/grub/disk.h: Likewise.
+	* include/grub/dl.h: Likewise.
+	* include/grub/elfload.h: Likewise.
+	* include/grub/env.h: Likewise.
+	* include/grub/err.h: Likewise.
+	* include/grub/file.h: Likewise.
+	* include/grub/font.h: Likewise.
+	* include/grub/fs.h: Likewise.
+	* include/grub/fshelp.h: Likewise.
+	* include/grub/gzio.h: Likewise.
+	* include/grub/hfs.h: Likewise.
+	* include/grub/kernel.h: Likewise.
+	* include/grub/loader.h: Likewise.
+	* include/grub/lvm.h: Likewise.
+	* include/grub/misc.h: Likewise.
+	* include/grub/mm.h: Likewise.
+	* include/grub/net.h: Likewise.
+	* include/grub/normal.h: Likewise.
+	* include/grub/parser.h: Likewise.
+	* include/grub/partition.h: Likewise.
+	* include/grub/pc_partition.h: Likewise.
+	* include/grub/raid.h: Likewise.
+	* include/grub/rescue.h: Likewise.
+	* include/grub/script.h: Likewise.
+	* include/grub/setjmp.h: Likewise.
+	* include/grub/symbol.h: Likewise.
+	* include/grub/term.h: Likewise.
+	* include/grub/terminfo.h: Likewise.
+	* include/grub/tparm.h: Likewise.
+	* include/grub/types.h: Likewise.
+	* include/grub/video.h: Likewise.
+	* include/grub/efi/api.h: Likewise.
+	* include/grub/efi/chainloader.h: Likewise.
+	* include/grub/efi/console.h: Likewise.
+	* include/grub/efi/console_control.h: Likewise.
+	* include/grub/efi/disk.h: Likewise.
+	* include/grub/efi/efi.h: Likewise.
+	* include/grub/efi/pe32.h: Likewise.
+	* include/grub/efi/time.h: Likewise.
+	* include/grub/i386/linux.h: Likewise.
+	* include/grub/i386/setjmp.h: Likewise.
+	* include/grub/i386/types.h: Likewise.
+	* include/grub/i386/efi/kernel.h: Likewise.
+	* include/grub/i386/efi/loader.h: Likewise.
+	* include/grub/i386/efi/time.h: Likewise.
+	* include/grub/i386/pc/biosdisk.h: Likewise.
+	* include/grub/i386/pc/boot.h: Likewise.
+	* include/grub/i386/pc/chainloader.h: Likewise.
+	* include/grub/i386/pc/console.h: Likewise.
+	* include/grub/i386/pc/init.h: Likewise.
+	* include/grub/i386/pc/kernel.h: Likewise.
+	* include/grub/i386/pc/loader.h: Likewise.
+	* include/grub/i386/pc/memory.h: Likewise.
+	* include/grub/i386/pc/multiboot.h: Likewise.
+	* include/grub/i386/pc/serial.h: Likewise.
+	* include/grub/i386/pc/time.h: Likewise.
+	* include/grub/i386/pc/vbe.h: Likewise.
+	* include/grub/i386/pc/vbeblit.h: Likewise.
+	* include/grub/i386/pc/vbefill.h: Likewise.
+	* include/grub/i386/pc/vbeutil.h: Likewise.
+	* include/grub/i386/pc/vga.h: Likewise.
+	* include/grub/ieee1275/ieee1275.h: Likewise.
+	* include/grub/ieee1275/ofdisk.h: Likewise.
+	* include/grub/powerpc/libgcc.h: Likewise.
+	* include/grub/powerpc/setjmp.h: Likewise.
+	* include/grub/powerpc/types.h: Likewise.
+	* include/grub/powerpc/ieee1275/biosdisk.h: Likewise.
+	* include/grub/powerpc/ieee1275/console.h: Likewise.
+	* include/grub/powerpc/ieee1275/ieee1275.h: Likewise.
+	* include/grub/powerpc/ieee1275/kernel.h: Likewise.
+	* include/grub/powerpc/ieee1275/loader.h: Likewise.
+	* include/grub/powerpc/ieee1275/multiboot.h: Likewise.
+	* include/grub/powerpc/ieee1275/time.h: Likewise.
+	* include/grub/powerpc/ieee1275/util/biosdisk.h: Likewise.
+	* include/grub/sparc64/libgcc.h: Likewise.
+	* include/grub/sparc64/setjmp.h: Likewise.
+	* include/grub/sparc64/types.h: Likewise.
+	* include/grub/sparc64/ieee1275/console.h: Likewise.
+	* include/grub/sparc64/ieee1275/ieee1275.h: Likewise.
+	* include/grub/sparc64/ieee1275/kernel.h: Likewise.
+	* include/grub/sparc64/ieee1275/time.h: Likewise.
+	* include/grub/util/biosdisk.h: Likewise.
+	* include/grub/util/getroot.h: Likewise.
+	* include/grub/util/lvm.h: Likewise.
+	* include/grub/util/misc.h: Likewise.
+	* include/grub/util/raid.h: Likewise.
+	* include/grub/util/resolve.h: Likewise.
+	* io/gzio.c: Likewise.
+	* kern/device.c: Likewise.
+	* kern/disk.c: Likewise.
+	* kern/dl.c: Likewise.
+	* kern/elf.c: Likewise.
+	* kern/env.c: Likewise.
+	* kern/err.c: Likewise.
+	* kern/file.c: Likewise.
+	* kern/fs.c: Likewise.
+	* kern/loader.c: Likewise.
+	* kern/main.c: Likewise.
+	* kern/misc.c: Likewise.
+	* kern/mm.c: Likewise.
+	* kern/parser.c: Likewise.
+	* kern/partition.c: Likewise.
+	* kern/rescue.c: Likewise.
+	* kern/term.c: Likewise.
+	* kern/efi/efi.c: Likewise.
+	* kern/efi/init.c: Likewise.
+	* kern/efi/mm.c: Likewise.
+	* kern/i386/dl.c: Likewise.
+	* kern/i386/efi/init.c: Likewise.
+	* kern/i386/efi/startup.S: Likewise.
+	* kern/i386/pc/init.c: Likewise.
+	* kern/i386/pc/lzo1x.S: Likewise.
+	* kern/i386/pc/startup.S: Likewise.
+	* kern/ieee1275/ieee1275.c: Likewise.
+	* kern/powerpc/cache.S: Likewise.
+	* kern/powerpc/dl.c: Likewise.
+	* kern/powerpc/ieee1275/cmain.c: Likewise.
+	* kern/powerpc/ieee1275/crt0.S: Likewise.
+	* kern/powerpc/ieee1275/init.c: Likewise.
+	* kern/powerpc/ieee1275/openfw.c: Likewise.
+	* kern/sparc64/cache.S: Likewise.
+	* kern/sparc64/dl.c: Likewise.
+	* kern/sparc64/ieee1275/init.c: Likewise.
+	* kern/sparc64/ieee1275/openfw.c: Likewise.
+	* loader/efi/chainloader.c: Likewise.
+	* loader/efi/chainloader_normal.c: Likewise.
+	* loader/i386/efi/linux.c: Likewise.
+	* loader/i386/efi/linux_normal.c: Likewise.
+	* loader/i386/pc/chainloader.c: Likewise.
+	* loader/i386/pc/chainloader_normal.c: Likewise.
+	* loader/i386/pc/linux.c: Likewise.
+	* loader/i386/pc/linux_normal.c: Likewise.
+	* loader/i386/pc/multiboot.c: Likewise.
+	* loader/i386/pc/multiboot_normal.c: Likewise.
+	* loader/powerpc/ieee1275/linux.c: Likewise.
+	* loader/powerpc/ieee1275/linux_normal.c: Likewise.
+	* normal/arg.c: Likewise.
+	* normal/cmdline.c: Likewise.
+	* normal/command.c: Likewise.
+	* normal/completion.c: Likewise.
+	* normal/execute.c: Likewise.
+	* normal/function.c: Likewise.
+	* normal/lexer.c: Likewise.
+	* normal/main.c: Likewise.
+	* normal/menu.c: Likewise.
+	* normal/menu_entry.c: Likewise.
+	* normal/misc.c: Likewise.
+	* normal/parser.y: Likewise.
+	* normal/script.c: Likewise.
+	* normal/i386/setjmp.S: Likewise.
+	* normal/powerpc/setjmp.S: Likewise.
+	* normal/sparc64/setjmp.S: Likewise.
+	* partmap/acorn.c: Likewise.
+	* partmap/amiga.c: Likewise.
+	* partmap/apple.c: Likewise.
+	* partmap/gpt.c: Likewise.
+	* partmap/pc.c: Likewise.
+	* partmap/sun.c: Likewise.
+	* term/gfxterm.c: Likewise.
+	* term/terminfo.c: Likewise.
+	* term/efi/console.c: Likewise.
+	* term/i386/pc/console.c: Likewise.
+	* term/i386/pc/serial.c: Likewise.
+	* term/i386/pc/vesafb.c: Likewise.
+	* term/i386/pc/vga.c: Likewise.
+	* term/ieee1275/ofconsole.c: Likewise.
+	* util/biosdisk.c: Likewise.
+	* util/console.c: Likewise.
+	* util/genmoddep.c: Likewise.
+	* util/getroot.c: Likewise.
+	* util/grub-emu.c: Likewise.
+	* util/grub-mkdevicemap.c: Likewise.
+	* util/grub-probe.c: Likewise.
+	* util/lvm.c: Likewise.
+	* util/misc.c: Likewise.
+	* util/raid.c: Likewise.
+	* util/resolve.c: Likewise.
+	* util/update-grub.in: Likewise.
+	* util/update-grub_lib.in: Likewise.
+	* util/grub.d/00_header.in: Likewise.
+	* util/grub.d/10_hurd.in: Likewise.
+	* util/grub.d/10_linux.in: Likewise.
+	* util/i386/efi/grub-install.in: Likewise.
+	* util/i386/efi/grub-mkimage.c: Likewise.
+	* util/i386/pc/grub-install.in: Likewise.
+	* util/i386/pc/grub-mkimage.c: Likewise.
+	* util/i386/pc/grub-mkrescue.in: Likewise.
+	* util/i386/pc/grub-setup.c: Likewise.
+	* util/i386/pc/misc.c: Likewise.
+	* util/powerpc/ieee1275/grub-install.in: Likewise.
+	* util/powerpc/ieee1275/grub-mkimage.c: Likewise.
+	* util/powerpc/ieee1275/misc.c: Likewise.
+	* video/bitmap.c: Likewise.
+	* video/video.c: Likewise.
+	* video/i386/pc/vbe.c: Likewise.
+	* video/i386/pc/vbeblit.c: Likewise.
+	* video/i386/pc/vbefill.c: Likewise.
+	* video/i386/pc/vbeutil.c: Likewise.
+	* video/readers/tga.c: Likewise.
+
+2007-07-02  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-efi.rmk: Replace obsolete reference to
+	util/i386/pc/biosdisk.c with util/biosdisk.c, and util/i386/pc/getroot.c
+	with util/getroot.c.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	* conf/sparc64-ieee1275.rmk: Likewise.
+
+	* util/grub-emu.c (main): Fix unchecked pointer handling.
+
+2007-07-02  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/efi/grub-install.in: Allow `grub_probe --target=partmap'
+	invocation to fail, in order to support partition-less media.
+
+	* util/i386/pc/grub-install.in: Likewise.
+
+	* util/powerpc/ieee1275/grub-install.in: Use grub-probe to determine
+	which fs or partmap modules are needed (akin to its sister scripts).
+
+	Also use grub-probe to get rid of unportable /proc/mounts check.
+
+	Print the same informational message that the other scripts do, before
+	exiting.
+
+2007-06-23  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in (font_path): New function.  Determine whether
+	a font file can be found and, if so, echo the GRUB path to it.
+
+	* util/update-grub.in: Handle multiple terminals depending on user
+	input, platform availability and font file presence.  Propagate
+	variables of our findings to /etc/grub.d/ children.
+
+	* util/grub.d/00_header.in: Handle multiple terminals, based on
+	environment setup by update-grub.
+
+2007-06-23  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-pc.rmk (pkgdata_MODULES): Add serial.mod.
+
+2007-06-21  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/pc/kernel.h: Define GRUB_KERNEL_MACHINE_DATA_END to
+	indicate end of data section in kernel image.
+	* include/grub/i386/efi/kernel.h: Define GRUB_KERNEL_MACHINE_PREFIX and
+	GRUB_KERNEL_MACHINE_DATA_END.
+
+	* kern/i386/pc/startup.S: Do not initialize grub_prefix, only reserve
+	space for it.
+	* kern/i386/efi/startup.S: Likewise.
+
+	* util/i386/pc/grub-mkimage.c: Initialize grub_prefix to /boot/grub
+	during image generation.  Implement --prefix option to override this
+	patch.
+	* util/i386/efi/grub-mkimage.c: Likewise.
+
+	* util/update-grub_lib.in (convert_system_path_to_grub_path): Split
+	code to make path relative to its root into a separate function.
+
+	* util/i386/pc/grub-install.in: Use newly provided
+	make_system_path_relative_to_its_root() to convert ${grubdir}, then
+	pass the result to grub-install --prefix.
+
+2007-06-13  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/util/misc.h: Define DEFAULT_DIRECTORY and
+	DEFAULT_DEVICE_MAP.
+	* util/grub-emu.c: Use above definitions from misc.h instead of
+	defining them.
+	* util/grub-mkdevicemap.c: Likewise.
+	* util/i386/pc/grub-setup.c: Likewise.
+	* util/grub-probe.c: Likewise.
+	(probe): Abort with grub_util_error() when either
+	grub_guess_root_device or grub_util_get_grub_dev fails.
+
+2007-06-12  Robert Millan  <rmh@aybabtu.com>
+
+	* normal/command.c (grub_command_execute): Use NULL rather than 0 for
+	"pager" assignment.
+	* util/biosdisk.c (grub_util_biosdisk_get_grub_dev): Likewise for
+	"pcdata".
+	* util/grub-probe.c (probe): Likewise for "drive_name".
+
+2007-06-11  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-mkrescue.in: Pad both floppy images with zeroes,
+	not just the cdrom one.
+
+2007-06-11  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-mkrescue.in: Add "set -e".
+	Add --pkglibdir=DIR option to override pkglibdir.
+	Mention --image-type=TYPE in help output.
+	Fix --grub-mkimage (it was a no-op).
+	Abort gracefully when no parameter is given.
+
+2007-06-11  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-mkrescue.in: New file.
+	* conf/i386-pc.rmk: Add its build declarations.  Put it in bin_SCRIPTS.
+	* Makefile.in: Handle bin_SCRIPTS.
+
+2007-06-10  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* term/gfxterm.c (grub_gfxterm_init): Added support for specifying
+	list of video modes.
+
+2007-06-06  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in (convert_system_path_to_grub_path): Abort if
+	file doesn't exist, or if it is in a filesystem grub can't read.
+
+	* util/update-grub.in: Set fallback for GRUB_FS check to "unknown".  Do
+	not abort if GRUB_DRIVE could not be defined.  Rearrange generated
+	header comment to fit in 80 columns when the variables are resolved.
+
+	* util/grub.d/00_header.in: Only set root variable when GRUB_DRIVE
+	could be identified by update-grub.  Remove redundant check for
+	unifont.pff existence (since convert_system_path_to_grub_path now
+	handles that).
+
+2007-06-04  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-efi.rmk (grub_probe_SOURCES): Add partmap/apple.c.
+
+	* conf/i386-pc.rmk (grub_probe_SOURCES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_probe_SOURCES): Add partmap/pc.c.
+
+2007-06-04  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/powerpc-ieee1275.rmk: Enable grub-mkdevicemap and grub-probe.
+
+	* include/grub/partition.h: Declare grub_apple_partition_map_init and
+	grub_apple_partition_map_fini.
+
+	* util/biosdisk.c
+	(grub_util_biosdisk_open): Replace BLKGETSIZE with BLKGETSIZE64 (needed
+	to access >2 TiB disks).
+
+	Print disk->total_sectors with %llu instead of %lu, since this
+	variable is always 64-bit (prevents wrong disk size from being displayed
+	on either >2 TiB disk or big-endian CPU).
+
+	(grub_util_biosdisk_get_grub_dev): Convert gpt_partition_map handling
+	into a generic case that supports all (sane) partition maps.
+
+	Stop using grub_cpu_to_le32() on dos_part / bsd_part since it actually
+	breaks big-endian.
+
+	* util/grub-probe.c: Call grub_apple_partition_map_init() before probe()
+	and grub_apple_partition_map_fini() after that.
+
+2007-06-01  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub.in: Export GRUB_CMDLINE_LINUX.
+
+	* util/grub.d/00_header.in: Only enable gfxterm when
+	convert_system_path_to_grub_path() succeeds.
+
+2007-05-20  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub_lib.in: New file.
+	* DISTLIST: Add update-grub_lib.in.
+	* conf/common.rmk: Generate update-grub_lib and install it in
+	$(lib_DATA).
+	* Makefile.in: Add install routine for $(lib_DATA).
+
+	* util/grub.d/00_header.in: Use convert_system_path_to_grub_path()
+	function provided by update-grub_lib to support arbitrary paths of
+	unifont.pff.
+	* util/update-grub.in: Use convert_system_path_to_grub_path() to
+	initialize GRUB_DRIVE_BOOT and GRUB_DRIVE_BOOT_GRUB variables.
+
+2007-05-19  Robert Millan  <rmh@aybabtu.com>
+
+	* commands/i386/cpuid.c: New module.
+	* DISTLIST: Add it.
+	* conf/i386-efi.rmk: Enable cpuid.mod.
+	* conf/i386-pc.rmk: Likewise.
+
+2007-05-18  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* kern/disk.c (grub_disk_read): Check return value of
+	grub_realloc().
+
+2007-05-18  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* util/getroot.c (grub_util_get_grub_dev): Support partitionable
+	arrays.
+	* disk/raid.c (grub_raid_open): Likewise.
+
+2007-05-17  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* util/biosdisk.c (linux_find_partition): Allocate real_dev on the
+	stack instead of on the heap.
+
+	* kern/disk.c (grub_disk_read): Make sure tmp_buf is big enough
+	before doing a read on it.
+
+	* configure.ac: Only use -fno-stack-protector for the target
+	environment.
+
+2007-05-17  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* video/i386/pc/vbe.c (grub_video_vbe_create_render_target): Add
+	__attribute_ ((unused)) to mode_type argument.
+
+	* util/getroot.c (grub_guess_root_device): Fix #endif.
+
+	* kern/misc.c (memcmp): Fix prototype.
+
+	* include/grub/partition.h [GRUB_UTIL]
+	(grub_gpt_partition_map_init): Add prototype.
+	(grub_gpt_partition_map_fini): Likewise.
+
+	* fs/jfs.c (struct grub_jfs_inode): Put __attribute__ ((packed)
+	at the right place.
+
+	* fs/fat.c (grub_fat_mount): Replace ~0UL with ~0U.
+	(grub_fat_read_data): Likewise.
+	(grub_fat_find_dir): Likewise.
+
+	* font/manager.c (find_glyph): Make table a const.
+	(grub_font_get_glyph): Remove bitmap from if statement.
+
+2007-05-16  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* util/getroot.c (grub_guess_root_device): Remove RAID and LVM
+	code, first search for device in /dev/mapper, then in /dev.
+	(grub_util_get_grub_dev): New function.
+	* include/grub/util/getroot.h (grub_util_get_grub_dev): Add
+	prototype.
+	* util/grub-probe.c (probe): Remove check for RAID, call
+	grub_util_get_grub_dev() instead of
+	grub_util_biosdisk_get_grub_dev().
+	* util/grub-emu.c (main): Call grub_util_get_grub_dev() instead of
+	grub_util_biosdisk_get_grub_dev().
+	* util/i386/pc/grub-setup.c (main): Likewise.
+
+2007-05-16  Robert Millan  <rmh@aybabtu.com>
+
+	* DISTLIST: Update for the latest changes.
+	* conf/i386-pc.rmk: Use the new paths for util/getroot.c,
+	util/grub-mkdevicemap.c, util/grub-probe.c and util/biosdisk.c.
+	* util/grub-emu.c: Replace grub/i386/pc/util/biosdisk.h with
+	grub/util/biosdisk.h.
+	* util/i386/pc/grub-setup.c: Replace grub/machine/util/biosdisk.h with
+	grub/util/biosdisk.h.
+
+2007-05-16  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/00_header.in: Set default gfxmode to `640x480'.
+
+2007-05-16  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/efi/grub-install.in: New.
+	* conf/i386-efi.rmk: Enable grub-mkdevicemap, grub-probe and the
+	newly added grub-install.
+	* util/biosdisk.c: Remove unnecessary grub/machine/biosdisk.h
+	include.
+	* util/getroot.c: Replace grub/i386/pc/util/biosdisk.h with
+	grub/util/biosdisk.h.
+	* util/grub-probe.c: Replace grub/machine/util/biosdisk.h with
+	grub/util/biosdisk.h.
+
+2007-05-16  Robert Millan  <rmh@aybabtu.com>
+
+	* include/grub/i386/pc/util/biosdisk.h: Moved to ...
+	* include/grub/util/biosdisk.h: ... here.
+	* util/i386/pc/biosdisk.c: Moved to ...
+	* util/biosdisk.c: ... here.
+	* util/i386/pc/getroot.c: Moved to ...
+	* util/getroot.c: ... here.
+	* util/i386/pc/grub-mkdevicemap.c: Moved to ...
+	* util/grub-mkdevicemap.c: ... here.
+	* util/i386/pc/grub-probe.c: Moved to ...
+	* util/grub-probe.c: ... here.
+
+2007-05-15  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub.in: Remove duplicated line in grub.cfg header
+	message.
+
+2007-05-13  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub.in: Fix a few assumptions about the devices holding
+	/, /boot and /boot/grub being the same.
+	* util/grub.d/00_header.in: Likewise.
+	* util/grub.d/10_hurd.in: Likewise.
+	* util/grub.d/10_linux.in: Likewise.
+
+	* util/grub.d/10_linux.in: Implement Linux image sorting with arbitrary
+	patterns.  Use that to define the `.old' suffix as older than `'.
+
+	* util/grub.d/00_header.in: Set default gfxmode to `800x600x16'.
+
+	* util/update-grub.in: Add a reference to ${sysconfdir}/default/grub in
+	the grub.cfg header message.
+
+2007-05-11  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub.in: Create device.map if it doesn't already exist,
+	before attempting to run grub-probe.
+	Check for grub-probe and grub-mkdevicemap with the same code
+	grub-install is using.
+	Remove test mode.
+
+2007-05-09  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* Makefile.in: Add the datarootdir autoconf variable.
+
+2007-05-09  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-probe.c (probe): When detecting partition map,
+	fail gracefully if dev->disk->partition == NULL.
+
+2007-05-07  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-probe.c: Add `grub-probe -t partmap' parameter to
+	determine partition map module.
+	* util/i386/pc/grub-install.in: Use this feature to decide which
+	partition module to load, instead of hardcoding pc and gpt.
+
+2007-05-07  Robert Millan  <rmh@aybabtu.com>
+
+	* Makefile.in: Fix assumption that $(srcdir) has a trailing slash when
+	source directory differs from build directory.
+
+2007-05-05  Robert Millan  <rmh@aybabtu.com>
+
+	* util/powerpc/ieee1275/grub-install.in: Fix syntax error in pkglibdir
+	initialisation.
+
+2007-05-05  Robert Millan  <rmh@aybabtu.com>
+
+	* util/update-grub.in: Create ${grub_prefix} if it doesn't exist.
+
+2007-05-05  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub.d/10_linux.in: Allow the administrator to insert Linux
+	command-line arguments via ${GRUB_CMDLINE_LINUX}.
+
+2007-05-05  Robert Millan  <rmh@aybabtu.com>
+
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add partmap/gpt.c.
+	(grub_probe_SOURCES): Likewise.
+	* util/i386/pc/biosdisk.c (grub_util_biosdisk_get_grub_dev): Detect
+	GPT and initialize dos_part and bsd_part accordingly.
+	* util/i386/pc/grub-setup.c (setup): Ditto for install_dos_part and
+	install_bsd_part.
+	(main): Activate gpt module for use during partition identification,
+	and deactivate it afterwards.
+	* util/i386/pc/grub-install.in: Add gpt module to core.img.
+	* util/i386/pc/grub-probe.c (main): Activate gpt module for use during
+	partition identification, and deactivate it afterwards.
+
+2007-05-05  Robert Millan  <rmh@aybabtu.com>
+
+	* term/i386/pc/console.c (grub_console_fini): Call
+	grub_term_set_current() before grub_term_unregister().
+
+2007-05-04  Robert Millan  <rmh@aybabtu.com>
+
+	* DISTLIST: Add util/update-grub.in, util/grub.d/00_header.in,
+	util/grub.d/10_hurd.in, util/grub.d/10_linux.in and util/grub.d/README.
+	* Makefile.in: Build update-grub_SCRIPTS.  Install update-grub_SCRIPTS
+	and update-grub_DATA.
+	* conf/common.rmk: Build and install update-grub components.
+	* conf/common.mk: Regenerate.
+	* util/update-grub.in: New.  Core of update-grub.
+	* util/grub.d/00_header.in: New.  Generates grub.cfg header.
+	* util/grub.d/10_hurd.in: New.  Generates boot entries for the Hurd.
+	* util/grub.d/10_linux.in: New.  Generates boot entries for Linux.
+	* util/grub.d/README: New.  Document grub.d directory layout.
+
+2007-05-01  Robert Millan  <rmh@aybabtu.com>
+
+	* util/grub-emu.c: Move initialization functions
+	grub_util_biosdisk_init() and grub_init_all() before
+	grub_util_biosdisk_get_grub_dev(), which relies on them.
+
+2007-04-19  Robert Millan  <rmh@aybabtu.com>
+
+	* util/powerpc/ieee1275/grub-install.in: Initialize ${bindir}, since
+	it is used later.
+
+2007-04-18  Jerone Young  <jerone@gmail.com>
+
+	* kernel/elf.c: Add missing parenthesis for conditional statement
+	stanza.
+
+2007-04-10  Jerone Young  <jerone@gmail.com>
+
+	* util/i386/pc/getroot.c: Update so that if root device is /dev/root ,
+	continue on and look for device node with real device name.
+
+2007-04-10  Jerone Young  <jerone@gmail.com>
+
+	* configure.ac: Add argument for autoconf to use transformation
+	ability.
+	* Makefile.in: Add autoconf package transformation code.
+	* util/i386/pc/grub-install.in: Likewise.
+	* util/powerpc/ieee1275/grub-install.in: Likewise.
+
+2007-03-19  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* fs/ext2.c (EXT2_GOOD_OLD_REVISION): New macro.
+	(EXT2_GOOD_OLD_INODE_SIZE): Likewise.
+	(EXT2_REVISION): Likewise.
+	(EXT2_INODE_SIZE): Likewise.
+	(struct grub_ext2_block_group): Added a missing member
+	"used_dirs".
+	(grub_ext2_read_inode): Divide by the inode size in a superblock
+	instead of 128 to obtain INODES_PER_BLOCK.
+	Use the macro EXT2_INODE_SIZE instead of directly using
+	SBLOCK->INODE_SIZE.
+
+2007-03-18  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* fs/ext2.c (grub_ext2_read_inode): Use the inode size in a
+	superblock instead of the structure size to compute an
+	offset. This fixes the problem that GRUB could not read a
+	filesystem when inode size is different from 128-byte.
+
+2007-03-05  Marco Gerards  <marco@gnu.org>
+
+	* normal/main.c (read_config_file): When "menu" is not set, create
+	an initial context.
+
+2007-02-21  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/powerpc/ieee1275/init.c (HEAP_SIZE): Removed.
+	(HEAP_LIMIT): New macro.
+	(grub_claim_heap): Claim memory up to `heaplimit'.
+
+2007-02-21  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* conf/powerpc-ieee1275.rmk (kernel_elf_LDFLAGS): Link at 64KB.
+	* kern/powerpc/ieee1275/init.c (_end): Add declaration.
+	(_start): Likewise.
+	(grub_arch_modules_addr): Return address after `_end'.
+	* util/powerpc/ieee1275/grub-mkimage.c: Include grub/misc.h.
+	(load_modules): Use new parameter as `p_paddr' and `p_vaddr'.
+	(add_segments): Calculate `_end' from phdr size and location.
+	(ALIGN_UP): Moved to ...
+	* include/grub/misc.h: here.
+	* include/grub/powerpc/ieee1275/kernel.h (GRUB_IEEE1275_MOD_ALIGN):
+	New macro.
+	(GRUB_IEEE1275_MODULE_BASE): Removed.
+
+2007-02-20  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/powerpc/ieee1275/openfw.c (grub_available_iterate): Correct
+	loop boundary.
+
+2007-02-20  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* include/grub/elfload.h (grub_elf32_load_hook_t): Return grub_err_t.
+	All users updated.
+	(grub_elf64_load_hook_t): Likewise.
+	* kern/elf.c: Call `grub_error_push' before `grub_error'. Improve
+	debug output.
+
+2007-02-20  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/mm.c: Update copyright.
+	(grub_mm_debug): Correct syntax error.
+	(grub_mm_dump_free): New function.
+	(grub_debug_free): Call `grub_free'.
+	* include/grub/mm.h: Update copyright.
+	(grub_mm_dump_free): Add declaration.
+
+2007-02-12  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* include/grub/ieee1275/ieee1275.h: Update copyright.
+	* kern/powerpc/ieee1275/init.c: Likewise.
+	* kern/powerpc/ieee1275/openfw.c: Likewise.
+
+	* loader/powerpc/ieee1275/linux.c: Likewise.
+	* include/grub/elfload.h: Likewise.
+	* kern/elf.c: Likewise.
+	(grub_elf32_load): Pass `base' and `size' parameters.  Update all
+	callers.
+	(grub_elf64_load): Likewise.
+	(grub_elf32_load_segment): Move to a nested function.
+	(grub_elf64_load_segment): Likewise.
+
+2007-02-12  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* include/grub/ieee1275/ieee1275.h (grub_available_iterate): New
+	prototype.
+	* kern/powerpc/ieee1275/init.c (grub_heap_start): Removed.
+	(grub_heap_len): Likewise.
+	(HEAP_SIZE): New macro.
+	(grub_claim_heap): New function.
+	(grub_machine_init): Don't claim heap directly.  Call
+	`grub_claim_heap'.
+	* kern/powerpc/ieee1275/openfw.c: Include alloca.h.
+	(grub_available_iterate): New function.
+
+2007-02-03  Thomas Schwinge  <tschwinge@gnu.org>
+
+	* aclocal.m4 (grub_CHECK_STACK_PROTECTOR): New definition.
+	* configure.ac: Use it for testing the HOST and TARGET compilers.
+
+2006-12-13  Thomas Schwinge  <tschwinge@gnu.org>
+
+	* Makefile.in (enable_grub_emu): New variable.
+	* configure.ac (--enable-grub-emu): New option.
+	Do the checks for (n)curses only if `--enable-grub-emu' is requested.
+	* conf/i386-efi.rmk (sbin_UTILITIES): Add `grub-emu' only if requested.
+	* conf/i386-pc.rmk: Likewise.
+	* conf/powerpc-ieee1275.rmk: Likewise.
+	* conf/sparc64-ieee1275.rmk (bin_UTILITIES): Likewise.
+
+2006-12-12  Marco Gerards  <marco@gnu.org>
+
+	* include/grub/err.h (grub_err_t): Add `GRUB_ERR_MENU'.
+
+	* kern/env.c (grub_env_unset): Don't free the member `value' when
+	the type is GRUB_ENV_VAR_DATA, in this case it's a user defined
+	pointer.
+
+	* normal/main.c (current_menu): Removed.
+	(free_menu): Unset the `menu' environment variable.
+	(grub_normal_menu_addentry): Make use of the environment variable
+	`menu', instead of using the global `current_menu'.  Allocate
+	memory for the sourcecode of this entry.
+	(read_config_file): New argument `nested', changed all callers.
+	Only in the case of a new context, initialize a new menu.  Set the
+	`menu' environment variable.
+	(grub_normal_execute): Don't set and unset the environment
+	variable `menu' here anymore.  Only free the menu when leaving the
+	context.
+
+	* util/i386/pc/biosdisk.c (linux_find_partition): Fixed a memory
+	leak.
+
+2006-12-11  Marco Gerards  <marco@gnu.org>
+
+	* normal/menu_entry.c (run): Fix off by one bug so the last line
+	is executed.  Move the loader check to outside the loop.
+
+2006-12-08  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/powerpc/ieee1275/cmain.c (cmain): Mark r3 and r4 as `UNUSED'.
+
+2006-11-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/i386/pc/grub-mkimage.c (generate_image): Fix the offset of
+	the number of sectors.	Reported by Andrey Shuvikov
+	<mr_hyro@yahoo.com>.
+
+2006-11-11  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* kern/disk.c (grub_disk_read): When there is a read error, always
+	try to read only the necessary data.
+
+	* conf/i386-pc.rmk (grub_probe_SOURCES): Add disk/lvm.c and
+	disk/raid.c.
+	* include/grub/disk.h [GRUB_UTIL] (grub_raid_init): New
+	prototype.
+	[GRUB_UTIL] (grub_raid_fini): Likewise.
+	[GRUB_UTIL] (grub_lvm_init): Likewise.
+	[GRUB_UTIL] (grub_lvm_fini): Likewise.
+	* util/i386/pc/grub-probe.c (probe): Check whether DEVICE_NAME is
+	RAID device and copy DEVICE_NAME to DRIVE_NAME in that case.
+	(main): Call grub_raid_init(), grub_lvm_init(), grub_lvm_fini()
+	and grub_raid_fini().
+
+2006-11-09  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* include/grub/types.h (__unused): Rename to UNUSED.
+	* kern/elf.c (grub_elf32_size): Use UNUSED instead of __unused.
+	(grub_elf64_size): Likewise.
+
+2006-11-03  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/elf.c (grub_elf_file): Call grub_file_seek. Call
+	grub_error_push and grub_error_pop in the error-handling path.
+	(grub_elf32_load_segment): Only call grub_file_read with non-zero
+	length.
+
+2006-11-03  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Add kern/elf.c.
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	(kernel_elf_SOURCES): Likewise.
+	* conf/i386-efi.rmk (kernel_mod_HEADERS): Add elfload.h and cache.h.
+	* conf/i386-pc.rmk (kernel_mod_HEADERS): Likewise.
+	* conf/powerpc-ieee1275.rmk (kernel_elf_HEADERS): Likewise.
+	* conf/sparc64-ieee1275.rmk (kernel_elf_HEADERS): Likewise.
+	* conf/common.rmk (pkgdata_MODULES): Add elf.mod.
+	(elf_mod_SOURCES): New variable.
+	(elf_mod_CFLAGS): Likewise.
+	(elf_mod_LDFLAGS): Likewise.
+	* include/grub/types.h (__unused): New macro.
+	* include/grub/elfload.h: New file.
+	* kern/elf.c: Likewise.
+	* loader/powerpc/ieee1275/linux.c: Include elfload.h.
+	(ELF32_LOADMASK): New macro.
+	(ELF64_LOADMASK): Likewise.
+	(vmlinux): Removed.
+	(grub_linux_load32): New function.
+	(grub_linux_load64): Likewise.
+	(grub_rescue_cmd_linux): Call grub_linux_load32 or grub_linux_load64.
+	Use grub_elf_t instead of grub_file_t.
+
+2006-11-02  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/ieee1275/ieee1275.c (grub_ieee1275_set_color): Add
+	`catch_result' to struct set_color_args.
+
+2006-10-28  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* normal/menu.c: Include grub/script.h.
+	* normal/menu_entry.c: Likewise.
+	* include/grub/normal.h: Do not include grub/script.h.
+
+2006-10-27  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/disk.c (grub_disk_read): Correct debug printf formatting.
+
+2006-10-27  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/disk.c (grub_disk_open): Print debug messages when opening a
+	disk.
+	(grub_disk_close): Print debug messages when closing a disk.
+	(grub_disk_read): Print debug messages when disk read fails.
+	* kern/fs.c (grub_fs_probe): Print debug messages when detecting
+	filesystem type.
+	* kern/partition.c: Include misc.h.
+	(grub_partition_iterate): Print debug messages when detecting
+	partition type.
+
+2006-10-27  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* disk/ieee1275/ofdisk.c (grub_ofdisk_read): Return error if `status'
+	is negative.
+	* kern/ieee1275/ieee1275.c (IEEE1275_IHANDLE_INVALID): Change to 0.
+
+2006-10-26  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/powerpc/ieee1275/openfw.c (grub_ieee1275_encode_devname):
+	Reverse GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS test.
+
+2006-10-25  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* disk/lvm.c (grub_lvm_scan_device): Malloc sizeof(*lv) bytes
+	instead of sizeof(lv). Patch by Michael Guntsche.
+
+2006-10-18  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* disk/lvm.c: Rename VGS to VG_LIST.
+	(grub_lvm_iterate): Change VGS->LV to VG-LV.
+	(grub_lvm_open): Likewise.
+	Thanks to Michael Guntsche for finding this bug.
+
+2006-10-15  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.ac (AC_INIT): Bumped to 1.95.
+
+2006-10-14  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/getroot.c (grub_guess_root_device): Don't compare os_dev
+	with "/dev/.static/dev/md".
+
+2006-10-14  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/i386/pc/grub-probe.c (probe): Print DEVICE_NAME instead of
+	DRIVE_NAME when grub_util_biosdisk_get_grub_dev fails. Open
+	DRIVE_NAME instead of DEVICE_NAME. Make sure that DEVICE_NAME and
+	DRIVE_NAME are always freed.
+
+	* util/i386/pc/biosdisk.c (make_device_name): Add one into
+	DOS_PART, as a DOS partition is counted from one instead of zero
+	now. Reported by Robert Millan.
+
+2006-10-14  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/getroot.c (grub_guess_root_device): Stop using
+	grub_util_biosdisk_get_grub_dev to convert system device to GRUB device.
+	* util/grub-emu.c (main): Use grub_util_biosdisk_get_grub_dev with the
+	string returned by grub_guess_root_device.
+	* util/i386/pc/grub-setup.c: Likewise.
+	* util/i386/pc/grub-probefs.c: Likewise.
+
+	* util/i386/pc/grub-probefs.c: Rename to ...
+	* util/i386/pc/grub-probe.c: ... this.
+	* DISTLIST: Remove grub-probefs, add grub-probe.
+	* conf/i386-efi.rmk: Likewise.
+	* conf/i386-pc.rmk: Likewise.
+	* util/i386/pc/grub-install.in: Likewise.
+
+	* util/i386/pc/grub-probe.c: Add --target=(fs|device|drive) option to
+	choose which information we want to print.
+
+2006-10-14  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Added commands/echo.c, disk/lvm.c, disk/raid.c,
+	include/grub/bitmap.h, include/grub/lvm.h, include/grub/raid.h,
+	include/grub/i386/pc/vbeutil.h, include/grub/util/lvm.h,
+	include/grub/util/raid.h, util/lvm.c, util/raid.c, video/bitmap.c,
+	video/readers/tga.c and video/i386/pc/vbeutil.c.
+
+2006-10-14  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	Added support for RAID and LVM.
+
+	* disk/lvm.c: New file.
+	* disk/raid.c: Likewise.
+	* include/grub/lvm.h: Likewise.
+	* include/grub/raid.h: Likewise.
+	* include/grub/util/lvm.h: Likewise.
+	* include/grub/util/raid.h: Likewise.
+	* util/lvm.c: Likewise.
+	* util/raid.c: Likewise.
+
+	* include/grub/disk.h (grub_disk_dev_id): Add
+	GRUB_DISK_DEVICE_RAID_ID and GRUB_DISK_DEVICE_LVM_ID.
+	(grub_disk_get_size): New prototype.
+	* kern/disk.c (grub_disk_open): Check whether grub_partition_probe()
+	returns a partition.
+	(grub_disk_get_size): New function.
+
+	* kern/i386/pc/init.c (make_install_device): Copy the prefix
+	verbatim if grub_install_dos_part is -2.
+
+	* util/i386/pc/getroot.c (grub_guess_root_device): Support RAID
+	and LVM devices.
+
+	* util/i386/pc/grub-setup.c (setup): New argument
+	MUST_EMBED. Force embedding of GRUB when the argument is
+	true. Close FILE before	returning.
+	(main): Add support for RAID and LVM.
+
+	* conf/common.rmk: Add RAID and LVM modules.
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add util/raid.c and
+	util/lvm.c.
+	(grub_emu_SOURCES): Add disk/raid.c and disk/lvm.c.
+
+	* kern/misc.c (grub_strstr): New function.
+	* include/grub/misc.h (grub_strstr): New prototype.
+
+2006-10-10  Tristan Gingold  <tristan.gingold@bull.net>
+
+	* include/grub/efi/api.h (GRUB_EFI_ERROR_CODE): Long constant.
+
+2006-10-05  Tristan Gingold  <tristan.gingold@bull.net>
+
+	* kern/misc.c (grub_strtoull): Guess the base only if not
+	specified.
+
+2006-10-01  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/powerpc/ieee1275/cmain.c (cmain): Remove incomplete Old World
+	PowerMac support.
+
+2006-10-01  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Cast `size' to long.
+
+	* include/grub/ieee1275/ieee1275.h (grub_ieee1275_next_property):
+	Remove `flags' argument.  All callers changed.
+	* kern/ieee1275/ieee1275.c (IEEE1275_PHANDLE_ROOT): Removed.
+	(IEEE1275_IHANDLE_INVALID): New variable.
+	(IEEE1275_CELL_INVALID): New variable.
+	(grub_ieee1275_finddevice, grub_ieee1275_get_property,
+	grub_ieee1275_get_property_length, grub_ieee1275_instance_to_package,
+	grub_ieee1275_package_to_path, grub_ieee1275_instance_to_path,
+	grub_ieee1275_peer, grub_ieee1275_child, grub_ieee1275_open,
+	grub_ieee1275_claim, grub_ieee1275_set_property): Error-check return
+	codes from Open Firmware.  All callers updated.
+	(grub_ieee1275_next_property): Directly return Open Firmware return
+	code.
+	* kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options):
+	Standardize error checking from `grub_ieee1275_get_property'.
+	* kern/powerpc/ieee1275/openfw.c (grub_devalias_iterate): Rename
+	`devalias' to `aliases'.  Correct comments.  Consolidate error paths.
+
+2006-10-01  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/ieee1275/ieee1275.c (grub_ieee1275_instance_to_path): Rename
+	`instance_to_package_args' to `instance_to_path_args'.
+
+	* kern/powerpc/ieee1275/init.c (grub_machine_init): Use
+	`grub_ieee1275_chosen'.
+
+	* term/ieee1275/ofconsole.c (grub_ofconsole_init): Call
+	`grub_ieee1275_interpret'.
+
+2006-09-25  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* util/powerpc/ieee1275/grub-mkimage.c: Include config.h.
+
+2006-09-25  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* include/grub/powerpc/libgcc.h (__floatdisf): New prototype.
+	(__cmpdi): Likewise.
+
+	* kern/powerpc/ieee1275/openfw.c (grub_devalias_iterate): Pass 0 as
+	`flags' to `grub_ieee1275_next_property'.  Change `pathlen' to type
+	`grub_ssize_t'.
+
+	* kern/powerpc/ieee1275/cmain.c: Include grub/misc.h.
+
+	* loader/powerpc/ieee1275/linux.c (grub_linux_boot): Change `actual'
+	to type `grub_ssize_t'.
+	(grub_rescue_cmd_linux): Cast -1 to `grub_off_t'.
+
+2006-09-22  Marco Gerards  <marco@gnu.org>
+
+	* normal/script.c (grub_script_create_cmdmenu): Skip leading
+	newlines.
+
+2006-09-22  Marco Gerards  <marco@gnu.org>
+
+	* commands/echo.c: New file.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add `commands/echo.c'.
+
+	* conf/common.rmk (echo_mod_SOURCES): New variable.
+	(echo_mod_CFLAGS): Likewise.
+	(echo_mod_LDFLAGS): Likewise.
+
+2006-09-22  Marco Gerards  <marco@gnu.org>
+
+	* normal/main.c (get_line): Malloc memory instead of using
+	preallocated memory.  Removed the arguments `cmdline' and
+	`max_len'.  Updated all callers.
+
+2006-09-22  Marco Gerards  <marco@gnu.org>
+
+	* conf/i386-efi.rmk (grub_emu_DEPENDENCIES): New variable.
+	(normal_mod_DEPENDENCIES): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_DEPENDENCIES): Likewise.
+	(normal_mod_DEPENDENCIES): Likewise.
+
+	* conf/sparc64-ieee1275.rmk (normal_mod_DEPENDENCIES): Likewise.
+
+2006-09-22  Johan Rydberg  <jrydberg@gnu.org>
+
+	* genmk.rb: Add DEPENDENCIES variables to modules, utilities, and
+	programs.
+	* conf/i386-pc.rmk (grub_emu_DEPENDENCIES): Declare.
+	(normal_mod_DEPENDENCIES): Likewise.
+	* conf/i386-pc.mk: Regenerate.
+	* conf/i386-efi.mk: Likewise
+	* conf/common.mk: Likewise.
+	* conf/powerpc-ieee1275.mk: Likewise.
+	* conf/sparc64-ieee1275.mk: Likewise.
+
+2006-09-22  Robert Millan  <rmh@aybabtu.com>
+
+	Sync with i386 version.
+	* conf/powerpc-ieee1275.rmk (bin_UTILITIES): Remove grub-emu, add grub-mkimage.
+	* conf/powerpc-ieee1275.rmk (sbin_UTILITIES): Remove grub-mkimage, add grub-emu.
+
+2006-09-21  Robert Millan  <rmh@aybabtu.com>
+
+	Import from GRUB Legacy (lib/device.c):
+	* util/i386/pc/grub-mkdevicemap.c (get_i2o_disk_name): New function.
+	(init_device_map) [__linux__]: Add support for I2O devices.
+
+2006-09-14  Marco Gerards  <marco@gnu.org>
+
+	* conf/i386-pc.rmk (COMMON_LDFLAGS): Use `-m32' instead of
+	`-melf_i386'.
+
+2006-09-14  Robert Millan  <rmh@aybabtu.com>
+
+	* util/i386/pc/grub-install.in: Skip menu.lst when removing
+	/boot/grub/*.lst.
+
+	* util/i386/pc/getroot.c: Don't recurse into dotdirs (e.g. ".static").
+
+	* util/i386/pc/grub-mkdevicemap.c: Make sure the floppy device exists
+	before adding it to device.map.
+
+2006-08-15  Johan Rydberg  <jrydberg@gnu.org>
+
+	* genmk.rb: Let GCC generate dependencies the first time it
+	compiles a file; using the -MD option.
+	* conf/common.mk: Regenerate.
+	* conf/i386-pc.mk: Likewise.
+	* conf/i386-efi.mk: Likewise.
+	* conf/powerpc-ieee1275.mk: Likewise.
+	* conf/sparc64-ieee1275.mk: Likewise.
+
+2006-08-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Move the prototypes of grub_setjmp and grub_longjmp to
+	cpu/setjmp.h, so that each architecture may specify different
+	attributes.
+
+	* include/grub/i386/setjmp.h (grub_setjmp): New prototype.
+	(grub_longjmp): Likewise.
+	* include/grub/powerpc/setjmp.h (grub_setjmp): Likewise..
+	(grub_longjmp): Likewise.
+	* include/grub/sparc64/setjmp.h (grub_setjmp): Likewise..
+	(grub_longjmp): Likewise.
+
+	* include/grub/setjmp.h [!GRUB_UTIL] (grub_setjmp): Removed.
+	[!GRUB_UTIL] (grub_longjmp): Removed.
+
+2006-08-01  Pelletier Vincent  <subdino2004@yahoo.fr>
+
+	* kern/ieee1275/ieee1275.c (grub_ieee1275_set_color): IEEE1275
+	"color!" method does not return any value.
+
+2006-07-29  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* include/grub/bitmap.h: New file.
+
+	* include/grub/i386/pc/vbeutil.h: Likewise.
+
+	* video/bitmap.c: Likewise.
+
+	* video/readers/tga.c: Likewise.
+
+	* video/i386/pc/vbeutil.c: Likewise.
+
+	* commands/videotest.c: Code cleanup and updated to reflect to new
+	video API.
+
+	* term/gfxterm.c: Likewise.
+
+	* video/video.c: Likewise.
+
+	* conf/i386-pc.rmk (pkgdata_MODULES): Added tga.mod and bitmap.mod.
+	(vbe_mod_SOURCES): Added video/i386/pc/vbeutil.c.
+	(bitmap_mod_SOURCES): New entry.
+	(bitmap_mod_CFLAGS): Likewise.
+	(bitmap_mod_LDFLAGS): Likewise.
+	(tga_mod_SOURCES): Likewise.
+	(tga_mod_CFLAGS): Likewise.
+	(tga_mod_LDFLAGS): Likewise.
+
+	* include/grub/video.h (grub_video_blit_operators): New enum type.
+	(grub_video_render_target): Changed as forward declaration and moved
+	actual definition to be video driver specific.
+	(grub_video_adapter.blit_bitmap): Added blitting operator.
+	(grub_video_adapter.blit_render_target): Likewise.
+	(grub_video_blit_bitmap): Likewise.
+	(grub_video_blit_render_target): Likewise.
+
+	* include/grub/i386/pc/vbe.h (grub_video_render_target): Added
+	driver specific render target definition.
+	(grub_video_vbe_map_rgba): Added driver internal helper.
+	(grub_video_vbe_unmap_color): Updated to use
+	grub_video_i386_vbeblit_info.
+	(grub_video_vbe_get_video_ptr): Likewise.
+
+	* include/grub/i386/pc/vbeblit.h
+	(grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8): Updated to use
+	grub_video_i386_vbeblit_info.
+	(grub_video_i386_vbeblit_R8G8B8_R8G8B8A8): Likewise.
+	(grub_video_i386_vbeblit_index_R8G8B8A8): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8A8_R8G8B8): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8_R8G8B8): Likewise.
+	(grub_video_i386_vbeblit_index_R8G8B8): Likewise.
+	(grub_video_i386_vbeblit_index_index): Likewise.
+	(grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8): New blitter function.
+	(grub_video_i386_vbeblit_R8G8B8_R8G8B8X8): Likewise.
+	(grub_video_i386_vbeblit_index_R8G8B8X8): Likewise.
+	(grub_video_i386_vbeblit_blend): Added generic blitter for blend
+	operator.
+	(grub_video_i386_vbeblit_replace): Added generic blitter for replace
+	operator.
+
+	* video/i386/pc/vbeblit.c: Updated to reflect changes on
+	include/grub/i386/pc/vbeblit.h.
+
+	* include/grub/i386/pc/vbefill.h (grub_video_i386_vbefill_R8G8B8A8):
+	Updated to use grub_video_i386_vbeblit_info.
+	(grub_video_i386_vbefill_R8G8B8): Likewise.
+	(grub_video_i386_vbefill_index): Likewise.
+	(grub_video_i386_vbefill): Added generic filler.
+
+	* video/i386/pc/vbefill.c: Updated to reflect changes on
+	include/grub/i386/pc/vbefill.h.
+
+	* video/i386/pc/vbe.c (grub_video_vbe_get_video_ptr): Updated to use
+	grub_video_i386_vbeblit_info.
+	(grub_video_vbe_unmap_color): Likewise.
+	(grub_video_vbe_blit_glyph): Likewise.
+	(grub_video_vbe_scroll): Likewise.
+	(grub_video_vbe_draw_pixel): Removed function.
+	(grub_video_vbe_get_pixel): Likewise.
+	(grub_video_vbe_fill_rect): Moved all blitters to vbefill.c and
+	updated code to use it.
+	(common_blitter): Added common blitter for render target and bitmap.
+	(grub_video_vbe_blit_bitmap): Updated to use common_blitter.
+	(grub_video_vbe_blit_render_target): Likewise.
+
+2006-07-30  Johan Rydberg  <jrydberg@gnu.org>
+
+	* kern/efi/efi.c (grub_efi_set_text_mode): Assume console already
+	is in text mode if there is no console control protocol instance
+	available.
+
+2006-07-29  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* include/grub/video.h: Code cleanup.
+
+	* include/grub/i386/pc/vbe.h: Likewise.
+
+	* video/i386/pc/vbe.c: Likewise.
+
+	* video/i386/pc/vbeblit.c: Likewise.
+
+	* video/i386/pc/vbefill.c: Likewise.
+
+	* video/video.c: Likewise.  Also added more comments.
+
+2006-07-29  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* disk/i386/pc/biosdisk.c (struct grub_biosdisk_drp): Moved to ...
+	(struct grub_biosdisk_dap): Likewise.
+
+	* include/grub/i386/pc/biosdisk.h: ... to here.  Also corrected
+	linkage settings for all functions.
+
+2006-07-12  Marco Gerards  <marco@gnu.org>
+
+	* configure.ac (--enable-mm-debug): Fix typo.
+
+	* genkernsyms.sh.in: Use proper quoting for `CC'.
+
+2006-07-02  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* conf/i386-pc.rmk (COMMON_ASFLAGS): Add "-m32".
+	(normal_mod_ASFLAGS): Remove "-m32".
+
+2006-06-14  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/misc.c: Include config.h.
+	[!HAVE_MEMALIGN]: Do not include malloc.h.
+	(grub_memalign): Use posix_memalign, if present. Then, use
+	memalign, if present. Otherwise, emit an error.
+
+	* util/grub-emu.c: Do not include malloc.h.
+
+	* include/grub/util/misc.h: Include unistd.h. This is required for
+	FreeBSD, because off_t is defined in unistd.h. Reported by Harley
+	D. Eades III <hde@foobar-qux.org>.
+
+	* configure.ac (AC_GNU_SOURCE): Added.
+	(AC_CHECK_FUNCS): Check posix_memalign and memalign for the host
+	type.
+
+2006-06-09  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* loader/i386/pc/linux.c (grub_rescue_cmd_initrd): Make sure that
+	ADDR_MAX does not exceed GRUB_LINUX_INITRD_MAX_ADDRESS.
+
+2006-06-07  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* include/grub/types.h (grub_host_addr_t): Rename to
+	grub_target_addr_t.
+	(grub_host_off_t): Rename to grub_target_off_t.
+	(grub_host_size_t): Rename to grub_target_size_t.
+	(grub_host_ssize_t): Rename to grub_target_ssize_t.
+	Refer to GRUB_TARGET_SIZEOF_VOID_P to define those variables.
+
+	* include/grub/kernel.h (struct grub_module_header): Change type
+	of OFFSET to grub_target_off_t and type of SIZE to grub_target_size_t.
+	(grub_module_info): Likewise.
+
+2006-06-05  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* loader/i386/pc/linux.c (grub_rescue_cmd_initrd): The conditional
+	of checking LINUX_MEM_SIZE was reverse. Reported by Jesus
+	Velazquez <jesus.velazquez@gmail.com>.
+
+2006-06-05  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Count partitions from 1 instead of 0 in the string representation
+	of partitions. Still use 0-based internally.
+
+	* partmap/sun.c (grub_sun_is_valid): A cosmetic change.
+	(sun_partition_map_iterate): Use grub_partition_t instead of
+	struct grub_partition *. Cast DESC->START_CYLINDER to
+	grub_uint64_t after converting the endian.
+	(sun_partition_map_probe): Subtract 1 for PARTNUM.
+	(sun_partition_map_get_name): Add 1 to P->INDEX.
+
+	* partmap/pc.c (grub_partition_parse): Subtract 1 for
+	PCDATA->DOS_PART.
+	(pc_partition_map_get_name): Add 1 into PCDATA->DOS_PART.
+
+	* partmap/gpt.c (gpt_partition_map_iterate): Initialize PARTNO to
+	zero instead of one.
+	(gpt_partition_map_probe): Subtract 1 for PARTNUM.
+	(gpt_partition_map_get_name): Add 1 into P->INDEX.
+
+	* partmap/apple.c (apple_partition_map_iterate): Change the type
+	of POS to unsigned.
+	(apple_partition_map_probe): Subtract 1 for PARTNUM.
+	(apple_partition_map_get_name): Add 1 into P->INDEX.
+
+	* partmap/amiga.c (amiga_partition_map_iterate): Change the type
+	of POS to unsigned.
+	(amiga_partition_map_iterate): Cast NEXT to grub_off_t to
+	calculate the offset of a partition.
+	(amiga_partition_map_probe): Subtract 1 for PARTNUM.
+	(amiga_partition_map_get_name): Add 1 into P->INDEX.
+
+	* partmap/acorn.c (acorn_partition_map_find): Change the type of
+	SECTOR to grub_disk_addr_t.
+	(acorn_partition_map_iterate): Likewise.
+	(acorn_partition_map_probe): Subtract 1 for PARTNUM.
+	Change the type of SECTOR to grub_disk_addr_t. Declare P on the
+	top.
+	(acorn_partition_map_get_name): Add 1 into P->INDEX.
+
+	* kern/i386/pc/init.c (make_install_device): Add 1 into
+	GRUB_INSTALL_DOS_PART.
+
+	* fs/iso9660.c (grub_iso9660_mount): Fixed a reversed
+	conditional.
+
+2006-06-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Clean up the code to support 64-bit addressing in disks and
+	files. This change is not enough for filesystems yet.
+
+	* util/i386/pc/grub-setup.c (struct boot_blocklist): Change the
+	type of "start" to grub_uint64_t.
+	(setup): Change the types of KERNEL_SECTOR and FIRST_SECTOR to
+	grub_disk_addr_t * and grub_disk_addr_t. Fix the format string in
+	save_first_sector and save_blocklists. Use grub_le_to_cpu64 to
+	convert addresses.
+
+	* util/i386/pc/biosdisk.c (open_device): Change the type of SECTOR
+	to grub_disk_addr_t.
+
+	* partmap/gpt.c (gpt_partition_map_iterate): Fix the format
+	string.
+
+	* partmap/pc.c (pc_partition_map_iterate): Likewise.
+
+	* partmap/amiga.c (amiga_partition_map_iterate): Cast RDSK.MAGIC
+	to char *.
+
+	* normal/script.c (grub_script_parse): Remove unused MEMFREE.
+
+	* normal/parser.y (YYLTYPE_IS_TRIVIAL): New macro.
+
+	* normal/lexer.c (grub_script_yyerror): Specify unused to LEX.
+
+	* loader/i386/pc/multiboot.c (grub_multiboot_load_elf64): Cast -1
+	to grub_off_t, to detect an error from grub_file_seek.
+	(grub_multiboot_load_elf32): Likewise.
+
+	* kern/misc.c (grub_strtoul): Use grub_strtoull. Return the
+	maximum unsigned long value when an overflow is detected.
+	(grub_strtoull): New function.
+	(grub_divmod64): Likewise.
+	(grub_lltoa): use grub_divmod64.
+
+	* kern/fs.c (struct grub_fs_block): Change the type of "offset" to
+	grub_disk_addr_t.
+	(grub_fs_blocklist_open): Increase P if P is not NULL to advance
+	the pointer to next character. Use grub_strtoull instead of
+	grub_strtoul.
+	(grub_fs_blocklist_read): Change the types of SECTOR, OFFSET and
+	SIZE to grub_disk_addr_t, grub_off_t and grub_size_t,
+	respectively.
+
+	* kern/file.c (grub_file_read): Prevent an overflow of LEN, as the
+	return value is signed.
+	(grub_file_seek): Change the type of OLD to grub_off_t. Do not
+	test if OFFSET is less than zero, as OFFSET is unsigned now.
+
+	* kern/disk.c (struct grub_disk_cache): Change the type of
+	"sector" to grub_disk_addr_t.
+	(grub_disk_cache_get_index): Change the type of SECTOR to
+	grub_disk_addr_t. Calculate the hash with SECTOR casted to
+	unsigned after shifting.
+	(grub_disk_cache_invalidate): Change the type of SECTOR to
+	grub_disk_addr_t.
+	(grub_disk_cache_unlock): Likewise.
+	(grub_disk_cache_store): Likewise.
+	(grub_disk_check_range): Change the types of SECTOR, OFFSET, SIZE,
+	START and LEN to grub_disk_addr_t *, grub_off_t *, grub_size_t,
+	grub_disk_addr_t and grub_uint64_t, respectively.
+	(grub_disk_read): Use an unsigned variable REAL_OFFSET for the
+	body, as the value of OFFSET is tweaked by
+	grub_disk_check_range. Change the types of START_SECTOR, LEN and
+	POS to grub_disk_addr_t, grub_size_t and grub_size_t,
+	respectively.
+	(grub_disk_write): Use an unsigned variable REAL_OFFSET for the
+	body, as the value of OFFSET is tweaked by
+	grub_disk_check_range. Change the types of LEN and N to
+	grub_size_t.
+
+	* io/gzio.c (struct grub_gzio): Change the types of "data_offset"
+	and "saved_offset" to grub_off_t.
+	(test_header): Cast BUF to char *.
+	(get_byte): Cast GZIO->DATA_OFFSET to grub_off_t. Cast GZIO->INBUF
+	to char *.
+	(grub_gzio_read): Change the types of OFFSET and SIZE to
+	grub_off_t and grub_size_t, respectively.
+
+	* include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_FORCE_LBA):
+	Removed.
+	(GRUB_BOOT_MACHINE_BOOT_DRIVE):	Changed to 0x4c.
+	(GRUB_BOOT_MACHINE_KERNEL_ADDRESS): Changed to 0x40.
+	(GRUB_BOOT_MACHINE_KERNEL_SEGMENT): Changed to 0x42.
+	(GRUB_BOOT_MACHINE_DRIVE_CHECK): Changed to 0x4e.
+	(GRUB_BOOT_MACHINE_LIST_SIZE): Increased to 12.
+
+	* include/grub/types.h (grub_off_t): Unconditionally set to
+	grub_uint64_t.
+	(grub_disk_addr_t): Changed to grub_uint64_t.
+
+	* include/grub/partition.h (struct grub_partition): Change the
+	types of "start", "len" and "offset" to grub_disk_addr_t,
+	grub_uint64_t and grub_disk_addr_t, respectively.
+	(grub_partition_get_start): Return grub_disk_addr_t.
+	(grub_partition_get_len): Return grub_uint64_t.
+
+	* include/grub/misc.h (grub_strtoull): New prototype.
+	(grub_divmod64): Likewise.
+
+	* include/grub/fshelp.h (grub_fshelp_read_file): Change the types
+	of SECTOR, LEN and FILESIZE to grub_disk_addr_t, grub_size_t and
+	grub_off_t, respectively.
+	All callers and references changed.
+
+	* include/grub/fs.h (struct grub_fs): Change the type of LEN to
+	grub_size_t in "read".
+	All callers and references changed.
+
+	* include/grub/file.h (struct grub_file): Change the types of
+	"offset" and "size" to grub_off_t and grub_off_t,
+	respectively. Change the type of SECTOR to grub_disk_addr_t in
+	"read_hook".
+	(grub_file_read): Change the type of LEN to grub_size_t.
+	(grub_file_seek): Return grub_off_t. Change the type of OFFSET to
+	grub_off_t.
+	(grub_file_size): Return grub_off_t.
+	(grub_file_tell): Likewise.
+	All callers and references changed.
+
+	* include/grub/disk.h (struct grub_disk_dev): Change the types of
+	SECTOR and SIZE to grub_disk_addr_t and grub_size_t in "read" and
+	"write".
+	(struct grub_disk): Change the type of "total_sectors" to
+	grub_uint64_t. Change the type of SECTOR to grub_disk_addr_t in
+	"read_hook".
+	(grub_disk_read): Change the types of SECTOR, OFFSET and SIZE to
+	grub_disk_addr_t, grub_off_t and grub_size_t, respectively.
+	(grub_disk_write): Likewise.
+	All callers and references changed.
+
+	* fs/iso9660.c (grub_iso9660_susp_iterate): Cast parameters to
+	char * for grub_strncmp to silence gcc.
+	(grub_iso9660_mount): Likewise.
+	(grub_iso9660_mount): Likewise.
+	(grub_iso9660_read_symlink): Likewise. Also, remove the nonsense
+	return statement.
+	(grub_iso9660_iterate_dir): Likewise.
+	(grub_iso9660_label): Cast DATA->VOLDESC.VOLNAME to char *.
+
+	* fs/hfs.c (grub_hfs_read_file): Change the types of SECTOR and
+	LEN to grub_disk_addr_t and grub_size_t, respectively.
+
+	* fs/hfsplus.c (grub_hfsplus_read_file): Likewise.
+
+	* fs/jfs.c (grub_jfs_read_file): Likewise.
+
+	* fs/minix.c (grub_jfs_read_file): Likewise.
+
+	* fs/sfs.c (grub_jfs_read_file): Likewise.
+
+	* fs/ufs.c (grub_jfs_read_file): Likewise.
+
+	* fs/xfs.c (grub_jfs_read_file): Likewise.
+
+	* fs/fat.c (grub_fat_read_data): Change the types of SECTOR, LEN
+	and SIZE to grub_disk_addr_t, grub_size_t and grub_size_t,
+	respectively.
+
+	* fs/ext2.c (grub_ext2_read_block): When an error happens, set
+	BLKNR to -1 instead of returning GRUB_ERRNO.
+	(grub_ext2_read_file): Change the types of SECTOR and
+	LEN to grub_disk_addr_t and grub_size_t, respectively.
+
+	* fs/affs.c (grub_affs_read_file): Change the types of SECTOR and
+	LEN to grub_disk_addr_t and grub_size_t, respectively.
+
+	* font/manager.c (grub_font_get_glyph): Cast BITMAP to char * for
+	grub_file_read.
+
+	* disk/ieee1275/ofdisk.c (grub_ofdisk_read): Fix the format
+	string. Do not cast SECTOR explicitly.
+
+	* disk/i386/pc/biosdisk.c (grub_biosdisk_open): Change the type of
+	TOTAL_SECTORS to grub_uint64_t. Do not mask DRP->TOTAL_SECTORS.
+	(grub_biosdisk_rw): Change the types of SECTOR and SIZE to
+	grub_disk_addr_t and grub_size_t, respectively. If the sector is
+	over 2TB and LBA mode is not supported, raise an error.
+	(get_safe_sectors): New function.
+	(grub_biosdisk_read): Use get_safe_sectors.
+	(grub_biosdisk_write): Likewise.
+
+	* disk/efi/efidisk.c (grub_efidisk_read): Fix the format string.
+	(grub_efidisk_write): Likewise.
+
+	* disk/loopback.c (delete_loopback): Cosmetic changes.
+	(grub_cmd_loopback): Likewise. Also, test NEWDEV->FILENAME
+	correctly.
+	(grub_loopback_open): Likewise.
+	(grub_loopback_read): Likewise. Also, change the type of POS to
+	grub_off_t, and fix the usage of grub_memset.
+
+	* commands/i386/pc/play.c: Include grub/machine/time.h.
+
+	* commands/ls.c (grub_ls_list_files): Use "llu" instead of "d" to
+	print FILE->SIZE.
+
+	* commands/configfile.c: Include grub/env.h.
+
+	* commands/cmp.c (grub_cmd_cmp): Do not use ERR, but use
+	GRUB_ERRNO directly instead. Change the type of POS to
+	grub_off_t. Follow the coding standard.
+
+	* commands/blocklist.c: Include grub/partition.h.
+	(grub_cmd_blocklist): Return an error if the underlying device is
+	not a disk. Take the starting sector of a partition into account,
+	if a partition is used.
+
+	* boot/i386/pc/diskboot.S (bootloop): Adapted to the new offset of
+	a length field.
+	(lba_mode): Support 64-bit addresses.
+	(chs_mode): Likewise.
+	(copy_buffer): Adapted to the new offsets of a length field and a
+	segment field.
+	(blocklist_default_start): Allocate 64-bit space.
+
+	* boot/i386/pc/boot.S (force_lba): Removed.
+	(boot_drive): Moved to under KERNEL_SECTOR.
+	(kernel_sector): Moved to under KERNEL_SEGMENT. Allocate 64-bit
+	space.
+	(real_start): Set %si earlier. Remove code for FORCE_LBA, since it
+	is useless.
+	(lba_mode): Refactored to support a 64-bit address. More size
+	optimization.
+	(setup_sectors): Likewise.
+
+2006-06-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Added include/grub/i386/linux.h. Removed
+	include/grub/i386/pc/linux.h
+
+	* configure.ac (AC_INIT): Bumped to 1.94.
+
+	* config.guess: Updated from gnulib.
+	* config.sub: Likewise.
+	* install-sh: Likewise.
+	* mkinstalldirs: Likewise.
+
+2006-06-02  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* conf/common.rmk (grub_modules_init.lst): Depended on
+	grub_emu_SOURCES, excluding grub_emu_init.c, instead of
+	MODSRCFILES.
+
+	* genmk.rb (PModule::rule): Reverted the previous change.
+
+2006-06-02  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* conf/common.rmk (grub_modules_init.lst): Depends on
+	$(MODSRCFILES). Grep only the files in $(MODSRCFILES). Make sure
+	that the target does not exist before producing.
+	(grub_modules_init.h): Remove the target before generating.
+	(grub_emu_init.c): Likewise.
+
+	* genmk.rb (PModule::rule): Add source files into MODSRCFILES.
+
+2006-05-31  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* configure.ac: Don't set host_m32 for x86_64. Also reset LIBS
+	for the target-specific tests. Make sure that we also have the
+	up-to-date target variables for those tests.
+
+2006-05-31  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* genmk.rb (Image::rule): Prefix CFLAGS or ASFLAGS with TARGET_.
+	(PModule::rule): Likewise.
+
+2006-05-31  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* genmk.rb (Image::rule): Set FLAG to CFLAGS or ASFLAGS instead of
+	TARGET_CFLAGS or TARGET_ASFLAGS. There is no reason why
+	target-specific flags should be prefixed.
+	(PModule::rule): Likewise.
+
+2006-05-30  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.ac (CMP): Check if cmp is available explicitly.
+
+2006-05-29  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/powerpc/ieee1275/grub-install.in (host_cpu): Removed.
+	(target_cpu): New variable.
+	(pkglibdir): Use target_cpu instead of host_cpu.
+
+	* util/i386/pc/grub-install.in (host_cpu): Removed.
+	(target_cpu): New variable.
+	(pkglibdir): Use target_cpu instead of host_cpu.
+
+	* util/genmoddep.c: Removed.
+
+	* kern/efi/mm.c (filter_memory_map): Use GRUB_CPU_SIZEOF_VOID_P
+	instead of GRUB_HOST_SIZEOF_VOID_P.
+	* kern/dl.c: Likewise.
+
+	* include/grub/i386/types.h (GRUB_HOST_SIZEOF_VOID_P): Renamed to
+	...
+	(GRUB_TARGET_SIZEOF_VOID_P): ... this.
+	(GRUB_HOST_SIZEOF_LONG): Renamed to ...
+	(GRUB_TARGET_SIZEOF_LONG): ... this.
+	(GRUB_HOST_WORDS_BIGENDIAN): Renamed to ...
+	(GRUB_TARGET_WORDS_BIGENDIAN): ... this.
+	* include/grub/powerpc/types.h (GRUB_HOST_SIZEOF_VOID_P): Renamed
+	to ...
+	(GRUB_TARGET_SIZEOF_VOID_P): ... this.
+	(GRUB_HOST_SIZEOF_LONG): Renamed to ...
+	(GRUB_TARGET_SIZEOF_LONG): ... this.
+	(GRUB_HOST_WORDS_BIGENDIAN): Renamed to ...
+	(GRUB_TARGET_WORDS_BIGENDIAN): ... this.
+	* include/grub/sparc64/types.h (GRUB_HOST_SIZEOF_VOID_P): Renamed
+	to ...
+	(GRUB_TARGET_SIZEOF_VOID_P): ... this.
+	(GRUB_HOST_SIZEOF_LONG): Renamed to ...
+	(GRUB_TARGET_SIZEOF_LONG): ... this.
+	(GRUB_HOST_WORDS_BIGENDIAN): Renamed to ...
+	(GRUB_TARGET_WORDS_BIGENDIAN): ... this.
+
+	* include/grub/types.h [!GRUB_UTIL] (GRUB_CPU_SIZEOF_VOID_P): Use
+	GRUB_TARGET_SIZEOF_VOID_P instead of GRUB_HOST_SIZEOF_VOID_P.
+	[!GRUB_UTIL] (GRUB_CPU_SIZEOF_LONG): Use GRUB_TARGET_SIZEOF_LONG
+	instead of GRUB_HOST_SIZEOF_LONG.
+	[!GRUB_UTIL]: Refer to GRUB_TARGET_WORDS_BIGENDIAN instead of
+	GRUB_HOST_WORDS_BIGENDIAN to define or undefine
+	GRUB_CPU_WORDS_BIGENDIAN.
+	Refer to SIZEOF_VOID_P instead of GRUB_HOST_SIZEOF_VOID_P to
+	define grub_host_addr_t, grub_host_off_t, grub_host_size_t and
+	grub_host_ssize_t.
+
+	* conf/i386-efi.rmk (noinst_UTILITIES): Removed.
+	(genmoddep_SOURCES): Likewise.
+	* conf/i386-pc.rmk (noinst_UTILITIES): Likewise.
+	(genmoddep_SOURCES): Likewise.
+	* conf/conf/powerpc-ieee1275.rmk (noinst_UTILITIES): Likewise.
+	(genmoddep_SOURCES): Likewise.
+	* conf/conf/conf/sparc64-ieee1275.rmk (noinst_UTILITIES):
+	Likewise.
+	(genmoddep_SOURCES): Likewise.
+
+	* genmoddep.awk: New file.
+
+	* genmk.rb (Image::rule): Use TARGET_CC, TARGET_CPPFLAGS,
+	TARGET_CFLAGS, TARGET_ASFLAGS and TARGET_LDFLAGS instead of CC,
+	CPPFLAGS, CFLAGS, ASFLAGS and LDFLAGS, respectively.
+	(PModule::rule): Likewise.
+	(Program::rule): Likewise.
+	(Utility::rule): Use CC, CPPFLAGS, CFLAGS and LDFLAGS instead of
+	BUILD_CC, BUILD_CPPFLAGS, BUILD_CFLAGS and BUILD_LDFLAGS,
+	respectively.
+
+	* configure.ac: Rewritten intensively to use host and target
+	instead of build and host, respectively.
+
+	* Makefile.in (pkglibdir): Use target_cpu instead of host_cpu.
+	(host_cpu): Removed.
+	(target_cpu): New variable.
+	(CPPFLAGS): Added @CPPFLAGS@ and -DGRUB_LIBDIR=\"$(pkglibdir)\".
+	(BUILD_CC): Removed.
+	(BUILD_CFLAGS): Likewise.
+	(BUILD_CPPFLAGS): Likewise.
+	(TARGET_CC): New variable.
+	(TARGET_CFLAGS): Likewise.
+	(TARGET_CPPFLAGS): Likewise.
+	(TARGET_LDFLAGS): Likewise.
+	(AWK): Likewise.
+	(include): Use target_cpu instead of host_cpu.
+	(moddep.lst:): Use genmoddep.awk instead of genmoddep.
+
+	* DISTLIST: Added genmoddep.awk. Removed util/genmoddep.c.
+
+2006-05-29  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* include/grub/script.h (grub_script_cmdif): Renamed field 'bool' to
+	'exec_to_evaluate'.  Renamed field 'true' to 'exec_on_true'.  Renamed
+	field 'false' to 'exec_on_false'.
+	(grub_script_create_cmdif): Renamed argument names to reflect above
+	changes.
+
+	* normal/execute.c (grub_script_execute_cmdif): Likewise.
+
+	* normal/script.c (grub_script_create_cmdif): Likewise.
+
+2006-05-28  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* fs/hfsplus.c (grub_hfsplus_btree_recoffset): Moved to near the
+	top.
+	(grub_hfsplus_btree_recptr): Likewise.
+	(grub_hfsplus_find_block): Do not take RETRY any longer. Use
+	FILEBLOCK both to pass a block number and store next block
+	number.
+	(grub_hfsplus_read_block): Rewritten heavily to support an extent
+	overflow file correctly. Specify errors appropriately, because
+	fshelp expects that GRUB_ERRNO is set when fails. Reuse
+	grub_hfsplus_btree_recptr to get the pointer to a found key.
+	(grub_hfsplus_btree_search): Return 1 instead of 0 when no match
+	is found.
+
+	* conf/i386-efi.rmk (pkgdata_MODULES): Added _linux.mod and
+	linux.mod.
+	(_linux_mod_SOURCES): New variable.
+	(_linux_mod_CFLAGS): Likewise.
+	(_linux_mod_LDFLAGS): Likewise.
+	(linux_mod_SOURCES): Likewise.
+	(linux_mod_CFLAGS): Likewise.
+	(linux_mod_LDFLAGS): Likewise.
+
+	* DISTLIST: Added loader/i386/efi/linux.c,
+	loader/i386/efi/linux_normal.c and
+	include/grub/i386/efi/loader.h.
+
+	* loader/i386/efi/linux.c: New file.
+	* loader/i386/efi/linux_normal.c: Likewise.
+	* include/grub/i386/efi/loader.h: Likewise.
+
+2006-05-27  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* commands/blocklist.c: New file.
+
+	* DISTLIST: Added commands/blocklist.c.
+
+	* term/efi/console.c (grub_console_highlight_color): Use a lighter
+	color for the background, and a darker color for the foreground.
+	(grub_console_checkkey): Return READ_KEY.
+	(grub_console_cls): Set the background to
+	GRUB_EFI_BACKGROUND_BLACK temporarily to clean out the screen.
+
+	* kern/efi/efi.c (grub_efi_exit_boot_services): New function.
+
+	* include/grub/i386/linux.h (struct linux_kernel_params): Fixed
+	the size of "padding5", "hd0_drive_info" and "hd1_drive_info".
+
+	* include/grub/efi/efi.h (grub_efi_exit_boot_services): New
+	prototype.
+
+	* include/grub/efi/api.h (GRUB_EFI_TEXT_ATTR): Do not shift
+	BG. The spec is wrong again.
+
+	* include/grub/normal.h [GRUB_UTIL] (grub_blocklist_init): New
+	prototype.
+	[GRUB_UTIL] (grub_blocklist_fini): Likewise.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Added
+	commands/blocklist.c.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+	* conf/common.rmk (pkgdata_MODULES): Added blocklist.mod.
+	(blocklist_mod_SOURCES): New variable.
+	(blocklist_mod_CFLAGS): Likewise.
+	(blocklist_mod_LDFLAGS): Likewise.
+
+2006-05-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* boot/i386/pc/boot.S (real_start): Set %si earlier to eliminate
+	duplication.
+	(lba_mode): Use %eax more intensively to reduce the code size.
+
+2006-05-20  Marco Gerards  <marco@gnu.org>
+
+	* normal/lexer.c (grub_script_yylex): Don't filter out newlines.
+
+	* normal/parser.y (commandblock): Defined as <cmd>.  A subroutine
+	for `menuentry'.
+	(script): Accept leading newlines.
+	(newlines): New rule to describe 0 or more newlines.
+	(commands): Accept `command' with trailing newline.  Fixed the
+	order in which arguments were passed to `grub_script_add_cmd'.
+	Accept commands separated by newlines.
+	(function): Changed to accept newlines.
+	(menuentry) Rewritten.
+
+	* normal/script.c (grub_script_create_cmdmenu): Add new entries in
+	front of the list, instead of to the end.
+
+2006-05-19  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/i386/pc/grub-install.in (bindir): New variable.
+	(grub_mkimage): Use BINDIR instead of SBINDIR. Reported by Lee
+	Shaver <lbgwjl@gmail.com>.
+
+2006-05-14  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/i386/pc/startup.S: Include grub/cpu/linux.h instead of
+	grub/machine/linux.h
+	* loader/i386/pc/linux.c: Likewise.
+
+	* include/grub/i386/pc/linux.h: Moved to ...
+	* include/grub/i386/linux.h: ... here.
+
+	* include/grub/i386/linux.h (struct linux_kernel_params): New
+	struct.
+
+2006-05-09  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* video/i386/pc/vbe.c (grub_video_vbe_fill_rect): Corrected bounds
+	checking.
+	(grub_video_vbe_blit_glyph): Likewise.
+	(grub_video_vbe_blit_bitmap): Likewise.
+	(grub_video_vbe_blit_render_target): Likewise.
+
+2006-05-09  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.ac (--with-platform): Properly quote the square
+	brackets.
+
+2006-05-08  Marco Gerards  <marco@gnu.org>
+
+	* conf/powerpc-ieee1275.rmk (grubof_HEADERS): Renamed from
+	this...
+	(kernel_elf_HEADERS): ...to this.  Updated all users.
+	(grubof_symlist.c): Renamed from this...
+	(kernel_elf_symlist.c): ...to this.  Updated all users.
+	(pkgdata_PROGRAMS): Changed `grubof' to `kernel.elf'.
+	(grubof_SOURCES): Renamed from this...
+	(kernel_elf_SOURCES): ...to this.
+	(grubof_HEADERS): Renamed from this...
+	(kernel_elf_HEADERS): ...to this.
+	(grubof_CFLAGS): Renamed from this...
+	(kernel_elf_CFLAGS): ...to this.
+	(grubof_ASFLAGS): Renamed from this...
+	(kernel_elf_ASFLAGS): ...to this.
+	(grubof_LDFLAGS): Renamed from this...
+	(kernel_elf_LDFLAGS): ...to this.
+
+	* conf/sparc64-ieee1275.rmk (grubof_HEADERS): Renamed from
+	this...
+	(kernel_elf_HEADERS): ...to this.  Updated all users.
+	(grubof_symlist.c): Renamed from this...
+	(kernel_elf_symlist.c): ...to this.  Updated all users.
+	(pkgdata_PROGRAMS): Changed `grubof' to `kernel.elf'.
+	(grubof_SOURCES): Renamed from this...
+	(kernel_elf_SOURCES): ...to this.
+	(grubof_HEADERS): Renamed from this...
+	(kernel_elf_HEADERS): ...to this.
+	(grubof_CFLAGS): Renamed from this...
+	(kernel_elf_CFLAGS): ...to this.
+	(grubof_ASFLAGS): Renamed from this...
+	(kernel_elf_ASFLAGS): ...to this.
+	(grubof_LDFLAGS): Renamed from this...
+	(kernel_elf_LDFLAGS): ...to this.
+
+	* util/powerpc/ieee1275/grub-mkimage.c (add_segments): Use
+	`kernel.elf' instead of `grubof'.
+
+2006-05-08  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Add --with-platform to configure. Use pkglibdir instead of
+	pkgdatadir. This is reported by Roger Leigh.
+
+	* util/powerpc/ieee1275/grub-install.in (datadir): Removed.
+	(host_vendor): Likewise.
+	(host_os): Likewise.
+	(pkgdatadir): Likewise.
+	(platform): New variable.
+	(pkglibdir): Likewise.
+	Use PKGLIBDIR instead of PKGDATADIR.
+
+	* util/i386/pc/grub-install.in (datadir): Removed.
+	(host_vendor): Likewise.
+	(host_os): Likewise.
+	(pkgdatadir): Likewise.
+	(platform): New variable.
+	(pkglibdir): Likewise.
+	Use PKGLIBDIR instead of PKGDATADIR.
+
+	* util/powerpc/ieee1275/grub-mkimage.c (usage): Use GRUB_LIBDIR
+	instead of GRUB_DATADIR.
+	(main): Likewise.
+	* util/i386/pc/grub-mkimage.c (usage): Likewise.
+	(main): Likewise.
+	* util/i386/efi/grub-mkimage.c (usage): Likewise.
+	(main): Likewise.
+
+	* configure.ac (--with-platform): New option.
+	Use PLATFORM instead of HOST_VENDOR to specify a platform.
+
+	* Makefile.in: Include a makefile based on PLATFORM instead of
+	HOST_VENDOR.
+	(pkgdatadir): Not appended by the machine type.
+	(pkglibdir): Appended by the machine type.
+	(host_vendor): Removed.
+	(platform): New variable.
+	(BUILD_CPPFLAGS): Specify GRUB_LIBDIR instead of GRUB_DATADIR.
+	(install-local): Use PKGLIBDIR instead of PKGDATADIR.
+	(uninstall): Likewise.
+
+2006-05-07  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Use the environment context in the menu. Remove the commands
+	"default" and "timeout", and use variables instead.
+
+	* normal/menu.c: Include grub/env.h.
+	(print_entry): Cast TITLE to silence gcc.
+	(get_timeout): New function.
+	(set_timeout): Likewise.
+	(get_entry_number): Likewise.
+	(run_menu): Use a default entry, a fallback entry and a timeout
+	in the environment variables "default", "fallback" and
+	"timeout". Also, tweak the default entry if it is not within the
+	current menu entries.
+	(grub_menu_run): Use a fallback entry in the environment variable
+	"fallback".
+
+	* normal/main.c (read_config_file): Do not initialize
+	NEWMENU->DEFAULT_ENTRY, NEWMENU->FALLBACK_ENTRY or
+	NEWMENU->TIMEOUT.
+	(grub_normal_execute): Use a data slot to store the menu.
+
+	* include/grub/normal.h (struct grub_menu): Removed default_entry,
+	fallback_entry and timeout.
+	(struct grub_menu_list): Removed.
+	(grub_menu_list_t): Likewise.
+	(struct grub_context): Likewise.
+	(grub_context_t): Likewise.
+	(grub_context_get): Likewise.
+	(grub_context_get_current_menu): Likewise.
+	(grub_context_push_menu): Likewise.
+	(grub_context_pop_menu): Likewise.
+	(grub_default_init): Likewise.
+	(grub_default_fini): Likewise.
+	(grub_timeout_init): Likewise.
+	(grub_timeout_fini): Likewise.
+
+	* conf/sparc64-ieee1275.rmk (pkgdata_MODULES): Removed default.mod
+	and timeout.mod.
+	(normal_mod_SOURCES): Removed normal/context.c.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Removed
+	commands/default.c, commands/timeout.c and normal/context.c.
+	(normal_mod_SOURCES): Removed normal/context.c.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Removed commands/default.c,
+	commands/timeout.c and normal/context.c.
+	(normal_mod_SOURCES): Removed normal/context.c.
+
+	* conf/i386-efi.rmk (grub_emu_SOURCES): Removed
+	commands/default.c, commands/timeout.c and normal/context.c.
+	(normal_mod_SOURCES): Removed normal/context.c.
+
+	* conf/common.rmk (pkgdata_MODULES): Removed default.mod and
+	timeout.mod.
+	(default_mod_SOURCES): Removed.
+	(default_mod_CFLAGS): Likewise.
+	(default_mod_LDFLAGS): Likewise.
+	(timeout_mod_SOURCES): Removed.
+	(timeout_mod_CFLAGS): Likewise.
+	(timeout_mod_LDFLAGS): Likewise.
+
+	* DISTLIST: Removed commands/default.c, commands/timeout.c and
+	normal/context.c.
+
+	* commands/default.c: Removed.
+	* commands/timeout.c: Likewise.
+	* normal/context.c: Likewise.
+
+2006-05-07  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* kern/i386/pc/startup.S (grub_exit): Added missing .code32 tag.
+
+2006-05-02  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/env.c (struct grub_env_context): Removed "sorted". Renamed
+	"next" to "prev" for readability.
+	(struct grub_env_sorted_var): New struct.
+	(grub_env_context): Renamed to ...
+	(initial_context): ... this.
+	(grub_env_var_context): Renamed to ...
+	(current_context): ... this.
+	(grub_env_find): Look only at CURRENT_CONTEXT.
+	(grub_env_context_open): Rewritten to copy exported variables from
+	previous context.
+	(grub_env_context_close): Rewritten according to the new
+	scheme. Also, add an assertion to prevent the initial context from
+	removed.
+	(grub_env_insert): Removed the code for the sorted list.
+	(grub_env_remove): Likewise.
+	(grub_env_export): Simply mark the variable with
+	GRUB_ENV_VAR_GLOBAL.
+	(grub_env_set): A cosmetic change for naming consistency.
+	(grub_env_get): Likewise.
+	(grub_env_unset): Likewise.
+	(grub_env_iterate): Rewritten to sort variables within this
+	function.
+	(grub_register_variable_hook): Fixed for naming consistency. Call
+	grub_env_find again, only if NAME is not found at the first time.
+	(mangle_data_slot_name): New function.
+	(grub_env_set_data_slot): Likewise.
+	(grub_env_get_data_slot): Likewise.
+	(grub_env_unset_data_slot): Likewise.
+
+	* include/grub/env.h (grub_env_var_type): New enum.
+	(GRUB_ENV_VAR_LOCAL): New constant.
+	(GRUB_ENV_VAR_GLOBAL): Likewise.
+	(GRUB_ENV_VAR_DATA): Likewise.
+	(struct grub_env_var): Removed "sort_next" and "sort_prevp". Added
+	"type".
+	(grub_env_set): Replace VAR with NAME for consistency.
+	(grub_register_variable_hook): Likewise.
+	(grub_env_export): Specify the name of the argument.
+	(grub_env_set_data_slot): New prototype.
+	(grub_env_get_data_slot): Likewise.
+	(grub_env_unset_data_slot): Likewise.
+
+2006-04-30  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Extend the loader so that GRUB can accept a loader which comes
+	back to GRUB when a loaded image exits. Also, this change adds
+	support for a chainloader on EFI.
+
+	* term/efi/console.c: Include grub/misc.h.
+	(grub_console_checkkey): Display a scan code on the top for
+	debugging. This will be removed once the EFI port gets stable.
+	Correct the scan code mapping.
+
+	* kern/efi/mm.c (sort_memory_map): Sort in a descending order to
+	allocate memory from larger regions, in order to reduce the number
+	of allocated regions. Otherwise, the MacOSX loader panics.
+	(filter_memory_map): Avoid less than 1MB for compatibility with
+	other loaders.
+	(add_memory_regions): Allocate from the tail of a region, if
+	possible, to avoid allocating a region near to 1MB, for the MacOSX
+	loader.
+
+	* kern/efi/init.c (grub_efi_set_prefix): Specify
+	GRUB_EFI_IMAGE_HANDLE to grub_efi_get_loaded_image.
+
+	* kern/efi/efi.c (grub_efi_get_loaded_image): Accept a new
+	argument IMAGE_HANDLE and specify it to get a loaded image.
+	(grub_arch_modules_addr): Specify GRUB_EFI_IMAGE_HANDLE to
+	grub_efi_get_loaded_image.
+	(grub_efi_get_filename): Divide the length by the size of
+	grub_efi_char16_t.
+	(grub_efi_get_device_path): New function.
+	(grub_efi_print_device_path): Print End Device Path nodes. Divide
+	the length by the size of grub_efi_char16_t for a file path device
+	path node.
+
+	* kern/loader.c (grub_loader_noreturn): New variable.
+	(grub_loader_set): Accept a new argument NORETURN. Set
+	GRUB_LOADER_NORETURN to NORETURN.
+	All callers changed.
+	(grub_loader_boot): If GRUB_LOADER_NORETURN is false, do not call
+	grub_machine_fini.
+
+	* include/grub/efi/efi.h (grub_efi_get_device_path): New
+	prototype.
+	(grub_efi_get_loaded_image): Take an argument to specify an image
+	handle.
+
+	* include/grub/loader.h (grub_loader_set): Added one more argument
+	NORETURN.
+
+	* disk/efi/efidisk.c (make_devices): Use grub_efi_get_device_path
+	instead of grub_efi_open_protocol.
+	(grub_efidisk_get_device_name): Likewise.
+	(grub_efidisk_close): Print a newline.
+	(grub_efidisk_get_device_handle): Fixed to use
+	GRUB_EFI_DEVICE_PATH_SUBTYPE instead of
+	GRUB_EFI_DEVICE_PATH_TYPE.
+
+	* disk/efi/efidisk.c (device_path_guid): Moved to ...
+	* kern/efi/efi.c (device_path_guid): ... here.
+
+	* conf/i386-efi.rmk (pkgdata_MODULES): Added _chain.mod and
+	chain.mod.
+	(kernel_mod_HEADERS): Added efi/disk.h.
+	(_chain_mod_SOURCES): New variable.
+	(_chain_mod_CFLAGS): Likewise.
+	(_chain_mod_LDFLAGS): Likewise.
+	(chain_mod_SOURCES): Likewise.
+	(chain_mod_CFLAGS): Likewise.
+	(chain_mod_LDFLAGS): Likewise.
+
+	* DISTLIST: Added include/grub/efi/chainloader.h,
+	loader/efi/chainloader.c and loader/efi/chainloader_normal.c.
+
+	* include/grub/efi/chainloader.h: New file.
+	* loader/efi/chainloader.c: Likewise.
+	* loader/efi/chainloader_normal.c: Likewise.
+
+2006-04-30  Marco Gerards  <marco@gnu.org>
+
+	* commands/configfile.c (grub_cmd_source): New function.
+	(GRUB_MOD_INIT): Register the commands `source' and `.'.
+	(GRUB_MOD_FINI): De-register the commands `source' and `.'.
+
+2006-04-30  Marco Gerards  <marco@gnu.org>
+
+	* normal/execute.c (grub_script_execute_cmd): Change the return
+	type to `grub_err_t'.  Correctly return the error.
+	(grub_script_execute_cmdline): In case a command line is not a
+	command or a function, try to interpret it as an assignment.
+
+2006-04-30  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* fs/hfsplus.c (grub_hfsplus_read_block): Fixed a memory leak.
+	(grub_hfsplus_iterate_dir): Reordered to skip unknown nodes. Also,
+	skip a node whose name is obviously invalid as UTF-16,
+	i.e. contains a NUL character. Stop the iteration when the last
+	directory entry is found. Instead of using the return value of
+	grub_hfsplus_btree_iterate_node, store the value in RET and use
+	it, because the iterator can be stopped by the last directory
+	entry.
+
+2006-04-30  Marco Gerards  <marco@gnu.org>
+
+	* include/grub/env.h (grub_env_export): New prototype.  Reported
+	by Jan C. Kleinsorge <jan.kleinsorge@udo.edu>.
+
+2006-04-30  Marco Gerards  <marco@gnu.org>
+
+	* fs/hfsplus.c (grub_hfsplus_iterate_dir): Correctly calculate the
+	size of the extents in a catalog file record.
+
+2006-04-29  Marco Gerards  <marco@gnu.org>
+
+	* commands/configfile.c (grub_cmd_configfile): Execute the
+	configfile within its own context.
+
+	* include/grub/env.h (grub_env_context_open): New prototype.
+	(grub_env_context_close): Likewise.
+
+	* kern/env.c (grub_env): Removed.
+	(grub_env_sorted): Likewise.
+	(grub_env_context): New variable.
+	(grub_env_var_context): Likewise.
+	(grub_env_find): Search both the active context and the global
+	context.
+	(grub_env_context_open): New function.
+	(grub_env_context_close): Likewise.
+	(grub_env_insert): Likewise.
+	(grub_env_remove): Likewise.
+	(grub_env_export): Likewise.
+	(grub_env_set): Changed to use helper functions to avoid code
+	duplication.
+	(grub_env_iterate): Rewritten so both the current context and the
+	global context are being used.
+
+	* normal/command.c (export_command): New function.
+	(grub_command_init): Register the `export' function.
+
+2006-04-26  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/i386/pc/grub-mkimage.c (compress_kernel): Cast arguments
+	explicitly to suppress gcc's warnings.
+	* fs/fat.c (grub_fat_find_dir): Likewise.
+	(grub_fat_label): Likewise.
+	* fs/xfs.c (grub_xfs_read_inode): Likewise.
+	(grub_xfs_mount): Likewise.
+	(grub_xfs_label): Likewise.
+	* fs/affs.c (grub_affs_mount): Likewise.
+	(grub_affs_label): Likewise.
+	(grub_affs_iterate_dir): Likewise.
+	* fs/sfs.c (grub_sfs_mount): Likewise.
+	(grub_sfs_iterate_dir): Likewise.
+	* fs/ufs.c (grub_ufs_lookup_symlink): Likewise.
+	* fs/hfs.c (grub_hfs_mount): Likewise.
+	(grub_hfs_cmp_catkeys): Likewise.
+	(grub_hfs_find_dir): Likewise.
+	(grub_hfs_dir): Likewise.
+	(grub_hfs_label): Likewise.
+	* fs/jfs.c (grub_jfs_mount): Likewise.
+	(grub_jfs_opendir): Likewise.
+	(grub_jfs_getent): Likewise.
+	(grub_jfs_lookup_symlink): Likewise.
+	(grub_jfs_label): Likewise.
+	* fs/hfsplus.c (grub_hfsplus_cmp_catkey): Likewise.
+	(grub_hfsplus_iterate_dir): Likewise.
+	(grub_hfsplus_btree_iterate_node): Made static.
+
+	* util/grub-emu.c (prefix): New variable.
+	(grub_machine_set_prefix): New function.
+	(main): Do not set the environment variable "prefix" here. Only
+	set PREFIX, which is used later by grub_machine_set_prefix.
+
+	* include/grub/video.h: Do not include grub/symbol.h.
+	(grub_video_register): Not exported. This symbol is not defined in
+	the kernel.
+	(grub_video_unregister): Likewise.
+	(grub_video_iterate): Likewise.
+	(grub_video_setup): Likewise.
+	(grub_video_restore): Likewise.
+	(grub_video_get_info): Likewise.
+	(grub_video_get_blit_format): Likewise.
+	(grub_video_set_palette): Likewise.
+	(grub_video_get_palette): Likewise.
+	(grub_video_set_viewport): Likewise.
+	(grub_video_get_viewport): Likewise.
+	(grub_video_map_color): Likewise.
+	(grub_video_map_rgb): Likewise.
+	(grub_video_map_rgba): Likewise.
+	(grub_video_fill_rect): Likewise.
+	(grub_video_blit_glyph): Likewise.
+	(grub_video_blit_bitmap): Likewise.
+	(grub_video_blit_render_target): Likewise.
+	(grub_video_scroll): Likewise.
+	(grub_video_swap_buffers): Likewise.
+	(grub_video_create_render_target): Likewise.
+	(grub_video_delete_render_target): Likewise.
+	(grub_video_set_active_render_target): Likewise.
+
+	* include/grub/symbol.h [GRUB_SYMBOL_GENERATOR] (EXPORT_FUNC):
+	Undefined.
+	[GRUB_SYMBOL_GENERATOR] (EXPORT_VAR): Likewise.
+
+	* conf/sparc64-ieee1275.rmk (grubof_symlist.c): Depended on
+	config.h. Use gensymlist.sh instead of $(srcdir)/gensymlist.sh.
+	(kernel_syms.lst): Depended on config.h. Use genkernsyms.sh
+	instead of $(srcdir)/genkernsyms.sh.
+
+	* conf/powerpc-ieee1275.rmk (grubof_symlist.c): Depended on
+	config.h. Use gensymlist.sh instead of $(srcdir)/gensymlist.sh.
+	(kernel_syms.lst): Depended on config.h. Use genkernsyms.sh
+	instead of $(srcdir)/genkernsyms.sh.
+
+	* conf/i386-pc.rmk (symlist.c): Depended on config.h. Use
+	gensymlist.sh instead of $(srcdir)/gensymlist.sh.
+	(kernel_syms.lst): Depended on config.h. Use genkernsyms.sh
+	instead of $(srcdir)/genkernsyms.sh.
+
+	* conf/i386-efi.rmk (symlist.c): Depended on config.h. Use
+	gensymlist.sh instead of $(srcdir)/gensymlist.sh.
+	(kernel_syms.lst): Depended on config.h. Use genkernsyms.sh
+	instead of $(srcdir)/genkernsyms.sh.
+
+	* configure.ac (AC_CONFIG_FILES): Added gensymlist.sh and
+	genkernsyms.sh.
+
+	* Makefile.in (DISTCLEANFILES): Added gensymlist.sh and
+	genkernsyms.sh.
+	(gensymlist.sh): New target.
+	(genkernsyms.sh): Likewise.
+
+	* DISTLIST: Removed genkernsyms.sh and gensymlist.sh. Added
+	genkernsyms.sh.in and gensymlist.sh.in.
+
+	* genkernsyms.sh: Removed.
+	* gensymlist.sh: Likewise.
+
+	* genkernsyms.sh.in: New file.
+	* gensymlist.sh.in: Likewise.
+
+2006-04-25  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/powerpc/ieee1275/init.c (grub_machine_set_prefix): Do not
+	clobber "prefix", since we may have already set it manually.
+
+2006-04-25  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/misc.c (abort): New alias for grub_abort.
+
+2006-04-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	A new machine-specific function "grub_machine_set_prefix" is
+	defined. This is called after loading modules, so that a prefix
+	initialization can use modules. Also, this change adds an
+	intensive debugging feature for the memory manager via the
+	configure option "--enable-mm-debug".
+
+	* partmap/gpt.c (gpt_partition_map_iterate): Add one more into
+	PART.LEN.
+
+	* kern/sparc64/ieee1275/init.c (abort): Removed.
+	(grub_stop): Likewise.
+	(grub_exit): New function.
+	(grub_set_prefix): Renamed to ...
+	(grub_machine_set_prefix): ... this.
+	(grub_machine_init): Do not call grub_set_prefix.
+
+	* kern/powerpc/ieee1275/init.c (grub_set_prefix): Renamed to ...
+	(grub_machine_set_prefix): ... this.
+	(grub_machine_init): Do not call grub_set_prefix.
+
+	* kern/i386/pc/init.c (grub_machine_set_prefix): New function.
+	(grub_machine_init): Do not set the prefix here.
+
+	* kern/i386/efi/init.c (grub_machine_set_prefix): New function.
+
+	* kern/efi/init.c: Include grub/mm.h.
+	(grub_efi_set_prefix): New function.
+
+	* kern/efi/efi.c (grub_exit): Call grub_efi_fini.
+	(grub_efi_get_filename): New function.
+	(grub_print_device_path): Renamed to ...
+	(grub_efi_print_device_path): ... this.
+
+	* kern/mm.c [MM_DEBUG] (grub_malloc): Undefined.
+	[MM_DEBUG] (grub_realloc): Likewise.
+	[MM_DEBUG] (grub_free): Likewise.
+	[MM_DEBUG] (grub_memalign): Likewise.
+	[MM_DEBUG] (grub_mm_debug): New variable.
+	[MM_DEBUG] (grub_debug_malloc): New function.
+	[MM_DEBUG] (grub_debug_free): New function.
+	[MM_DEBUG] (grub_debug_realloc): New function.
+	[MM_DEBUG] (grub_debug_memalign): New function.
+
+	* kern/misc.c (grub_abort): Print a newline to distinguish
+	the message.
+
+	* kern/main.c (grub_main): Call grub_machine_set_prefix and
+	grub_set_root_dev after loading modules. This is necessary when
+	setting a prefix depends on modules.
+
+	* include/grub/efi/efi.h (grub_print_device_path): Renamed to ...
+	(grub_efi_print_device_path): ... this.
+	(grub_efi_get_filename): New prototype.
+	(grub_efi_set_prefix): Likewise.
+
+	* include/grub/efi/disk.h: Include grub/efi/api.h, grub/symbol.h
+	and grub/disk.h.
+	(grub_efidisk_get_device_handle): New prototype.
+	(grub_efidisk_get_device_name): Likewise.
+
+	* include/grub/mm.h: Include config.h.
+	(MM_DEBUG): Removed.
+	[MM_DEBUG && !GRUB_UTIL] (grub_mm_debug): New prototype.
+	[MM_DEBUG && !GRUB_UTIL] (grub_malloc): New macro.
+	[MM_DEBUG && !GRUB_UTIL] (grub_realloc): Likewise.
+	[MM_DEBUG && !GRUB_UTIL] (grub_memalign): Likewise.
+	[MM_DEBUG && !GRUB_UTIL] (grub_free): Likewise.
+	[MM_DEBUG && !GRUB_UTIL] (grub_debug_malloc): New prototype.
+	[MM_DEBUG && !GRUB_UTIL] (grub_debug_realloc): New prototype.
+	[MM_DEBUG && !GRUB_UTIL] (grub_debug_memalign): New prototype.
+	[MM_DEBUG && !GRUB_UTIL] (grub_debug_free): New prototype.
+
+	* include/grub/kernel.h (grub_machine_set_prefix): New prototype.
+
+	* disk/efi/efidisk.c: Include grub/partition.h.
+	(iterate_child_devices): New function.
+	(add_device): First, compare only last device path nodes, so that
+	devices are sorted by the types.
+	(grub_efidisk_get_device_handle): New function.
+	(grub_efidisk_get_device_name): Likewise.
+
+	* configure.ac (--enable-mm-debug): New option to enable the
+	memory manager debugging feature. This makes the binary much
+	bigger, so is disabled by default.
+
+2006-04-23  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Use grub_abort instead of grub_stop, and grub_exit must be
+	define in each architecture now. Also, this change adds support
+	for EFI disks.
+
+	* util/i386/pc/grub-probefs.c: Include grub/term.h.
+	(grub_getkey): New function.
+	(grub_term_get_current): Likewise.
+
+	* util/i386/pc/grub-setup.c: Include grub/term.h.
+	(grub_getkey): New function.
+	(grub_term_get_current): Likewise.
+
+	* util/misc.c (grub_stop): Renamed to ...
+	(grub_exit): ... this.
+
+	* kern/powerpc/ieee1275/init.c (abort): Renamed to ...
+	(grub_exit): ... this.
+	(grub_machine_init): Use grub_abort instead of abort.
+	(grub_stop): Removed.
+
+	* kern/powerpc/ieee1275/cmain.c (cmain): Use grub_abort instead of
+	abort.
+
+	* kern/i386/pc/startup.S (grub_exit): New function.
+	(cold_reboot): New label.
+
+	* kern/efi/init.c: Include grub/efi/disk.h and grub/env.h.
+	(grub_efi_init): Call grub_efidisk_init.
+	(grub_efi_fini): Call grub_efidisk_fini.
+
+	* kern/efi/efi.c: Include grub/mm.h.
+	(grub_efi_console_control_guid): Renamed to ...
+	(console_control_guid): ... this.
+	(grub_efi_loaded_image_guid): Renamed to ...
+	(loaded_image_guid): ... this.
+	(grub_efi_locate_handle): New function.
+	(grub_efi_open_protocol): Likewise.
+	(grub_efi_set_text_mode): Use CONSOLE_CONTROL_GUID instead of
+	GRUB_EFI_CONSOLE_CONTROL_GUID.
+	(grub_efi_exit): Removed.
+	(grub_stop): Likewise.
+	(grub_efi_get_loaded_image): Use grub_efi_open_protocol.
+	(grub_exit): New function.
+	(grub_print_device_path): Likewise.
+
+	* kern/rescue.c (grub_rescue_cmd_exit): New function.
+	(grub_enter_rescue_mode): Register "exit".
+
+	* kern/misc.c (grub_real_dprintf): A cosmetic change.
+	(grub_abort): New function.
+
+	* kern/err.c (grub_fatal): Use grub_abort instead of grub_stop.
+
+	* include/grub/sparc64/ieee1275/kernel.h (abort): Removed.
+
+	* include/grub/powerpc/ieee1275/kernel.h (abort): Removed.
+
+	* include/grub/efi/efi.h (grub_efi_exit): Removed.
+	(grub_print_device_path): New prototype.
+	(grub_efi_locate_handle): Likewise.
+	(grub_efi_open_protocol): Likewise.
+
+	* include/grub/efi/disk.h (grub_efidisk_fini): New file.
+	* disk/efi/efidisk.c: Likewise.
+
+	* DISTLIST: Added disk/efi/efidisk.c and include/grub/efi/disk.h.
+
+	* include/grub/efi/console_control.h
+	(GRUB_EFI_CONSOLE_CONTROL_GUID): Use an array for the last 8 bytes.
+
+	* include/grub/efi/api.h (GRUB_EFI_LOADED_IMAGE_GUID): Specify the
+	last 8 bytes as an array.
+	(GRUB_EFI_DISK_IO_GUID): New macro.
+	(GRUB_EFI_BLOCK_IO_GUID): Likewise.
+	(GRUB_EFI_DEVICE_PATH_GUID): Likewise.
+	(grub_efi_ipv6_address_t): Change the type to grub_uint16_t from
+	grub_uint8_t.
+	(struct grub_efi_guid): Use an array to specify the last 8 bytes.
+	(struct grub_efi_device_path): Rename the member "sub_type" to
+	"subtype".
+	(GRUB_EFI_DEVICE_PATH_TYPE): New macro.
+	(GRUB_EFI_DEVICE_PATH_SUBTYPE): Likewise.
+	(GRUB_EFI_DEVICE_PATH_LENGTH): Likewise.
+	(GRUB_EFI_END_DEVICE_PATH_TYPE): Likewise.
+	(GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE): Likewise.
+	(GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE): Likewise.
+	(GRUB_EFI_END_ENTIRE_DEVICE_PATH): Likewise.
+	(GRUB_EFI_NEXT_DEVICE_PATH): Likewise.
+	(GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE): Likewise.
+	(GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE): Likewise.
+	(struct grub_efi_pci_device_path): New structure.
+	(grub_efi_pci_device_path_t): New type.
+	(GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_pccard_device_path): New structure.
+	(grub_efi_pccard_device_path_t): New type.
+	(GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_memory_mapped_device_path): New structure.
+	(grub_efi_memory_mapped_device_path_t): New type.
+	(GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_vendor_device_path): New structure.
+	(grub_efi_vendor_device_path_t): New type.
+	(GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_controller_device_path): New structure.
+	(grub_efi_controller_device_path_t): New type.
+	(GRUB_EFI_ACPI_DEVICE_PATH_TYPE): New macro.
+	(GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE): Likewise.
+	(struct grub_efi_acpi_device_path): New structure.
+	(grub_efi_acpi_device_path_t): New type.
+	(GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_expanded_acpi_device_path): New structure.
+	(grub_efi_expanded_acpi_device_path_t): New type.
+	(GRUB_EFI_EXPANDED_ACPI_HIDSTR): New macro.
+	(GRUB_EFI_EXPANDED_ACPI_UIDSTR): Likewise.
+	(GRUB_EFI_EXPANDED_ACPI_CIDSTR): Likewise.
+	(GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE): Likewise.
+	(GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE): Likewise.
+	(struct grub_efi_atapi_device_path): New structure.
+	(grub_efi_atapi_device_path_t): New type.
+	(GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_fibre_channel_device_path): New structure.
+	(grub_efi_fibre_channel_device_path_t): New type.
+	(GRUB_EFI_1394_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_1394_device_path): New structure.
+	(grub_efi_1394_device_path_t): New type.
+	(GRUB_EFI_USB_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_usb_device_path): New structure.
+	(grub_efi_usb_device_path_t): New type.
+	(GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_usb_class_device_path): New structure.
+	(grub_efi_usb_class_device_path_t): New type.
+	(GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_i2o_device_path): New structure.
+	(grub_efi_i2o_device_path_t): New type.
+	(GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_mac_address_device_path): New structure.
+	(grub_efi_mac_address_device_path_t): New type.
+	(GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_ipv4_device_path): New structure.
+	(grub_efi_ipv4_device_path_t): New type.
+	(GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_ipv6_device_path): New structure.
+	(grub_efi_ipv6_device_path_t): New type.
+	(GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_infiniband_device_path): New structure.
+	(grub_efi_infiniband_device_path_t): New type.
+	(GRUB_EFI_UART_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_uart_device_path): New structure.
+	(grub_efi_uart_device_path_t): New type.
+	(GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_vendor_messaging_device_path): New structure.
+	(grub_efi_vendor_messaging_device_path_t): New type.
+	(GRUB_EFI_MEDIA_DEVICE_PATH_TYPE): New macro.
+	(GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE): Likewise.
+	(struct grub_efi_hard_drive_device_path): New structure.
+	(grub_efi_hard_drive_device_path_t): New type.
+	(GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_cdrom_device_path): New structure.
+	(grub_efi_cdrom_device_path_t): New type.
+	(GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_vendor_media_device_path): New structure.
+	(grub_efi_vendor_media_device_path_t): New type.
+	(GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_file_path_device_path): New structure.
+	(grub_efi_file_path_device_path_t): New type.
+	(GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE): New macro.
+	(struct grub_efi_protocol_device_path): New structure.
+	(grub_efi_protocol_device_path_t): New type.
+	(GRUB_EFI_BIOS_DEVICE_PATH_TYPE): New macro.
+	(GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE): Likewise.
+	(struct grub_efi_bios_device_path): New structure.
+	(grub_efi_bios_device_path_t): New type.
+	(struct grub_efi_disk_io): New structure.
+	(grub_efi_disk_io_t): New type.
+	(struct grub_efi_block_io_media): New structure.
+	(grub_efi_block_io_media_t): New type.
+	(struct grub_efi_block_io): New structure.
+	(grub_efi_block_io_t): New type.
+
+	* include/grub/misc.h (grub_stop): Removed.
+	(grub_exit): New prototype.
+	(grub_abort): Likewise.
+
+	* include/grub/disk.h (enum grub_disk_dev_id): Added
+	GRUB_DISK_DEVICE_EFIDISK_ID.
+
+	* conf/i386-efi.rmk (kernel_mod_SOURCES): Added
+	disk/efi/efidisk.c.
+	(kernel_syms.lst): Remove the target if an error occurs.
+
+2006-04-22  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/misc.c (grub_lltoa): Rewritten the decimal conversion part,
+	as it was simply too buggy.
+
+2006-04-21  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/misc.c (grub_lltoa): New function.
+	(grub_vsprintf): Added support for the long long suffix,
+	i.e. "ll".
+
+2006-04-20  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* Makefile.in (LDFLAGS): Add variable.
+	(LD): Remove variable.
+	* configure.ac: Add -m32 to LDFLAGS.
+	* genmk.rb (PModule#rule): Use $(CC) instead of $(LD).
+	* conf/powerpc-ieee1275.rmk (COMMON_LDFLAGS): Add variable.
+	(grubof_LDFLAGS): Use $(COMMON_LDFLAGS).
+	(_linux_mod_LDFLAGS, linux_mod_LDFLAGS, normal_mod_LDFLAGS,
+	suspend_mod_LDFLAGS, reboot_mod_LDFLAGS, halt_mod_LDFLAGS): New
+	variables.
+	* conf/sparc64-ieee1275.rmk (COMMON_LDFLAGS): Add -nostdlib.
+	* conf/i386-pc.rmk (COMMON_LDFLAGS): Add -nostdlib.
+	* conf/i386-efi.rmk (COMMON_LDFLAGS): Add -nostdlib.
+
+2006-04-20  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* term/gfxterm.c (grub_gfxterm_getcharwidth): Fixed character
+	length for unknown glyph.
+
+2006-04-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Add support for pre-loaded modules into the EFI port.
+
+	* util/i386/efi/grub-mkimage.c (make_mods_section): Rewritten
+	completely. Accept one more argument DIR. The caller has changed.
+
+	* kern/i386/efi/init.c (grub_arch_modules_addr): Removed.
+
+	* kern/efi/efi.c: Include grub/efi/pe32.h and grub/kernel.h.
+	(grub_efi_loaded_image_guid): New variable.
+	(grub_efi_get_loaded_image): New function.
+	(grub_arch_modules_addr): Likewise.
+
+	* include/grub/efi/efi.h (grub_efi_get_loaded_image): New
+	prototype.
+
+	* include/grub/efi/api.h (GRUB_EFI_LOADED_IMAGE_GUID): New macro.
+	(struct grub_efi_loaded_image): New structure.
+	(grub_efi_loaded_image_t): New type.
+
+2006-04-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* loader/i386/pc/linux.c (grub_rescue_cmd_linux): Compare the file
+	size with GRUB_OS_AREA_SIZE as grub_size_t instead of
+	grub_ssize_t. Reported by Jeff Chua <jeff84@silk.corp.fedex.com>.
+
+2006-04-19  Roger Leigh  <rleigh@whinlatter.ukfsn.org>
+
+	* DISTLIST: Added `util/powerpc/ieee1275/grub-install.in'.
+
+2006-04-19  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Added include/grub/efi/console.h,
+	include/grub/efi/time.h, include/grub/i386/efi/kernel.h,
+	kern/efi/init.c, kern/efi/mm.c, and term/efi/console.c.
+
+	* include/grub/efi/console.h: New file.
+	* include/grub/efi/time.h: Likewise.
+	* include/grub/i386/efi/kernel.h: Likewise.
+	* kern/efi/init.c: Likewise.
+	* kern/efi/mm.c: Likewise.
+	* term/efi/console.c: Likewise.
+
+	* kern/i386/efi/init.c: Do not include grub/machine/time.h.
+	(grub_stop): Removed.
+	(grub_get_rtc): Likewise.
+	(grub_machine_init): Simply call grub_efi_init.
+	(grub_machine_fini): Call grub_efi_fini.
+
+	* kern/efi/efi.c: Include grub/machine/time.h and grub/term.h.
+	(grub_efi_output_string): Removed.
+	(grub_efi_stall): New function.
+	(grub_stop): Likewise.
+	(grub_get_rtc): Likewise.
+
+	* include/grub/efi/efi.h (grub_efi_output_string): Removed.
+	(grub_efi_stall): New prototype.
+	(grub_efi_allocate_pages): Likewise.
+	(grub_efi_free_pages): Likewise.
+	(grub_efi_get_memory_map): Likewise.
+	(grub_efi_mm_init): Likewise.
+	(grub_efi_mm_fini): Likewise.
+	(grub_efi_init): Likewise.
+	(grub_efi_fini): Likewise.
+
+	* include/grub/i386/efi/time.h: Do not include
+	grub/symbol.h. Include grub/efi/time.h.
+	(GRUB_TICKS_PER_SECOND): Removed.
+	(grub_get_rtc): Likewise.
+
+	* include/grub/efi/api.h (struct grub_efi_memory_descriptor):
+	Added padding. The EFI spec is buggy.
+	(GRUB_EFI_BLACK): New macro.
+	(GRUB_EFI_BLUE): Likewise.
+	(GRUB_EFI_GREEN): Likewise.
+	(GRUB_EFI_CYAN): Likewise.
+	(GRUB_EFI_RED): Likewise.
+	(GRUB_EFI_MAGENTA): Likewise.
+	(GRUB_EFI_BROWN): Likewise.
+	(GRUB_EFI_LIGHTGRAY): Likewise.
+	(GRUB_EFI_BRIGHT): Likewise.
+	(GRUB_EFI_DARKGRAY): Likewise.
+	(GRUB_EFI_LIGHTBLUE): Likewise.
+	(GRUB_EFI_LIGHTGREEN): Likewise.
+	(GRUB_EFI_LIGHTCYAN): Likewise.
+	(GRUB_EFI_LIGHTRED): Likewise.
+	(GRUB_EFI_LIGHTMAGENTA): Likewise.
+	(GRUB_EFI_YELLOW): Likewise.
+	(GRUB_EFI_WHITE): Likewise.
+	(GRUB_EFI_BACKGROUND_BLACK): Likewise.
+	(GRUB_EFI_BACKGROUND_BLUE): Likewise.
+	(GRUB_EFI_BACKGROUND_GREEN): Likewise.
+	(GRUB_EFI_BACKGROUND_CYAN): Likewise.
+	(GRUB_EFI_BACKGROUND_RED): Likewise.
+	(GRUB_EFI_BACKGROUND_MAGENTA): Likewise.
+	(GRUB_EFI_BACKGROUND_BROWN): Likewise.
+	(GRUB_EFI_BACKGROUND_LIGHTGRAY): Likewise.
+	(GRUB_EFI_TEXT_ATTR): Likewise.
+
+	* conf/i386-efi.rmk (kernel_mod_SOURCES): Added kern/efi/efi.c,
+	kern/efi/init.c, kern/efi/mm.c, and term/efi/console.c.
+	(kernel_mod_HEADERS): Added efi/time.h.
+
+2006-04-18  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Added conf/i386-efi.mk, conf/i386-efi.rmk,
+	include/grub/efi/api.h, include/grub/efi/console_control.h,
+	include/grub/efi/efi.h, include/grub/efi/pe32.h,
+	include/grub/i386/efi/time.h, kern/efi/efi.c,
+	kern/i386/efi/init.c, kern/i386/efi/startup.S,
+	and util/i386/efi/grub-mkimage.c.
+
+	* Makefile.in (RMKFILES): Added i386-efi.rmk.
+
+	* genmk.rb (PModule#rule): Do not export symbols if
+	#{prefix}_EXPORTS is set to "no".
+
+	* conf/i386-efi.mk: New file.
+	* conf/i386-efi.rmk: Likewise.
+	* include/grub/efi/api.h: Likewise.
+	* include/grub/efi/console_control.h: Likewise.
+	* include/grub/efi/efi.h: Likewise.
+	* include/grub/efi/pe32.h: Likewise.
+	* include/grub/i386/efi/time.h: Likewise.
+	* kern/efi/efi.c: Likewise.
+	* kern/i386/efi/init.c: Likewise.
+	* kern/i386/efi/startup.S: Likewise.
+	* util/i386/efi/grub-mkimage.c: Likewise.
+
+2006-04-17  Marco Gerards  <marco@gnu.org>
+
+	* include/grub/script.h: Include <grub/parser.h> and
+	"grub_script.tab.h".
+	(struct grub_lexer_param): New struct.
+	(struct grub_parser_param): Likewise.
+	(grub_script_create_arglist): Pass the state in an argument.
+	(grub_script_add_arglist): Likewise.
+	(grub_script_create_cmdline): Likewise.
+	(grub_script_create_cmdblock): Likewise.
+	(grub_script_create_cmdif): Likewise.
+	(grub_script_create_cmdmenu): Likewise.
+	(grub_script_add_cmd): Likewise.
+	(grub_script_arg_add): Likewise.
+	(grub_script_lexer_ref): Likewise.
+	(grub_script_lexer_deref): Likewise.
+	(grub_script_lexer_record_start): Likewise.
+	(grub_script_lexer_record_stop): Likewise.
+	(grub_script_mem_record): Likewise.
+	(grub_script_mem_record_stop): Likewise.
+	(grub_script_malloc): Likewise.
+	(grub_script_yylex): Likewise.
+	(grub_script_yyparse): Likewise.
+	(grub_script_yyerror): Likewise.
+	(grub_script_yylex): Likewise.
+	(grub_script_lexer_init): Return the state.
+
+	* normal/lexer.c (grub_script_lexer_state): Removed variable.
+	(grub_script_lexer_done): Likewise.
+	(grub_script_lexer_getline): Likewise.
+	(grub_script_lexer_refs): Likewise.
+	(script): Likewise.
+	(newscript): Likewise.
+	(record): Likewise.
+	(recording): Likewise.
+	(recordpos): Likewise.
+	(recordlen): Likewise.
+	(grub_script_lexer_init): Return the state instead of setting
+	global variables.
+	(grub_script_lexer_ref): Use the newly added argument for state
+	instead of globals.
+	(grub_script_lexer_deref): Likewise.
+	(grub_script_lexer_record_start): Likewise.
+	(grub_script_lexer_record_stop): Likewise.
+	(recordchar): Likewise.
+	(nextchar): Likewise.
+	(grub_script_yylex2): Likewise.
+	(grub_script_yylex): Likewise.
+	(grub_script_yyerror): Likewise.
+
+	* normal/parser.y (func_mem): Removed variable.
+	(menu_entry): Likewise.
+	(err): Likewise.
+	(%lex-param): New parser option.
+	(%parse-param): Likewise.
+	(script): Always return the AST.
+	(argument): Pass the state around.
+	(arguments): Likewise.
+	(grubcmd): Likewise.
+	(commands): Likewise.
+	(function): Likewise.
+	(menuentry): Likewise.
+	(if_statement): Likewise.
+	(if): Likewise.
+
+	* normal/script.c (grub_script_memused): Removed variable.
+	(grub_script_parsed): Likewise.
+	(grub_script_malloc): Added a state argument.  Use that instead of
+	global variables.
+	(grub_script_mem_record): Likewise.
+	(grub_script_mem_record_stop): Likewise.
+	(grub_script_arg_add): Likewise.
+	(grub_script_add_arglist): Likewise.
+	(grub_script_create_cmdline): Likewise.
+	(grub_script_create_cmdif): Likewise.
+	(grub_script_create_cmdmenu): Likewise.
+	(grub_script_add_cmd): Likewise.
+	(grub_script_parse): Setup the state before calling the parser.
+
+2006-04-16  Marco Gerards  <marco@gnu.org>
+
+	* normal/command.c (grub_command_init): Remove the title command.
+
+	* normal/lexer.c (grub_script_yylex): Renamed from this...
+	(grub_script_yylex2): ... to this.
+	(grub_script_yylex): New function.  Temporary
+	introduced to filter some tokens.
+	(grub_script_yyerror): Print a newline.
+
+	* normal/main.c (read_config_file): Output information about the
+	lines that contain errors.  Wait for a key after all lines have
+	been processed.  Don't return an empty menu.
+
+	* normal/parser.y (func_mem): Don't initialize.
+	(menu_entry): Likewise.
+	(err): New variable.
+	(script): Don't return anything when an error was encountered.
+	(ws, returns): Removed rules.
+	(argument): Disabled concatenated variable support.
+	(arguments): Remove explicit separators.
+	(grubcmd): Likewise.
+	(function): Likewise.
+	(menuentry): Likewise.
+	(if): Likewise.
+	(commands): Likewise.  Add error handling.
+
+	* normal/script.c (grub_script_create_cmdline): If
+	`grub_script_parsed' is 0, assume the parser encountered an error.
+
+2006-04-02  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.ac: Add support for EFI. Fix the typo
+	BUILD_LDDFLAGS. Restore the LDFLAGS after testing.
+
+2006-04-01  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* util/unifont2pff.rb: Removed unnecessary byte ordering.  Now
+	foreign multibyte characters should be shown correctly.
+
+2006-04-01  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* normal/main.c (grub_normal_menu_addentry): Fixed menu size
+	calculation.
+	(read_config_file): Made it to close file before returning.
+
+2006-03-31  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* DISTLIST: Added include/grub/i386/pc/vbeblit.h,
+	include/grub/i386/pc/vbefill.h, video/i386/pc/vbeblit.c,
+	video/i386/pc/vbefill.c.
+
+	* conf/i386-pc.rmk (vbe_mod_SOURCES): Added video/i386/pc/vbeblit.c,
+	video/i386/pc/vbefill.c.
+
+	* include/grub/video.h (grub_video_blit_format): New enum.
+	(grub_video_mode_info): Added new member blit_format.
+	(grub_video_get_blit_format): New function prototype.
+
+	* include/grub/i386/pc/vbe.h (grub_video_vbe_get_video_ptr): New
+	function prototype.
+	(grub_video_vbe_map_rgb): Likewise.
+	(grub_video_vbe_unmap_color): Likewise.
+
+	* include/grub/i386/pc/vbeblit.h: New file.
+
+	* include/grub/i386/pc/vbefill.h: New file.
+
+	* video/video.c (grub_video_get_blit_format): New function.
+	(grub_video_vbe_get_video_ptr): Re-declared as non-static.
+	(grub_video_vbe_map_rgb): Likewise.
+	(grub_video_vbe_unmap_color): Likewise.
+
+	* video/i386/pc/vbe.c (grub_video_vbe_fill_rect): Changed to use more
+	optimized fills.
+	(grub_video_vbe_blit_render_target): Changed to use more optimized
+	blits.
+	(grub_video_vbe_setup): Added detection for optimized settings.
+	(grub_video_vbe_create_render_target): Likewise.
+
+	* video/i386/pc/vbeblit.c: New file.
+
+	* video/i386/pc/vbefill.c: New file.
+
+2006-03-30  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* font/manager.c (grub_font_get_glyph): Removed font fixup from
+	here...
+
+	* util/unifont2pff.rb: ... and moved it to here.  Improved argument
+	parsing to support both hex and dec ranges.  If filename was missing
+	show usage information.
+
+2006-03-14  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* DISTLIST: Added include/grub/video.h, term/gfxterm.c,
+	video/video.c, commands/videotest.c.  Removed term/i386/pc/vesafb.c.
+
+	* conf/i386-pc.rmk (pkgdata_MODULES): Added video.mod,
+	gfxterm.mod, videotest.mod.  Removed vga.mod, vesafb.mod.
+	(video_mod_SOURCES): Added.
+	(video_mod_CFLAGS): Likewise.
+	(video_mod_LDFLAGS): Likewise.
+	(gfxterm_mod_SOURCES): Likewise.
+	(gfxterm_mod_CFLAGS): Likewise.
+	(gfxterm_mod_LDFLAGS): Likewise.
+	(videotest_mod_SOURCES): Likewise.
+	(videotest_mod_CFLAGS): Likewise.
+	(videotest_mod_LDFLAGS): Likewise.
+	(vesafb_mod_SOURCES): Removed.
+	(vesafb_mod_CFLAGS): Likewise.
+	(vesafb_mod_LDFLAGS): Likewise.
+	(vga_mod_SOURCES): Likewise.
+	(vga_mod_CFLAGS): Likewise.
+	(vga_mod_LDFLAGS): Likewise.
+
+	* commands/videotest.c: New file.
+
+	* font/manager.c (fill_with_default_glyph): Modified to use
+	grub_font_glyph.
+	(grub_font_get_glyph): Likewise.
+	(fontmanager): Renamed from this...
+	(font_manager): ... to this.
+
+	* include/grub/font.h (grub_font_glyph): Added new structure.
+	(grub_font_get_glyph): Modified to use grub_font_glyph.
+
+	* include/grub/misc.h (grub_abs): Added as inline function.
+
+	* include/grub/video.h: New file.
+
+	* include/grub/i386/pc/vbe.h (GRUB_VBE_STATUS_OK): New macro.
+	(GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL): Likewise.
+	(GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR): Likewise.
+	(grub_vbe_get_controller_info): Renamed from this...
+	(grub_vbe_bios_get_controller_info): ... to this.
+	(grub_vbe_get_mode_info): Renamed from this...
+	(grub_vbe_bios_get_mode_info): ... to this.
+	(grub_vbe_set_mode): Renamed from this...
+	(grub_vbe_bios_set_mode): ... to this.
+	(grub_vbe_get_mode): Renamed from this...
+	(grub_vbe_bios_get_mode): ... to this.
+	(grub_vbe_set_memory_window): Renamed from this...
+	(grub_vbe_bios_set_memory_window): ... to this.
+	(grub_vbe_get_memory_window): Renamed from this...
+	(grub_vbe_bios_get_memory_window): ... to this.
+	(grub_vbe_set_scanline_length): Renamed from this...
+	(grub_vbe_set_scanline_length): ... to this.
+	(grub_vbe_get_scanline_length): Renamed from this...
+	(grub_vbe_bios_get_scanline_length): ... to this.
+	(grub_vbe_set_display_start): Renamed from this...
+	(grub_vbe_bios_set_display_start): ... to this.
+	(grub_vbe_get_display_start): Renamed from this...
+	(grub_vbe_bios_get_display_start): ... to this.
+	(grub_vbe_set_palette_data): Renamed from this...
+	(grub_vbe_bios_set_palette_data): ... to this.
+	(grub_vbe_set_pixel_rgb): Removed.
+	(grub_vbe_set_pixel_index): Likewise.
+
+	* kern/i386/pc/startup.S (grub_vbe_get_controller_info): Renamed
+	from this...
+	(grub_vbe_bios_get_controller_info): ... to this.
+	(grub_vbe_get_mode_info): Renamed from this...
+	(grub_vbe_bios_get_mode_info): ... to this.
+	(grub_vbe_set_mode): Renamed from this...
+	(grub_vbe_bios_set_mode): ... to this.
+	(grub_vbe_get_mode): Renamed from this...
+	(grub_vbe_bios_get_mode): ... to this.
+	(grub_vbe_set_memory_window): Renamed from this...
+	(grub_vbe_bios_set_memory_window): ... to this.
+	(grub_vbe_get_memory_window): Renamed from this...
+	(grub_vbe_bios_get_memory_window): ... to this.
+	(grub_vbe_set_scanline_length): Renamed from this...
+	(grub_vbe_set_scanline_length): ... to this.
+	(grub_vbe_get_scanline_length): Renamed from this...
+	(grub_vbe_bios_get_scanline_length): ... to this.
+	(grub_vbe_set_display_start): Renamed from this...
+	(grub_vbe_bios_set_display_start): ... to this.
+	(grub_vbe_get_display_start): Renamed from this...
+	(grub_vbe_bios_get_display_start): ... to this.
+	(grub_vbe_set_palette_data): Renamed from this...
+	(grub_vbe_bios_set_palette_data): ... to this.
+	(grub_vbe_bios_get_controller_info): Fixed problem with registers
+	getting corrupted after calling it.  Added more pushes and pops.
+	(grub_vbe_bios_set_mode): Likewise.
+	(grub_vbe_bios_get_mode): Likewise.
+	(grub_vbe_bios_get_memory_window): Likewise.
+	(grub_vbe_bios_set_scanline_length): Likewise.
+	(grub_vbe_bios_get_scanline_length): Likewise.
+	(grub_vbe_bios_get_display_start): Likewise.
+	(grub_vbe_bios_set_palette_data): Likewise.
+
+	* normal/cmdline.c (cl_set_pos): Refresh the screen.
+	(cl_insert): Likewise.
+	(cl_delete): Likewise.
+
+	* term/gfxterm.c: New file.
+
+	* term/i386/pc/vesafb.c: Removed file.
+
+	* video/video.c: New file.
+
+	* video/i386/pc/vbe.c (real2pm): Added new function.
+	(grub_video_vbe_draw_pixel): Likewise.
+	(grub_video_vbe_get_video_ptr): Likewise.
+	(grub_video_vbe_get_pixel): Likewise
+	(grub_video_vbe_init): Likewise.
+	(grub_video_vbe_fini): Likewise.
+	(grub_video_vbe_setup): Likewise.
+	(grub_video_vbe_get_info): Likewise.
+	(grub_video_vbe_set_palette): Likewise.
+	(grub_video_vbe_get_palette): Likewise.
+	(grub_video_vbe_set_viewport): Likewise.
+	(grub_video_vbe_get_viewport): Likewise.
+	(grub_video_vbe_map_color): Likewise.
+	(grub_video_vbe_map_rgb): Likewise.
+	(grub_video_vbe_map_rgba): Likewise.
+	(grub_video_vbe_unmap_color): Likewise.
+	(grub_video_vbe_fill_rect): Likewise.
+	(grub_video_vbe_blit_glyph): Likewise.
+	(grub_video_vbe_blit_bitmap): Likewise.
+	(grub_video_vbe_blit_render_target): Likewise.
+	(grub_video_vbe_scroll): Likewise.
+	(grub_video_vbe_swap_buffers): Likewise.
+	(grub_video_vbe_create_render_target): Likewise.
+	(grub_video_vbe_delete_render_target): Likewise.
+	(grub_video_vbe_set_active_render_target): Likewise.
+	(grub_vbe_set_pixel_rgb): Remove function.
+	(grub_vbe_set_pixel_index): Likewise.
+	(index_color_mode): Remove static variable.
+	(active_mode): Likewise.
+	(framebuffer): Likewise.
+	(bytes_per_scan_line): Likewise.
+	(grub_video_vbe_adapter): Added new static variable.
+	(framebuffer): Likewise.
+	(render_target): Likewise.
+	(initial_mode): Likewise.
+	(mode_in_use): Likewise.
+	(mode_list): Likewise.
+
+2006-03-10  Marco Gerards  <marco@gnu.org>
+
+	* configure.ac (AC_INIT): Bumped to 1.93.
+
+	* DISTLIST: Added `include/grub/hfs.h'.
+
+2006-02-01  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* boot/i386/pc/boot.S (general_error): Before looping, try INT
+	18H, which might help the BIOS falling back to next boot media.
+
+2006-01-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/i386/pc/grub-install.in: Escape a backslash. Reported by
+	Poe Chen <poe.poechen@gmail.com>.
+
+2006-01-17  Marco Gerards  <marco@gnu.org>
+
+	* include/grub/normal.h: Include <grub/script.h>.
+	(grub_command_list): Removed struct.
+	(grub_command_list_t): Removed type.
+	(grub_menu_entry): Remove members `num' and `command_list'.  Add
+	members `commands' and `sourcecode'.
+	* include/grub/script.h: Add inclusion guards.
+	(grub_script_cmd_menuentry): New struct.
+	(grub_script_execute_menuentry): New prototype.
+	(grub_script_lexer_record_start): Likewise.
+	(grub_script_lexer_record_stop): Likewise.
+	* normal/execute.c (grub_script_execute_menuentry): New function.
+	* normal/lexer.c (record, recording, recordpos, recordlen): New
+	variables.
+	(grub_script_lexer_record_start): New function.
+	(grub_script_lexer_record_stop): Likewise.
+	(recordchar): Likewise.
+	(nextchar): Likewise.
+	(grub_script_yylex): Use `nextchar' to fetch new characters.  Use
+	2048 as the buffer size.  Add the tokens `menuentry' and `@'.
+	* normal/main.c: Include <grub/parser.h> and <grub/script.h>
+	(current_menu): New variable.
+	(free_menu): Mainly rewritten.
+	(grub_normal_menu_addentry): New function.
+	(read_config_file): Rewritten.
+	* normal/menu.c (run_menu_entry): Mainly rewritten.
+	* normal/menu_entry.c (make_screen): Rewritten the code to insert
+	the menu entry.
+	(run): Mainly rewritten.
+	* normal/parser.y (menu_entry): New variable.
+	(GRUB_PARSER_TOKEN_MENUENTRY): New token.
+	(menuentry): New rule.
+	(command): Add `menuentry'.
+	(if_statement): Allow additional returns before `fi'.
+	* normal/script.c (grub_script_create_cmdmenu): New function.
+
+2006-01-03  Marco Gerards  <marco@gnu.org>
+
+	* INSTALL: GNU Bison is required.
+	* configure.ac: Rewritten the test to detect Bison.
+	* Makefile.in (YACC): New variable.  Reported by Xun Sun
+	<xun.sun.cn@gmail.com>.
+
+2006-01-03  Marco Gerards  <marco@gnu.org>
+
+	* fs/hfsplus.c (grub_hfsplus_read_block): Convert the offset of
+	the HFS+ filesystem to filesystem blocks.
+	(grub_hfsplus_iterate_dir): Cast the `fileinfo' assignment so a
+	GCC warning is silenced.
+
+2006-01-03  Marco Gerards  <marco@gnu.org>
+
+	* partmap/apple.c (apple_partition_map_iterate): Convert the data
+	read from disk from big	endian to host byte order.
+
+2006-01-03  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* fs/hfs.c: Include <grub/hfs.h>.  Added reference to the official
+	documentation.
+	(GRUB_HFS_EMBED_HFSPLUS_SIG): New macro.
+	(grub_hfs_mount): Grammar fix in error. Make sure this is not an
+	embedded HFS+ filesystem.
+	(GRUB_HFS_MAGIC, grub_hfs_extent, grub_hfs_datarecord_t)
+	(grub_hfs_sblock): Move from here...
+	* include/grub/hfs.h: To here...  New file.
+	* fs/hfsplus.c: Include <grub/hfs.h>.  Added reference to the official
+	documentation.
+	(GRUB_HFSPLUS_MAGIC, GRUB_HFSPLUSX_MAGIC, GRUB_HFSPLUS_SBLOCK):
+	New macros.
+	(grub_hfsplus_volheader): Change type of member `magic' to
+	`grub_uint16_t'.
+	(grub_hfsplus_data): Add new member `embedded_offset'.
+	(grub_hfsplus_read_block): Add the HFS+ wrapper offset to the
+	returned block.
+	(grub_hfsplus_mount): Read the HFS+ wrapper if it exists.
+	Calculate the offset.
+
+2005-12-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_DRP_ADDR):
+	Removed.
+	(GRUB_BOOT_MACHINE_DRP_SIZE): Likewise.
+
+2005-12-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/env.c (grub_env_set): Check if ENV->VALUE instead of
+	ENV->NAME is NULL after	allocating ENV->VALUE.
+
+2005-12-25  Marco Gerards  <marco@gnu.org>
+
+	* kern/env.c (grub_env_set): Rewritten the error handling code.
+
+2005-12-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* geninit.sh: Made more robust, and more portable.
+
+2005-12-25  Marco Gerards  <marco@gnu.org>
+
+	Add support for Apple HFS+ filesystems.
+
+	* fs/hfsplus.c: New file.
+
+	* DISTLIST: Added `fs/hfsplus.c'.
+
+	* conf/common.rmk (pkgdata_MODULES): Add `hfsplus.mod'.
+	(hfsplus_mod_SOURCES): New variable.
+	(hfsplus_mod_CFLAGS): Likewise.
+	(hfsplus_mod_LDFLAGS): Likewise.
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add `fs/hfsplus.c'.
+	(grub_setup_SOURCES): Likewise.
+	(grub_mkdevicemap_SOURCES): Likewise.
+	(grub_emu_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+
+	* fs/fshelp.c (grub_fshelp_log2blksize): New function.
+
+	* include/grub/fshelp.h (grub_fshelp_log2blksize): new prototype.
+
+2005-12-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Added geninitheader.sh, geninit.sh, commands/test.c,
+	commands/i386/pc/play.c, conf/common.mk, conf/common.rmk,
+	include/grub/parser.h, include/grub/script.h, kern/parser.c,
+	kern/sparc64/cache.S, normal/execute.c, normal/function.c,
+	normal/lexer.c, normal/parser.y, normal/script.c, and
+	partmap/gpt.c.
+	Removed kern/sparc64/cache.c.
+
+	* conf/common.rmk (DISTCLEANFILES): Added grub_script.tab.c,
+	grub_script.tab.h, grub_modules_init.lst, grub_modules_init.h,
+	grub_emu_init.c.
+
+	* configure.ac (AC_INIT): Bumped to 1.92.
+
+2005-12-24  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* kern/err.c (grub_error_push): Added new function to support error
+	stacks.
+	(grub_error_pop): Likewise.
+	(grub_error_stack_items): New local variable to support error stacks.
+	(grub_error_stack_pos): Likewise.
+	(grub_error_stack_assert): Likewise.
+	(GRUB_ERROR_STACK_SIZE): Added new define to configure maximum error
+	stack depth.
+	(grub_print_error): Added support to print errors from error stack.
+
+	* include/grub/err.h (grub_error_push): Added function prototype.
+	(grub_error_pop): Likewise.
+
+2005-12-09  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* configure.ac: Accept `powerpc64' as host_cpu.
+	(amd64): Rename to `biarch32'.
+
+	* kern/powerpc/cache.S (grub_arch_sync_caches): Handle
+	non-cacheline-aligned addresses.
+
+	* kern/dl.c (grub_dl_load_core): Add grub_dprintf messages.
+	(grub_dl_flush_cache): Likewise.  Only call `grub_arch_sync_caches'
+	if `size' is non-zero.
+
+2005-12-03  Marco Gerards  <mgerards@xs4all.nl>
+
+	* conf/common.rmk (grub_modules_init.lst): Use `-printf "%P\n"'
+	and `cd' to make sure the filename is not prefixed with a
+	directory name.
+	(pkgdata_MODULES): Add `gpt.mod'.
+	(gpt_mod_SOURCES): New variable.
+	(gpt_mod_CFLAGS): Likewise.
+	(gpt_mod_LDFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add `partmap/gpt.c'.
+
+	* include/grub/pc_partition.h (GRUB_PC_PARTITION_TYPE_GPT_DISK):
+	New macro.
+
+	* partmap/gpt.c: New file.
+
+	* partmap/pc.c (pc_partition_map_iterate): Don't continue when a
+	GPT partition map is detected.
+
+2005-12-03  Vincent Pelletier  <subdino2004@yahoo.fr>
+
+	* commands/i386/pc/play.c: New file.
+	* conf/i386-pc.rmk (pkgdata_MODULES): Added play.mod.
+	(play_mod_SOURCES, play_mod_CFLAGS, play_mod_LDFLAGS): New
+	macros.
+
+2005-11-27  Marco Gerards  <mgerards@xs4all.nl>
+
+	* include/grub/dl.h (GRUB_MOD_INIT): Use `__attribute__
+	((unused))' to silence gcc warning.
+
+2005-11-26  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* configure.ac: Correct `AC_PROG_YACC' test.
+
+2005-11-22  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* util/powerpc/ieee1275/grub-install.in: Run the mount point
+	check before installing files.
+
+2005-11-22  Mike Small  <smallm@panix.com>
+
+	* util/powerpc/ieee1275/grub-install.in (grubdir): Fixed partition
+	number regex so multidigit numbers are recognized correctly.
+
+2005-11-22  Mike Small  <smallm@panix.com>
+
+	* loader/powerpc/ieee1275/linux.c (grub_rescue_cmd_linux): Add a
+	debugging message before attempting to claim memory.
+	(grub_rescue_cmd_initrd): Add a claim debugging message and try
+	multiple addresses in case of failure.
+
+2005-11-22  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* term/tparm.c (get_space): Remove empty `if' statement.
+
+	* fs/ufs.c (grub_ufs_find_file): Remove `grub_le_to_cpu32'.
+
+	* kern/parser.c (check_varstate): Rename `state' to 's'.
+
+2005-11-22  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* partmap/acorn.c: Change `unsigned' to `unsigned int'.  Move all
+	variable definitions to the beginning of each function.  Sort stack
+	variables by size.
+	(find): Rename to `acorn_partition_map_find'.  Cast `grub_disk_read'
+	`buf' argument to `char *'.
+
+2005-11-22  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* conf/powerpc-ieee1275.rmk: Include conf/common.mk.
+	(pkgdata_MODULES): Removed fshelp.mod, fat.mod, ext2.mod, ufs.mod,
+	minix.mod, hfs.mod, jfs.mod, xfs.mod, affs.mod, sfs.mod,
+	hello.mod, boot.mod, terminal.mod, ls.mod, cmp.mod, cat.mod,
+	help.mod, font.mod, terminfo.mod, amiga.mod, apple.mod, pc.mod,
+	sun.mod, acorn.mod, loopback.mod, default.mod, timeout.mod,
+	configfile.mod, search.mod, gzio.mod and test.mod.
+	(symlist.c, grub_script.tab.c, grub_script.tab.h, kernel_syms.lst)
+	(grub_modules_init.lst, grub_modules_init.h, grub_emu_init.c)
+	(fshelp_mod_SOURCES, fshelp_mod_CFLAGS, fshelp_mod_LDFLAGS)
+	(fat_mod_SOURCES, fat_mod_CFLAGS, fat_mod_LDFLAGS)
+	(ext2_mod_SOURCES, ext2_mod_CFLAGS, ext2_mod_LDFLAGS)
+	(ufs_mod_SOURCES, ufs_mod_CFLAGS, ufs_mod_LDFLAGS)
+	(minix_mod_SOURCES, minix_mod_CFLAGS, minix_mod_LDFLAGS)
+	(hfs_mod_SOURCES, hfs_mod_CFLAGS, hfs_mod_LDFLAGS, jfs_mod_SOURCES)
+	(jfs_mod_CFLAGS, jfs_mod_LDFLAGS, iso9660_mod_SOURCES)
+	(iso9660_mod_CFLAGS, iso9660_mod_LDFLAGS, xfs_mod_SOURCES)
+	(xfs_mod_CFLAGS, xfs_mod_LDFLAGS, affs_mod_SOURCES)
+	(affs_mod_CFLAGS, affs_mod_LDFLAGS, sfs_mod_SOURCES)
+	(sfs_mod_CFLAGS, sfs_mod_LDFLAGS, hello_mod_SOURCES)
+	(hello_mod_CFLAGS, hello_mod_LDFLAGS, boot_mod_SOURCES)
+	(boot_mod_CFLAGS, boot_mod_LDFLAGS, terminal_mod_SOURCES)
+	(terminal_mod_CFLAGS, terminal_mod_LDFLAGS, ls_mod_SOURCES)
+	(ls_mod_CFLAGS, ls_mod_LDFLAGS, cmp_mod_SOURCES, cmp_mod_CFLAGS)
+	(cmp_mod_LDFLAGS, cat_mod_SOURCES, cat_mod_CFLAGS, cat_mod_LDFLAGS)
+	(help_mod_SOURCES, help_mod_CFLAGS, help_mod_LDFLAGS)
+	(font_mod_SOURCES, font_mod_CFLAGS, font_mod_LDFLAGS)
+	(terminfo_mod_SOURCES, terminfo_mod_CFLAGS, terminfo_mod_LDFLAGS)
+	(amiga_mod_SOURCES, amiga_mod_CFLAGS, amiga_mod_LDFLAGS)
+	(apple_mod_SOURCES, apple_mod_CFLAGS, apple_mod_LDFLAG): Removed.
+
+	* conf/common.mk (grub_modules_init.lst): Use `find' instead of
+	`grep --include'.
+	(pkgdata_MODULES): Add test.mod.
+
+2005-11-18  Timothy Baldwin  <T.E.Baldwin99@members.leeds.ac.uk>
+
+	* genmk.rb: Fixed list rules moved to Makefile.in.  Recognise
+	appending to variables with "+=".
+	(PModule): Use full pathname to generate *.lst filenames.
+
+	* Makefile.in: Fixed list rules moved from genmk.rb.
+	(.DELETE_ON_ERROR): New special target.
+	(RMKFILES): Add common.rmk and sparc64-ieee1275.rmk.
+
+	* conf/i386-pc.rmk: Include conf/common.mk.
+	(pkgdata_MODULES): Removed fshelp.mod, fat.mod, ext2.mod, ufs.mod,
+	minix.mod, hfs.mod, jfs.mod, xfs.mod, affs.mod, sfs.mod,
+	hello.mod, boot.mod, terminal.mod, ls.mod, cmp.mod, cat.mod,
+	help.mod, font.mod, terminfo.mod, amiga.mod, apple.mod, pc.mod,
+	sun.mod, acorn.mod, loopback.mod, default.mod, timeout.mod,
+	configfile.mod, search.mod, gzio.mod and test.mod.
+	(symlist.c, grub_script.tab.c, grub_script.tab.h, kernel_syms.lst)
+	(grub_modules_init.lst, grub_modules_init.h, grub_emu_init.c)
+	(fshelp_mod_SOURCES, fshelp_mod_CFLAGS, fshelp_mod_LDFLAGS)
+	(fat_mod_SOURCES, fat_mod_CFLAGS, fat_mod_LDFLAGS)
+	(ext2_mod_SOURCES, ext2_mod_CFLAGS, ext2_mod_LDFLAGS)
+	(ufs_mod_SOURCES, ufs_mod_CFLAGS, ufs_mod_LDFLAGS)
+	(minix_mod_SOURCES, minix_mod_CFLAGS, minix_mod_LDFLAGS)
+	(hfs_mod_SOURCES, hfs_mod_CFLAGS, hfs_mod_LDFLAGS, jfs_mod_SOURCES)
+	(jfs_mod_CFLAGS, jfs_mod_LDFLAGS, iso9660_mod_SOURCES)
+	(iso9660_mod_CFLAGS, iso9660_mod_LDFLAGS, xfs_mod_SOURCES)
+	(xfs_mod_CFLAGS, xfs_mod_LDFLAGS, affs_mod_SOURCES)
+	(affs_mod_CFLAGS, affs_mod_LDFLAGS, sfs_mod_SOURCES)
+	(sfs_mod_CFLAGS, sfs_mod_LDFLAGS, hello_mod_SOURCES)
+	(hello_mod_CFLAGS, hello_mod_LDFLAGS, boot_mod_SOURCES)
+	(boot_mod_CFLAGS, boot_mod_LDFLAGS, terminal_mod_SOURCES)
+	(terminal_mod_CFLAGS, terminal_mod_LDFLAGS, ls_mod_SOURCES)
+	(ls_mod_CFLAGS, ls_mod_LDFLAGS, cmp_mod_SOURCES, cmp_mod_CFLAGS)
+	(cmp_mod_LDFLAGS, cat_mod_SOURCES, cat_mod_CFLAGS, cat_mod_LDFLAGS)
+	(help_mod_SOURCES, help_mod_CFLAGS, help_mod_LDFLAGS)
+	(font_mod_SOURCES, font_mod_CFLAGS, font_mod_LDFLAGS)
+	(terminfo_mod_SOURCES, terminfo_mod_CFLAGS, terminfo_mod_LDFLAGS)
+	(amiga_mod_SOURCES, amiga_mod_CFLAGS, amiga_mod_LDFLAGS)
+	(apple_mod_SOURCES, apple_mod_CFLAGS, apple_mod_LDFLAG): Move from
+	here...
+	* conf/common.rmk: ... to here.  New file.
+
+	* conf/common.mk: New file.
+
+2005-11-18  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* conf/powerpc-ieee1275.rmk (grub_script.tab.h): Unified to ...
+	(grub_script.tab.c): ... here.
+
+	* conf/sparc64-ieee1275.rmk (grub_script.tab.h): Unified to ...
+	(grub_script.tab.c): ... here.
+
+	* conf/i386-pc.rmk (grub_script.tab.h): Unified to ...
+	(grub_script.tab.c): ... here.
+
+	* normal/command.c (grub_command_find): Fixed a memory leak of
+	MODULE_NAME. Reported by Mike Small <smallm@panix.com>.
+
+2005-11-13  Timothy Baldwin  <T.E.Baldwin99@members.leeds.ac.uk>
+
+	* include/grub/symbol.h: (FUNCTION): Use double quotes instead of
+	"@" which marks the start of a comment on ARM.
+	(VARIABLE): Likewise.
+
+2005-11-13  Timothy Baldwin  <T.E.Baldwin99@members.leeds.ac.uk>
+
+	Add support for Linux/ADFS partition tables.
+
+	* partmap/acorn.c: New file.
+
+	* include/grub/acorn_filecore.h: Likewise.
+
+	* DISTLIST: Added `partmap/acorn.c' and
+	`include/grub/acorn_filecore.h'.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add
+	`partmap/acorn.c'.
+	(pkgdata_MODULES): Add `acorn.mod'.
+	(acorn_mod_SOURCES): New variable.
+	(acorn_mod_CFLAGS): Likewise.
+
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Add
+	`partmap/acorn.c'.
+	(pkgdata_MODULES): Add `acorn.mod'.
+	(acorn_mod_SOURCES): New variable.
+	(acorn_mod_CFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add `partmap/acorn.c'.
+	(pkgdata_MODULES): Add `acorn.mod'.
+	(acorn_mod_SOURCES): New variable.
+	(acorn_mod_CFLAGS): Likewise.
+	(acorn_mod_LDFLAGS): Likewise.
+
+	* include/types.h (grub_disk_addr_t): New typedef.
+
+2005-11-13  Marco Gerards  <mgerards@xs4all.nl>
+
+	* geninit.sh: New file.
+
+	* geninitheader.sh: Likewise.
+
+	* commands/boot.c (grub_boot_init, grub_boot_fini): Removed.
+	* commands/cat.c (grub_cat_init, grub_cat_fini): Likewise.
+	* commands/cmp.c (grub_cmp_init, grub_cmp_fini): Likewise.
+	* commands/configfile.c (grub_configfile_init)
+	(grub_configfile_fini): Likewise.
+	* commands/default.c (grub_default_init, grub_default_fini):
+	Likewise.
+	* commands/help.c (grub_help_init, grub_help_fini): Likewise.
+	* commands/ls.c (grub_ls_init, grub_ls_fini): Likewise.
+	* commands/search.c (grub_search_init, grub_search_fini): Likewise.
+	* commands/terminal.c (grub_terminal_init, grub_terminal_fini):
+	Likewise.
+	* commands/test.c (grub_test_init, grub_test_fini): Likewise.
+	* commands/timeout.c (grub_timeout_init, grub_timeout_fini):
+	Likewise.
+	* commands/i386/pc/halt.c (grub_halt_init, grub_halt_fini): Likewise.
+	* commands/ieee1275/halt.c (grub_halt_init, grub_halt_fini):
+	Likewise.
+	* commands/i386/pc/reboot.c (grub_reboot_init, grub_reboot_fini):
+	Likewise.
+	* commands/ieee1275/reboot.c (grub_reboot_init, grub_reboot_fini):
+	Likewise.
+	* disk/loopback.c (grub_loop_init, grub_loop_fini): Likewise.
+	* fs/affs.c (grub_affs_init, grub_affs_fini): Likewise.
+	* fs/ext2.c (grub_ext2_init, grub_ext2_fini): Likewise.
+	* fs/fat.c (grub_fat_init, grub_fat_fini): Likewise.
+	* fs/hfs.c (grub_hfs_init, grub_hfs_fini): Likewise.
+	* fs/iso9660.c (grub_iso9660_init, grub_iso9660_fini): Likewise.
+	* fs/jfs.c (grub_jfs_init, grub_jfs_fini): Likewise.
+	* fs/minix.c (grub_minix_init, grub_minix_fini): Likewise.
+	* fs/sfs.c (grub_sfs_init, grub_sfs_fini): Likewise.
+	* fs/ufs.c (grub_ufs_init, grub_ufs_fini): Likewise.
+	* fs/xfs.c (grub_xfs_init, grub_xfs_fini): Likewise.
+	* normal/main.c (grub_normal_init, grub_normal_fini): Likewise.
+	* partmap/amiga.c (grub_amiga_partition_map_init)
+	(grub_amiga_partition_map_fini): Likewise.
+	* partmap/apple.c (grub_apple_partition_map_init)
+	(grub_apple_partition_map_fini): Likewise.
+	* partmap/pc.c (grub_pc_partition_map_init)
+	(grub_pc_partition_map_fini): Likewise.
+	* partmap/sun.c (grub_sun_partition_map_init,
+	grub_sun_partition_map_fini): Likewise.
+	* term/terminfo.c (grub_terminal_init, grub_terminal_fini):
+	Likewise.
+
+	* util/grub-emu.c: Include <grub_modules_init.h>.
+	(main): Don't initialize and de-initialize any modules directly,
+	use `grub_init_all' and `grub_fini_all' instead.
+
+	* term/i386/pc/vesafb.c (grub_vesafb_init): Renamed to
+	`grub_vesafb_mod_init'.
+	(grub_vesafb_fini): Renamed to `grub_vesafb_mod_fini'.  Updated
+	all users.
+	* term/i386/pc/vga.c (grub_vga_init): Renamed to
+	`grub_vga_mod_init'.  Updated all users.
+	(grub_vga_fini): Renamed to `grub_vga_mod_fini'.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add `grub_emu_init.c'.
+	(grub_modules_init.lst, grub_modules_init.h, grub_emu_init.c): New
+	rules.
+
+	* include/grub/dl.h (GRUB_MOD_INIT): Add argument `name'.
+	Generate a function to initialize the module in utilities.
+	Updated all callers.
+	(GRUB_MOD_FINI): Add argument `name'.  Generate a function to
+	initialize the module in utilities.  Updated all callers.
+
+2005-11-09  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* term/ieee1275/ofconsole.c (grub_ofconsole_cls): Use both the ANSI
+	escape sequence and a literal ^L to clear the screen.
+
+	* commands/ieee1275/suspend.c (grub_cmd_suspend): Clear the screen
+	when returning from Open Firmware.
+
+2005-11-09  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* term/ieee1275/ofconsole.c (grub_ofconsole_width): New variable.
+	(grub_ofconsole_height): Likewise.
+	(grub_ofconsole_putchar): If `grub_curr_x' exceeds console width,
+	manually insert a '\n'.
+	(grub_ofconsole_getwh): Set and return `grub_ofconsole_width' and
+	`grub_ofconsole_height'.  Return early if these are already set.
+
+2005-11-07  Vincent Pelletier  <subdino2004@yahoo.fr>
+
+	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Add
+	`commands/test.c', `fs/affs.c', `fs/sfs.c', `fs/xfs.c',
+	`normal/execute.c', `normal/lexer.c', `io/gzio.c',
+	`kern/parser.c', `grub_script.tab.c', `normal/function.c'
+	and `normal/script.c'.
+	(normal_mod_SOURCES): `normal/execute.c', `normal/lexer.c',
+	`grub_script.tab.c', `normal/function.c' and `normal/script.c'.
+	(test_mod_SOURCES): New	variable.
+	(test_mod_CFLAGS): Likewise.
+	(test_mod_LDFLAGS): Likewise.
+	(pkgdata_MODULES): Add `test.mod'.
+	(grub_script.tab.c): New rule.
+	(grub_script.tab.h): Likewise.
+
+2005-11-07  Marco Gerards  <mgerards@xs4all.nl>
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add
+	`commands/test.c', `normal/execute.c', `normal/lexer.c',
+	`grub_script.tab.c', `normal/function.c' and `normal/script.c'.
+	(normal_mod_SOURCES): `normal/execute.c', `normal/lexer.c',
+	`grub_script.tab.c', `normal/function.c' and `normal/script.c'.
+	(test_mod_SOURCES): New variable.
+	(test_mod_CFLAGS): Likewise.
+	(pkgdata_MODULES): Add `test.mod'.
+	(grub_script.tab.c): New rule.
+	(grub_script.tab.h): Likewise.
+
+2005-11-06  Marco Gerards  <mgerards@xs4all.nl>
+
+	Add initial scripting support.
+
+	* commands/test.c: New file.
+	* include/grub/script.h: Likewise.
+	* normal/execute.c: Likewise.
+	* normal/function.c: Likewise.
+	* normal/lexer.c: Likewise.
+	* normal/parser.y: Likewise.
+	* normal/script.c: Likewise.
+
+	* configure.ac: Add `AC_PROG_YACC' test.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add `commands/test.c',
+	`normal/execute.c', `normal/lexer.c', `grub_script.tab.c',
+	`normal/function.c' and `normal/script.c'.
+	(normal_mod_SOURCES): `normal/execute.c', `normal/lexer.c',
+	`grub_script.tab.c', `normal/function.c' and `normal/script.c'.
+	(test_mod_SOURCES, test_mod_CFLAGS, test_mod_LDFLAGS): New
+	variables.
+	(pkgdata_MODULES): Add `test.mod'.
+	(grub_script.tab.c): New rule.
+	(grub_script.tab.h): Likewise.
+
+	* include/grub/err.h (grub_err_t): Add `GRUB_ERR_TEST_FAILURE'.
+
+	* include/grub/normal.h (grub_test_init): New prototype.
+	(grub_test_fini): Likewise.
+
+	* normal/command.c: Include <grub/script.h>.
+	(grub_command_execute): Rewritten.
+
+	* util/grub-emu.c (main): Call `grub_test_init' and
+	`grub_test_fini'.
+
+2005-11-03  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/powerpc/ieee1275/init.c (grub_get_rtc): Initialize `msecs'
+	to 0.
+	* term/ieee1275/ofconsole.c (grub_ofconsole_checkkey): Return -1 if
+	there are no pending characters.
+
+2005-11-03  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/powerpc/ieee1275/openfw.c (grub_ieee1275_get_devname): Use
+	`grub_strndup' to drop device arguments. Replace unnecessary
+	`grub_strndup' with `grub_strdup'.
+
+2005-11-03  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/term.c (grub_cls): Do not call grub_cur_term->cls() if the
+	`debug' environment variable has been set.
+
+2005-11-02  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* Makefile.in (install-local): Use $(DATA).
+	(uninstall): Likewise.
+	* conf/powerpc-ieee1275.rmk (bin_UTILITIES): Move grub-mkimage...
+	(sbin_UTILITIES): ... to here.
+	(sbin_SCRIPTS): New variable.
+	(grub_install_SOURCES): New variable.
+	* util/powerpc/ieee1275/grub-install.in: New file.
+	* util/powerpc/ieee1275/grub-mkimage.c (kernel_path): Remove
+	variable.
+	(add_segments): Call `grub_util_get_path'.
+
+2005-10-28  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Timothy Baldwin:
+	* commands/ls.c (grub_ls_list_files): Close FILE with
+	grub_file_close.
+	* kern/misc.c (grub_vsprintf): Terminate the string S with NUL.
+
+2005-10-24  Marco Gerards  <mgerards@xs4all.nl>
+
+	* include/grub/parser.h: New file.
+
+	* kern/parser.c: Likewise.
+
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/parser.c'.
+	(grub_setup_SOURCES): Likewise.
+	(grub_probefs_SOURCES): Likewise.
+	(grub_emu_SOURCES): Likewise.
+	(kernel_img_HEADERS): Add `parser.h'.
+
+	* conf/powerpc-ieee1275.rmk (grubof_HEADERS): Add `parser.h'.
+	(grub_emu_SOURCES): Add `kern/parser.c'.
+	(grubof_SOURCES): Likewise.
+
+	* conf/sparc64-ieee1275.rmk (grubof_HEADERS): Add `parser.h'.
+	(grubof_SOURCES): Add `kern/parser.c'.
+
+	* include/grub/misc.h (grub_split_cmdline): Removed prototype.
+
+	* kern/misc.c (grub_split_cmdline): Removed function.
+
+	* kern/rescue.c: Include <grub/parser.h>.
+	(grub_enter_rescue_mode): Use `grub_parser_split_cmdline' instead
+	of `grub_split_cmdline'.
+
+	* normal/command.c: Include <grub/parser.h>.
+	(grub_command_execute):  Use `grub_parser_split_cmdline' instead
+	of `grub_split_cmdline'.
+
+	* normal/completion.c: Include <grub/parser.h>.
+	(cmdline_state): New variable.
+	(iterate_dir): End the filename with a quote depending on the
+	command line state.
+	(get_state): new function.
+	(grub_normal_do_completion): Use `grub_parser_split_cmdline' to
+	split the arguments and determine the current argument.  When the
+	argument string is not quoted, escape all spaces.
+
+2005-10-23  Vincent Pelletier  <subdino2004@yahoo.fr>
+
+	* normal/sparc64/setjmp.S: New file.
+
+2005-10-23  Vincent Pelletier  <subdino2004@yahoo.fr>
+
+	* include/grub/sparc64/libgcc.h: New file.
+	* conf/sparc64-ieee1275.rmk (COMMON_ASFLAGS): Remove -Av9.
+	(normal_mod_SOURCES): Use normal/sparc64/setjmp.S instead of
+	normal/sparc64/setjmp.c.
+
+2005-10-23  Vincent Pelletier  <subdino2004@yahoo.fr>
+
+	* kern/sparc64/dl.c: Rewritten for SPARCV9 ELF.
+	* kern/sparc64/cache.S: New file.
+	* kern/sparc64/cache.c: Removed.
+	* conf/sparc64-ieee1275.rmk (COMMON_ASFLAGS): Add -Av9.
+	(COMMON_CFLAGS): Add -mno-app-regs.  Remove -mcpu=v9 and
+	-mtune=ultrasparc.
+	(COMMON_LDFLAGS): Add -melf64_sparc.
+	(grubof_HEADERS): Add sparc64/libgcc.h and machine/kernel.h.
+	(grubof_SOURCES): Use cache.S instead of cache.c.
+	(grubof_LDFLAGS): Add -mno-app-regs.  Replace "-Xlinker
+	--oformat -Xlinker elf64-sparc" by "-Bstatic,-melf64_sparc".
+	(pkgdata_MODULES): Uncomment. Leave linux.mod and _linux.mod
+	commented though.
+	(normal_mod_SOURCES): Add normal/completion.c and normal/misc.c.
+	(_linux_mod_SOURCES, _linux_mod_CFLAGS, linux_mod_SOURCES)
+	(linux_mod_CFLAGS): Commented out.
+	(_linux_mod_LDFLAGS, linux_mod_LDFLAGS): New macro, commented
+	out because module isn't built.
+	(fshelp_mod_LDFLAGS, fat_mod_LDFLAGS, ext2_mod_LDFLAGS)
+	(ufs_mod_LDFLAGS, minix_mod_LDFLAGS, hfs_mod_LDFLAGS)
+	(jfs_mod_LDFLAGS, iso9660_mod_LDFLAGS, normal_mod_LDFLAGS)
+	(hello_mod_LDFLAGS, boot_mod_LDFLAGS, terminal_mod_LDFLAGS)
+	(ls_mod_LDFLAGS, cmp_mod_LDFLAGS, cat_mod_LDFLAGS)
+	(font_mod_LDFLAGS, amiga_mod_LDFLAGS, apple_mod_LDFLAGS)
+	(pc_mod_LDFLAGS, sun_mod_LDFLAGS, loopback_mod_LDFLAGS)
+	(suspend_mod_LDFLAGS, reboot_mod_LDFLAGS, halt_mod_LDFLAGS)
+	(help_mod_LDFLAGS, default_mod_LDFLAGS, timeout_mod_LDFLAGS)
+	(configfile_mod_LDFLAGS, search_mod_LDFLAGS, xfs_mod_SOURCES)
+	(xfs_mod_CFLAGS, xfs_mod_LDFLAGS, affs_mod_SOURCES)
+	(affs_mod_CFLAGS, affs_mod_LDFLAGS, sfs_mod_SOURCES)
+	(sfs_mod_CFLAGS, sfs_mod_LDFLAGS, gzio_mod_SOURCES)
+	(gzio_mod_CFLAGS, gzio_mod_LDFLAGS): New macro.
+
+2005-10-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/i386/pc/grub-probefs.c (main): Call grub_xfs_init and
+	grub_xfs_fini. Do not call grub_hfs_init or grub_hfs_fini any
+	longer, because HFS should not be used on PC.
+
+2005-10-20  Timothy Baldwin  <T.E.Baldwin99@members.leeds.ac.uk>
+
+	* io/gzio.c (grub_gzio_read): Use OFFSET instead of FILE->OFFSET
+	consistently within the loop.
+
+2005-10-15  Marco Gerards  <mgerards@xs4all.nl>
+
+	* fs/xfs.c (grub_xfs_iterate_dir): Detect an error if part of a
+	directory can not be read.
+
+2005-10-15  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.ac (AC_INIT): Increase the version number to 1.91.
+
+	* DISTLIST: Added include/grub/terminfo.h, include/grub/tparm.h,
+	include/grub/i386/pc/serial.h, term/terminfo.c, term/tparm.c and
+	term/i386/pc/serial.c.
+
+2005-10-15  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/file.c (grub_file_seek): Seeking to an offset equal to a
+	file size must be permitted.
+
+	* kern/i386/pc/startup.S (multiboot_trampoline): Fix a mistake
+	between %ah and %al.
+
+2005-10-15  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* fs/xfs.c (grub_xfs_iterate_dir): Change the type of BLK to
+	grub_uint64_t.
+	Call the hook with a NUL-terminated filename.
+	(grub_xfs_mount): Use grub_be_to_cpu32 instead of
+	grub_cpu_to_be32.
+
+	* kern/term.c (cursor_state): New variable.
+	(grub_term_set_current): Reset the cursor state on a new
+	terminal.
+	(grub_setcursor): Rewritten to use CURSOR_STATE.
+	(grub_getcursor): New function.
+
+	* include/grub/term.h (grub_getcursor): New prototype.
+
+	* io/gzio.c (test_header): Align BUF for accessing it as 32-bit
+	integers on ARM. Reported by Timothy Baldwin
+	<T.E.Baldwin99@members.leeds.ac.uk>.
+
+2005-10-11  Marco Gerards  <mgerards@xs4all.nl>
+
+	* fs/sfs.c (grub_sfs_open): Don't free `data->label' if it is not
+	allocated.
+	(grub_sfs_dir): Likewise.
+
+2005-10-09  Marco Gerards  <mgerards@xs4all.nl>
+
+	Add support for the SFS filesystem.
+
+	* fs/sfs.c: New file.
+
+	* DISTLIST: Added `fs/sfs.c'.
+
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add `fs/sfs.c'.
+	(grub_probefs_SOURCES): Likewise.
+	(grub_emu_SOURCES): Likewise.
+	(pkgdata_MODULES): Add `sfs.mod'.
+	(sfs_mod_SOURCES): New variable.
+	(sfs_mod_CFLAGS): Likewise.
+	(sfs_mod_LDFLAGS): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `fs/sfs.c'.
+	(pkgdata_MODULES): Add `sfs.mod'.
+	(sfs_mod_SOURCES): New variable.
+	(sfs_mod_CFLAGS): Likewise.
+
+	* util/grub-emu.c (main): Call `grub_sfs_init' and
+	`grub_sfs_fini'.
+
+	* include/grub/fs.h (grub_sfs_init): New prototype.
+	(grub_sfs_fini): Likewise.
+
+2005-10-07  Marco Gerards  <mgerards@xs4all.nl>
+
+	Add support for the AFFS filesystem.
+
+	* fs/affs.c: New file.
+
+	* DISTLIST: Added `fs/affs.c'.
+
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add `fs/affs.c'.
+	(grub_probefs_SOURCES): Likewise.
+	(grub_emu_SOURCES): Likewise.
+	(pkgdata_MODULES): Add `affs.mod'.
+	(affs_mod_SOURCES): New variable.
+	(affs_mod_CFLAGS): Likewise.
+	(affs_mod_LDFLAGS): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `fs/affs.c'.
+	(pkgdata_MODULES): Add `affs.mod'.
+	(affs_mod_SOURCES): New variable.
+	(affs_mod_CFLAGS): Likewise.
+
+	* util/grub-emu.c (main): Call `grub_affs_init' and
+	`grub_affs_fini'.
+
+	* include/grub/fs.h (grub_affs_init): New prototype.
+	(grub_affs_fini): Likewise.
+
+2005-10-01  Marco Gerards  <mgerards@xs4all.nl>
+
+	* fs/xfs.c (grub_xfs_iterate_dir): Add parentheses.
+
+2005-10-01  Marco Gerards  <mgerards@xs4all.nl>
+
+	* configure.ac: Accept `x86_64' as host_cpu.  In that case add
+	`-m32' to CFLAGS.
+
+	* genmk.rb (class PModule): Always use `$(#{prefix}_LDFLAGS)' when
+	linking.
+
+	* conf/i386-pc.rmk (COMMON_CFLAGS): Add `-m32'.
+	(COMMON_LDFLAGS): New variable.
+	(kernel_img_LDFLAGS): Include `COMMON_FLAGS'.
+	(_chain_mod_LDFLAGS, fshelp_mod_LDFLAGS, fat_mod_LDFLAGS)
+	(ext2_mod_LDFLAGS, ufs_mod_LDFLAGS, minix_mod_LDFLAGS)
+	(hfs_mod_LDFLAGS, jfs_mod_LDFLAGS, iso9660_mod_LDFLAGS)
+	(xfs_mod_LDFLAGS, _linux_mod_LDFLAGS, linux_mod_LDFLAGS)
+	(normal_mod_LDFLAGS, hello_mod_LDFLAGS, boot_mod_LDFLAGS)
+	(terminal_mod_LDFLAGS, ls_mod_LDFLAGS, cmp_mod_LDFLAGS)
+	(cat_mod_LDFLAGS, help_mod_LDFLAGS, reboot_mod_LDFLAGS)
+	(halt_mod_LDFLAGS, vga_mod_LDFLAGS, font_mod_LDFLAGS)
+	(terminfo_mod_LDFLAGS, serial_mod_LDFLAGS, _multiboot_mod_LDFLAGS)
+	(multiboot_mod_LDFLAGS, amiga_mod_LDFLAGS, apple_mod_LDFLAGS)
+	(pc_mod_LDFLAGS, sun_mod_LDFLAGS, loopback_mod_LDFLAGS)
+	(default_mod_LDFLAGS, timeout_mod_LDFLAGS, configfile_mod_LDFLAGS)
+	(vbe_mod_LDFLAGS, vesafb_mod_LDFLAGS, vbeinfo_mod_LDFLAGS)
+	(vbetest_mod_LDFLAGS, search_mod_LDFLAGS, gzio_mod_LDFLAGS): New
+	variables.
+	(normal_mod_ASFLAGS): Add `-m32'.
+
+	* include/grub/types.h (grub_host_addr_t, grub_host_off_t)
+	(grub_host_size_t, grub_host_ssize_t): New types.
+	(grub_addr_t, grub_off_t, grub_size_t, grub_ssize_t): Make type
+	dependent of `GRUB_CPU_SIZEOF_VOID_P' instead on
+	`GRUB_HOST_SIZEOF_VOID_P'.
+
+	* include/grub/kernel.h (struct grub_module_header): Type of
+	member offset changed to `grub_host_off_t'.  Type of member size
+	changed to `grub_host_size_t'.
+	(struct grub_module_info): Type of member offset changed to
+	`grub_host_off_t'.  Type of member size changed to
+	`grub_host_size_t'.
+
+2005-09-29  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Make GRUB's kernel compliant to Multiboot Specification.
+
+	* kern/i386/pc/startup.S (multiboot_header): New label.
+	(multiboot_entry): Likewise.
+	(multiboot_trampoline): Likewise.
+
+	* include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE):
+	Increased to 0x4A0.
+
+	* fs/xfs.c (grub_xfs_iterate_dir): Fix a syntax error. You may not
+	put parentheses after a question mark.
+	[!GRUB_UTIL] (my_mod): New variable.
+
+	* util/grub-emu.c (main): Call grub_xfs_init and grub_xfs_fini.
+
+2005-09-28  Marco Gerards  <mgerards@xs4all.nl>
+
+	Adds support for the XFS filesystem.  Btrees are not supported
+	yet.
+
+	* fs/xfs.c: New file.
+
+	* DISTLIST: Added `fs/xfs.c'.
+
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add `fs/xfs.c'.
+	(grub_probefs_SOURCES): Likewise.
+	(grub_emu_SOURCES): Likewise.
+	(pkgdata_MODULES): Add `xfs.mod'.
+	(xfs_mod_SOURCES): New variable.
+	(xfs_mod_CFLAGS): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `fs/xfs.c'.
+	(pkgdata_MODULES): Add `xfs.mod'.
+	(xfs_mod_SOURCES): New variable.
+	(xfs_mod_CFLAGS): Likewise.
+
+	* util/grub-emu.c (main): Call `grub_xfs_init' and
+	`grub_xfs_fini'.
+
+	* include/grub/fs.h (grub_xfs_init): New prototype.
+	(grub_xfs_fini): Likewise.
+
+
+2005-09-18  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* video/i386/pc/vbe.c (grub_vbe_set_video_mode): In indexed
+	color modes, allow greater than 16 colors to be configured as
+	a default palette.
+
+2005-09-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* normal/completion.c (complete_arguments): Add the qualifier
+	const into OPTIONS.
+
+	From Omniflux <omniflux+lists@omniflux.com>:
+	* include/grub/terminfo.h: New file.
+	* include/grub/tparm.h: Likewise.
+	* include/grub/i386/pc/serial.h: Likewise.
+	* term/terminfo.c: Likewise.
+	* term/tparm.c: Likewise.
+	* term/i386/pc/serial.c: Likewise.
+	* conf/i386-pc.rmk (pkgdata_MODULES): Added terminfo.mod and
+	serial.mod.
+	(terminfo_mod_SOURCES): New variable.
+	(terminfo_mod_CFLAGS): Likewise.
+	(serial_mod_SOURCES): Likewise.
+	(serial_mod_CFLAGS): Likewise.
+
+2005-08-31  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Replaced boot/powerpc/ieee1275/crt0.S and
+	boot/powerpc/ieee1275/cmain.c with kern/powerpc/ieee1275/crt0.S
+	and kern/powerpc/ieee1275/cmain.c, respectively.
+
+	* boot/powerpc/ieee1275/crt0.S: Moved to ...
+	* kern/powerpc/ieee1275/crt0.S: ... here.
+
+	* boot/powerpc/ieee1275/cmain.c: Moved to ...
+	* kern/powerpc/ieee1275/cmain.c: ... here.
+
+	* conf/powerpc-ieee1275.rmk (grubof_SOURCES): Use
+	kern/powerpc/ieee1275/crt0.S and kern/powerpc/ieee1275/cmain.c
+	instead of boot/powerpc/ieee1275/crt0.S and
+	boot/powerpc/ieee1275/cmain.c, respectively.
+
+	* boot/i386/pc/boot.S (lba_mode): Do not store the total number of
+	sectors. It was not used anyway.
+
+2005-08-30  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* term/ieee1275/ofconsole.c (grub_ofconsole_getcharwidth): Fix
+	`unused parameter' warning.
+
+2005-08-30  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* term/ieee1275/ofconsole.c (grub_ofconsole_getcharwidth): New
+	function.
+	(grub_ofconsole_term): Specify grub_ofconsole_getcharwidth as
+	getcharwidth.
+
+2005-08-28  Marco Gerards  <metgerards@student.han.nl>
+
+	* include/grub/normal.h (enum grub_completion_type): Added
+	`GRUB_COMPLETION_TYPE_ARGUMENT'.
+
+	* normal/cmdline.c (print_completion): Handle
+	the `GRUB_COMPLETION_TYPE_ARGUMENT' type.
+	* normal/menu_entry.c (store_completion): Likewise.
+
+	* normal/completion.c (complete_arguments): New function.
+	(grub_normal_do_completion): Call `complete_arguments' when the
+	current words start with a dash.
+
+2005-08-27  Marco Gerards  <metgerards@student.han.nl>
+
+	* conf/powerpc-ieee1275.rmk (pkgdata_MODULES): Fix typo (use
+	`gzio.mod' instead of `io.mod').
+
+2005-08-22  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* gendistlist.sh (EXTRA_DISTFILES): Added genfslist.sh.
+	(DISTDIRS): Added io and video.
+	Rewrite the search routine to make an output consistently.
+
+	* DISTLIST: Added conf/sparc64-ieee1275.mk,
+	conf/sparc64-ieee1275.rmk, include/grub/gzio.h,
+	include/grub/ieee1275/ieee1275.h, include/grub/ieee1275/ofdisk.h,
+	io/gzio.c, kern/sparc64/cache.c, kern/sparc64/dl.c,
+	kern/sparc64/ieee1275/init.c, kern/sparc64/ieee1275/openfw.c and
+	util/powerpc/ieee1275/misc.c.
+
+	* include/grub/gzio.h: New file.
+	* io/gzio.c: Likewise.
+
+	* kern/file.c (grub_file_close): Call grub_device_close only if
+	FILE->DEVICE is not NULL.
+
+	* include/grub/mm.h [!NULL] (NULL): New macro.
+
+	* include/grub/err.h (GRUB_ERR_BAD_GZIP_DATA): New constant.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added io/gzip.c.
+	(pkgdata_MODULES): Added gzio.mod.
+	(gzio_mod_SOURCES): New variable.
+	(gzio_mod_CFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Added io/gzip.c.
+	(pkgdata_MODULES): Added gzio.mod.
+	(gzio_mod_SOURCES): New variable.
+	(gzio_mod_CFLAGS): Likewise.
+
+	* commands/cat.c: Include grub/gzio.h.
+	(grub_cmd_cat): Use grub_gzfile_open instead of
+	grub_file_open.
+
+	* commands/cmp.c: Include grub/gzio.h.
+	(grub_cmd_cmp): Use grub_gzfile_open instead of
+	grub_file_open.
+
+	* loader/i386/pc/multiboot.c: Include grub/gzio.h.
+	(grub_rescue_cmd_multiboot): Use grub_gzfile_open instead of
+	grub_file_open.
+	(grub_rescue_cmd_module): Likewise.
+
+2005-08-21  Vincent Pelletier  <subdino2004@yahoo.fr>
+
+	* conf/sparc64-ieee1275.rmk (grubof_SOURCES): The first file must be
+	kern/sparc64/ieee1275/init.c because it contains _start.
+	* conf/sparc64-ieee1275.mk: Generated from conf/sparc64-ieee1275.rmk.
+
+2005-08-21  Vincent Pelletier  <subdino2004@yahoo.fr>
+
+	* configure.ac: Add support for sparc64 host with ieee1275
+	firmware.
+	* configure: Generated from configure.ac.
+	* disk/ieee1275/ofdisk.c (grub_ofdisk_open): Use grub_ssize_t
+	instead of int.
+	(grub_ofdisk_read): Likewise.
+	(grub_ofdisk_open): Use %p to print pointer values, and cast the
+	pointers as (void *) to remove a warning.
+	(grub_ofdisk_close): Likewise.
+	(grub_ofdisk_read): Likewise.
+	* kern/ieee1275/ieee1275.c (grub_ieee1275_exit): This never
+	returns, so make it return void to remove a warning.
+	* include/grub/ieee1275/ieee1275.h (grub_ieee1275_exit):
+	Corresponding prototype change.
+	* kern/mm.c (grub_mm_init_region): Use %p to print pointer
+	values, and cast the pointers as (void *) to remove a warning.
+	(grub_mm_dump): Likewise.
+	* conf/sparc64-ieee1275.mk: New file.
+	* conf/sparc64-ieee1275.rmk: Likewise.
+	* include/grub/sparc64/setjmp.h: Likewise.
+	* include/grub/sparc64/types.h: Likewise.
+	* include/grub/sparc64/ieee1275/console.h: Likewise.
+	* include/grub/sparc64/ieee1275/ieee1275.h: Likewise.
+	* include/grub/sparc64/ieee1275/kernel.h: Likewise.
+	* include/grub/sparc64/ieee1275/time.h: Likewise.
+	* kern/sparc64/cache.c: Likewise.
+	* kern/sparc64/dl.c: Likewise.
+	* kern/sparc64/ieee1275/init.c: Likewise.
+	* kern/sparc64/ieee1275/openfw.c: Likewise.
+
+2005-08-21  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/console.c (grub_ncurses_putchar): If C is greater than
+	0x7f, set C to a question mark.
+	(grub_ncurses_getcharwidth): New function.
+	(grub_ncurses_term): Specify grub_ncurses_getcharwidth as
+	getcharwidth.
+
+	* normal/menu.c (print_entry): Made aware of Unicode. First,
+	convert TITLE to UCS-4, and predict the cursor position by
+	grub_getcharwidth.
+
+	* include/grub/misc.h (grub_utf8_to_ucs4): Specify the qualifier
+	const to SRC.
+	* kern/misc.c (grub_utf16_to_utf8): Likewise.
+
+2005-08-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* loader/powerpc/ieee1275/linux.c (grub_rescue_cmd_linux): Specify
+	the boot file by the option BOOT_IMAGE. Use grub_stpcpy instead of
+	grub_strcat.
+
+	* loader/i386/pc/linux.c (grub_rescue_cmd_linux): Specify the boot
+	file by the option BOOT_IMAGE. Use grub_stpcpy instead of
+	grub_strcpy and grub_strlen. Take it into account that a space
+	character is inserted as a delimiter.
+
+2005-08-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* partmap/pc.c (pc_partition_map_iterate): Include the value of an
+	invalid magic in the error.
+
+	* commands/search.c: New file.
+
+	* util/grub-emu.c (main): Call grub_search_init and
+	grub_search_fini.
+
+	* kern/rescue.c (grub_rescue_print_disks): Removed.
+	(grub_rescue_print_devices): New function.
+	(grub_rescue_cmd_ls): Use grub_device_iterate with
+	grub_rescue_print_devices instead of grub_disk_dev_iterate with
+	grub_rescue_print_disks.
+
+	* kern/partition.c (grub_partition_iterate): Return the result of
+	PARTMAP->ITERATE instead of GRUB_ERRNO.
+
+	* kern/device.c: Include grub/partition.h.
+	(grub_device_iterate): New function.
+
+	* include/grub/partition.h (grub_partition_iterate): Return int
+	instead of grub_err_t.
+
+	* include/grub/normal.h [GRUB_UTIL] (grub_search_init): New
+	prototype.
+	[GRUB_UTIL] (grub_search_fini): Likewise.
+
+	* include/grub/device.h (grub_device_iterate): New prototype.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added
+	commands/search.c.
+	(pkgdata_MODULES): Added search.mod.
+	(search_mod_SOURCES): New variable.
+	(search_mod_CFLAGS): Likewise.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Added commands/search.c.
+	(pkgdata_MODULES): Added search.mod.
+	(search_mod_SOURCES): New variable.
+	(search_mod_CFLAGS): Likewise.
+
+	* commands/ls.c (grub_ls_list_disks): Renamed to ...
+	(grub_ls_list_devices): ... this, and use grub_device_iterate.
+	All callers changed.
+
+	* DISTLIST: Added commands/search.c.
+
+2005-08-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/term.c (grub_putchar): Use grub_utf8_to_ucs4 for the
+	conversion.
+	(grub_getcharwidth): New function.
+
+	* kern/misc.c (grub_utf8_to_ucs4): New function.
+
+	* include/grub/term.h (struct grub_term): Added a new member
+	"getcharwidth".
+	(grub_getcharwidth): New prototype.
+
+	* include/grub/misc.h (grub_utf8_to_ucs4): New prototype.
+
+	* term/i386/pc/console.c (map_char): New function. Segregated from
+	grub_console_putchar.
+	(grub_console_putchar): Use map_char.
+	(grub_console_getcharwidth): New function.
+	(grub_console_term): Specified grub_console_getcharwidth as
+	getcharwidth.
+
+	* term/i386/pc/vga.c (grub_vga_getcharwidth): New function.
+	(grub_vga_term): Specified grub_vga_getcharwidth as getcharwidth.
+
+	* term/i386/pc/vesafb.c (grub_virtual_screen_setup): Return
+	GRUB_ERRNO.
+	(grub_vesafb_init): Do not use RC. Instead, use GRUB_ERRNO. Rely
+	on grub_strtoul completely.
+	(write_char): Declare local variables in the beginning of the
+	function.
+	(grub_vesafb_getcharwidth): New function.
+	(grub_vesafb_term): Specified grub_vesafb_getcharwidth as
+	getcharwidth.
+
+2005-08-19  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Replace commands/i386/pc/vbe_list_modes.c and
+	commands/i386/pc/vbe_test.c with commands/i386/pc/vbeinfo.c and
+	commands/i386/pc/vbetest.c.
+
+	* video/i386/pc/vbe.c (grub_vbe_probe): If INFOBLOCK is not NULL,
+	call grub_vbe_get_controller_info again, because the returned
+	information is volatile.
+	(grub_vbe_set_video_mode): Mostly rewritten.
+	(grub_vbe_get_video_mode): Use grub_vbe_probe and use
+	grub_vbe_status_t correctly.
+	(grub_vbe_get_video_mode_info): Likewise.
+	(grub_vbe_set_pixel_rgb): Use a switch statement rather than
+	several if statements.
+
+	* commands/i386/pc/vbe_list_modes.c: Renamed to ...
+	* commands/i386/pc/vbeinfo.c: ... this.
+
+	* commands/i386/pc/vbe_test.c: Renamed to ...
+	* commands/i386/pc/vbetest.c: ... this.
+
+	* commands/i386/pc/vbeinfo.c (grub_cmd_vbe_list_modes): Renamed to
+	...
+	(grub_cmd_vbeinfo): ... this. Save video modes before
+	iterating. Skip a video mode, if it is not available, not enough
+	information is given or it is monochrome. Show the memory
+	model. Leave the interpretation of MODEVAR to grub_strtoul
+	completely.
+	(GRUB_MOD_INIT): Rename vbe_list_modes to vbeinfo.
+	(GRUB_MOD_FINI): Likewise.
+
+	* commands/i386/pc/vbetest.c (grub_cmd_vbe_test): Renamed to ...
+	(grub_cmd_vbetest): ... this. Don't print unnecessarily. Use
+	grub_err_t instead of grub_uint32_t. Don't use SPTR. Remove a
+	duplicated grub_env_get. Leave the interpretation of MODEVAR to
+	grub_strtoul completely.
+	(real2pm): Removed.
+	(GRUB_MOD_INIT): Rename vbe_test to vbetest.
+	(GRUB_MOD_FINI): Likewise.
+
+	* normal/misc.c: Include grub/mm.h.
+
+	* conf/i386-pc.rmk (pkgdata_MODULES): Replaced vbe_test.mod and
+	vbe_list_modes with vbetest.mod and vbeinfo.mod.
+	(vbe_list_modes_mod_SOURCES): Removed.
+	(vbe_list_modes_mod_CFLAGS): Likewise.
+	(vbe_test_mod_SOURCES): Likewise.
+	(vbe_test_mod_CFLAGS): Likewise.
+	(vbeinfo_mod_SOURCES): New variable.
+	(vbeinfo_mod_CFLAGS): Likewise.
+	(vbetest_mod_SOURCES): Likewise.
+	(vbetest_mod_CFLAGS): Likewise.
+
+2005-08-18  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* normal/misc.c: New file.
+
+	* DISTLIST: Added normal/misc.c.
+
+	* partmap/amiga.c (amiga_partition_map_iterate): Add an argument
+	DISK to HOOK. Call HOOK with DISK.
+	* partmap/apple.c (apple_partition_map_iterate): Likewise.
+	* partmap/pc.c (pc_partition_map_iterate): Likewise.
+	* partmap/sun.c (sun_partition_map_iterate): Likewise.
+
+	* normal/menu_entry.c (struct screen): Added a new member
+	"completion_shown".
+	(completion_buffer): New global variable.
+	(make_screen): Set SCREEN->COMPLETION_SHOWN to zero.
+	(store_completion): New function.
+	(complete): Likewise.
+	(clear_completions): Likewise.
+	(grub_menu_entry_run): If SCREEN->COMPLETION_SHOWN is non-zero,
+	call clear_completions and reset SCREEN->COMPLETION_SHOWN. If C is
+	a tab, call complete.
+
+	* normal/completion.c (disk_dev): Removed.
+	(print_simple_completion): Likewise.
+	(print_partition_completion): Likewise.
+	(print_func): New global variable.
+	(add_completion): Do not take the arguments WHAT or PRINT any
+	longer. Added a new argument TYPE. Instead of printing directly,
+	call PRINT_FUNC if not NULL.
+	All callers changed.
+	(complete_device): Use a local variable DEV instead of
+	DISK_DEV. Do not move CURRENT_WORD to the end of a device name.
+	(grub_normal_do_completion): Take a new argument HOOK. Do not
+	initialize DISK_DEV. Initialize PRINT_FUNC to HOOK. If RET is an
+	empty string, return NULL instead.
+	All callers changed.
+
+	* normal/cmdline.c (print_completion): New function.
+
+	* kern/partition.c (grub_partition_iterate): Add an argument DISK
+	to HOOK.
+	All callers changed.
+
+	* kern/disk.c (grub_print_partinfo): Removed.
+
+	* include/grub/partition.h (struct grub_partition_map): Add a new
+	argument DISK into HOOK of ITERATE.
+	(grub_partition_iterate): Add a new argument DISK to HOOK.
+
+	* include/grub/normal.h (enum grub_completion_type): New enum.
+	(grub_completion_type_t): New type.
+	(GRUB_COMPLETION_TYPE_COMMAND): New constant.
+	(GRUB_COMPLETION_TYPE_DEVICE): Likewise.
+	(GRUB_COMPLETION_TYPE_PARTITION): Likewise.
+	(GRUB_COMPLETION_TYPE_FILE): Likewise.
+	(grub_normal_do_completion): Added a new argument HOOK.
+	(grub_normal_print_device_info): New prototype.
+
+	* include/grub/disk.h (grub_print_partinfo): Removed.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Added normal/misc.c.
+	(normal_mod_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	(normal_mod_SOURCES): Likewise.
+
+	* commands/ls.c (grub_ls_list_disks): Use
+	grub_normal_print_device_info instead of grub_print_partinfo. Free
+	PNAME.
+	(grub_ls_list_files): Use grub_normal_print_device_info instead of
+	duplicating the code.
+
+2005-08-16  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* commands/i386/pc/vbe_list_modes.c: Update source formatting to
+	follow GCS more precisely.
+	* commands/i386/pc/vbe_test.c: Likewise.
+	* include/grub/i386/pc/vbe.h: Likewise.
+	* term/i386/pc/vesafb.c: Likewise.
+	* video/i386/pc/vbe.c: Likewise.
+
+2005-08-16  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* DISTLIST: Added term/i386/pc/vesafb.c
+	DISTLIST: Added video/i386/pc/vbe.c
+	DISTLIST: Added commands/i386/pc/vbe_list_modes.c.
+	DISTLIST: Added commands/i386/pc/vbe_test.c.
+	* commands/i386/pc/vbe_list_modes.c: New file.
+	* commands/i386/pc/vbe_test.c: Likewise.
+	* term/i386/pc/vesafb.c: Likewise.
+	* video/i386/pc/vbe.c: Likewise.
+	* include/grub/i386/pc/vbe.h (GRUB_VBE_DEFAULT_VIDEO_MODE): Added define.
+	(grub_vbe_probe) Added prototype.
+	(grub_vbe_set_video_mode) Likewise.
+	(grub_vbe_get_video_mode) Likewise.
+	(grub_vbe_get_video_mode_info) Likewise.
+	(grub_vbe_set_pixel_rgb) Likewise.
+	(grub_vbe_set_pixel_index) Likewise.
+	* conf/i386-pc.rmk (pkgdata_MODULES): Added vbe.mod.
+	(pkgdata_MODULES): Added vesafb.mod.
+	(pkgdata_MODULES): Added vbe_list_modes.mod.
+	(pkgdata_MODULES): Added vbe_test.mod.
+	(vbe_mod_SOURCES): Added.
+	(vbe_mod_CFLAGS): Likewise.
+	(vesafb_mod_SOURCES): Likewise.
+	(vesafb_mod_CFLAGS): Likewise.
+	(vbe_list_modes_mod_SOURCES): Likewise.
+	(vbe_list_modes_mod_CFLAGS): Likewise.
+	(vbe_test_mod_SOURCES): Likewise.
+	(vbe_test_mod_CFLAGS): Likewise.
+
+2005-08-14  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* normal/command.c (grub_command_execute): If INTERACTIVE is
+	false and GRUB_COMMAND_FLAG_NO_ECHO is not specified, print
+	CMDLINE. Disable the pager if INTERACTIVE is true.
+	All callers are changed.
+
+	* normal/main.c (grub_normal_execute): Read command.lst and fs.lst
+	before reading a config file.
+	* normal/main.c (read_config_file): Even if a command is not
+	found, register it if it is within an entry.
+
+	* util/grub-emu.c: Include sys/types.h and unistd.h.
+	(options): Added --hold.
+	(struct arguments): Added a new member "hold".
+	(parse_opt): If KEY is 'H', set ARGS->HOLD to ARG or -1 if ARG is
+	missing.
+	(main): Initialize ARGS.HOLD to zero. Wait until ARGS.HOLD is
+	cleared by a debugger, if it is not zero.
+
+	* include/grub/normal.h (grub_command_execute): Add an argument
+	INTERACTIVE.
+
+2005-08-14  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* DISTLIST: Added include/grub/i386/pc/vbe.h.
+
+2005-08-13  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* aclocal.m4 (grub_I386_CHECK_REGPARM_BUG): Replace the test
+	program with another one, because the old one didn't detect a bug
+	in gcc-3.4. Always use regparm 2, because the new test is still
+	not enough for gcc-4.0. Someone must investigate a simple test
+	case which detects a bug in gcc-4.0.
+
+2005-08-12  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Added normal/completion.c.
+
+	* normal/completion.c: New file.
+
+	* term/i386/pc/console.c (grub_console_getwh): New function.
+	(grub_console_term): Assign grub_console_getwh to getwh.
+
+	* normal/cmdline.c (grub_tab_complete): Removed. Now the same
+	function is defined in normal/completion.c as
+	grub_normal_do_completion.
+	(grub_cmdline_get): Use grub_normal_do_completion instead of
+	grub_tab_complete.
+
+	* kern/partition.c (grub_partition_map_iterate): Return 1 if HOOK
+	returns non-zero, otherwise return 0.
+	(grub_partition_iterate): First, probe the partition map. Then,
+	call ITERATE only for this partition map.
+
+	* kern/misc.c (grub_strncmp): Rewritten.
+
+	* kern/disk.c (grub_disk_dev_iterate): Return 1 if P->ITERATE
+	returns non-zero. Otherwise return 0.
+
+	* include/grub/partition.h (grub_partition_map_iterate): Return
+	int instead of void.
+
+	* include/grub/normal.h (grub_normal_do_completion): New prototype.
+
+	* include/grub/misc.h (grub_strncmp): Change the type of N to
+	grub_size_t.
+
+	* include/grub/disk.h (grub_disk_dev_iterate): Return int instead
+	of void.
+
+	* normal/menu.c (draw_border): Cast GRUB_TERM_BORDER_WIDTH to
+	unsigned explicitly before comparing it with I.
+
+	* kern/main.c (grub_env_write_root): Add the attribute unused into
+	VAR.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added
+	normal/completion.c.
+	(normal_mod_SOURCES): Likewise.
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Likewise.
+	(normal_mod_SOURCES): Likewise.
+
+	* normal/command.c (grub_iterate_commands): If ITERATE returns
+	non-zero, return one immediately.
+
+2005-08-09  Vesa Jaaskelainen  <chaac@nic.fi>
+
+	* conf/i386-pc.rmk (kernel_img_HEADERS): Added machine/vbe.h.
+	* kern/i386/pc/startup.S: Updated Global Descriptor table's
+	descriptions.
+	(grub_vbe_get_controller_info): New function.
+	(grub_vbe_get_mode_info): Likewise.
+	(grub_vbe_set_mode): Likewise.
+	(grub_vbe_get_mode): Likewise.
+	(grub_vbe_set_memory_window): Likewise.
+	(grub_vbe_get_memory_window): Likewise.
+	(grub_vbe_set_scanline_length): Likewise.
+	(grub_vbe_get_scanline_length): Likewise.
+	(grub_vbe_set_display_start): Likewise.
+	(grub_vbe_get_display_start): Likewise.
+	(grub_vbe_set_palette_data): Likewise.
+	* include/grub/i386/pc/vbe.h: New file.
+
+2005-08-08  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* conf/powerpc-ieee1275.rmk (grubof_SOURCES): Replaced
+	kern/ieee1275/of.c with kern/ieee1275/ieee1275.c.
+	* DISTLIST: Likewise.
+	* kern/ieee1275/of.c: Moved to ...
+	* kern/ieee1275/ieee1275.c: ... here.
+
+2005-08-08  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* term/ieee1275/ofconsole.c: Include <grub/mm.h>.
+	(grub_ofconsole_getwh): Cast -1 to type grub_ieee1275_ihandle_t.
+	Pass 0 as `end' parameter to grub_strtoul().
+
+2005-08-08  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* include/grub/powerpc/ieee1275/console.h: Do not include
+	<grub/types.h>.  Do not include <grub/symbol.h>.  Remove ASM_FILE
+	ifdef.
+	(grub_console_cur_color): Remove i386-specific prototype.
+	(grub_console_real_putchar): Likewise.
+	(grub_console_checkkey): Likewise.
+	(grub_console_getkey): Likewise.
+	(grub_console_getxy): Likewise.
+	(grub_console_gotoxy): Likewise.
+	(grub_console_cls): Likewise.
+	(grub_console_setcursor): Likewise.
+	* kern/powerpc/ieee1275/init.c: Don't include <grub/console.h>.
+	Include <grub/machine/console.h>.
+	* term/ieee1275/ofconsole.c: Likewise.
+
+2005-08-08  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* Makefile.in (LIBLZO): New variable.
+
+	* configure.ac: Check for LZO version 2.
+
+	* util/i386/pc/grub-mkimage.c [HAVE_LZO_LZO1X_H]: Include
+	lzo/lzo1x.h instead of lzo1x.h.
+
+	* conf/i386-pc.rmk (grub_mkimage_LDFLAGS): Use $(LIBLZO) instead
+	of -llzo.
+
+	* util/i386/pc/grub-setup.c (main): Do not free PREFIX
+	twice. Reported by Vladimir Serbinenko <phcoder@gmail.com>.
+
+	* partmap/pc.c (pc_partition_map_probe): Restore P->DATA after
+	copying the data from PARTITION to P.
+
+2005-08-07  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/rescue.c (grub_rescue_cmd_rmmod): If the reference count is
+	negative, unload the module.
+
+	* util/i386/pc/grub-setup.c (setup): The name of the PC partition
+	map is "pc_partition_map" but not "pc".
+	(usage): Fix the description. The options are --boot-image and
+	--core-image but not --boot-file or --core-file.
+	(main): If not specified explicitly, make BOOT_FILE and CORE_FILE
+	based on DEFAULT_BOOT_FILE and DEFAULT_CORE_FILE with DIR or
+	DEFAULT_DIRECTORY.
+
+	* util/i386/pc/grub-install.in: Do not specify --boot-file or
+	--core-file. Specify INSTALL_DEVICE as an argument.
+
+	* util/console.c: Include config.h.
+	[HAVE_NCURSeS_CURSES_H]: Include ncurses/curses.h.
+	[HAVE_NCURSES_H]: Include ncurses.h.
+	[HAVE_CURSES_H]: Include curses.h.
+	[!A_NORMAL] (A_NORMAL): Defined as zero.
+	[!A_STANDOUT] (A_STANDOUT): Likewise.
+
+	* conf/i386-pc.rmk (grub_emu_LDFLAGS): Use $(LIBCURSES) instead of
+	-lncurses.
+	* conf/powerpc-ieee1275.rmk (grub_emu_LDFLAGS): Likewise.
+
+	* configure.ac: Check for curses libraries and headers.
+
+	* Makefile.in (LIBCURSES): New variable.
+
+	* genmk.rb (Script::rule): Set the executable bits.
+
+	* util/i386/pc/biosdisk.c (grub_util_biosdisk_get_grub_dev): The
+	name of the PC partition map is "pc_partition_map" but not "pc".
+
+2005-08-07  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/i386/pc/grub-install.in (grub_probefs): New variable.
+	(modules): Likewise.
+	(usage): Added descriptions for --modules and --grub-probefs.
+	Handle --modules and --grub-probefs. Save the arguments in MODULES
+	and GRUB_PROBEFS, respectively.
+	Auto-detect a filesystem module against GRUBDIR. If the result is
+	empty and modules are not specified explicitly, abort the
+	installation. Add the result to MODULES.
+
+	* DISTLIST: Removed boot/powerpc/ieee1275/ieee1275.c,
+	disk/powerpc/ieee1275/ofdisk.c,
+	include/grub/powerpc/ieee1275/init.h and
+	term/powerpc/ieee1275/ofconsole.c.
+	Added disk/ieee1275/ofdisk.c, kern/ieee1275/of.c and
+	term/ieee1275/ofconsole.c.
+
+	* include/grub/powerpc/ieee1275/console.h: Resurrected.
+
+	* COPYING: Upgraded to the latest version. Only the address of the
+	FSF office has changed.
+
+2005-08-07  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* conf/powerpc-ieee1275.rmk (grubof_SOURCES): Replaced
+	kern/ieee1275.c with kern/ieee1275/of.c.
+
+	* kern/ieee1275.c: Moved to ...
+	* kern/ieee1275/of.c: ... here.
+
+2005-08-06  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* conf/i386-pc.rmk (kernel_img_HEADERS): Reordered for
+	readability.
+
+	* config.guess: Updated to the latest version from gnulib.
+	* config.sub: Likewise.
+	* install.sh: Likewise.
+	* mkinstalldirs: Likewise.
+
+	* include/grub/console.h: Removed. This file is arch-specific. Do
+	not put this in include/grub.
+
+	* include/grub/i386/pc/console.h: Resurrected.
+
+	* util/console.c: Include grub/machine/console.h instead of
+	grub/console.h.
+	* util/grub-emu.c: Likewise.
+
+2005-08-04  Marco Gerards  <metgerards@student.han.nl>
+
+	* kern/term.c (grub_putcode): Use `grub_getwh' instead of
+	hardcoded value.
+
+	From Vincent Pelletier  <subdino2004@yahoo.fr>
+	* include/grub/term.h (GRUB_TERM_WIDTH, GRUB_TERM_HEIGHT):
+	Redefined to use grub_getwh.
+	(grub_term): New member named getwh.
+	(grub_getwh): New prototype.
+	* kern/term.c (grub_getwh): New function.
+	* term/i386/pc/console.c (grub_console_getwh): New function.
+	(grub_console_term): New member `getwh'.
+	* term/i386/pc/vga.c (grub_vga_getwh): New function.
+	(grub_vga_term): New member `getwh'.
+	* term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Use
+	grub_ssize_t.
+	(grub_ofconsole_getw): New function.
+	(grub_ofconsole_init): Use grub_ssize_t and unsigned char.
+	(grub_ofconsole_term): New field named getwh and new initial
+	value.
+
+2005-08-03  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* include/grub/powerpc/ieee1275/ieee1275.h: Move ...
+	* include/grub/ieee1275/ieee1275.h: ... to here.  All users updated.
+	Move `abort', `grub_reboot', and `grub_halt' prototypes ...
+	* include/grub/powerpc/ieee1275/kernel.h: ... to here.
+	* commands/ieee1275/halt.c: Include <grub/machine/kernel.h> instead
+	of <grub/machine/ieee1275.h>.
+	* commands/ieee1275/reboot.c: Likewise.
+	* boot/powerpc/ieee1275/ieee1275.c: Move ...
+	* kern/ieee1275.c: ... to here.  All users updated.  Change all
+	parameter structs to use new type `grub_ieee1275_cell_t'.
+	* term/powerpc/ieee1275/ofconsole.c: Move ...
+	* term/ieee1275/ofconsole.c: ... to here.  All users updated.
+	* disk/powerpc/ieee1275/ofdisk.c: Move ...
+	* disk/ieee1275/ofdisk.c: ... to here.  All users updated.
+	* boot/powerpc/ieee1275/cmain.c: Change `grub_ieee1275_entry_fn' type
+	to return int.
+	* include/grub/i386/pc/console.h: Move to include/grub/console.h.
+	Remove unused prototypes.  All users updated.
+	* include/grub/powerpc/ieee1275/console.h: Removed.
+	* include/grub/powerpc/ieee1275/ieee1275.h: Define
+	`grub_ieee1275_cell_t'.
+	* kern/powerpc/ieee1275/openfw.c: Include <grub/machine/kernel.h>.
+	Cast comparisons with -1 to the correct type.
+	* loader/powerpc/ieee1275/linux.c (kernel_entry_t): Change parameter
+	type to match `grub_ieee1275_entry_fn'.
+
+2005-08-01  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Added util/i386/pc/grub-probefs.c.
+
+	* conf/i386-pc.rmk (sbin_UTILITIES): Added grub-probefs.
+	(grub_setup_SOURCES): Removed partmap/amiga.c, partmap/apple.c and
+	partmap/sun.c.
+	(grub_probefs_SOURCES): New variable.
+
+	* util/i386/pc/grub-probefs.c: New file.
+
+	* util/i386/pc/grub-setup.c (main): Call
+	grub_pc_partition_map_init, grub_ufs_init, grub_minix_init,
+	grub_hfs_init and grub_jfs_init to initialize the system. Call
+	grub_ufs_fini, grub_minix_fini, grub_hfs_fini, grub_jfs_init and
+	grub_pc_partition_map_fini to finish the system.
+
+2005-07-31  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* loader/i386/pc/multiboot.c (grub_multiboot_is_elf32): New
+	function.
+	(grub_multiboot_load_elf32): Likewise.
+	(grub_multiboot_is_elf64): Likewise.
+	(grub_multiboot_load_elf64): Likewise.
+	(grub_multiboot_load_elf): Likewise.
+	(grub_rescue_cmd_multiboot): Call grub_multiboot_load_elf to load
+	an ELF32 or ELF64 file.
+	This is based on a patch from Ruslan Nikolaev <nruslan@mail.com>.
+
+	From Serbinenko Vladimir <serbinenko.vova@list.ru>:
+	* kern/disk.c (grub_print_partinfo): Check if FS->LABEL is not
+	NULL before calling FS->LABEL.
+	* fs/fat.c (grub_fat_dir): Initialize DIRNAME to NULL.
+	* commands/ls.c (grub_ls_list_files): Show labels, if possible.
+	(grub_ls_list_disks): Check if FS and FS->LABEL are not NULL
+	before calling FS->LABEL.
+
+2005-07-26  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/i386/pc/grub-install.in (datadir): New variable.
+	(libdir): Removed.
+	(pkgdatadir): New variable.
+	(pkglibdir): Removed.
+
+2005-07-24  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Added util/i386/pc/grub-install.in.
+
+	* util/i386/pc/grub-install.in: New file.
+
+	* conf/i386-pc.rmk (sbin_SCRIPTS): New variable.
+	(grub_install_SOURCES): Likewise.
+
+	* genmk.rb: Added support for scripts.
+	(Script): New class.
+	(scripts): New variable.
+
+	* Makefile.in (install-local): Install sbin_SCRIPTS by
+	INSTALL_SCRIPT.
+	(uninstall): Remove sbin_SCRIPTS.
+
+	* util/i386/pc/grub-setup.c (main): If the argument is not a GRUB
+	device, try to get a GRUB device by
+	grub_util_biosdisk_get_grub_dev.
+	Free DEST_DEV.
+
+	* util/i386/pc/grub-mkdevicemap.c (usage): Remove a duplicated
+	description for --device-map.
+
+2005-07-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Change the semantics of variable hooks. They now return	strings
+	instead of error values.
+
+	* util/i386/pc/grub-setup.c: Include grub/env.h.
+	(setup): Use grub_device_set_root instead of grub_env_set.
+
+	* kern/rescue.c (grub_rescue_cmd_root): Use grub_env_set and
+	grub_env_get instead of grub_device_set_root and
+	grub_device_get_root, respectively.
+
+	* kern/main.c (grub_env_write_root): New function.
+	(grub_set_root_dev): Register grub_env_write_hook for "root". Use
+	grub_env_set instead of grub_device_set_root.
+
+	* kern/env.c (HASHSZ): Reduced to 13, because GRUB does not need
+	many variables.
+	(grub_env_set): Set ENV->VALUE to the result of ENV->WRITE_HOOK
+	rather than calling ENV->WRITE_HOOK afterwards.
+	(grub_env_get): Return the result of ENV->READ_HOOK rather than
+	passing a pointer of a pointer.
+	(grub_register_variable_hook): Change the types of "read_hook" and
+	"write_hook" to grub_env_read_hook_t and grub_env_write_hook_t,
+	respectively.
+	Allocate the default empty string on the heap, because this string
+	may be freed later.
+
+	* kern/device.c: Include grub/env.h.
+	(grub_device_set_root): Removed.
+	(grub_device_get_root): Likewise.
+	(grub_device_open): Use grub_env_get instead of
+	grub_device_get_root.
+
+	* include/grub/env.h (grub_env_read_hook_t): New type.
+	(grub_env_write_hook_t): Likewise.
+	(grub_env_var): Change the types of "read_hook" and "write_hook"
+	to grub_env_read_hook_t and grub_env_write_hook_t, respectively.
+	(grub_register_variable_hook): Likewise.
+
+	* include/grub/device.h (grub_device_set_root): Removed.
+	(grub_device_set_root): Likewise.
+
+	* fs/fat.c (grub_fat_dir): Make a copy of PATH in DIRNAME, and
+	make sure that DIRNAME terminates with '/', so that
+	grub_fat_find_dir will fail if PATH is not a directory.
+
+	* commands/ls.c (grub_ls_list_files): Remove the qualifier const
+	from DIRNAME.
+	Use the qualifier auto for print_files and print_files_long.
+	If FS->DIR sets GRUB_ERRNO to GRUB_ERR_BAD_FILE_TYPE, try DIRNAME
+	as a regular file.
+	Put a newline only if there is no error.
+	(grub_cmd_ls): Remove grub_ls_print_files, because this is not
+	used.
+
+2005-07-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/partition.c (grub_partition_probe): Initialize PART to
+	NULL. Otherwise, when no partition map is registered, this returns
+	a garbage.
+
+2005-07-19  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* partmap/apple.c (apple_partition_map_iterate): Check if POS
+	equals GRUB_DISK_SECTOR_SIZE to see if the partition table is
+	valid.
+
+2005-07-18  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* commands/ls.c (grub_ls_list_disks): Print the filesystem
+	information on each device, if it does not have partitions. Print
+	"Device" instead of "Disk", because this function is not specific
+	to disk devices.
+
+	* normal/main.c (grub_rescue_cmd_normal): Make the variable CONFIG
+	static to ensure that it is put on the memory rather than a
+	register.
+
+2005-07-17  Yoshinori Okuji  <okuji@enbug.org>
+
+	* commands/cat.c (GRUB_MOD_INIT): Use better documentation.
+	(grub_cat_init): Likewise.
+	* loader/i386/pc/chainloader_normal.c (GRUB_MOD_INIT): Likewise.
+	(options): Likewise.
+	* commands/configfile.c (GRUB_MOD_INIT): Likewise.
+	(grub_configfile_init): Likewise.
+	* font/manager.c (GRUB_MOD_INIT): Likewise.
+	* commands/help.c (GRUB_MOD_INIT): Likewise.
+	(grub_help_init): Likewise.
+	* normal/command.c (grub_command_init): Likewise.
+	* loader/i386/pc/linux_normal.c (GRUB_MOD_INIT): Likewise.
+	* disk/loopback.c (grub_loop_init): Likewise.
+	(GRUB_MOD_INIT): Likewise.
+	* commands/ls.c (grub_ls_init): Likewise.
+	(GRUB_MOD_INIT): Likewise.
+	(options): Likewise.
+	* commands/boot.c (grub_boot_init): Likewise.
+	(GRUB_MOD_INIT): Likewise.
+	* loader/i386/pc/multiboot_normal.c (GRUB_MOD_INIT): Likewise.
+	* commands/i386/pc/reboot.c (grub_reboot_init): Likewise.
+	(GRUB_MOD_INIT): Likewise.
+	* commands/cmp.c (grub_cmp_init): Likewise.
+	(GRUB_MOD_INIT): Likewise.
+
+	* normal/arg.c: Use <> instead of "" to include header files.
+	(SHORT_ARG_HELP): New macro.
+	(SHORT_ARG_USAGE): Likewise.
+	(help_options): Specify SHORT_ARG_HELP and SHORT_ARG_USAGE instead
+	of 'h' and 'u' for help and usage, respectively. Use more GNU-like
+	descriptions.
+	(find_short): Check if C is 'h' or 'u' explicitly.
+	(grub_arg_show_help): Use space characters instead of tabs. Treat
+	SHORT_ARG_HELP and SHORT_ARG_USAGE exceptionally so that -h and -u
+	are shown with --help and --usage only if they are not used for
+	the command itself.
+	(parse_option): Use SHORT_ARG_HELP and SHORT_ARG_USAGE instead of
+	'h' and 'u'.
+
+	* include/grub/arg.h (struct grub_arg_option): Add the qualifier
+	const into "longarg". Change the type of "shortarg" to int.
+
+2005-07-17  Yoshinori Okuji  <okuji@enbug.org>
+
+	* boot/i386/pc/boot.S (boot_drive_check): New label.
+
+	* include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_DRIVE_CHECK): New
+	macro.
+
+	* util/i386/pc/grub-setup.c (setup): Added a workaround for BIOSes
+	which do not pass a boot drive correctly. Copied from GRUB Legacy.
+
+2005-07-17  Yoshinori Okuji  <okuji@enbug.org>
+
+	* kern/i386/pc/startup.S (gate_a20_try_system_control_port_a):
+	When turning off Gate A20, skip the check and return immediately,
+	because this is not fatal usually.
+
+2005-07-17  Yoshinori Okuji  <okuji@enbug.org>
+
+	* conf/i386-pc.rmk (pxeboot_img_LDFLAGS): The text address should
+	be 0x7C00 instead of 0x8000.
+
+	* boot/i386/pc/pxeboot.S: Rewritten.
+
+	* kern/i386/pc/startup.S (gate_a20_try_bios): No need to specify
+	EXT_C.
+	(gate_a20_check_state): Read a byte from 0x108000. Invert the
+	result.
+
+2005-07-16  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/i386/pc/startup.S (grub_gate_a20): Rewritten for
+	robustness. This routine now supports a BIOS call and System
+	Control Port A to modify the gate A20.
+
+	* include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE):
+	Increased to 0x440.
+
+2005-07-12  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_open): dprintf the
+	device path and resulting ihandle.
+	(grub_ofdisk_close): dprintf the ihandle being closed.
+	(grub_ofdisk_read): dprintf function parameters.
+	* kern/mm.c (grub_mm_init_region): Likewise.
+	* loader/powerpc/ieee1275/linux.c: Remove extra whitespace.
+	(grub_linux_boot): dprintf the Linux entry point, initrd address and
+	size, and boot arguments.
+	(grub_rescue_cmd_linux): dprintf each ELF segment's address and size
+	before loading into memory.
+	(grub_rescue_cmd_initrd): dprintf the initrd's address and size
+	before loading into memory.
+
+2005-07-12  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/mm.c: Added much documentation.
+	(GRUB_MM_ALIGN_LOG2): When GRUB_CPU_SIZEOF_VOID_P is
+	8, set to 5 instead of 8.
+
+2005-07-10  Yoshinori Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Added util/i386/pc/grub-mkimage.c.
+
+	* conf/i386-pc.rmk (sbin_UTILITIES): Added grub-mkdevicemap.
+	(grub_mkdevicemap_SOURCES): New variable.
+
+	* util/i386/pc/grub-mkdevicemap.c: New file. Mostly copied from
+	lib/device.c of GRUB Legacy.
+
+2005-07-10  Yoshinori Okuji  <okuji@enbug.org>
+
+	* commands/ls.c (grub_ls_list_files): Check if *PATH is NUL
+	instead of PATH is NULL.
+
+2005-07-09  Vincent Pelletier  <subdino2004@yahoo.fr>
+
+	* commands/cmp.c (BUFFER_SIZE): New macro.
+	(grub_cmd_cmp): Close the right file at the right time.  Compare
+	only data just read.  Don't report files of different  size as
+	identical.  Dynamically allocate buffers.  Move variable
+	declarations at the beginning of function.
+
+2005-07-09  Yoshinori Okuji  <okuji@enbug.org>
+
+	* aclocal.m4 (grub_I386_CHECK_REGPARM_BUG): The return value was
+	reverse.
+
+2004-07-04  Vincent Pelletier  <subdino2004@yahoo.fr>
+
+	* normal/cmdline.c (grub_cmdline_get): Don't fallback on ctrl-d
+	when backspace is pressed at beginning of line.
+
+2005-07-03  Yoshinori Okuji  <okuji@enbug.org>
+
+	* DISTLIST: Added genfslist.sh.
+
+	* normal/main.c (fs_module_list): New variable.
+	(autoload_fs_module): New function.
+	(read_fs_list): Likewise.
+	(grub_normal_execute): Call read_fs_list.
+
+	* kern/fs.c (grub_fs_autoload_hook): New variable.
+	(grub_fs_probe): Added support for auto-loading.
+
+	* include/grub/normal.h (struct grub_fs_module_list): New struct.
+	(grub_fs_module_list_t): New type.
+
+	* include/grub/fs.h (grub_fs_autoload_hook_t): New type.
+	(grub_fs_autoload_hook): New prototype.
+
+	* genfslist.sh: New file.
+
+	* genmk.rb: Added a rule to generate a filesystem list.
+
+2005-06-30  Marco Gerards  <metgerards@student.han.nl>
+
+	* configure.ac: Fix the test for cross-compiling.
+
+	* genmk.rb (Program): Use `$(CC)' instead of `$(BUILD_CC)'.  Don't
+	define GRUB_UTIL anymore.
+
+	* util/powerpc/ieee1275/grub-mkimage.c (load_note): Endian fixes
+	so this function works on other systems than just big endian.
+	(load_modules): Likewise.
+	(add_segments): Likewise.
+
+2005-06-23  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/misc.c (grub_vsprintf): Add `longfmt'.  If format string
+	contains `l' modifier, get a long from va_arg().
+
+2005-06-23  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/mm.c (grub_free): If the next free block which is being
+	merged is the first free block, set the first block to the block
+	being freed.
+	Reported by Vincent Guffens <guffens@inma.ucl.ac.be>.
+
+2005-05-08  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* boot/powerpc/ieee1275/cmain.c (cmain): Initialize
+	`grub_ieee1275_chosen'.
+
+2005-05-08  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* boot/powerpc/ieee1275/cmain.c	(module_info): Remove definition.
+	(grub_ieee1275_chosen): New variable.
+	(cmain): Initialize and use `grub_ieee1275_chosen' instead of
+	`chosen'.
+	* boot/powerpc/ieee1275/crt0.S (init_stack): Remove stack space.
+	* boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_get_property):
+	Rename first argument to `phandle' for consistency.
+	(grub_ieee1275_get_property_length): Likewise.
+	(grub_ieee1275_next_property): Likewise.  Change type of first argument
+	to grub_ieee1275_phandle_t.
+	* include/grub/powerpc/ieee1275/ieee1275.h (grub_ieee1275_entry_fn):
+	Move export next to declaration.
+	(grub_ieee1275_chosen): New variable.
+	* include/grub/powerpc/ieee1275/kernel.h (GRUB_IEEE1275_MODULE_BASE):
+	Correct cosmetic typo.
+	* kern/powerpc/ieee1275/init.c (grub_set_prefix): Use
+	`grub_ieee1275_chosen'.
+	* kern/powerpc/ieee1275/openfw.c (grub_map): Likewise.
+	* loader/powerpc/ieee1275/linux.c (grub_linux_boot): Likewise.
+	(grub_rescue_cmd_linux): Set `initrd_addr' to 0.
+	* term/powerpc/ieee1275/ofconsole.c (grub_ofconsole_refresh): Use
+	`grub_ieee1275_chosen'.
+
+2005-05-10  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* boot/powerpc/ieee1275/cmain.c (cmain): Remove code to parse
+	/chosen/bootargs.
+	* kern/powerpc/ieee1275/init.c (grub_machine_init): Parse
+	/chosen/bootargs as "variable=value" pairs.
+
+2005-05-08  Vincent Pelletier  <subdino2004@yahoo.fr>
+
+	* include/grub/misc.h (grub_dprintf): New macro.
+	(grub_real_dprintf): New prototype.
+	(grub_strword): Likewise.
+	(grub_iswordseparator): Likewise.
+	* kern/misc.c (grub_real_dprintf): New function.
+	(grub_strword): Likewise.
+	(grub_iswordseparator): Likewise.
+
+2005-04-30  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* boot/powerpc/ieee1275/cmain.c: Don't include grub/machine/init.h.
+	(roundup): Remove macro.
+	(grub_ieee1275_flags): Make static.
+	(grub_ieee1275_realmode): Remove.
+	(grub_ieee1275_test_flag): New function.
+	(grub_ieee1275_set_flag): Likewise.
+	(find_options): Rename to `grub_ieee1275_find_options'; update
+	callers. Set GRUB_IEEE1275_FLAG_REAL_MODE and
+	GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS.
+	(cmain): New prototype.
+	(cmain): Use `grub_ieee1275_set_flag' instead of accessing
+	`grub_ieee1275_flags' directly.
+	* conf/powerpc-ieee1275.rmk (grubof_HEADERS): Remove
+	machine/biosdisk.h.
+	* disk/powerpc/ieee1275/ofdisk.c: Include grub/machine/ofdisk.h.
+	Don't include grub/machine/init.h.
+	(grub_ofdisk_open): Call `grub_ieee1275_test_flag'.
+	* include/grub/powerpc/ieee1275/ieee1275.h (grub_ieee1275_flags):
+	Remove prototype.
+	(grub_ieee1275_realmode): Likewise.
+	(grub_ieee1275_flag): New enum.
+	(grub_ieee1275_test_flag): New prototype.
+	(grub_ieee1275_set_flag): New prototype.
+	* include/grub/powerpc/ieee1275/init.h: Remove file.
+	* include/grub/powerpc/ieee1275/ofdisk.h: New file.
+	* kern/powerpc/ieee1275/init.c: Don't include grub/machine/init.h.
+	Include grub/machine/console.h.  Include grub/machine/ofdisk.h.
+	(grub_machine_fini): Don't call `grub_ieee1275_release'.  Remove
+	comment.
+	* kern/powerpc/ieee1275/openfw.c (grub_claimmap): Call
+	`grub_ieee1275_test_flag'.
+	(grub_ieee1275_encode_devname): Likewise.
+
+2005-04-21  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* include/grub/powerpc/ieee1275/ieee1275.h
+	(grub_ieee1275_encode_devname): New prototype.
+	(grub_ieee1275_get_filename): Likewise.
+	* kern/powerpc/ieee1275/init.c (grub_translate_ieee175_path): New
+	function.
+	(grub_set_prefix): Likewise.
+	(grub_machine_init): Call grub_set_prefix.
+	* kern/powerpc/ieee1275/openfw.c: Fix typos.
+	(grub_parse_type): New enum.
+	(grub_ieee1275_get_devargs): New function.
+	(grub_ieee1275_get_devname): Likewise.
+	(grub_ieee1275_parse_args): Likewise.
+	(grub_ieee1275_get_filename): Likewise.
+	(grub_ieee1275_encode_devname): Likewise.
+
+2005-03-30  Marco Gerards  <metgerards@student.han.nl>
+
+	* kern/powerpc/ieee1275/init.c (grub_machine_fini): Don't call
+	`grub_loader_unset'.
+
+2005-03-26  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* commands/ieee1275/halt.c (grub_cmd_halt): Call grub_halt
+	instead of grub_ieee1275_interpret.
+	(grub_halt_init): New function.
+	(grub_halt_fini): Likewise.
+	(GRUB_MOD_INIT): Correct message grammar.
+	* commands/ieee1275/reboot.c (grub_cmd_reboot): Call grub_reboot
+	instead of grub_ieee1275_interpret.
+	(grub_reboot_init): New function.
+	(grub_reboot_fini): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Replace
+	commands/i386/pc/halt.c, commands/i386/pc/reboot.c, and
+	util/i386/pc/misc.c with commands/ieee1275/halt.c,
+	commands/ieee1275/reboot.c, and util/powerpc/ieee1275/misc.c.
+	* disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_fini): New
+	function.
+	* include/grub/powerpc/ieee1275/console.h (grub_console_fini):
+	Add prototype.
+	* include/grub/powerpc/ieee1275/ieee1275.h (grub_reboot): Add
+	prototype.
+	(grub_halt): Likewise.
+	* include/grub/powerpc/ieee1275/init.h: Remove inaccurate comment.
+	(cmain): Remove __attribute__((unused)).
+	* kern/powerpc/ieee1275/init.c (grub_heap_start): New variable.
+	(grub_heap_len): Likewise.
+	(grub_machine_fini): New function.
+	* kern/powerpc/ieee1275/openfw.c (grub_reboot): New function.
+	(grub_halt): Likewise.
+	* term/powerpc/ieee1275/ofconsole.c (grub_console_fini): New
+	function.
+	* util/powerpc/ieee1275/misc.c: New file.
+
+2005-03-19  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* DISTLIST: New file.
+	* gendistlist.sh: Likewise.
+
+	* Makefile.in (COMMON_DISTFILES): Removed.
+	(BOOT_DISTFILES): Likewise.
+	(CONF_DISTFILES): Likewise.
+	(DISK_DISTFILES): Likewise.
+	(FS_DISTFILES): Likewise.
+	(INCLUDE_DISTFILES): Likewise.
+	(KERN_DISTFILES): Likewise.
+	(LOADER_DISTFILES): Likewise.
+	(TERM_DISTFILES): Likewise.
+	(UTIL_DISTFILES): Likewise.
+	(DISTFILES): Likewise.
+	(uninstall): Uninstall files in $(pkgdata_DATA).
+	(DISTLIST): New target.
+	(distdir): Use the contents of the file DISTLIST to get a list of
+	distributed files.
+
+2005-03-18  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* fs/fat.c (grub_fat_mount): Ignore the 3rd bit of a media
+	descriptor. This is ported from GRUB Legacy.
+
+	* gencmdlist.sh: Added an extra semicolon to make it work with
+	old sed versions. Reported by Robert Bihlmeyer
+	<robbe@orcus.priv.at>.
+
+2005-03-08  Yoshinori Okuji  <okuji@enbug.org>
+
+	Automatic loading of commands is supported.
+
+	* normal/main.c (read_command_list): New function.
+	(grub_normal_execute): Call read_command_list.
+
+	* normal/command.c (grub_register_command): Return zero or CMD.
+	Allocate CMD->NAME from the heap.
+	Initialize CMD->MODULE_NAME to zero.
+	Find the same name as well. If the same command is found and it is
+	a dummy command, overwrite members. If it is not a dummy command,
+	return zero.
+	(grub_unregister_command): Free Q->NAME and Q->MODULE_NAME.
+	(grub_command_find): If a dummy command is found, load a module
+	and retry to find a command only once.
+
+	* normal/cmdline.c (grub_tab_complete): Call grub_command_find to
+	make sure that each command is loaded.
+
+	* include/grub/normal.h (GRUB_COMMAND_FLAG_NOT_LOADED): New
+	macro.
+	(struct grub_command): Remove const from the member `name'.
+	Add a new member `module_name'.
+	(grub_register_command): Return grub_command_t.
+
+	* commands/help.c (grub_cmd_help): Call grub_command_find to make
+	sure that each command is loaded.
+
+	* genmk.rb (PModule::rule): Specify a module name without the
+	suffix ".mod" to gencmdlist.sh.
+
+2005-03-02  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* gencmdlist.sh: New file.
+
+	* genmk.rb (PModule::rule): Generate a rule for a command list.
+	Clean command.lst.
+	Generate command.lst from $(COMMANDFILES).
+
+	* Makefile.in (COMMON_DISTFILES): Added gencmdlist.sh.
+	(DATA): Added $(pkgdata_DATA).
+	(install-local): Install files in $(pkgdata_DATA).
+
+2005-03-02  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* term/i386/pc/vga.c (debug_command): Removed.
+	(GRUB_MOD_INIT): Do not register the command "debug".
+
+	From Hollis Blanchard:
+	* commands/configfile.c: New file.
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Added
+	commands/configfile.c.
+	(pkgdata_MODULES): Added configfile.mod.
+	(configfile_mod_SOURCES): New variable.
+	(configfile_mod_CFLAGS): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added
+	commands/configfile.c.
+	(pkgdata_MODULES): Added configfile.mod.
+	(configfile_mod_SOURCES): New variable.
+	(configfile_mod_CFLAGS): Likewise.
+	* util/grub-emu.c (main): Call grub_configfile_init and
+	grub_configfile_fini.
+	* include/grub/normal.h [GRUB_UTIL] (grub_configfile_init): New
+	prototype.
+	[GRUB_UTIL] (grub_configfile_fini): Likewise.
+
+2005-02-27  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* normal/arg.c (grub_arg_show_help): Do not show the bug report
+	address.
+
+	* commands/help.c (grub_cmd_help): Do not print newlines after
+	the last command in print_command_help.
+
+2005-02-27  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* commands/default.h: New file.
+	* commands/timeout.h: Likewise.
+	* normal/context.c: Likewise.
+
+	* util/misc.c: Do not include sys/times.h.
+	Include sys/time.h and grub/machine/time.h.
+	(grub_get_rtc): Rewritten with gettimeofday.
+
+	* util/grub-emu.c (main): Call grub_default_init and
+	grub_timeout_init before grub_normal_init, and call
+	grub_timeout_fini and grub_default_fini after grub_main.
+
+	* util/console.c (grub_ncurses_checkkey): Return the read
+	character or -1.
+
+	* normal/menu.c (run_menu): Set MENU->TIMEOUT to -1 once it
+	timeouts.
+
+	* normal/main.c (read_config_file): Push MENU. If this fails,
+	print an error and wait for a user input.
+	Print an error only if GRUB_ERRNO is not GRUB_ERR_NONE.
+	If a menu is empty or an error occurs, pop MENU.
+	(grub_normal_execute): Pop and free MENU after grub_menu_run
+	returns.
+
+	* kern/loader.c (grub_loader_boot): Call grub_machine_fini.
+
+	* include/grub/powerpc/ieee1275/time.h [GRUB_UTIL]: Do not
+	include	time.h.
+	[GRUB_UTIL] (GRUB_TICKS_PER_SECOND): Use the same definition as
+	without GRUB_UTIL.
+	* include/grub/i386/pc/time.h [GRUB_UTIL]: Do not include
+	time.h.
+	[GRUB_UTIL] (GRUB_TICKS_PER_SECOND): Use the same definition as
+	without GRUB_UTIL.
+
+	* include/grub/normal.h (struct grub_menu_list): New struct.
+	(grub_menu_list_t): New type.
+	(struct grub_context): New struct.
+	(grub_context_t): New type.
+	(grub_register_command): Got rid of EXPORT_FUNC.
+	(grub_unregister_command): Likewise.
+	(grub_context_get): New prototype.
+	(grub_context_get_current_menu): Likewise.
+	(grub_context_push_menu): Likewise.
+	(grub_context_pop_menu): Likewise.
+	[GRUB_UTIL] (grub_default_init): Likewise.
+	[GRUB_UTIL] (grub_default_fini): Likewise.
+	[GRUB_UTIL] (grub_timeout_init): Likewise.
+	[GRUB_UTIL] (grub_timeout_fini): Likewise.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Added commands/default.c,
+	commands/timeout.c and normal/context.c.
+	(pkgdata_MODULES): Added default.mod and timeout.mod.
+	(normal_mod_SOURCES): Added normal/context.c.
+	(default_mod_SOURCES): New variable.
+	(default_mod_CFLAGS): Likewise.
+	(timeout_mod_SOURCES): Likewise.
+	(timeout_mod_CFLAGS): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Copied from
+	conf/i386-pc.rmk.
+	(pkgdata_MODULES): Added default.mod and timeout.mod.
+	(normal_mod_SOURCES): Added normal/context.c.
+	(default_mod_SOURCES): New variable.
+	(default_mod_CFLAGS): Likewise.
+	(timeout_mod_SOURCES): Likewise.
+	(timeout_mod_CFLAGS): Likewise.
+
+	* Makefile.in (all-local): Added $(MKFILES).
+
+2005-02-21  Vincent Pelletier  <subdino2004@yahoo.fr>
+
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add `partmap/sun.c'.
+	(grub_emu_SOURCES): Likewise.
+	(pkgdata_MODULES): Add `sun.mod'.
+	(sun_mod_SOURCES, sun_mod_CFLAGS): New variables.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add
+	`partmap/sun.c'.
+	(pkgdata_MODULES): Add `sun.mod'.
+	(sun_mod_SOURCES, sun_mod_CFLAGS): New variables.
+	* include/grub/partition.h (grub_sun_partition_map_init): New
+	prototype.
+	(grub_sun_partition_map_fini): Likewise.
+	* partmap/sun.c: New file.
+	* util/grub-emu.c (main): Initialize and de-initialize the sun
+	partitionmap support.
+
+2005-02-19  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	This implements an Emacs-like menu entry editor.
+
+	* normal/menu_entry.c: New file.
+
+	* util/console.c (grub_ncurses_putchar): Translate some Unicode
+	characters to ASCII.
+	(saved_char): New variable.
+	(grub_ncurses_checkkey): Rewritten completely.
+	(grub_ncurses_getkey): Likewise.
+	(grub_ncurses_init): Call raw instead of cbreak.
+
+	* normal/menu.c (print_entry): Do not put a space.
+	(init_page): Renamed to ...
+	(grub_menu_init_page): ... this. All callers changed.
+	(edit_menu_entry): Removed.
+	(run_menu): Call grub_menu_entry_run instead of edit_menu_entry.
+
+	* normal/cmdline.c (grub_cmdline_run): Call grub_setcursor.
+
+	* kern/misc.c (grub_vprintf): Call grub_refresh.
+
+	* normal/menu.c (DISP_LEFT): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_DISP_LEFT): ... this.
+	* normal/menu.c (DISP_UP): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_DISP_UP): ... this.
+	* normal/menu.c (DISP_RIGHT): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_DISP_RIGHT): ... this.
+	* normal/menu.c (DISP_DOWN): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_DISP_DOWN): ... this.
+	* normal/menu.c (DISP_HLINE): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_DISP_HLINE): ... this.
+	* normal/menu.c (DISP_VLINE): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_DISP_VLINE): ... this.
+	* normal/menu.c (DISP_UL): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_DISP_UL): ... this.
+	* normal/menu.c (DISP_UR): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_DISP_UR): ... this.
+	* normal/menu.c (DISP_LL): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_DISP_LL): ... this.
+	* normal/menu.c (DISP_LR): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_DISP_LR): ... this.
+	* normal/menu.c (TERM_WIDTH): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_WIDTH): ... this.
+	* normal/menu.c (TERM_HEIGHT): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_HEIGHT): ... this.
+	* normal/menu.c (TERM_INFO_HEIGHT): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_INFO_HEIGHT): ... this.
+	* normal/menu.c (TERM_MARGIN): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_MARGIN): ... this.
+	* normal/menu.c (TERM_SCROLL_WIDTH): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_SCROLL_WIDTH): ... this.
+	* normal/menu.c (TERM_TOP_BORDER_Y): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_TOP_BORDER_Y): ... this.
+	* normal/menu.c (TERM_LEFT_BORDER_X): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_LEFT_BORDER_X): ... this.
+	* normal/menu.c (TERM_BORDER_WIDTH): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_BORDER_WIDTH): ... this.
+	* normal/menu.c (TERM_MESSAGE_HEIGHT): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_MESSAGE_HEIGHT): ... this.
+	* normal/menu.c (TERM_BORDER_HEIGHT): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_BORDER_HEIGHT): ... this.
+	* normal/menu.c (TERM_NUM_ENTRIES): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_NUM_ENTRIES): ... this.
+	* normal/menu.c (TERM_FIRST_ENTRY_Y): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_FIRST_ENTRY_Y): ... this.
+	* normal/menu.c (TERM_ENTRY_WIDTH): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_ENTRY_WIDTH): ... this.
+	* normal/menu.c (TERM_CURSOR_X): Renamed to ...
+	* include/grub/term.h (GRUB_TERM_CURSOR_X): ... this.
+	All callers changed.
+
+	* include/grub/normal.h: New prototype.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Added
+	normal/menu_entry.c.
+	(normal_mod_SOURCES): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
+	(normal_mod_SOURCES): Likewise.
+
+2005-02-15  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* include/grub/normal.h (grub_halt_init): New prototype.
+	(grub_halt_fini): Likewise.
+	(grub_reboot_init): Likewise.
+	(grub_reboot_fini): Likewise.
+
+	* util/grub-emu.c: Include signal.h.
+	(main_env): New global variable.
+	(grub_machine_init): Ignore SIGINT. Otherwise grub-emu cannot
+	catch C-c.
+	(grub_machine_fini): New function.
+	(main): Call grub_halt_init and grub_reboot_init before
+	grub_main, and grub_reboot_fini and grub_halt_fini after it.
+	Call setjmp with MAIN_ENV to go back afterwards.
+	Call grub_machine_fini right before return.
+
+	* include/grub/util/misc.h: Include setjmp.h.
+	(main_env): New prototype.
+
+	* include/grub/kernel.h (grub_machine_fini): New prototype.
+	* include/grub/i386/pc/biosdisk.h (grub_biosdisk_fini): Likewise.
+	* include/grub/i386/pc/console.h (grub_console_fini): Likewise.
+
+	* disk/i386/pc/biosdisk.c (grub_biosdisk_fini): New function.
+	* kern/i386/pc/init.c (grub_machine_fini): Likewise.
+	* term/i386/pc/console.c (grub_console_fini): Likewise.
+
+	* util/i386/pc/misc.c: New file.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Added
+	util/i386/pc/misc.c, commands/i386/pc/halt.c and
+	commands/i386/pc/reboot.c.
+
+2005-02-14  Guillem Jover  <guillem@hadrons.org>
+
+	* include/grub/dl.h (grub_dl_check_header): New prototype.
+	(grub_arch_dl_check_header): Change return type to grub_err_t,
+	remove size parameter and export function.  Update all callers.
+	* kern/dl.c (grub_dl_check_header): New function.
+	(grub_dl_load_core): Use `grub_dl_check_header' instead of
+	`grub_arch_dl_check_header'.  Check ELF type.  Check if sections
+	are inside the core.
+	* kern/i386/dl.c (grub_arch_dl_check_header): Remove arch
+	independent ELF header checks.
+	* kern/powerpc/dl.c (grub_arch_dl_check_header): Likewise.
+	* loader/i386/pc/multiboot.c (grub_rescue_cmd_multiboot): Use
+	`grub_dl_check_header' instead of explicit checks.  Check for the
+	ELF type.
+	* loader/powerpc/ieee1275/linux.c (grub_rescue_cmd_linux): Use
+	`grub_dl_check_header' instead of explicit checks.  Remove arch
+	specific ELF header checks.
+
+	* util/grub-emu.c (grub_arch_dl_check_header): Remove the
+	argument SIZE.
+
+2005-02-13  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* conf/powerpc-ieee1275.rmk (pkgdata_MODULES): Add ls.mod.
+	* include/grub/powerpc/libgcc.h (__mulsf3): New prototype.
+
+2005-02-12  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/partition.c (grub_partition_probe): Clear `grub_errno' and
+	return 0 if `grub_errno' is GRUB_ERR_BAD_PART_TABLE.
+	(part_map_iterate): Clear `grub_errno' and return 0 if
+	`partmap->iterate' returns GRUB_ERR_BAD_PART_TABLE.
+	* partmap/amiga.c (amiga_partition_map_iterate): Return
+	GRUB_ERR_BAD_PART_TABLE if no partition map magic is found.
+	* partmap/apple.c (apple_partition_map_iterate): Likewise.
+
+2005-02-01  Guillem Jover  <guillem@hadrons.org>
+
+	* loader/i386/pc/multiboot_normal.c (GRUB_MOD_INIT): Fix module
+	help info.
+
+2005-01-31  Marco Gerards  <metgerards@student.han.nl>
+
+	* include/grub/powerpc/ieee1275/loader.h (grub_load_linux):
+	Removed prototype.
+	(grub_rescue_cmd_linux): New prototype.
+	(grub_rescue_cmd_initrd): Likewise.
+	* powerpc/ieee1275/linux.c (grub_linux_boot): Remove struct
+	`bi_rec'.
+	(grub_linux_release_mem): Release the memory for the initrd.
+	(grub_load_linux): Renamed from this...
+	(grub_rescue_cmd_linux): ...To this.  Changed all callers.
+	Changed `entry' not to be static.  Loop over memory regions to
+	find another one when the default fails.
+	(grub_rescue_cmd_initrd): New function.
+	(grub_linux_init): Remove function.
+	(grub_linux_fini): Likewise.
+	(GRUB_MOD_INIT): Register `initrd'.
+	(GRUB_MOD_FINI): Unregister `initrd'.
+	* powerpc/ieee1275/linux_normal.c (grub_linux_normal_init):
+	Function removed.
+	(grub_linux_normal_fini): Likewise.
+	(GRUB_MOD_INIT): Register `initrd'.
+	(GRUB_MOD_FINI): Unregister `initrd'.
+
+2005-01-31  Marco Gerards  <metgerards@student.han.nl>
+
+	* commands/help.c: New file.
+	* normal/arg.c (show_help): Renamed to...
+	(grub_arg_show_help): ... this.
+	* commands/i386/pc/halt.c: New file.
+	* commands/i386/pc/reboot.c: Likewise.
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add `commands/help.c'.
+	(pkgdata_MODULES): Add `reboot.mod', `halt.mod' and `help.mod'.
+	(help_mod_SOURCES, help_mod_CFLAGS, reboot_mod_SOURCES)
+	(reboot_mod_CFLAGS, halt_mod_SOURCES, halt_mod_CFLAGS): New
+	variables.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add
+	`commands/help.c'.
+	(pkgdata_MODULES): Add `help.mod'.
+	(help_mod_SOURCES, help_mod_CFLAGS): New variables.
+	* grub/i386/pc/init.h (grub_reboot): New prototype.
+	(grub_halt): Likewise.
+	* include/grub/normal.h (grub_arg_show_help): New prototype.
+	(grub_help_init): Likewise.
+	(grub_help_fini): Likewise.
+	* util/grub-emu.c (main): Initialize and deinitialize the help
+	command.
+
+	* normal/cmdline.c (grub_cmdline_get): Doc fix.
+
+	* normal/command.c (grub_command_init): Fixed the description of
+	the `set' and `unset' commands.
+
+2005-01-31  Marco Gerards  <metgerards@student.han.nl>
+
+	* boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_interpret): New
+	function.
+	* commands/ieee1275/halt.c: New file.
+	* commands/ieee1275/reboot.c: Likewise.
+	* commands/ieee1275/suspend.c (grub_cmd_suspend): Use
+	`__attribute__ ((unused))'.  Some GCS related fixed.
+	(grub_suspend_init) [GRUB_UTIL]: Function removed.
+	(grub_suspend_fini): Likewise.
+	* conf/powerpc-ieee1275.rmk (pkgdata_MODULES): Add `reboot.mod'
+	and `halt.mod'.
+	(reboot_mod_SOURCES, reboot_mod_CFLAGS, halt_mod_SOURCES)
+	(halt_mod_CFLAGS): New variables.
+	* include/grub/powerpc/ieee1275/ieee1275.h
+	(grub_ieee1275_interpret): New prototype.
+
+2005-01-29  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* include/grub/misc.h (memmove): New prototype.
+	(memcpy): Likewise.
+
+2005-01-22  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_open): Don't initialize
+	`devpath' to 0.  Use `name' instead of `devpath' with `grub_strndup'.
+
+2005-01-22  Marco Gerards  <metgerards@student.han.nl>
+
+	* kern/misc.c (grub_strndup): Function rewritten.
+
+2005-01-22  Vincent Pelletier  <subdino2004@yahoo.fr>
+
+	* normal/menu.c (TERM_WIDTH): Macro redefined.
+	(TERM_TOP_BORDER_Y): Likewise.
+	(draw_border): Replaced while-loop by a for-loop.  Make the number
+	of lines consistent with the number of lines displayed in
+	print_entries.  Added a margin below the rectangle.
+	(print_entry): Make the entry fit in the rectangle.
+	(print_entries): Display the scroll arrows next to the right
+	border.
+
+2005-01-21  Marco Gerards  <metgerards@student.han.nl>
+
+	* fs/minix.c (grub_minix_find_file): Reserve more space for
+	`fpath' so the \0 can be stored.  Use `grub_strcpy' instead of
+	`grub_strncpy' to copy `path' into it.
+
+2005-01-21  Marco Gerards  <metgerards@student.han.nl>
+
+	Add the loopback device, a device via which files can be accessed
+	as devices.
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/loopback.c'.
+	(pkgdata_MODULES): Add loopback.mod.
+	(loopback_mod_SOURCES): New variable.
+	(loopback_mod_CFLAGS): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add
+	`disk/loopback.c'.
+	(pkgdata_MODULES): Add loopback.mod.
+	(loopback_mod_SOURCES): New variable.
+	(loopback_mod_CFLAGS): Likewise.
+	* disk/loopback.c: new file.
+	* include/grub/normal.h (grub_loop_init): New prototype.
+	(grub_loop_fini): New prototype.
+	* util/grub-emu.c (main): Initialize and de-initialize loopback
+	support.
+	* include/grub/disk.h (grub_disk_dev_id): Add
+	`GRUB_DISK_DEVICE_LOOPBACK_ID'.
+
+2005-01-20  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_enter): New
+	function.
+	* conf/powerpc-ieee1275.rmk (pkgdata_MODULES): Add suspend.mod.
+	(suspend_mod_SOURCES): New variable.
+	(suspend_mod_CFLAGS): Likewise.
+	* include/grub/powerpc/ieee1275/ieee1275.h (grub_ieee1275_enter):
+	New prototype.
+	* commands/ieee1275/suspend.c: New file.
+
+2005-01-20  Timothy Baldwin  <T.E.Baldwin99@members.leeds.ac.uk>
+
+	* include/grub/dl.h (GRUB_MOD_INIT): Changed `__attribute__
+	((unused))' to `__attribute__ ((used))'.
+	(GRUB_MOD_FINI): Likewise.
+	* kern/dl.c (grub_dl_load_file): Fix null pointer dereference.
+	* genmk.rb (PModule): Assign space to common symbols when linking
+	modules.
+
+2005-01-20  Marco Gerards  <metgerards@student.han.nl>
+
+	* include/grub/mm.h (grub_mm_init_region): Change the type of the
+	`unsigned' arguments to `grub_size_t'.
+	(grub_malloc): Likewise.
+	(grub_realloc): Likewise.
+	(grub_memalign): Likewise.
+	* kern/i386/dl.c (grub_arch_dl_check_header): Likewise.
+	* kern/powerpc/dl.c (grub_arch_dl_check_header): Likewise.
+	* util/misc.c (grub_malloc): Likewise.
+	(grub_realloc): Likewise.
+	* kern/mm.c (get_header_from_pointer): Change the casts to
+	`unsigned' into a cast to `grub_size_t'.
+
+	* fs/fshelp.c (grub_fshelp_find_file): The `oldnode' should always
+	point to `currnode' when `currnode' is changed.
+
+	* util/grub-emu.c (main): Initialize `progname'.  Reported by Nico
+	Schottelius <nico-linux@schottelius.org>.
+
+2005-01-09  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* util/powerpc/ieee1275/grub-mkimage.c: Include <string.h>.
+	(note_path): Remove variable.
+	(GRUB_IEEE1275_NOTE_NAME): New macro.
+	(GRUB_IEEE1275_NOTE_TYPE): Likewise.
+	(grub_ieee1275_note_hdr): New structure.
+	(grub_ieee1275_note_desc): Likewise.
+	(grub_ieee1275_note): Likewise.
+	(load_note): Remove `dir' argument.  All callers updated.  Remove
+	`note_img' and `path'.  Do not load a file from `note_path'.
+	Initialize a struct grub_ieee1275_note and write that to `out'.
+	Use GRUB_IEEE1275_MODULE_BASE instead of MODULE_BASE.
+
+2005-01-05  Marco Gerards  <metgerards@student.han.nl>
+
+	* util/misc.c (grub_util_read_image): Revert last change.  It
+	called `grub_util_read_at', which seeks from the beginning of the
+	file.
+
+2005-01-04  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* TODO: Add note about endianness in grub-mkimage.
+	* boot/powerpc/ieee1275/crt0.S (note): Remove unused .note
+	section.
+	* conf/powerpc-ieee1275.rmk (bin_UTILITIES): Add grub-mkimage.
+	(grub_mkimage_SOURCES): New target.
+	* include/grub/kernel.h (grub_start_addr): Remove variable.
+	(grub_end_addr): Likewise.
+	(grub_total_module_size): Likewise.
+	(grub_kernel_image_size): Likewise.
+	(GRUB_MODULE_MAGIC): New constant.
+	(grub_module_info): New structure.
+	(grub_arch_modules_addr): New prototype.
+	(grub_get_end_addr): Remove prototype.
+	* include/grub/i386/pc/kernel.h (grub_end_addr): New prototype.
+	* include/grub/powerpc/ieee1275/kernel.h: New file.
+	* include/grub/util/misc.h (grub_util_get_fp_size): New
+	prototype.
+	(grub_util_read_at): Likewise.
+	(grub_util_write_image_at): Likewise.
+	* kern/main.c (grub_get_end_addr): Remove function.
+	(grub_load_modules): Call grub_arch_modules_addr instead of using
+	grub_end_addr.  Look for a grub_module_info struct in memory.  Use
+	the grub_module_info fields instead of calling grub_get_end_addr
+	as loop conditions.  Move grub_add_unused_region code here.
+	(grub_add_unused_region): Remove function.
+	* kern/i386/pc/init.c: Include grub/cache.h.
+	(grub_machine_init): Remove call to grub_get_end_addr.  Remove
+	one call to add_mem_region.
+	(grub_arch_modules_addr): New function.
+	* kern/powerpc/ieee1275/init.c (grub_end_addr): Remove variable.
+	(grub_total_module_size): Likewise.
+	Include grub/machine/kernel.h.
+	(grub_arch_modules_addr): New function.
+	* util/grub-emu.c (grub_end_addr): Remove variable.
+	(grub_total_module_size): Likewise.
+	(grub_arch_modules_addr): New function.
+	* util/misc.c: Include unistd.h.
+	(grub_util_get_fp_size): New function.
+	(grub_util_read_at): Likewise.
+	(grub_util_write_image_at): Likewise.
+	(grub_util_read_image): Call grub_util_read_at.
+	(grub_util_write_image): Call grub_util_write_image_at.
+	* util/i386/pc/grub-mkimage.c (generate_image): Allocate
+	additional memory in kernel_img for a struct grub_module_info.
+	Fill in that grub_module_info.
+	* util/powerpc/ieee1275/grub-mkimage.c: New file.
+
+2005-01-03  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_milliseconds):
+	New function.
+	* include/grub/powerpc/ieee1275/ieee1275.h
+	(grub_ieee1275_milliseconds): New prototype.
+	* include/grub/powerpc/ieee1275/time.h (GRUB_TICKS_PER_SECOND):
+	Change to 1000.
+	* kern/powerpc/ieee1275/init.c (grub_get_rtc): Call
+	grub_ieee1275_milliseconds.
+
+2005-01-03  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* boot/powerpc/ieee1275/cmain.c (grub_ieee1275_realmode): New
+	variable.
+	(find_options): New function.
+	(cmain): Call find_options.
+	* include/grub/powerpc/ieee1275/ieee1275.h
+	(grub_ieee1275_realmode): New extern variable.
+	* kern/powerpc/ieee1275/openfw.c (grub_claimmap): Only call
+	grub_map if grub_ieee1275_realmode is false.
+
+2004-12-29  Marco Gerards  <metgerards@student.han.nl>
+
+	* normal/cmdline.c (grub_cmdline_get): Redone logic so no empty
+	lines are inserted and make it work like readline.  Reported by
+	Vincent Pelletier <subdino2004@yahoo.fr>.
+
+2004-12-28  Marco Gerards  <metgerards@student.han.nl>
+
+	* boot/powerpc/ieee1275/crt0.S (_start): Don't set up the stack.
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCE): Remove
+	`kern/powerpc/cache.S'.
+
+2004-12-27  Marco Gerards  <metgerards@student.han.nl>
+
+	* genmk.rb: Handle the `Program' class in the main loop.  Written
+	by Johan Rydberg <jrydberg@gnu.org>.
+	(Program): New class.
+	(programs): New variable.
+	* boot/powerpc/ieee1275/cmain.c: Include <grub/machine/ieee1275.h>
+	instead of "grub/machine/ieee1275.h".  Include <grub/kernel.h>
+	instead of "grub/kernel.h".  Include <grub/machine/init.h>.
+	(help_arch): Function removed.
+	* conf/powerpc-ieee1275.rmk (grubof_HEADERS): Add
+	`powerpc/libgcc.h' and `loader.h'.
+	(pkgdata_PROGRAMS): New variable.
+	(sbin_UTILITIES): Variable removed.
+	(grub_emu_SOURCES): Added kern/powerpc/cache.S.
+	(grubof_SOURCES): Variable re-defined so it only includes the
+	core functionality.
+	(grubof_CFLAGS): Remove `-DGRUBOF'.
+	(pkgdata_MODULES, fshelp_mod_SOURCES, fshelp_mod_CFLAGS,
+	(fat_mod_SOURCES, fat_mod_CFLAGS, ext2_mod_SOURCES)
+	(ext2_mod_CFLAGS, ufs_mod_SOURCES, ufs_mod_CFLAGS)
+	(minix_mod_SOURCES, minix_mod_CFLAGS, hfs_mod_SOURCES)
+	(hfs_mod_CFLAGS, jfs_mod_SOURCES, jfs_mod_CFLAGS)
+	(iso9660_mod_SOURCES, iso9660_mod_CFLAGS, _linux_mod_SOURCES)
+	(_linux_mod_CFLAGS, linux_mod_SOURCES, linux_mod_CFLAGS)
+	(normal_mod_SOURCES, normal_mod_CFLAGS, normal_mod_ASFLAGS)
+	(hello_mod_SOURCES, hello_mod_CFLAGS, boot_mod_SOURCES)
+	(boot_mod_CFLAGS, terminal_mod_SOURCES, terminal_mod_CFLAGS)
+	(ls_mod_SOURCES, ls_mod_CFLAGS, cmp_mod_SOURCES, cmp_mod_CFLAGS)
+	(cat_mod_SOURCES, cat_mod_CFLAGS, font_mod_SOURCES)
+	(font_mod_CFLAGS, amiga_mod_SOURCES, amiga_mod_CFLAGS)
+	(apple_mod_SOURCES, apple_mod_CFLAGS, pc_mod_SOURCES)
+	(pc_mod_CFLAGS): New variables.
+	* disk/powerpc/ieee1275/ofdisk.c: Include <grub/machine/init.h>.
+	(grub_ofdisk_iterate): Add a prototype for `dev_iterate'.
+	* include/grub/dl.h (grub_arch_dl_sync_caches): New prototype.
+	* include/grub/loader.h (grub_os_area_addr, grub_os_area_size):
+	Moved from here...
+	* include/grub/i386/pc/init.h (grub_os_area_addr)
+	(rub_os_area_size): ... to here.
+	* include/grub/powerpc/ieee1275/ieee1275.h
+	(grub_ieee1275_entry_fn): Export symbol.
+	* include/grub/powerpc/ieee1275/init.h: New file.
+	* include/grub/powerpc/libgcc.h: Likewise.
+	* include/grub/cache.h: Likewise.
+	* kern/powerpc/cache.S: Likewise.  Written by Hollis Blanchard
+	<hollis@penguinppc.org>.
+	* kern/dl.c: Include <grub/cache.h>.
+	(grub_dl_flush_cache): New function.
+	(grub_dl_load_core): Call `grub_dl_flush_cache' to flush the cache
+	for this module.
+	* kern/powerpc/ieee1275/init.c (grub_ofdisk_init)
+	(grub_console_init): Removed prototypes.
+	(grub_machine_init): Don't initialize the modules anymore.
+	* kern/powerpc/ieee1275/openfw.c (grub_map): Make the function
+	static.
+	* include/grub/powerpc/types.h (GRUB_HOST_WORDS_LITTLEENDIAN):
+	Macro undef removed.
+	(GRUB_HOST_WORDS_BIGENDIAN): New macro.
+	* kern/powerpc/dl.c (grub_arch_dl_relocate_symbols): Add
+	relocation `R_PPC_REL32'.  Return an error when the relocation is
+	unknown.
+	* Makefile.in (DATA): Add `$(pkgdata_PROGRAMS)'.
+	* kern/i386/pc/init.c (grub_arch_sync_caches): New function.
+	* util/misc.c (grub_arch_sync_caches): Likewise.
+
+2004-12-19  Marco Gerards  <metgerards@student.han.nl>
+
+	* conf/powerpc-ieee1275.rmk (MOSTLYCLEANFILES): Remove
+	`symlist.c', add `grubof_symlist.c'.
+	(symlist.c): Variable removed.
+	(grubof_HEADERS): Variable added.
+	(grubof_symlist.c): New target.
+	(kernel_syms.lst): Use `grubof_HEADERS' instead of
+	`kernel_img_HEADERS'.
+	(grubof_SOURCES): Add `kern/powerpc/dl.c' and `grubof_symlist.c'.
+	* kern/powerpc/dl.c: New file.
+	* kern/powerpc/ieee1275/init.c (grub_arch_dl_check_header):
+	Function removed.
+	(grub_arch_dl_relocate_symbols): Likewise.
+	(grub_register_exported_symbols): Likewise.
+
+2004-12-13  Marco Gerards  <metgerards@student.han.nl>
+
+	* fs/ext2.c (grub_ext2_open): Don't use data after freeing it.
+	(grub_ext2_dir): Likewise.  Don't return in case of an error, jump
+	to fail instead.  Reported by Vincent Pelletier
+	<subdino2004@yahoo.fr>.
+
+	* fs/fshelp.c (grub_fshelp_find_file): Don't free `oldnode' when
+	it is not allocated.  Reported by Vincent Pelletier
+	<subdino2004@yahoo.fr>.
+
+	* normal/cmdline.c (grub_tab_complete): Add a blank line to the
+	output so the output looks better.
+
+2004-12-04  Marco Gerards  <metgerards@student.han.nl>
+
+	Modulize the partition map support and add support for the amiga
+	partition map.
+
+	* commands/ls.c: Include <grub/partition.h> instead of
+	<grub/machine/partition.h>.
+	* kern/disk.c: Likewise.
+	* kern/rescue.c: Likewise.
+	* loader/i386/pc/chainloader.c: Likewise.
+	* normal/cmdline.c: Likewise.
+	* kern/powerpc/ieee1275/init.c: Likewise.
+	(grub_machine_init): Call `grub_pc_partition_map_init',
+	`grub_amiga_partition_map_init' and
+	`grub_apple_partition_map_init'.
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Remove
+	`disk/i386/pc/partition.c'.  Add `kern/partition.c'.
+	(kernel_img_HEADERS): Remove `machine/partition.h'.  Add
+	`partition.h' and `pc_partition.h'.
+	(grub_setup_SOURCES): Remove
+	`disk/i386/pc/partition.c'.  Add `kern/partition.c',
+	`partmap/amiga.c', `partmap/apple.c' and `partmap/pc.c'.
+	(grub_emu_SOURCES): Likewise.
+	(pkgdata_MODULES): Add `amiga.mod', `apple.mod' and `pc.mod'.
+	(amiga_mod_SOURCES, amiga_mod_CFLAGS, apple_mod_SOURCES)
+	(apple_mod_CFLAGS, pc_mod_SOURCES, pc_mod_CFLAGS): New variables.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Remove
+	`disk/powerpc/ieee1275/partition.c'.  Add `kern/partition.c',
+	`partmap/amiga.c', `partmap/apple.c' and `partmap/pc.c'.
+	(grubof_SOURCES): Likewise.
+	* disk/i386/pc/partition.c: File removed.
+	* disk/powerpc/ieee1275/partition.c: Likewise.
+	* include/grub/powerpc/ieee1275/partition.h: Likewise.
+	* include/grub/i386/pc/partition.h: Likewise.
+	* kern/partition.c: New file.
+	* partmap/amiga.c: Likewise.
+	* partmap/apple.c: Likewise.
+	* partmap/pc.c: Likewise.
+	* include/grub/partition.h: Likewise..
+	* include/grub/pc_partition.h: Likewise.
+	* util/grub-emu.c: Include <grub/partition.h> instead of
+	<grub/machine/partition.h>.
+	(main): Call `grub_pc_partition_map_init',
+	`grub_amiga_partition_map_init' and
+	`grub_apple_partition_map_init' and deinitialize afterwards.
+	* util/i386/pc/biosdisk.c: Include `#include
+	<grub/partition.h>' and `include <grub/pc_partition.h>' instead of
+	`<grub/machine/partition.h>'.
+	* util/i386/pc/grub-setup.c: Likewise.
+	* util/i386/pc/biosdisk.c: Likewise.
+	(grub_util_biosdisk_get_grub_dev): Only access the PC specific
+	partition information in case of a PC partition.
+	* util/i386/pc/grub-setup.c: Include `#include
+	<grub/partition.h>' and `include <grub/pc_partition.h>' instead of
+	`<grub/machine/partition.h>'.
+	(setup): Only access the PC specific partition information in case
+	of a PC partition.
+
+2004-11-17  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/powerpc/ieee1275/init.c (grub_setjmp): Remove function.
+	(grub_longjmp): Likewise.
+	* include/grub/powerpc/setjmp.h (grub_jmp_buf): Set array size to
+	20.
+	* normal/powerpc/setjmp.S: New file.
+	* conf/powerpc-ieee1275.rmk (grubof_SOURCES): Add
+	`normal/powerpc/setjmp.S'.
+	(grubof_CFLAGS): Add `-DGRUBOF'.
+	* include/grub/setjmp.h [GRUB_UTIL]: Changed condition to
+	[GRUB_UTIL && !GRUBOF].
+
+2004-11-16  Marco Gerards  <metgerards@student.han.nl>
+
+	* kern/powerpc/ieee1275/openfw.c (grub_devalias_iterate): Skip any
+	property named `name'.  Correctly handle the error returned by
+	`grub_ieee1275_finddevice' if a device can not be opened.
+
+2004-11-02  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* term/powerpc/ieee1275/ofconsole.c (grub_ofconsole_readkey): Test
+	`actual' for negativity.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Remove
+	kern/fshelp.c.
+
+2004-11-01  Marco Gerards  <metgerards@student.han.nl>
+
+	* term/i386/pc/vga.c (VGA_HEIGHT): Changed to 350.
+	(PAGE_OFFSET): New macro.
+	(CRTC_ADDR_PORT): Likewise.
+	(CRTC_DATA_PORT): Likewise.
+	(START_ADDR_HIGH_REGISTER): Likewise.
+	(START_ADDR_LOW_REGISTER): Likewise.
+	(GRAPHICS_ADDR_PORT): Likewise.
+	(GRAPHICS_DATA_PORT): Likewise.
+	(READ_MAP_REGISTER): Likewise.
+	(INPUT_STATUS1_REGISTER): Likewise.
+	(INPUT_STATUS1_VERTR_BIT): Likewise.
+	(page): New variable.
+	(wait_vretrace): New function.
+	(set_read_map): Likewise.
+	(set_start_address): Likewise.
+	(grub_vga_init): Use mode 0x10 instead of mode 0x12.  Switch to
+	the right page.
+	(check_vga_mem): Take the page into account.
+	(write_char): Likewise.
+	(write_cursor): Likewise.
+	(scroll_up): Likewise.  Copy the page to the page that is not
+	shown and switch between both pages.
+	(grub_vga_putchar): Fix off by one error.
+	(grub_vga_cls): Wait for the vertical retrace.  Take the page into
+	account.
+
+2004-11-01  Marco Gerards  <metgerards@student.han.nl>
+
+	Add support for iso9660 (including rockridge).
+
+	* conf/i386-pc.rmk (grub_emu_SOURCES): Add fs/iso9660.c.
+	(iso9660_mod_SOURCES): New variable.
+	(iso9660_mod_CFLAGS): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add fs/iso9660.c.
+	* include/grub/fs.h (grub_iso9660_init): New prototype.
+	* util/grub-emu.c (main): Call `grub_iso9660_init'.
+	* fs/iso9660.c: New file.
+
+	* include/grub/misc.h (grub_strncat): New prototype.
+	* kern/misc.c (grub_strncat): New function.
+
+	* fs/hfs.c (grub_hfs_mount): Translate the error
+	`GRUB_ERR_OUT_OF_RANGE' to `GRUB_ERR_BAD_FS'.
+	* fs/jfs.c (grub_jfs_mount): Likewise.
+	* fs/ufs.c (grub_ufs_mount): Likewise.
+
+2004-10-28  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* boot/powerpc/ieee1275/cmain.c (cmain): Remove asm statements
+	which initialized BAT registers.
+	* boot/powerpc/ieee1275/ieee1275.c (IEEE1275_CALL_ENTRY_FN,
+	grub_ieee1275_common_hdr, INIT_IEEE1275_COMMON):
+	Move from here...
+	* include/grub/powerpc/ieee1275/ieee1275.h (IEEE1275_CALL_ENTRY_FN,
+	grub_ieee1275_common_hdr, INIT_IEEE1275_COMMON):
+	... to here.
+	* kern/powerpc/ieee1275/openfw.c (grub_map): New function.
+	(grub_mapclaim): Likewise.
+	* loader/powerpc/ieee1275/linux.c (grub_load_linux): Use
+	grub_mapclaim instead of grub_ieee1275_claim.  Assign linux_addr by
+	hand.
+
+2004-10-19  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* conf/powerpc-ieee1275.rmk (COMMON_ASFLAGS): Remove -fno-builtin.
+	(COMMON_CFLAGS): Remove -fno-builtin and -D__ASSEMBLY__. Add
+	-ffreestanding and -msoft-float.
+
+2004-10-15  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_open): Do not
+	append ":0" to devpath if the GRUB_IEEE1275_NO_PARTITION_0 flag is
+	set in grub_ieee1275_flags.
+
+2004-10-14  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* include/grub/powerpc/ieee1275/ieee1275.h (abort): Add function
+	prototype.
+	* kern/powerpc/ieee1275/init.c (grub_machine_init): Call
+	grub_console_init first.
+	Change the memory range used for grub_ieee1275_claim and
+	grub_mm_init_region.
+	Print an error message if the claim fails.
+	Include <grub/misc.h>.
+
+2004-10-13  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_iterate):
+	Call grub_children_iterate for device nodes of type `scsi',
+	`ide', or `ata'.
+	(grub_ofdisk_open): Remove manual device alias resolution.
+	Fix memory leak when device cannot be opened.
+	* include/grub/powerpc/ieee1275/ieee1275.h
+	(grub_children_iterate): New prototype.
+	* kern/powerpc/ieee1275/openfw.c (grub_children_iterate):
+	New function.
+	* boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_get_property):
+	Return -1 if args.size was -1.
+
+2004-10-11  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* boot/powerpc/ieee1275/cmain.c (grub_ieee1275_flags): New global.
+	(cmain): Accept 3 parameters. Test for 0xdeadbeef, indicating Old
+	World Macintosh. If Old Wold, set flag in grub_ieee1275_flags; claim
+	Open Firmware's memory for it; claim memory from _start to _end.
+	* boot/powerpc/ieee1275/crt0.S (__bss_start): New extern.
+	(_end): New extern.
+	(_start): Zero BSS from __bss_start to _end.
+	* include/grub/powerpc/ieee1275/ieee1275.h (grub_ieee1275_flags):
+	New extern.
+	(GRUB_IEEE1275_NO_PARTITION_0): New #define.
+
+2004-10-11  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_claim): Return
+	-1 if args.base was -1.
+
+2004-10-08  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* term/powerpc/ieee1275/ieee1275.c (grub_ofconsole_cls): Use an ANSI
+	escape sequence instead of a literal ^L. Also call
+	grub_ofconsole_gotoxy.
+
+2004-10-03  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_claim): change
+	void *	arguments to grub_addr_t.  All callers updated.  Also make
+	the `result' argument optional.
+	(grub_ieee1275_release): change void * arguments to grub_addr_t.
+	All callers updated.
+
+2004-09-22  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* commands/ls.c (grub_ls_list_files): Use the string following the
+	initial ')', if present, as the filesystem path.
+	* kern/rescue.c (grub_rescue_cmd_ls): Likewise.
+
+	* conf/powerpc-ieee1275.rmk (grubof_SOURCES): List crt0.S first.
+
+2004-09-18  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Make the source code of the menu interface more readable.
+
+	* normal/menu.c: Include grub/mm.h.
+	(TERM_WIDTH): New macro.
+	(TERM_HEIGHT): Likewise.
+	(TERM_INFO_HEIGHT): Likewise.
+	(TERM_MARGIN): Likewise.
+	(TERM_SCROLL_WIDTH): Likewise.
+	(TERM_TOP_BORDER_Y): Likewise.
+	(TERM_LEFT_BORDER_X): Likewise.
+	(TERM_BORDER_WIDTH): Likewise.
+	(TERM_MESSAGE_HEIGHT): Likewise.
+	(TERM_BORDER_HEIGHT): Likewise.
+	(TERM_NUM_ENTRIES): Likewise.
+	(TERM_FIRST_ENTRY_Y): Likewise.
+	(TERM_ENTRY_WIDTH): Likewise.
+	(TERM_CURSOR_X): Likewise.
+	(draw_border): Use macros instead of magic numbers.
+	(print_entry): Likewise.
+	(print_entries): Likewise.
+	(run_menu): Likewise. Also, handle the key 'e'.
+	(run_menu_entry): Ignore empty command lines.
+	(print_message): Added a new argument EDIT. If EDIT is true,
+	print a different message.
+	(init_page): Likewise.
+	(edit_menu_entry): New function. Not implemented yet.
+
+2004-09-17  Marco Gerards  <metgerards@student.han.nl>
+
+	Add `linux.mod' and `multiboot.mod' so linux and multiboot kernels
+	can be loaded from normal mode.
+
+	* conf/i386-pc.rmk (pkgdata_MODULES): Add `linux.mod' and
+	`multiboot.mod'.
+	(linux_mod_SOURCES, linux_mod_CFLAGS, multiboot_mod_SOURCES)
+	(multiboot_mod_CFLAGS): New variables.
+	* loader/i386/pc/linux_normal.c: New file.
+	* loader/i386/pc/multiboot_normal.c: Likewise.
+
+	* loader/i386/pc/linux.c (grub_rescue_cmd_initrd): Don't use the
+	attribute `unused'.
+
+	* fs/ext2.c (grub_ext2_iterate_dir): Fix typos in inode type.  Use
+	`fdiro' to read the mode information from instead of `diro'.
+
+	* fs/fshelp.c (grub_fshelp_find_file): Set type to foundtype after
+	looking up a symlink.
+
+	* include/grub/normal.h (GRUB_COMMAND_FLAG_NO_ARG_PARSE): New
+	macro.
+	* normal/command.c (grub_command_execute): Don't parse the
+	arguments when `GRUB_COMMAND_FLAG_NO_ARG_PARSE' is set in the
+	flags of the command.
+
+	* normal/menu.c (grub_menu_run): Fix typo.
+
+2004-09-14  Hollis Blanchard  <hollis@penguinppc.org>
+
+	* kern/powerpc/ieee1275/init.c (abort): Trap into Open Firmware.
+
+	* term/powerpc/ieee1275/ofconsole.c (grub_ofconsole_gotoxy): Use
+	`y + 1' instead of `y - 1'.
+
+	* conf/powerpc-ieee1275.rmk (grubof_LDFLAGS): Add `-N' and `-S'.
+
+2004-09-14  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Hollis Blanchard <hollis@penguinppc.org>:
+	* kern/misc.c (memmove): New alias for grub_memmove.
+	(memcmp): New alias for grub_memcmp.
+	(memset): New alias for grub_memset.
+	* boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_get_property):
+	Change "int handle" to "grub_ieee1275_phandle_t handle".
+	* include/grub/powerpc/ieee1275/ieee1275.h
+	(grub_ieee1275_get_property): Likewise.
+
+2004-09-12  Tomas Ebenlendr  <ebik@ucw.cz>
+
+	Added normal mode command `chainloader' as module chain.mod, which
+	depends on normal.mod and _chain.mod.
+
+	* conf/i386-pc.rmk (pkgdata_MODULES): Add `chain.mod'.
+	(chain_mod_SOURCES, chain_mod_CFLAGS): Variables added.
+	* include/grub/i386/pc/loader.h (grub_rescue_cmd_chainloader):
+	Deleted prototype.
+	* loader/i386/pc/chainloader.c (grub_rescue_cmd_chainloader): All
+	but arguments parsing moved to ...
+	(grub_chainloader_cmd): ... here.  New function.
+	* include/grub/i386/pc/chainloader.h: New file.
+	* loader/i386/pc/chainloader_normal.c: Likewise.
+
+2004-09-11  Marco Gerards  <metgerards@student.han.nl>
+
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Added kern/fshelp.c.
+	(grub_mkimage_LDFLAGS): Likewise.
+	(grub_emu_SOURCES): Likewise.
+	(kernel_img_HEADERS): Added fshelp.h.
+	* fs/ext2.c: Include <grub/fshelp.h>.
+	(FILETYPE_REG): New macro.
+	(FILETYPE_INO_REG): Likewise.
+	(grub_ext_sblock): Renamed to `grub_ext2_sblock'.
+	Changed all users.
+	(ext2_block_group): Renamed to `grub_ext2_block_group'.  Changed
+	all users.
+	(grub_fshelp_node): New struct.
+	(grub_ext2_data): Added member `diropen'.  Changed member `inode'
+	to a pointer.
+	(grub_ext2_get_file_block): Removed function.
+	(grub_ext2_read_block): New function.
+	(grub_ext2_read_file): Replaced parameter `data' by `node'.
+	This function was written.
+	(grub_ext2_mount): Read the root inode.  Create a diropen struct.
+	(grub_ext2_find_file): Removed function.
+	(grub_ext2_read_symlink): New function.
+	(grub_ext2_iterate_dir): Likewise.
+	(grub_ext2_open): Rewritten.
+	(grub_ext2_dir): Rewritten.
+	* include/grub/fshelp.h: New file.
+	* fs/fshelp.c: Likewise.
+
+2004-09-10  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* normal/menu.c: Include grub/loader.h and grub/machine/time.h.
+	(print_message): Add a missing newline.
+	(run_menu): Added timeout support.
+	(run_menu_entry): New local function.
+	(grub_menu_run): Added support for booting.
+
+	* kern/loader.c (grub_loader_is_loaded): New function.
+
+	* include/grub/powerpc/ieee1275/time.h: Include grub/symbol.h.
+	(grub_get_rtc): Exported.
+
+	* include/grub/i386/pc/time.h: Include grub/symbol.h.
+	(grub_get_rtc): Exported.
+
+	* include/grub/normal.h (struct grub_command_list): Remove
+	constant from the member `command'.
+
+	* include/grub/loader.h (grub_loader_is_loaded): Declared.
+
+	* include/grub/err.h (GRUB_ERR_INVALID_COMMAND): New constant.
+
+	* conf/i386-pc.rmk (kernel_img_HEADERS): Added machine/time.h.
+
+2004-08-28  Marco Gerards  <metgerards@student.han.nl>
+
+	Add support for the JFS filesystem.
+
+	* fs/jfs.c: New file.
+	* include/grub/fs.h (grub_jfs_init): New prototype.
+	(grub_jfs_fini): New prototype.
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/jfs.c.
+	(grub_emu_SOURCES): Likewise.
+	(pkgdata_MODULES): Add jfs.mod.
+	(jfs_mod_SOURCES): New variable.
+	(jfs_mod_CFLAGS): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add fs.jfs.c.
+	(grubof_SOURCES): Likewise.
+	* util/grub-emu.c (main): Initialize and deinitialize JFS support.
+
+	* fs/fat.c (grub_fat_find_dir): Convert the filename little
+	endian to the host endian.
+	(grub_fat_utf16_to_utf8): Move function from there...
+	* kern/misc.c (grub_utf16_to_utf8): ...to here.  Do not convert
+	the endianness of the source string anymore.
+	* include/grub/misc.h (grub_utf16_to_utf8): New prototype.
+
+2004-08-24  Marco Gerards  <metgerards@student.han.nl>
+
+	* commands/boot.c (grub_boot_init) [GRUB_UTIL]: Make conditional.
+	(grub_boot_fini) [GRUB_UTIL]: Likewise.
+	(GRUB_MOD_INIT) [!GRUB_UTIL]: Likewise.
+	(GRUB_MOD_FINI) [!GRUB_UTIL]: Likewise.
+
+	* fs/hfs.c (grub_hfs_find_node): Add a prototype for `node_found'.
+	(grub_hfs_iterate_dir): Make the function static.  Add prototypes
+	for `node_found' and `it_dir'.
+	(grub_hfs_dir): Add prototype for `dir_hook'.
+
+	* fs/minix.c (grub_minix_get_file_block): Add prototype for
+	`grub_get_indir'.  Rename `indir' in two blocks to `indir16'
+	and `indir32' to silence a gcc warning.
+
+	* include/grub/fs.h (grub_hfs_init): New prototype.
+	(grub_hfs_fini): Likewise.
+
+
+2004-08-21  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Each disk device has its own id now. This is useful to make use
+	of multiple disk devices.
+
+	* include/grub/disk.h (grub_disk_dev_id): New enum.
+	(GRUB_DISK_DEVICE_BIOSDISK_ID): New constant.
+	(GRUB_DISK_DEVICE_OFDISK_ID): Likewise.
+
+	* disk/i386/pc/biosdisk.c (grub_biosdisk_dev): Specify
+	GRUB_DISK_DEVICE_BIOSDISK_ID as an id.
+
+	* disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_dev): Specify
+	GRUB_DISK_DEVICE_OFDISK_ID as an id.
+
+	* util/i386/pc/biosdisk.c (grub_util_biosdisk_dev): Specify
+	GRUB_DISK_DEVICE_BIOSDISK_ID as an id.
+
+	* include/grub/disk.h (struct grub_disk_dev): Added a new member
+	"id" which is used by the cache manager.
+
+	* normal/main.c (grub_normal_init_page): Use "GNU GRUB" instead
+	of just "GRUB".
+
+2004-08-18  Marco Gerards  <metgerards@student.han.nl>
+
+	* fs/hfs.c: New file.
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/hfs.c.
+	(grub_emu_SOURCES): Likewise.
+	(pkgdata_MODULES): Add hfs.mod.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add fs/hfs.c.
+	(grubof_SOURCES): Likewise.
+	* util/grub-emu.c (main): Initialize and deinitialize HFS support.
+
+	* include/grub/misc.h (grub_strncasecmp): Add prototype.
+	* kern/misc.c (grub_strncasecmp): Add function.
+
+2004-08-14  Marco Gerards  <metgerards@student.han.nl>
+
+	* include/grub/arg.h (GRUB_ARG_OPTION_OPTIONAL): Surround macro
+	with parentheses.
+
+	* fs/ext2.c (FILETYPE_UNKNOWN): New macro.
+	(grub_ext2_dir): In case the directory entry type is unknown, read
+	it from the inode.
+
+2004-08-02  Peter Bruin  <pjbruin@dds.nl>
+
+	* loader/powerpc/ieee1275/linux.c (grub_linux_init): Pass
+	grub_load_linux instead of grub_rescue_cmd_linux as second
+	argument of grub_rescue_register_command.
+
+	* Makefile.in (RMKFILES): Add conf/powerpc-ieee1275.rmk.
+
+2004-07-27  Marco Gerards  <metgerards@student.han.nl>
+
+	* boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_release): New
+	function.
+	* commands/boot.c: Remove the check for `GRUB_UTIL'.
+	* conf/powerpc-ieee1275.rmk (grubof_SOURCES): Add
+	`loader/powerpc/ieee1275/linux.c',
+	`loader/powerpc/ieee1275/linux_normal.c' and `commands/boot.c'.
+	* include/grub/powerpc/ieee1275/ieee1275.h
+	(grub_ieee1275_release): New prototype.
+	* include/grub/powerpc/ieee1275/loader.h: Rewritten.
+	* kern/powerpc/ieee1275/init.c (grub_machine_init): Initialize
+	normal, boot, linux and linux_normal.
+	* loader/powerpc/ieee1275/linux.c: New file.
+	* loader/powerpc/ieee1275/linux_normal.c: Likewise.
+
+2004-07-12  Marco Gerards  <metgerards@student.han.nl>
+
+	* normal/arg.c (grub_arg_parse): Correct error handling after
+	reallocating the argumentlist (check if `argl' is not null instead
+	of checking if `args' is not null).
+	* kern/mm.c (grub_realloc): Return the same pointer when using the
+	same region, instead of returning the header address.
+
+2004-07-11  Marco Gerards  <metgerards@student.han.nl>
+
+	* disk/powerpc/ieee1275/partition.c (grub_partition_iterate): Skip
+	one block instead of two when looking for the initial partition.
+	(grub_partition_probe): Initialize the local variable `p' with 0.
+	Use base 10 for the grub_strtoul call.
+	* kern/misc.c (grub_strncpy): Fix off by one bug.  Eliminated the
+	need for one local variable.
+	(grub_strtoul): Don't add the new value to `num', instead of that
+	just assign it.
+
+2004-07-11  Marco Gerards  <metgerards@student.han.nl>
+
+	* conf/i386-pc.rmk (pkgdata_IMAGE): Add pxeboot.img.
+	(pxeboot_img_SOURCES): New variable.
+	(pxeboot_img_ASFLAGS): Likewise.
+	(pxeboot_img_LDFLAGS): Likewise.
+	* boot/i386/pc/pxeboot.S: New file.  Based on pxeloader.S from
+	GRUB Legacy and boot.S.  Adopted for GRUB 2 by lode leroy
+	<lode_leroy@hotmail.com>.
+
+2004-06-27  Tomas Ebenlendr  <ebik@ucw.cz>
+
+	* kern/rescue.c (grub_enter_rescue_mode): Don't continue when
+	there was no input.
+
+2004-06-27  Tomas Ebenlendr  <ebik@ucw.cz>
+
+	* normal/cmdline.c (grub_set_history): Fix off by one bug.  Fixed
+	the history buffer logic.
+
+2004-06-27  Tomas Ebenlendr  <ebik@ucw.cz>
+
+	* fs/ext2.c (FILETYPE_INO_MASK, FILETYPE_INO_DIRECTORY)
+	(FILETYPE_INO_SYMLINK): New macros.
+	(grub_ext2_find_file): Check if the node is a directory using the
+	inode stat information instead of using the filetype in the
+	dirent.  Exclude the first character of an absolute symlink.
+	(grub_ext2_dir): Mask out the filetype part of the mode member of
+	the inode.
+
+2004-05-24  Marco Gerards  <metgerards@student.han.nl>
+
+	Add support for UFS version 1 and 2.  Add support for the minix
+	filesystem version 1 and 2, both the variants with 14 and 30 long
+	filenames.
+
+	* conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/ufs.c and
+	fs/minix.c.
+	(grub_emu_SOURCES): Likewise.
+	(pkgdata_MODULES): Add ufs.mod and minix.mod.
+	(ufs_mod_SOURCES): New variable.
+	(ufs_mod_CFLAGS): Likewise.
+	(minix_mod_SOURCES): Likewise.
+	(minix_mod_CFLAGS): Likewise.
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add fs/ufs.c and
+	fs/minix.c.
+	(grubof_SOURCES): Likewise.
+	* fs/ufs.c: New file.
+	* fs/minix.c: New file.
+	* include/grub/fs.h (grub_ufs_init): New prototype.
+	(grub_ufs_fini): Likewise.
+	(grub_minix_init): Likewise.
+	(grub_minix_fini): Likewise.
+	* util/grub-emu.c (main): Initialize and deinitialize UFS and
+	minix fs.
+
+2004-04-30  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add normal/arg.c,
+	commands/ls.c, commands/terminal.c, commands/boot.c,
+	commands/cmp.c and commands/cat.c.
+	(grubof_LDFLAGS): Add -nostdlib -static-libgcc -lgcc.
+
+	* kern/powerpc/ieee1275/init.c: Include "grub/env.h" instead of
+	"env.h"
+
+2004-04-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	All symbols prefixed with PUPA_ and pupa_ are renamed to GRUB_
+	and grub_, respectively. Because the conversion is trivial and
+	mechanical, I omit the details here. Please refer to the CVS
+	if you need more information.
+
+2004-04-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* include/pupa: Renamed to ...
+	* include/grub: ... this.
+	* util/i386/pc/pupa-mkimage.c: Renamed to ...
+	* util/i386/pc/grub-mkimage.c: ... this.
+	* util/i386/pc/pupa-setup.c: Renamed to ...
+	* util/i386/pc/grub-setup.c: ... this.
+	* util/pupa-emu.c: Renamed to ...
+	* util/grub-emu.c: ... this.
+
+2004-03-29  Marco Gerards  <metgerards@student.han.nl>
+
+	Add support for the newworld apple macintosh (PPC).  This has been
+	tested on the powerbook 2000 only.  It only adds support for
+	generic ieee1275 functions, console and disk support.  This should
+	be easy to port to other architectures with support for Open
+	Firmware.
+
+	* configure.ac: Accept the powerpc as host_cpu.  In the case of
+	the powerpc cpu set the host_vendor to ieee1275.  Make sure the i386
+	specific tests are only executed while building for the i386.
+	Inverse test for crosscompile.
+	* genmk.rb (Utility): Allow assembler files.
+	* normal/cmdline.c (pupa_tab_complete): Reset pupa_errno.
+	* conf/powerpc-ieee1275.rmk: New file.
+	* disk/powerpc/ieee1275/ofdisk.c: Likewise.
+	* disk/powerpc/ieee1275/partition.c: Likewise.
+	* include/pupa/powerpc/ieee1275/biosdisk.h: Likewise.
+	* include/pupa/powerpc/ieee1275/console.h: Likewise.
+	* include/pupa/powerpc/ieee1275/partition.h: Likewise.
+	* include/pupa/powerpc/ieee1275/time.h: Likewise.
+	* include/pupa/powerpc/ieee1275/util/biosdisk.h: Likewise.
+	* include/pupa/powerpc/ieee1275/multiboot.h: Likewise.
+	* include/pupa/powerpc/ieee1275/loader.h
+	* include/pupa/powerpc/setjmp.h: Likewise.
+	* include/pupa/powerpc/types.h: Likewise.
+	* kern/powerpc/ieee1275/init.c: Likewise.
+	* kern/powerpc/ieee1275/openfw.c: Likewise.
+	* term/powerpc/ieee1275/ofconsole.c: Likewise.
+
+	These files were written by Johan Rydberg
+	(jrydberg@night.trouble.net) and I only modified them slightly.
+
+	* boot/powerpc/ieee1275/cmain.c: New file.
+	* boot/powerpc/ieee1275/crt0.S: Likewise.
+	* boot/powerpc/ieee1275/ieee1275.c: Likewise.
+	* include/pupa/powerpc/ieee1275/ieee1275.h: Likewise.
+
+2004-03-14  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* Makefile.in: Update copyright.
+	* genmodsrc.sh: Likewise.
+	* gensymlist.sh: Likewise.
+	* term/i386/pc/vga.c: Indent correctly.
+
+	* util/i386/pc/pupa-mkimage.c (usage): Use PACKAGE_BUGREPORT as
+	bugreporting address.
+	* util/i386/pc/pupa-setup.c (usage): Likewise,
+	(main): Call pupa_ext2_init and pupa_ext2_fini.
+
+	* fs/fat.c (log2): Renamed to ...
+	(fat_log2): ... this.
+	All callers changed.
+	* kern/misc.c (memcpy): Alias to pupa_memmove.
+	* loader/i386/pc/multiboot.c (pupa_rescue_cmd_multiboot): Fix
+	lvalue cast.
+	* util/console.c (pupa_ncurses_fini): Return 0.
+
+	* util/i386/pc/biosdisk.c (pupa_util_biosdisk_open)[__linux__]:
+	Move fail label here.
+	[__GNU__]: Don't warn when using stat.
+	(open_device)[!__linux__]: Check if FD < 0 instead of !FD.
+	(pupa_util_biosdisk_get_pupa_dev)[__GNU__]: Change type of N to
+	long int. Use strtol instead of strtoul.
+
+2004-03-14  Marco Gerards  <metgerards@student.han.nl>
+
+	* commands/boot.c: New file.
+	* commands/cat.c: Likewise.
+	* commands/cmp.c: Likewise.
+	* commands/ls.c: Likewise.
+	* commands/terminal.c: Likewise.
+	* normal/command.c: Include <pupa/env.h> and <pupa/dl.h>.
+	(pupa_register_command): Changed interface to match the new
+	argument parser.
+	(pupa_command_execute): Changed (almost rewritten) so it uses
+	pupa_split_command.  Added support for setting variables using the
+	syntax `foo=bar'.
+	(rescue_command): Changed to work with the new argument parser.
+	(terminal_command): Moved from here to commands/terminal.c.
+	(set_command): New function.
+	(unset_command): New function.
+	(insmod_command): New function.
+	(rmmod_command): New function.
+	(lsmod_command): New function.
+	(pupa_command_init): Don't initialize the command terminal
+	anymore.  Initialize the commands set, unset, insmod, rmmod and
+	lsmod.
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Add kern/env.c.
+	(kernel_img_HEADERS): Add arg.h and env.h.
+	(pupa_mkimage_LDFLAGS): Add kern/env.c.
+	(pupa_emu_SOURCES): Add kern/env.c, commands/ls.c,
+	commands/terminal.c commands/boot.c commands/cmp.c commands/cat.c,
+	normal/arg.c.
+	(pkgdata_MODULES): Add ls.mod, boot.mod, cmp.mod, cat.mod and
+	terminal.mod.
+	(normal_mod_SOURCES): Add normal/arg.c and normal/arg.c.
+	(boot_mod_SOURCES): New variable.
+	(terminal_mod_SOURCES): Likewise.
+	(ls_mod_SOURCES): Likewise.
+	(cmp_mod_SOURCES): Likewise.
+	(cat_mod_SOURCES): Likewise.
+
+	* normal/arg.c: New file.
+	* kern/env.c: Likewise.
+	* include/pupa/arg.h: Likewise.
+	* include/pupa/env.h: Likewise.
+	* font/manager.c (font_command): Changed to match argument parsing
+	interface changes.
+	(PUPA_MOD_INIT): Likewise.
+	* hello/hello.c (pupa_cmd_hello): Likewise.
+	(PUPA_MOD_INIT): Likewise.
+	* include/pupa/disk.h: Include <pupa/device.h>.
+	(pupa_print_partinfo): New prototype.
+	* include/pupa/dl.h (pupa_dl_set_prefix): Prototype removed.
+	(pupa_dl_get_prefix): Likewise.
+	* include/pupa/misc.h: Include <pupa/err.h>.
+	(pupa_isgraph): New prototype.
+	(pupa_isdigit): Likewise.
+	(pupa_split_cmdline): Likewise.
+	* include/pupa/normal.h: Include <pupa/arg.h>.
+	(pupa_command): Changed the prototype of the member `func' to
+	match the argument parsing interface.  Added member `options'.
+	(pupa_register_command): Updated to match function.
+	(pupa_arg_parse): New prototype.
+	(pupa_hello_init) [PUPA_UTIL]: New prototype.
+	(pupa_hello_fini) [PUPA_UTIL]: Likewise.
+	(pupa_ls_init) [PUPA_UTIL]: Likewise.
+	(pupa_ls_fini) [PUPA_UTIL]: Likewise.
+	(pupa_cat_init) [PUPA_UTIL]: Likewise.
+	(pupa_cat_fini) [PUPA_UTIL]: Likewise.
+	(pupa_boot_init) [PUPA_UTIL]: Likewise.
+	(pupa_boot_fini) [PUPA_UTIL]: Likewise.
+	(pupa_cmp_init) [PUPA_UTIL]: Likewise.
+	(pupa_cmp_fini) [PUPA_UTIL]: Likewise.
+	(pupa_terminal_init) [PUPA_UTIL]: Likewise.
+	(pupa_terminal_fini) [PUPA_UTIL]: Likewise.
+	* kern/disk.c: Include <pupa/file.h>.
+	(pupa_print_partinfo): New function.
+	* kern/dl.c: Include <pupa/env.h>.
+	(pupa_dl_dir): Variable removed.
+	(pupa_dl_load): Use the environment variable `prefix' instead of
+	the variable pupa_dl_dir.
+	(pupa_dl_set_prefix): Function removed.
+	(pupa_dl_get_prefix): Likewise.
+	* kern/i386/pc/init.c: Include <pupa/env.h>.
+	(pupa_machine_init): Use the environment variable `prefix' instead of
+	using pupa_dl_set_prefix to set the prefix.
+	* kern/main.c: Include <pupa/env.h>.
+	(pupa_set_root_dev): Use the environment variable `prefix' instead of
+	using pupa_dl_get_prefix to get the prefix.
+	* kern/misc.c: Include <pupa/env.h>.
+	(pupa_isdigit): New function.
+	(pupa_isgraph): Likewise.
+	(pupa_ftoa): Likewise.
+	(pupa_vsprintf): Added support for printing values of the type
+	`double'.  Make it possible to format variable output when using
+	formatting like `%1.2%f'.
+	(pupa_split_cmdline): New function.
+	* kern/rescue.c: Include <pupa/env.h>.
+	(next_word): Removed function.
+	(pupa_rescue_cmd_prefix): Likewise.
+	(pupa_rescue_cmd_set): New function.
+	(pupa_rescue_cmd_unset): New function.
+	(pupa_enter_rescue_mode): Use the `pupa_split_cmdline' function to
+	split the command line instead of splitting it here.  Added
+	support for setting variables using the syntax `foo=bar'.  Don't
+	initialize the prefix command anymore.  Initialized the set and
+	unset commands.
+	* normal/cmdline.c: Include <pupa/env.h>.
+	(pupa_tab_complete): Added prototypes for print_simple_completion,
+	print_partition_completion, add_completion, iterate_commands,
+	iterate_dev, iterate_part and iterate_dir. Moved code to print
+	partition information from here to kern/disk.c.
+	(pupa_cmdline_run): Don't check if the function exists anymore.
+	* normal/main.c: Include <pupa/env.h>.
+	(pupa_rescue_cmd_normal): Use the environment variable `prefix'
+	instead of using pupa_dl_get_prefix to get the prefix.
+	* term/i386/pc/vga.c: Include <pupa/arg.h>.
+	(check_vga_mem): Cast pointers to `void *' to silence a gcc
+	warning.
+	(pupa_vga_putchar) [! DEBUG_VGA]: Removed for this case.
+	(pupa_vga_setcolor): Declare unused variables with `__attribute__
+	((unused))' to silence a gcc warning.
+	(pupa_vga_setcolor): Likewise.
+	(debug_command): Changed to match argument parsing
+	interface changes.
+	* util/pupa-emu.c: Include <pupa/env.h>.
+	(options): Added 0's for unused fields to silence a gcc warning.
+	(argp): Likewise.
+	(main): Use the environment variable `prefix' instead of using
+	pupa_dl_set_prefix to set the prefix.  Initialize the commands ls,
+	boot, cmp, cat and terminal.  Finish the commands boot, cmp, cat
+	and terminal.
+
+	* util/i386/pc/getroot.c: Include <pupa/i386/pc/util/biosdisk.h>.
+	* util/misc.c: Include <malloc.h>.
+	(pupa_malloc): Rewritten so errors are correctly reported.
+	(pupa_realloc): Likewise.
+	(pupa_memalign): Likewise.
+	(pupa_mm_init_region): Declare unused variables with
+	`__attribute__ ((unused))' to silence a gcc warning.
+	* normal/i386/setjmp.S: Remove tab at the end of the file to
+	silence a gcc warning.
+	* loader/i386/pc/linux.c (pupa_rescue_cmd_initrd): Declare unused
+	variables with `__attribute__ ((unused))' to silence a gcc
+	warning.
+	* loader/i386/pc/multiboot.c (pupa_multiboot_unload): Make the
+	local variable i unsigned to silence a gcc warning.
+
+	* kern/term.c: Include <pupa/misc.h>.
+	(pupa_more_lines): New variable.
+	(pupa_more): Likewise.
+	(pupa_putcode): When the pager is active pause at the end of every
+	screen.
+	(pupa_set_more): New function.
+	* include/pupa/term.h (pupa_set_more): New prototype.
+
+
+2004-03-07  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Now this project is GRUB 2 rather than PUPA. The location of
+	the CVS repository was moved to GRUB's.
+
+	* configure.ac: Use bug-grub as the reporting address.
+	Use GRUB instead of PUPA.
+	Change the version number to 1.90.
+
+2004-02-24  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* genkernsyms.sh: Updated copyright information.
+	* genmk.rb: Likewise.
+	* genmodsrc.sh: Likewise.
+	* gensymlist.sh: Likewise.
+	* boot/i386/pc/boot.S: Likewise.
+	* boot/i386/pc/diskboot.S: Likewise.
+	* disk/i386/pc/biosdisk.c: Likewise.
+	* disk/i386/pc/partition.c: Likewise.
+	* font/manager.c: Likewise.
+	* fs/ext2.c: Likewise.
+	* fs/fat.c: Likewise.
+	* include/pupa/boot.h: Likewise.
+	* include/pupa/device.h: Likewise.
+	* include/pupa/disk.h: Likewise.
+	* include/pupa/dl.h: Likewise.
+	* include/pupa/elf.h: Likewise.
+	* include/pupa/err.h: Likewise.
+	* include/pupa/file.h: Likewise.
+	* include/pupa/font.h: Likewise.
+	* include/pupa/fs.h: Likewise.
+	* include/pupa/kernel.h: Likewise.
+	* include/pupa/loader.h: Likewise.
+	* include/pupa/misc.h: Likewise.
+	* include/pupa/mm.h: Likewise.
+	* include/pupa/net.h: Likewise.
+	* include/pupa/normal.h: Likewise.
+	* include/pupa/rescue.h: Likewise.
+	* include/pupa/setjmp.h: Likewise.
+	* include/pupa/symbol.h: Likewise.
+	* include/pupa/term.h: Likewise.
+	* include/pupa/types.h: Likewise.
+	* include/pupa/i386/setjmp.h: Likewise.
+	* include/pupa/i386/types.h: Likewise.
+	* include/pupa/i386/pc/biosdisk.h: Likewise.
+	* include/pupa/i386/pc/boot.h: Likewise.
+	* include/pupa/i386/pc/console.h: Likewise.
+	* include/pupa/i386/pc/init.h: Likewise.
+	* include/pupa/i386/pc/kernel.h: Likewise.
+	* include/pupa/i386/pc/linux.h: Likewise.
+	* include/pupa/i386/pc/loader.h: Likewise.
+	* include/pupa/i386/pc/memory.h: Likewise.
+	* include/pupa/i386/pc/multiboot.h: Likewise.
+	* include/pupa/i386/pc/partition.h: Likewise.
+	* include/pupa/i386/pc/time.h: Likewise.
+	* include/pupa/i386/pc/vga.h: Likewise.
+	* include/pupa/i386/pc/util/biosdisk.h: Likewise.
+	* include/pupa/util/getroot.h: Likewise.
+	* include/pupa/util/misc.h: Likewise.
+	* include/pupa/util/resolve.h: Likewise.
+	* kern/device.c: Likewise.
+	* kern/disk.c: Likewise.
+	* kern/dl.c: Likewise.
+	* kern/err.c: Likewise.
+	* kern/file.c: Likewise.
+	* kern/fs.c: Likewise.
+	* kern/loader.c: Likewise.
+	* kern/main.c: Likewise.
+	* kern/misc.c: Likewise.
+	* kern/mm.c: Likewise.
+	* kern/rescue.c: Likewise.
+	* kern/term.c: Likewise.
+	* kern/i386/dl.c: Likewise.
+	* kern/i386/pc/init.c: Likewise.
+	* kern/i386/pc/lzo1x.S: Likewise.
+	* kern/i386/pc/startup.S: Likewise.
+	* loader/i386/pc/chainloader.c: Likewise.
+	* loader/i386/pc/linux.c: Likewise.
+	* loader/i386/pc/multiboot.c: Likewise.
+	* normal/cmdline.c: Likewise.
+	* normal/command.c: Likewise.
+	* normal/main.c: Likewise.
+	* normal/menu.c: Likewise.
+	* normal/i386/setjmp.S: Likewise.
+	* term/i386/pc/console.c: Likewise.
+	* term/i386/pc/vga.c: Likewise.
+	* util/console.c: Likewise.
+	* util/genmoddep.c: Likewise.
+	* util/misc.c: Likewise.
+	* util/pupa-emu.c: Likewise.
+	* util/resolve.c: Likewise.
+	* util/unifont2pff.rb: Likewise.
+	* util/i386/pc/biosdisk.c: Likewise.
+	* util/i386/pc/getroot.c: Likewise.
+	* util/i386/pc/pupa-mkimage.c: Likewise.
+	* util/i386/pc/pupa-setup.c: Likewise.
+
+2004-02-15  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* fs/ext2.c (pupa_ext2_read_file): Correct the value of BLOCKEND
+	when it is EXT2_BLOCK_SIZE (data).  New argument READ_HOOK, all
+	callers changed.  Set DATA->DISK->READ_HOOK to READ_HOOK before
+	reading and reset it after reading.
+	(pupa_ext2_close): Return PUPA_ERR_NONE.
+
+	* include/pupa/i386/pc/linux.h (PUPA_LINUX_INITRD_MAX_ADDRESS):
+	Correct value.
+	(struct linux_kernel_header): Add kernel_version and
+	initrd_addr_max.
+	* loader/i386/pc/linux.c (pupa_rescue_cmd_linux): Check whether
+	pupa_file_read succeeds.
+	(pupa_rescue_cmd_initrd): Implement.
+
+2003-12-03  Marco Gerards  <metgerards@student.han.nl>
+
+	* fs/ext2.c (pupa_ext2_label): New function.
+	(pupa_ext2_fs): Added label.
+	* fs/fat.c (pupa_fat_label): New function.
+	(pupa_fat_fs): Added label.
+	* include/pupa/fs.h (struct pupa_fs): Added prototype label.
+
+	* kern/misc.c (pupa_strndup): New function.
+	* include/pupa/misc.h (pupa_strndup): New prototype.
+
+	* include/pupa/normal.h: Include <pupa/err.h>.
+	(pupa_set_history): New prototype.
+	(pupa_iterate_commands): New prototype.
+	* normal/cmdline.c: Include <pupa/machine/partition.h>,
+	<pupa/disk.h>, <pupa/file.h>.
+	(hist_size): New variable.
+	(hist_lines): Likewise.
+	(hist_end): Likewise.
+	(hist_used): Likewise.
+	(pupa_set_history): New function.
+	(pupa_history_get): Likewise.
+	(pupa_history_add): Likewise.
+	(pupa_history_replace): Likewise.
+	(pupa_tab_complete): Likewise.
+	(pupa_cmdline_run): Added tab completion and history buffer.  Tab
+	completion shows partitionnames while completing partitions, this
+	feature was suggested by Jeff Bailey.
+	* normal/command.c (pupa_iterate_commands): New function.
+	* normal/main.c (PUPA_DEFAULT_HISTORY_SIZE): New macro.
+	(pupa_normal_init): Initialize history buffer.
+	(PUPA_MOD_INIT): Likewise.
+	(pupa_normal_fini): Free the history buffer.
+	(PUPA_MOD_FINI): Likewise.
+
+	* util/console.c (pupa_ncurses_getkey): Accept 127 as backspace
+	key.
+
+	* aclocal.m4 (pupa_I386_CHECK_REGPARM_BUG): New DEFUN.
+	* configure.ac [i386]: Check for regparam bug.
+	(NESTED_FUNC_ATTR) [! i386]: Defined.
+
+2003-11-17  Marco Gerards  <metgerards@student.han.nl>
+
+	* conf/i386-pc.rmk (sbin_UTILITIES): Added pupa-emu.
+	(pupa_setup_SOURCES): Added util/i386/pc/getroot.c.
+	(pupa_emu_SOURCES): New variable.
+	(pupa_emu_LDFLAGS): Likewise.
+	* include/pupa/fs.h (pupa_ext2_init) [PUPA_UTIL]: New prototype.
+	(pupa_ext2_fini) [PUPA_UTIL]: Likewise.
+	* include/pupa/normal.h (pupa_normal_init) [PUPA_UTIL]: Likewise.
+	(pupa_normal_fini) [PUPA_UTIL]: Likewise.
+	* include/pupa/setjmp.h [PUPA_UTIL]: Include <setjmp.h>.
+	(pupa_jmp_buf): New typedef.
+	(pupa_setjmp) [PUPA_UTIL]: New macro.
+	(pupa_longjmp) [PUPA_UTIL]: Likewise.
+	* include/pupa/term.h (struct pupa_term): New member `refresh'.
+	(pupa_refresh): New prototype.
+	* include/pupa/util/getroot.h: New file.
+	* kern/misc.c (pupa_vsprintf): Refresh the screen after updating
+	it.
+	* kern/rescue.c (pupa_rescue_get_command_line): Likewise.
+	(pupa_rescue_cmd_cat): Likewise.
+	(pupa_rescue_cmd_ls): Likewise.
+	(pupa_rescue_cmd_testload): Likewise.
+	(pupa_rescue_cmd_lsmod): Likewise.
+	* normal/cmdline.c (pupa_cmdline_get): Likewise.
+	* normal/menu.c (run_menu): Likewise.
+	* kern/term.c (pupa_cls): Likewise.
+	(pupa_refresh): New function.
+	* normal/normal.c (pupa_normal_init) [PUPA_UTIL]: New function.
+	(pupa_normal_fini) [PUPA_UTIL]: Likewise.
+	* util/console.c: New file.
+
+	* util/i386/pc/getroot.c: New file.
+	* util/i386/pc/pupa-setup.c: Include <pupa/util/getroot.h>.
+	(pupa_putchar): New function.
+	(pupa_refresh): Likewise.
+	(xgetcwd): Function moved to ...
+	(strip_extra_slashes): Likewise.
+	(get_prefix): Likewise.
+	* util/i386/pc/getroot.c: ... here.
+	(find_root_device): Function moved and renamed to...
+	* util/i386/pc/getroot.c (pupa_find_root_device): ... here.
+	Changed all callers.
+	* util/i386/pc/pupa-setup.c (guess_root_device): Function moved
+	and renamed to...
+	* util/i386/pc/getroot.c (pupa_guess_root_device): ... here.
+	Changed all callers.
+	* util/misc.c (pupa_memalign): New function.
+	(pupa_mm_init_region): Likewise.
+	(pupa_register_exported_symbols): Likewise.
+	(pupa_putchar): Function removed.
+	* util/pupa-emu.c: New file.
+
+2003-11-16  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* conf/i386-pc.rmk (pkgdata_MODULES): Add _multiboot.mod.
+	(_multiboot_mod_SOURCES): New variable.
+	(_multiboot_mod_CFLAGS): Likewise.
+	* loader/i386/pc/multiboot.c: New file.
+	* include/pupa/i386/pc/multiboot.h: Likewise.
+	* kern/i386/pc/startup.S: Include pupa/machine/multiboot.h.
+	(pupa_multiboot_real_boot): New function.
+	* include/pupa/i386/pc/loader.h: Include pupa/machine/multiboot.h.
+	(pupa_multiboot_real_boot): New prototype.
+	(pupa_rescue_cmd_multiboot): Likewise
+	(pupa_rescue_cmd_module): Likewise.
+
+	* kern/loader.c (pupa_loader_set): Continue when
+	pupa_loader_unload_func() fails.
+	(pupa_loader_unset): New function.
+	* include/pupa/loader.h (pupa_loader_unset): New prototype.
+
+	* kern/misc.c (pupa_stpcpy): New function.
+	* include/pupa/misc.h (pupa_stpcpy): New prototype.
+
+2003-11-12  Marco Gerards  <metgerards@student.han.nl>
+
+	* disk/i386/pc/biosdisk.c (pupa_biosdisk_open): Correctly check
+	for available extensions.
+
+	* include/pupa/i386/pc/time.h: New file.
+	* kern/disk.c: Include <pupa/machine/time.h>.
+	(PUPA_CACHE_TIMEOUT): New macro.
+	(pupa_last_time): New variable.
+	(pupa_disk_open): Flush the cache when there was a timeout.
+	(pupa_disk_close): Reset the timer.
+	* kern/i386/pc/startup.S (pupa_get_rtc): Renamed from
+	pupa_currticks.
+	* util/misc.c: Include <sys/times.h>
+	(pupa_get_rtc): New function.
+
+2003-11-09  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* fs/ext2.c (struct pupa_ext2_inode): Declare struct datablocks
+	as blocks.
+	(pupa_ext2_get_file_block): Use blocks member.
+
+	* fs/ext2.c (pupa_ext2_read_file): Only set skipfirst for the
+	first block. Return -1 instead of pupa_errno on error.
+
+2003-10-27  Marco Gerards  <metgerards@student.han.nl>
+
+	* README: In the pupa-mkimage example use _chain instead of chain
+	and ext2 instead of fat.
+	* TODO: Replace ext2fs with jfs as an example.  Add an item for
+	adding journal playback for ext2fs.
+	* conf/i386-pc.rmk (pupa_setup_SOURCES): Added fs/ext2.c.
+	(pkgdata_MODULES): Added ext2.mod.
+	(ext2_mod_SOURCES): New variable.
+	(ext2_mod_CFLAGS): Likewise.
+	* include/pupa/err.h (pupa_err_t): Added PUPA_ERR_SYMLINK_LOOP.
+	* include/pupa/misc.h (pupa_strncpy): New prototype.
+	(pupa_strcat): Likewise.
+	(pupa_strncmp): Likewise.
+	* kern/misc.c (pupa_strcat): Enable function.
+	(pupa_strncpy): New function.
+	(pupa_strncmp): Likewise.
+	* fs/ext2.c: New file.
+
+	* kern/disk.c (pupa_disk_read): Set pupa_errno to PUPA_ERR_NONE
+	when the read failed before retrying.
+	* util/i386/pc/biosdisk.c (_LARGEFILE_SOURCE): Removed.
+	(_FILE_OFFSET_BITS): Likewise.
+	* configure.ac: Added AC_SYS_LARGEFILE.
+
+2003-09-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* genmk.rb (PModule#rule): Make sure to get only symbol names
+	from the output of nm.
+	Reported by Robert Millan <zeratul2@wanadoo.es>.
+
+2003-09-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	I forgot to check in these changes for a long time. This adds
+	incomplete support for VGA console, and this is still very
+	buggy. Also, a lot of consideration is required for I18N,
+	UNICODE, and VGA font issues. Therefore, assume that this is
+	such that "better than nothing".
+
+	* font/manager.c: New file.
+	* include/pupa/font.h: Likewise.
+	* include/pupa/i386/pc/vga.h: Likewise.
+	* term/i386/pc/vga.c: Likewise.
+	* util/unifont2pff.rb: Likewise.
+
+	* conf/i386-pc.rmk (kernel_img_HEADERS): Added machine/vga.h.
+	(pkgdata_MODULES): Added vga.mod and font.mod.
+	(vga_mod_SOURCES): New variables.
+	(vga_mod_CFLAGS): Likewise.
+	(font_mod_SOURCES): Likewise.
+	(font_mod_CFLAGS): Likewise.
+
+	* include/pupa/err.h (PUPA_ERR_BAD_FONT): New constant.
+
+	* include/pupa/term.h: Include pupa/err.h.
+	(struct pupa_term): Added init and fini.
+	Changed the argument of putchar to pupa_uint32_t.
+
+	* include/pupa/i386/pc/console.h: Include pupa/symbol.h.
+	(pupa_console_real_putchar): New prototype.
+	(pupa_console_putchar): Removed.
+	(pupa_console_checkkey): Exported.
+	(pupa_console_getkey): Likewise.
+
+	* kern/misc.c (pupa_vsprintf): Add support for UNICODE
+	characters.
+
+	* kern/term.c (pupa_term_set_current): Rewritten.
+	(pupa_putchar): Likewise.
+	(pupa_putcode): New function.
+
+	* kern/i386/pc/startup.S (pupa_console_putchar): Renamed to ...
+	(pupa_console_real_putchar): ... this.
+	(pupa_vga_set_mode): New function.
+	(pupa_vga_get_font): Likewise.
+
+	* normal/command.c: Include pupa/term.h.
+	(terminal_command): New function.
+	(pupa_command_init): Register the command "terminal".
+
+	* normal/menu.c (DISP_LEFT): Changed to a UNICODE value.
+	(DISP_UP): Likewise.
+	(DISP_RIGHT): Likewise.
+	(DISP_DOWN): Likewise.
+	(DISP_HLINE): Likewise.
+	(DISP_VLINE): Likewise.
+	(DISP_UL): Likewise.
+	(DISP_UR): Likewise.
+	(DISP_LL): Likewise.
+	(DISP_LR): Likewise.
+
+	* term/i386/pc/console.c (pupa_console_putchar): New function.
+
+2003-02-08  NIIBE Yutaka  <gniibe@m17n.org>
+
+	* util/resolve.c (pupa_util_resolve_dependencies): BUG
+	FIX. Reverse the path_list.
+
+	* include/pupa/normal.h: Export pupa_register_command and
+	pupa_unregister_command.
+
+	* hello/hello.c (pupa_cmd_hello): New module.
+	* conf/i386-pc.rmk: Added hello.mod.
+
+2003-01-31  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/i386/pc/lzo1x.S: New file.
+
+	* util/i386/pc/pupa-mkimage.c: Include lzo1x.h.
+	(compress_kernel): New variable.
+	(generate_image): Heavily modified to support compressing a
+	large part of the core image.
+
+	* util/misc.c (pupa_util_read_image): Fix a file descriptor
+	leak.
+	(pupa_util_load_image): New function.
+
+	* kern/i386/pc/startup.S: Include pupa/machine/kernel.h.
+	(pupa_compressed_size): New variable.
+	(codestart): Enable Gate A20 here.
+	Decompress the compressed part of the core image.
+	Rearrange the code to put functions and variables which are
+	required for initialization in the non-compressed part.
+	Include lzo1x.S.
+
+	* kern/i386/pc/init.c (pupa_machine_init): Don't enable Gate A20
+	here.
+
+	* include/pupa/util/misc.h (pupa_util_write_image): Declared.
+
+	* include/pupa/i386/pc/kernel.h
+	(PUPA_KERNEL_MACHINE_COMPRESSED_SIZE): New macro.
+	(PUPA_KERNEL_MACHINE_INSTALL_DOS_PART): Increased by 4.
+	(PUPA_KERNEL_MACHINE_INSTALL_BSD_PART): Likewise.
+	(PUPA_KERNEL_MACHINE_PREFIX): Likewise.
+	(PUPA_KERNEL_MACHINE_RAW_SIZE): New macro.
+
+	* conf/i386-pc.rmk (pupa_mkimage_LDFLAGS): New variable.
+
+	* genmk.rb (Image#rule): Put LDFLAGS at the end of a line.
+	(Utility#rule): Likewise.
+
+	* configure.ac: Check if LZO is available.
+
+2003-01-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* include/pupa/normal.h: New file.
+	* include/pupa/setjmp.h: Likewise.
+	* include/pupa/i386/setjmp.h: Likewise.
+	* normal/cmdline.c: Likewise.
+	* normal/command.c: Likewise.
+	* normal/main.c: Likewise.
+	* normal/menu.c: Likewise.
+	* normal/i386/setjmp.S: Likewise.
+
+	* loader/i386/pc/linux.c (pupa_rescue_cmd_linux): Made global.
+	(pupa_rescue_cmd_initrd): Likewise.
+
+	* loader/i386/pc/chainloader.c (pupa_rescue_cmd_chainloader):
+	Likewise.
+
+	* kern/i386/pc/startup.S (translation_table): New variable.
+	(translate_keycode): New function.
+	(pupa_console_getkey): Call translate_keycode.
+
+	* kern/rescue.c (attempt_normal_mode): New function.
+	(pupa_enter_rescue_mode): Attempt to execute the normal mode. If
+	it failed, print a message.
+
+	* kern/mm.c (pupa_real_malloc): Print more information when a
+	free magic is broken.
+	(pupa_free): If the first free header is not free actually, set
+	it to P.
+
+	* kern/main.c (pupa_load_normal_mode): Just load the module
+	"normal".
+	(pupa_main): Don't print the message
+	"Entering into rescue mode..." here.
+
+	* include/pupa/i386/pc/loader.h (pupa_rescue_cmd_initrd):
+	Declared.
+	(pupa_rescue_cmd_initrd): Likewise.
+	(pupa_rescue_cmd_initrd): Likewise.
+
+	* include/pupa/symbol.h (FUNCTION): Specify the type.
+	(VARIABLE): Likewise.
+
+	* include/pupa/err.h (pupa_err_t): Added
+	PUPA_ERR_UNKNOWN_COMMAND.
+
+	* include/pupa/dl.h (pupa_dl_set_prefix): Exported.
+	(pupa_dl_get_prefix): Likewise.
+
+	* conf/i386-pc.rmk (pkgdata_MODULES): Added normal.mod.
+	Added _chain.mod and _linux.mod instead of chain.mod and
+	linux.mod.
+	(chain_mod_SOURCES): Renamed to ...
+	(_chain_mod_SOURCES): ... this.
+	(chain_mod_CFLAGS): Renamed to ...
+	(_chain_mod_CFLAGS): ... this.
+	(linux_mod_SOURCES): Renamed to ...
+	(_linux_mod_SOURCES): ... this.
+	(linux_mod_CFLAGS): Renamed to ...
+	(_linux_mod_CFLAGS): ... this.
+	(normal_mod_SOURCES): New variable.
+	(normal_mod_CFLAGS): Likewise.
+	(normal_mod_ASFLAGS): Likewise.
+
+2003-01-18  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/rescue.c (pupa_rescue_cmd_rmmod): Call pupa_dl_unload, if
+	possible.
+
+	* kern/dl.c (pupa_dl_ref): Refer depending modules
+	recursively.
+	(pupa_dl_unref): Unrefer depending modules recursively.
+	Don't call pupa_dl_unload implicitly, because PUPA can crash if
+	a module is unloaded before one depending on that module is
+	unloaded.
+	(pupa_dl_unload): Unload depending modules explicitly,
+	if possible.
+
+2003-01-17  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* include/pupa/i386/pc/linux.h: New file.
+	* loader/i386/pc/linux.c: Likewise.
+
+	* loader/i386/pc/chainloader.c (pupa_chainloader_boot_sector):
+	Removed.
+	(pupa_chainloader_unload): Return PUPA_ERR_NONE.
+	(pupa_rescue_cmd_chainloader): Read the image to 0x7C00 instead
+	of PUPA_CHAINLOADER_BOOT_SECTOR.
+
+	* kern/i386/pc/startup.S: Include pupa/machine/linux.h.
+	(pupa_linux_prot_size): New variable.
+	(pupa_linux_tmp_addr): Likewise.
+	(pupa_linux_real_addr): Likewise.
+	(pupa_linux_boot_zimage): New function.
+	(pupa_linux_boot_bzimage): Likewise.
+
+	* kern/i386/pc/init.c (struct mem_region): New structure.
+	(MAX_REGIONS): New macro.
+	(mem_regions): New variable.
+	(num_regions): Likewise.
+	(pupa_os_area_addr): Likewise.
+	(pupa_os_area_size): Likewise.
+	(pupa_lower_mem): Likewise.
+	(pupa_upper_mem): Likewise.
+	(add_mem_region): New function.
+	(compact_mem_regions): Likewise.
+	(pupa_machine_init): Set PUPA_LOWER_MEM and PUPA_UPPER_MEM to
+	the size of the conventional memory and that of so-called upper
+	memory (before the first memory hole).
+	Instead of adding each found region to free memory, use
+	add_mem_region and add them after removing overlaps.
+	Also, add only 1/4 of the upper memory to free memory. The rest
+	is used for loading OS images. Maybe this is ad hoc, but this
+	makes it much easier to relocate OS images when booting.
+
+	* kern/rescue.c (pupa_rescue_cmd_module): Removed.
+	(pupa_enter_rescue_mode): Don't register initrd and module.
+
+	* kern/mm.c: Include pupa/dl.h.
+
+	* kern/main.c: Include pupa/file.h and pupa/device.h.
+
+	* kern/loader.c (pupa_loader_load_module_func): Removed.
+	(pupa_loader_load_module): Likewise.
+
+	* kern/dl.c (pupa_dl_load): Use the suffix ``.mod'' instead of
+	``.o''.
+
+	* include/pupa/i386/pc/loader.h (pupa_linux_prot_size): Declared.
+	(pupa_linux_tmp_addr): Likewise.
+	(pupa_linux_real_addr): Likewise.
+	(pupa_linux_boot_zimage): Likewise.
+	(pupa_linux_boot_bzimage): Likewise.
+
+	* include/pupa/i386/pc/init.h (pupa_lower_mem): Declared.
+	(pupa_upper_mem): Likewise.
+	(pupa_gate_a20): Don't export, because turning off Gate A20 in a
+	module is too dangerous.
+
+	* include/pupa/loader.h (pupa_os_area_addr): Declared.
+	(pupa_os_area_size): Likewise.
+	(pupa_loader_set): Remove the first argument. Loader doesn't
+	manage modules or initrd any longer.
+	(pupa_loader_load_module): Removed.
+
+	* conf/i386-pc.rmk (pkgdata_MODULES): Added linux.mod.
+	(linux_mod_SOURCES): New variable.
+	(linux_mod_CFLAGS): Likewise.
+
+2003-01-07  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/i386/pc/pupa-setup.c (setup): Convert the endianness of
+	the length of a blocklist correctly.
+
+	* util/i386/pc/biosdisk.c (pupa_util_biosdisk_open) [__linux__]:
+	Use ioctl only if the OS file is a block device.
+	(pupa_util_biosdisk_open): Don't use ST.ST_BLOCKS, because it is
+	not very useful for normal files.
+
+	* kern/main.c (pupa_set_root_dev): New function.
+	(pupa_load_normal_mode): Likewise.
+	(pupa_main): Call those above.
+
+	* include/pupa/types.h (pupa_swap_bytes16): Cast the result to
+	pupa_uint16_t.
+
+	* include/pupa/kernel.h (pupa_enter_normal_mode): Removed.
+
+2003-01-06  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/i386/pc/pupa-setup.c: Include pupa/machine/kernel.h.
+	(setup): Configure the installed partition information and the
+	dl prefix.
+
+	* loader/i386/pc/chainloader.c (my_mod): New variable.
+	(pupa_chainloader_unload): New function.
+	(pupa_rescue_cmd_chainloader): Refer itself.
+	(PUPA_MOD_INIT): Save its own module in MY_MOD.
+
+	* kern/i386/pc/startup.S (install_partition): Removed.
+	(version_string): Likewise.
+	(config_file): Likewise.
+	(pupa_install_dos_part): New variable.
+	(pupa_install_bsd_part): Likewise.
+	(pupa_prefix): Likewise.
+	(pupa_chainloader_real_boot): Call pupa_dl_unload_all.
+
+	* kern/i386/pc/init.c: Include pupa/machine/kernel.h, pupa/dl.h
+	and pupa/misc.h.
+	(make_install_device): New function.
+	(pupa_machine_init): Set the dl prefix.
+
+	* kern/rescue.c: Include pupa/rescue.h and pupa/dl.h.
+	(buf): Renamed to ...
+	(linebuf): ... this.
+	(pupa_rescue_cmd_prefix): New function.
+	(pupa_rescue_cmd_insmod): Likewise.
+	(pupa_rescue_cmd_rmmod): Likewise.
+	(pupa_rescue_cmd_lsmod): Likewise.
+	(pupa_enter_rescue_mode): Register new commands: prefix, insmod,
+	rmmod and lsmod.
+
+	* kern/mm.c (pupa_memalign): If failed even after invalidating
+	disk caches, unload unneeded modules and retry.
+
+	* kern/misc.c (pupa_memmove): New function.
+	(pupa_memcpy): Removed.
+	(pupa_strcpy): New function.
+	(pupa_itoa): Made static.
+
+	* kern/dl.c (pupa_dl_iterate): New function.
+	(pupa_dl_ref): Likewise.
+	(pupa_dl_unref): Likewise.
+	(pupa_dl_unload): Return if succeeded or not.
+	(pupa_dl_unload_unneeded): New function.
+	(pupa_dl_unload_all): Likewise.
+	(pupa_dl_init): Renamed to ...
+	(pupa_dl_set_prefix): ... this.
+	(pupa_dl_get_prefix): New function.
+
+	* include/pupa/i386/pc/kernel.h: Include pupa/types.h.
+	(PUPA_KERNEL_MACHINE_INSTALL_DOS_PART): New macro.
+	(PUPA_KERNEL_MACHINE_INSTALL_BSD_PART): Likewise.
+	(PUPA_KERNEL_MACHINE_PREFIX): Likewise.
+	(pupa_install_dos_part): Declared.
+	(pupa_install_bsd_part): Likewise.
+	(pupa_prefix): Likewise.
+	(pupa_boot_drive): Likewise.
+
+	* include/pupa/types.h: Fix a typo.
+
+	* include/pupa/misc.h (pupa_memcpy): New macro. Just an alias to
+	pupa_memmove.
+	(pupa_memmove): Declared.
+	(pupa_strcpy): Likewise.
+
+	* include/pupa/dl.h (PUPA_MOD_INIT): Change the prototype. Now
+	pupa_mod_init takes one argument, its own module.
+	(pupa_dl_unload_unneeded): Declared.
+	(pupa_dl_unload_all): Likewise.
+	(pupa_dl_ref): Likewise.
+	(pupa_dl_unref): Likewise.
+	(pupa_dl_iterate): Likewise.
+	(pupa_dl_init): Renamed to ...
+	(pupa_dl_set_prefix): ... this.
+	(pupa_dl_get_prefix): Declared.
+
+	* fs/fat.c [!PUPA_UTIL] (my_mod): New variable.
+	(pupa_fat_dir) [!PUPA_UTIL]: Prevent the fat module from being
+	unloaded.
+	(pupa_fat_open) [!PUPA_UTIL]: Refer itself if succeeded.
+	(pupa_fat_close) [!PUPA_UTIL]: Unrefer itself.
+
+	* configure.ac (tmp_CFLAGS): Added -Wshadow, -Wpointer-arith,
+	-Wmissing-prototypes, -Wundef and -Wstrict-prototypes.
+
+2003-01-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/i386/pc/pupa-setup.c (setup): Define the internal
+	function find_first_partition_start at the top level, because GCC
+	3.0.x cannot compile internal functions in deeper scopes
+	correctly.
+	(find_root_device): Use lstat instead of stat.
+	Don't follow symbolic links.
+	Fix the path-constructing code.
+
+	* util/i386/pc/biosdisk.c [__linux__] (BLKFLSBUF): New macro.
+	(pupa_util_biosdisk_open) [__linux__]: Get the size of a device
+	by a BLKGETSIZE ioctl first, because block devices don't fill
+	the member st_mode of the structure stat on Linux.
+	[__linux__] (linux_find_partition): Use a temporary buffer
+	REAL_DEV for the working space. Copy it to DEV before returning.
+	(open_device) [__linux__]: Call ioctl with BLKFLSBUF to make the
+	buffer cache consistent.
+	(get_os_disk) [__linux__]: Use the length 5 instead of 4 for
+	strncmp. The previous value was merely wrong.
+	(pupa_util_biosdisk_get_pupa_dev): Use stat instead of lstat.
+
+	* fs/fat.c (pupa_fat_read_data): Shift 4 instead of 12 when the
+	FAT size is 12. The previous value was merely wrong.
+
+	* kern/main.c (pupa_main): Don't split the starting message from
+	newlines.
+
+	* kern/term.c (pupa_putchar): Put CR after LF instead of before
+	LF, because BIOS goes crazy about character attributes in this
+	case.
+
+2003-01-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* include/i386/pc/util/biosdisk.h: New file.
+	* util/i386/pc/biosdisk.c: Likewise.
+	* util/i386/pc/pupa-setup.c: Likewise.
+
+	* Makefile.in (INCLUDE_DISTFILES): Added
+	include/pupa/i386/pc/util/biosdisk.h.
+	(UTIL_DISTFILES): Added biosdisk.c and pupa-setup.c under the
+	directory util/i386/pc.
+	(install-local): Added a rule for sbin_UTILITIES.
+	(uninstall): Likewise.
+
+	* util/i386/pc/pupa-mkimage.c (usage): Fix a typo in the doc.
+
+	* util/misc.c (xrealloc): New function.
+	(pupa_malloc): Likewise.
+	(pupa_free): Likewise.
+	(pupa_realloc): Likewise.
+	(pupa_stop): Likewise.
+	(pupa_putchar): Likewise.
+
+	* kern/disk.c (pupa_disk_read): Prevent L from underflowing.
+
+	* include/pupa/util/misc.h (xrealloc): Declared.
+
+	* include/pupa/i386/pc/boot.h (PUPA_BOOT_MACHINE_BPB_START): New
+	macro.
+	(PUPA_BOOT_MACHINE_BPBEND): Renamed to ...
+	(PUPA_BOOT_MACHINE_BPB_END): ... this.
+
+	* include/pupa/fs.h [PUPA_UTIL] (pupa_fat_init): Declared.
+	[PUPA_UTIL] (pupa_fat_fini): Likewise.
+
+	* fs/fat.c [PUPA_UTIL] (pupa_fat_init): Defined. Maybe a better
+	way should be implemented.
+	[PUPA_UTIL] (pupa_fat_fini): Likewise.
+
+	* disk/i386/pc/biosdisk.c (pupa_biosdisk_call_hook): Increase
+	the size of NAME for safety.
+	(pupa_biosdisk_iterate): Search hard disks to 0x90 instead of
+	0x88.
+
+	* conf/i386-pc.rmk (sbin_UTILITIES): New variable.
+	(pupa_setup_SOURCES): Likewise.
+
+	* genmk.rb (Utility#rule): Add $(BUILD_CFLAGS) into the rules.
+
+2002-12-28  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* kern/i386/pc/startup.S (push_get_mmap_entry): Revert to a
+	bunch of pushl's from pusha, because this destroys the return
+	value.
+
+2002-12-28  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Use -mrtd and -mregparm=3 to reduce the generated code sizes.
+	This means that any missing prototypes could be fatal. Also, you
+	must take care when writing assembly code. See the comments at
+	the beginning of startup.S, for more details.
+
+	* kern/i386/pc/startup.S (pupa_halt): Modified for the new
+	compilation mechanism.
+	(pupa_chainloader_real_boot): Likewise.
+	(pupa_biosdisk_rw_int13_extensions): Likewise.
+	(pupa_biosdisk_rw_standard): Likewise.
+	(pupa_biosdisk_check_int13_extensions): Likewise.
+	(pupa_biosdisk_get_diskinfo_int13_extensions): Likewise.
+	(pupa_biosdisk_get_diskinfo_standard): Likewise.
+	(pupa_get_memsize): Likewise.
+	(pupa_get_mmap_entry): Likewise.
+	(pupa_console_putchar): Likewise.
+	(pupa_console_setcursor): Likewise.
+	(pupa_getrtsecs): Use pushl instead of push.
+
+	* kern/i386/pc/init.c (pupa_machine_init): Use the scratch
+	memory instead of the stack for a mmap entry, because some
+	BIOSes may ignore the maximum size and overflow.
+
+	* conf/i386-pc.rmk (COMMON_CFLAGS): Added -mrtd and -mregparm=3.
+
+	* genmk.rb (PModule#rule): Compile automatically generated
+	sources with module-specific CFLAGS as well as other sources.
+
+2002-12-27  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.ac: Check ld.
+	Replace CFLAGS and CPPFLAGS with BUILD_CFLAGS and BUILD_CPPFLAGS
+	respectively, before checking endianness and sizes.
+
+	* Makefile.in (LD): New variable.
+
+2002-12-27  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* Makefile.in (BUILD_CC): CC -> BUILD_CC.
+
+2002-12-27  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* Changelog: New file.
+
diff --git a/DISTLIST b/DISTLIST
new file mode 100644
index 0000000..f3b3fd7
--- /dev/null
+++ b/DISTLIST
@@ -0,0 +1,614 @@
+AUTHORS
+COPYING
+ChangeLog
+DISTLIST
+INSTALL
+NEWS
+README
+THANKS
+TODO
+Makefile.in
+aclocal.m4
+autogen.sh
+config.guess
+config.h.in
+config.sub
+configure
+configure.ac
+gencmdlist.sh
+gendistlist.sh
+genfslist.sh
+genhandlerlist.sh
+geninit.sh
+geninitheader.sh
+genkernsyms.sh.in
+genmk.rb
+genmoddep.awk
+genmodsrc.sh
+genpartmaplist.sh
+genparttoollist.sh
+gensymlist.sh.in
+install-sh
+mkinstalldirs
+stamp-h.in
+boot/i386/pc/boot.S
+boot/i386/pc/cdboot.S
+boot/i386/pc/diskboot.S
+boot/i386/pc/lnxboot.S
+boot/i386/pc/pxeboot.S
+boot/i386/qemu/boot.S
+boot/sparc64/ieee1275/boot.S
+boot/sparc64/ieee1275/diskboot.S
+bus/pci.c
+bus/usb/ohci.c
+bus/usb/uhci.c
+bus/usb/usb.c
+bus/usb/usbhub.c
+bus/usb/usbtrans.c
+commands/acpi.c
+commands/blocklist.c
+commands/boot.c
+commands/cat.c
+commands/cmp.c
+commands/configfile.c
+commands/crc.c
+commands/date.c
+commands/echo.c
+commands/extcmd.c
+commands/gptsync.c
+commands/halt.c
+commands/handler.c
+commands/hdparm.c
+commands/help.c
+commands/hexdump.c
+commands/keystatus.c
+commands/loadenv.c
+commands/ls.c
+commands/lsmmap.c
+commands/lspci.c
+commands/memrw.c
+commands/minicmd.c
+commands/parttool.c
+commands/password.c
+commands/probe.c
+commands/read.c
+commands/reboot.c
+commands/search.c
+commands/sleep.c
+commands/test.c
+commands/true.c
+commands/usbtest.c
+commands/videotest.c
+commands/xnu_uuid.c
+commands/efi/acpi.c
+commands/efi/fixvideo.c
+commands/efi/loadbios.c
+commands/i386/cpuid.c
+commands/i386/pc/acpi.c
+commands/i386/pc/drivemap.c
+commands/i386/pc/drivemap_int13h.S
+commands/i386/pc/halt.c
+commands/i386/pc/play.c
+commands/i386/pc/pxecmd.c
+commands/i386/pc/vbeinfo.c
+commands/i386/pc/vbetest.c
+commands/ieee1275/suspend.c
+conf/common.mk
+conf/common.rmk
+conf/i386-coreboot.mk
+conf/i386-coreboot.rmk
+conf/i386-efi.mk
+conf/i386-efi.rmk
+conf/i386-ieee1275.mk
+conf/i386-ieee1275.rmk
+conf/i386-pc-cygwin-img-ld.sc
+conf/i386-pc.mk
+conf/i386-pc.rmk
+conf/i386-qemu.mk
+conf/i386-qemu.rmk
+conf/i386.mk
+conf/i386.rmk
+conf/powerpc-ieee1275.mk
+conf/powerpc-ieee1275.rmk
+conf/sparc64-ieee1275.mk
+conf/sparc64-ieee1275.rmk
+conf/x86_64-efi.mk
+conf/x86_64-efi.rmk
+disk/ata.c
+disk/ata_pthru.c
+disk/dmraid_nvidia.c
+disk/fs_file.c
+disk/fs_uuid.c
+disk/host.c
+disk/loopback.c
+disk/lvm.c
+disk/mdraid_linux.c
+disk/memdisk.c
+disk/raid.c
+disk/raid5_recover.c
+disk/raid6_recover.c
+disk/scsi.c
+disk/usbms.c
+disk/efi/efidisk.c
+disk/i386/pc/biosdisk.c
+disk/ieee1275/nand.c
+disk/ieee1275/ofdisk.c
+docs/fdl.texi
+docs/grub.cfg
+docs/grub.texi
+docs/mdate-sh
+docs/texinfo.tex
+efiemu/loadcore.c
+efiemu/loadcore32.c
+efiemu/loadcore64.c
+efiemu/loadcore_common.c
+efiemu/main.c
+efiemu/mm.c
+efiemu/pnvram.c
+efiemu/prepare.c
+efiemu/prepare32.c
+efiemu/prepare64.c
+efiemu/symbols.c
+efiemu/i386/coredetect.c
+efiemu/i386/loadcore32.c
+efiemu/i386/loadcore64.c
+efiemu/i386/pc/cfgtables.c
+efiemu/runtime/config.h
+efiemu/runtime/efiemu.S
+efiemu/runtime/efiemu.c
+efiemu/runtime/efiemu.sh
+font/font.c
+font/font_cmd.c
+fs/affs.c
+fs/afs.c
+fs/afs_be.c
+fs/befs.c
+fs/befs_be.c
+fs/cpio.c
+fs/ext2.c
+fs/fat.c
+fs/fshelp.c
+fs/hfs.c
+fs/hfsplus.c
+fs/iso9660.c
+fs/jfs.c
+fs/minix.c
+fs/ntfs.c
+fs/ntfscomp.c
+fs/reiserfs.c
+fs/sfs.c
+fs/tar.c
+fs/udf.c
+fs/ufs.c
+fs/ufs2.c
+fs/xfs.c
+fs/i386/pc/pxe.c
+hello/hello.c
+hook/datehook.c
+include/multiboot.h
+include/multiboot2.h
+include/grub/acorn_filecore.h
+include/grub/acpi.h
+include/grub/aout.h
+include/grub/ata.h
+include/grub/auth.h
+include/grub/autoefi.h
+include/grub/bitmap.h
+include/grub/boot.h
+include/grub/bufio.h
+include/grub/cache.h
+include/grub/command.h
+include/grub/datetime.h
+include/grub/device.h
+include/grub/disk.h
+include/grub/dl.h
+include/grub/elf.h
+include/grub/elfload.h
+include/grub/env.h
+include/grub/err.h
+include/grub/extcmd.h
+include/grub/fbblit.h
+include/grub/fbfill.h
+include/grub/fbutil.h
+include/grub/file.h
+include/grub/font.h
+include/grub/fs.h
+include/grub/fshelp.h
+include/grub/gpt_partition.h
+include/grub/gzio.h
+include/grub/handler.h
+include/grub/hfs.h
+include/grub/kernel.h
+include/grub/list.h
+include/grub/loader.h
+include/grub/lvm.h
+include/grub/macho.h
+include/grub/machoload.h
+include/grub/memory.h
+include/grub/menu.h
+include/grub/menu_viewer.h
+include/grub/misc.h
+include/grub/mm.h
+include/grub/msdos_partition.h
+include/grub/multiboot.h
+include/grub/multiboot2.h
+include/grub/multiboot_loader.h
+include/grub/net.h
+include/grub/normal.h
+include/grub/ntfs.h
+include/grub/parser.h
+include/grub/partition.h
+include/grub/parttool.h
+include/grub/pci.h
+include/grub/raid.h
+include/grub/reader.h
+include/grub/script_sh.h
+include/grub/scsi.h
+include/grub/scsicmd.h
+include/grub/setjmp.h
+include/grub/symbol.h
+include/grub/term.h
+include/grub/terminfo.h
+include/grub/time.h
+include/grub/tparm.h
+include/grub/types.h
+include/grub/usb.h
+include/grub/usbdesc.h
+include/grub/usbtrans.h
+include/grub/video.h
+include/grub/video_fb.h
+include/grub/xnu.h
+include/grub/efi/api.h
+include/grub/efi/console.h
+include/grub/efi/console_control.h
+include/grub/efi/disk.h
+include/grub/efi/efi.h
+include/grub/efi/memory.h
+include/grub/efi/pe32.h
+include/grub/efi/time.h
+include/grub/efi/uga_draw.h
+include/grub/efiemu/efiemu.h
+include/grub/efiemu/runtime.h
+include/grub/i386/at_keyboard.h
+include/grub/i386/bsd.h
+include/grub/i386/cmos.h
+include/grub/i386/cpuid.h
+include/grub/i386/efiemu.h
+include/grub/i386/halt.h
+include/grub/i386/io.h
+include/grub/i386/kernel.h
+include/grub/i386/linux.h
+include/grub/i386/loader.h
+include/grub/i386/macho.h
+include/grub/i386/multiboot.h
+include/grub/i386/pci.h
+include/grub/i386/pit.h
+include/grub/i386/reboot.h
+include/grub/i386/setjmp.h
+include/grub/i386/time.h
+include/grub/i386/tsc.h
+include/grub/i386/types.h
+include/grub/i386/vga_common.h
+include/grub/i386/xnu.h
+include/grub/i386/coreboot/boot.h
+include/grub/i386/coreboot/console.h
+include/grub/i386/coreboot/init.h
+include/grub/i386/coreboot/kernel.h
+include/grub/i386/coreboot/loader.h
+include/grub/i386/coreboot/machine.h
+include/grub/i386/coreboot/memory.h
+include/grub/i386/coreboot/serial.h
+include/grub/i386/coreboot/time.h
+include/grub/i386/efi/kernel.h
+include/grub/i386/efi/loader.h
+include/grub/i386/efi/machine.h
+include/grub/i386/efi/memory.h
+include/grub/i386/efi/time.h
+include/grub/i386/ieee1275/console.h
+include/grub/i386/ieee1275/ieee1275.h
+include/grub/i386/ieee1275/kernel.h
+include/grub/i386/ieee1275/loader.h
+include/grub/i386/ieee1275/machine.h
+include/grub/i386/ieee1275/memory.h
+include/grub/i386/ieee1275/serial.h
+include/grub/i386/ieee1275/time.h
+include/grub/i386/pc/biosdisk.h
+include/grub/i386/pc/biosnum.h
+include/grub/i386/pc/boot.h
+include/grub/i386/pc/chainloader.h
+include/grub/i386/pc/console.h
+include/grub/i386/pc/efiemu.h
+include/grub/i386/pc/init.h
+include/grub/i386/pc/kernel.h
+include/grub/i386/pc/loader.h
+include/grub/i386/pc/machine.h
+include/grub/i386/pc/memory.h
+include/grub/i386/pc/pxe.h
+include/grub/i386/pc/serial.h
+include/grub/i386/pc/time.h
+include/grub/i386/pc/vbe.h
+include/grub/i386/pc/vga.h
+include/grub/i386/qemu/boot.h
+include/grub/i386/qemu/console.h
+include/grub/i386/qemu/init.h
+include/grub/i386/qemu/kernel.h
+include/grub/i386/qemu/loader.h
+include/grub/i386/qemu/machine.h
+include/grub/i386/qemu/memory.h
+include/grub/i386/qemu/serial.h
+include/grub/i386/qemu/time.h
+include/grub/ieee1275/ieee1275.h
+include/grub/ieee1275/ofdisk.h
+include/grub/lib/LzFind.h
+include/grub/lib/LzHash.h
+include/grub/lib/LzmaDec.h
+include/grub/lib/LzmaEnc.h
+include/grub/lib/LzmaTypes.h
+include/grub/lib/arg.h
+include/grub/lib/crc.h
+include/grub/lib/envblk.h
+include/grub/lib/hexdump.h
+include/grub/powerpc/kernel.h
+include/grub/powerpc/libgcc.h
+include/grub/powerpc/setjmp.h
+include/grub/powerpc/time.h
+include/grub/powerpc/types.h
+include/grub/powerpc/ieee1275/biosdisk.h
+include/grub/powerpc/ieee1275/console.h
+include/grub/powerpc/ieee1275/ieee1275.h
+include/grub/powerpc/ieee1275/kernel.h
+include/grub/powerpc/ieee1275/loader.h
+include/grub/powerpc/ieee1275/machine.h
+include/grub/powerpc/ieee1275/memory.h
+include/grub/powerpc/ieee1275/time.h
+include/grub/powerpc/ieee1275/util/biosdisk.h
+include/grub/sparc64/kernel.h
+include/grub/sparc64/libgcc.h
+include/grub/sparc64/setjmp.h
+include/grub/sparc64/time.h
+include/grub/sparc64/types.h
+include/grub/sparc64/ieee1275/boot.h
+include/grub/sparc64/ieee1275/console.h
+include/grub/sparc64/ieee1275/ieee1275.h
+include/grub/sparc64/ieee1275/kernel.h
+include/grub/sparc64/ieee1275/loader.h
+include/grub/sparc64/ieee1275/machine.h
+include/grub/sparc64/ieee1275/memory.h
+include/grub/sparc64/ieee1275/time.h
+include/grub/util/console.h
+include/grub/util/deviceiter.h
+include/grub/util/getroot.h
+include/grub/util/hostdisk.h
+include/grub/util/lvm.h
+include/grub/util/misc.h
+include/grub/util/ofpath.h
+include/grub/util/raid.h
+include/grub/util/resolve.h
+include/grub/x86_64/kernel.h
+include/grub/x86_64/linux.h
+include/grub/x86_64/macho.h
+include/grub/x86_64/pci.h
+include/grub/x86_64/setjmp.h
+include/grub/x86_64/time.h
+include/grub/x86_64/types.h
+include/grub/x86_64/xnu.h
+include/grub/x86_64/efi/kernel.h
+include/grub/x86_64/efi/loader.h
+include/grub/x86_64/efi/machine.h
+include/grub/x86_64/efi/memory.h
+include/grub/x86_64/efi/time.h
+io/bufio.c
+io/gzio.c
+kern/command.c
+kern/corecmd.c
+kern/device.c
+kern/disk.c
+kern/dl.c
+kern/elf.c
+kern/env.c
+kern/err.c
+kern/file.c
+kern/fs.c
+kern/handler.c
+kern/list.c
+kern/main.c
+kern/misc.c
+kern/mm.c
+kern/parser.c
+kern/partition.c
+kern/reader.c
+kern/rescue_parser.c
+kern/rescue_reader.c
+kern/term.c
+kern/time.c
+kern/efi/efi.c
+kern/efi/init.c
+kern/efi/mm.c
+kern/generic/millisleep.c
+kern/generic/rtc_get_time_ms.c
+kern/i386/dl.c
+kern/i386/halt.c
+kern/i386/loader.S
+kern/i386/misc.S
+kern/i386/multiboot_mmap.c
+kern/i386/pit.c
+kern/i386/realmode.S
+kern/i386/reboot.c
+kern/i386/tsc.c
+kern/i386/coreboot/init.c
+kern/i386/coreboot/mmap.c
+kern/i386/coreboot/startup.S
+kern/i386/efi/init.c
+kern/i386/efi/startup.S
+kern/i386/ieee1275/init.c
+kern/i386/ieee1275/startup.S
+kern/i386/pc/init.c
+kern/i386/pc/lzma_decode.S
+kern/i386/pc/mmap.c
+kern/i386/pc/startup.S
+kern/i386/qemu/mmap.c
+kern/i386/qemu/startup.S
+kern/ieee1275/cmain.c
+kern/ieee1275/ieee1275.c
+kern/ieee1275/init.c
+kern/ieee1275/mmap.c
+kern/ieee1275/openfw.c
+kern/powerpc/cache.S
+kern/powerpc/dl.c
+kern/powerpc/ieee1275/startup.S
+kern/sparc64/cache.S
+kern/sparc64/dl.c
+kern/sparc64/ieee1275/crt0.S
+kern/sparc64/ieee1275/ieee1275.c
+kern/sparc64/ieee1275/init.c
+kern/x86_64/dl.c
+kern/x86_64/efi/callwrap.S
+kern/x86_64/efi/startup.S
+lib/LzFind.c
+lib/LzmaDec.c
+lib/LzmaEnc.c
+lib/arg.c
+lib/crc.c
+lib/envblk.c
+lib/hexdump.c
+lib/efi/datetime.c
+lib/i386/datetime.c
+lib/i386/setjmp.S
+lib/i386/pc/biosnum.c
+lib/powerpc/setjmp.S
+lib/sparc64/setjmp.S
+lib/x86_64/setjmp.S
+loader/aout.c
+loader/macho.c
+loader/multiboot2.c
+loader/multiboot_loader.c
+loader/xnu.c
+loader/xnu_resume.c
+loader/efi/appleloader.c
+loader/efi/chainloader.c
+loader/i386/bsd.c
+loader/i386/bsd32.c
+loader/i386/bsd64.c
+loader/i386/bsdXX.c
+loader/i386/bsd_helper.S
+loader/i386/bsd_pagetable.c
+loader/i386/bsd_trampoline.S
+loader/i386/linux.c
+loader/i386/linux_trampoline.S
+loader/i386/multiboot.c
+loader/i386/multiboot_elfxx.c
+loader/i386/multiboot_helper.S
+loader/i386/xnu.c
+loader/i386/xnu_helper.S
+loader/i386/efi/linux.c
+loader/i386/efi/xnu.c
+loader/i386/ieee1275/linux.c
+loader/i386/pc/chainloader.c
+loader/i386/pc/linux.c
+loader/i386/pc/multiboot2.c
+loader/i386/pc/xnu.c
+loader/ieee1275/multiboot2.c
+loader/powerpc/ieee1275/linux.c
+loader/sparc64/ieee1275/linux.c
+mmap/mmap.c
+mmap/efi/mmap.c
+mmap/i386/mmap.c
+mmap/i386/uppermem.c
+mmap/i386/pc/mmap.c
+mmap/i386/pc/mmap_helper.S
+normal/auth.c
+normal/autofs.c
+normal/cmdline.c
+normal/color.c
+normal/completion.c
+normal/datetime.c
+normal/dyncmd.c
+normal/handler.c
+normal/main.c
+normal/menu.c
+normal/menu_entry.c
+normal/menu_text.c
+normal/menu_viewer.c
+normal/misc.c
+partmap/acorn.c
+partmap/amiga.c
+partmap/apple.c
+partmap/gpt.c
+partmap/msdos.c
+partmap/sun.c
+parttool/msdospart.c
+script/sh/execute.c
+script/sh/function.c
+script/sh/lexer.c
+script/sh/main.c
+script/sh/parser.y
+script/sh/script.c
+term/gfxterm.c
+term/terminfo.c
+term/tparm.c
+term/usb_keyboard.c
+term/efi/console.c
+term/i386/vga_common.c
+term/i386/pc/at_keyboard.c
+term/i386/pc/console.c
+term/i386/pc/serial.c
+term/i386/pc/vesafb.c
+term/i386/pc/vga.c
+term/i386/pc/vga_text.c
+term/ieee1275/ofconsole.c
+util/console.c
+util/deviceiter.c
+util/devicemap.c
+util/getroot.c
+util/grub-editenv.c
+util/grub-emu.c
+util/grub-fstest.c
+util/grub-macho2img.c
+util/grub-mkconfig.in
+util/grub-mkconfig_lib.in
+util/grub-mkdevicemap.c
+util/grub-mkfont.c
+util/grub-pe2elf.c
+util/grub-probe.c
+util/hostdisk.c
+util/hostfs.c
+util/lvm.c
+util/misc.c
+util/raid.c
+util/resolve.c
+util/update-grub_lib.in
+util/usb.c
+util/elf/grub-mkimage.c
+util/grub.d/00_header.in
+util/grub.d/10_freebsd.in
+util/grub.d/10_hurd.in
+util/grub.d/10_linux.in
+util/grub.d/10_windows.in
+util/grub.d/30_os-prober.in
+util/grub.d/40_custom.in
+util/grub.d/README
+util/i386/efi/grub-dumpdevtree
+util/i386/efi/grub-install.in
+util/i386/efi/grub-mkimage.c
+util/i386/pc/grub-install.in
+util/i386/pc/grub-mkimage.c
+util/i386/pc/grub-mkrescue.in
+util/i386/pc/grub-setup.c
+util/ieee1275/devicemap.c
+util/ieee1275/grub-install.in
+util/ieee1275/ofpath.c
+util/powerpc/ieee1275/grub-mkrescue.in
+util/sparc64/ieee1275/grub-install.in
+util/sparc64/ieee1275/grub-mkimage.c
+util/sparc64/ieee1275/grub-ofpathname.c
+util/sparc64/ieee1275/grub-setup.c
+video/bitmap.c
+video/video.c
+video/fb/fbblit.c
+video/fb/fbfill.c
+video/fb/fbutil.c
+video/fb/video_fb.c
+video/i386/pc/vbe.c
+video/readers/jpeg.c
+video/readers/png.c
+video/readers/tga.c
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..e751d50
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,155 @@
+-*- Text -*-
+
+This is the GRUB.  Welcome.
+
+This file contains instructions for compiling and installing the GRUB.
+
+The Requirements
+================
+
+GRUB depends on some software packages installed into your system. If
+you don't have any of them, please obtain and install them before
+configuring the GRUB.
+
+* GCC 4.1.3 or later
+* GNU Make
+* GNU Bison 2.3 or later
+* GNU binutils 2.9.1.0.23 or later
+* Other standard GNU/Unix tools
+* Ruby 1.6 or later
+* Autoconf 2.59 or later
+
+Configuring the GRUB
+====================
+
+The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a
+file `config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+If you need to do unusual things to compile the package, please try to
+figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+The file `configure.ac' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+
+Building the GRUB
+=================
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and
+     type `./autogen.sh' and then `./configure' to configure the
+     package for your system.  If you're using `csh' on an old version
+     of System V, you might need to type `sh ./configure' instead to
+     prevent `csh' from trying to execute `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  `cd' to the directory where you want the object files
+and executables to go and run the `configure' script.  `configure'
+automatically checks for the source code in the directory that
+`configure' is in and in `..'.
+
+
+Installation Names
+==================
+
+By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix by giving `configure' the option `--prefix=PATH'.
+
+You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If
+you give `configure' the option `--exec-prefix=PATH', the package will
+use PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for
+particular kinds of files.  Run `configure --help' for a list of the
+directories you can set and what kinds of files go in them.
+
+If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure'
+the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Please note, however, that the GRUB knows where it is located in the
+filesystem.  If you have installed it in an unusual location, the
+system might not work properly, or at all.  The chief utility of these
+options for the GRUB is to allow you to "install" in some alternate
+location, and then copy these to the actual root filesystem later.
+
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..e0edbdb
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,463 @@
+# -*- makefile -*-
+#
+# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2002,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+#
+# This Makefile.in is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+### The configure script will replace these variables.
+
+SHELL = /bin/sh
+
+@SET_MAKE@
+
+transform = @program_transform_name@
+
+srcdir = @srcdir@
+builddir = @builddir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datarootdir = @datarootdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+pkgdatadir = $(datadir)/`echo @PACKAGE_TARNAME@ | sed '$(transform)'`
+pkglibdir =  $(libdir)/`echo @PACKAGE_TARNAME@/$(target_cpu)-$(platform) | sed '$(transform)'`
+
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+
+host_os = @host_os@
+host_kernel = @host_kernel@
+host_cpu = @host_cpu@
+
+target_cpu = @target_cpu@
+platform = @platform@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+MKDIR_P = @MKDIR_P@
+
+mkinstalldirs = $(srcdir)/mkinstalldirs
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+ASFLAGS = @ASFLAGS@
+LDFLAGS = @LDFLAGS@
+CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/include -Wall -W \
+	 -DGRUB_LIBDIR=\"$(pkglibdir)\"
+TARGET_CC = @TARGET_CC@
+TARGET_CFLAGS = @TARGET_CFLAGS@
+TARGET_ASFLAGS = @TARGET_ASFLAGS@
+TARGET_MODULE_FORMAT = @TARGET_MODULE_FORMAT@
+TARGET_APPLE_CC = @TARGET_APPLE_CC@
+OBJCONV = @OBJCONV@
+TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/include \
+	-Wall -W
+TARGET_LDFLAGS = @TARGET_LDFLAGS@
+TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@
+TARGET_IMG_LDFLAGS = @TARGET_IMG_LDFLAGS@
+TARGET_IMG_CFLAGS = @TARGET_IMG_CFLAGS@
+TARGET_OBJ2ELF = @TARGET_OBJ2ELF@
+EXEEXT = @EXEEXT@
+OBJCOPY = @OBJCOPY@
+STRIP = @STRIP@
+NM = @NM@
+RUBY = @RUBY@
+MAKEINFO = @MAKEINFO@
+ifeq (, $(MAKEINFO))
+MAKEINFO = true
+endif
+HELP2MAN = @HELP2MAN@
+ifeq (, $(HELP2MAN))
+HELP2MAN = true
+else
+HELP2MAN := LANG=C $(HELP2MAN) --no-info --source=FSF
+endif
+AWK = @AWK@
+LIBCURSES = @LIBCURSES@
+LIBUSB = @LIBUSB@
+YACC = @YACC@
+UNIFONT_BDF = @UNIFONT_BDF@
+
+# Options.
+enable_grub_emu = @enable_grub_emu@
+enable_grub_emu_usb = @enable_grub_emu_usb@
+enable_grub_fstest = @enable_grub_fstest@
+enable_grub_pe2elf = @enable_grub_pe2elf@
+enable_grub_mkfont = @enable_grub_mkfont@
+freetype_cflags = @freetype_cflags@
+freetype_libs = @freetype_libs@
+enable_efiemu = @enable_efiemu@
+
+### General variables.
+
+RMKFILES = $(addprefix conf/,common.rmk i386-coreboot.rmk i386-efi.rmk \
+	i386-qemu.rmk i386-ieee1275.rmk i386-pc.rmk i386.rmk powerpc-ieee1275.rmk \
+	sparc64-ieee1275.rmk x86_64-efi.rmk)
+
+MKFILES = $(patsubst %.rmk,%.mk,$(RMKFILES))
+
+PKGLIB = $(pkglib_IMAGES) $(pkglib_MODULES) $(pkglib_PROGRAMS) \
+	$(pkglib_DATA) $(pkglib_BUILDDIR)
+PKGDATA = $(pkgdata_DATA)
+PROGRAMS = $(bin_UTILITIES) $(sbin_UTILITIES)
+SCRIPTS = $(bin_SCRIPTS) $(sbin_SCRIPTS) $(grub-mkconfig_SCRIPTS) \
+	$(lib_SCRIPTS)
+INFOS = $(info_INFOS)
+
+CLEANFILES =
+MOSTLYCLEANFILES =
+DISTCLEANFILES = config.status config.cache config.log config.h \
+	Makefile stamp-h include/grub/cpu include/grub/machine \
+	gensymlist.sh genkernsyms.sh build_env.mk
+MAINTAINER_CLEANFILES = $(srcdir)/configure $(addprefix $(srcdir)/,$(MKFILES)) \
+	$(srcdir)/DISTLIST $(srcdir)/config.h.in $(srcdir)/stamp-h.in $(INFOS)
+
+# The default target.
+all: all-local
+
+### Include an arch-specific Makefile.
+$(addprefix $(srcdir)/,$(MKFILES)): %.mk: %.rmk genmk.rb
+	if test "x$(RUBY)" = x; then \
+	  touch $@; \
+	else \
+	  $(RUBY) $(srcdir)/genmk.rb < $< > $@; \
+	fi
+
+include $(srcdir)/conf/$(target_cpu)-$(platform).mk
+
+### General targets.
+
+CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA)
+pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst
+moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk
+	cat $(DEFSYMFILES) /dev/null \
+	  | $(AWK) -f $(srcdir)/genmoddep.awk $(UNDSYMFILES) > $@ \
+	  || (rm -f $@; exit 1)
+
+command.lst: $(COMMANDFILES)
+	cat $^ /dev/null | sort > $@
+
+fs.lst: $(FSFILES)
+	cat $^ /dev/null | sort > $@
+
+partmap.lst: $(PARTMAPFILES)
+	cat $^ /dev/null | sort > $@
+
+handler.lst: $(HANDLERFILES)
+	cat $^ /dev/null | sort > $@
+
+parttool.lst: $(PARTTOOLFILES)
+	cat $^ /dev/null | sort | uniq > $@
+
+ifneq (true, $(MAKEINFO))
+info_INFOS += docs/grub.info
+endif
+
+MOSTLYCLEANFILES += vti.tmp
+MAINTAINER_CLEANFILES += docs/stamp-vti docs/version.texi
+docs/version.texi: docs/stamp-vti
+docs/stamp-vti: docs/grub.texi configure.ac
+	$(MKDIR_P) docs
+	(set `$(SHELL) $(srcdir)/docs/mdate-sh $<`; \
+	echo "@set UPDATED $$1 $$2 $$3"; \
+	echo "@set UPDATED-MONTH $$2 $$3"; \
+	echo "@set EDITION $(PACKAGE_VERSION)"; \
+	echo "@set VERSION $(PACKAGE_VERSION)") > vti.tmp
+	@cmp -s vti.tmp $(builddir)/docs/version.texi \
+	  || (echo "Updating $(builddir)/docs/version.texi"; \
+	      cp vti.tmp $(builddir)/docs/version.texi)
+	-@rm -f vti.tmp
+	@cp $(builddir)/docs/version.texi $@
+
+# Use --force until such time as the documentation is cleaned up.
+docs/grub.info: docs/grub.texi docs/version.texi docs/fdl.texi
+	$(MKDIR_P) docs
+	$(MAKEINFO) -P $(builddir)/docs --no-split --force $< -o $@ || :
+
+ifeq (, $(UNIFONT_BDF))
+else
+
+ifeq ($(enable_grub_mkfont),yes)
+
+pkgdata_DATA += unicode.pf2 ascii.pf2
+
+# Arrows and lines are needed to draw the menu, so we always include them
+UNICODE_ARROWS=0x2190-0x2193
+UNICODE_LINES=0x2501-0x251B
+
+unicode.pf2: $(UNIFONT_BDF) grub-mkfont
+	$(builddir)/grub-mkfont -o $@ $(UNIFONT_BDF)
+
+ascii.pf2: $(UNIFONT_BDF) grub-mkfont
+	$(builddir)/grub-mkfont -o $@ $(UNIFONT_BDF) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES)
+endif
+endif
+
+# Used for building modules externally
+pkglib_BUILDDIR += build_env.mk
+build_env.mk: Makefile
+	(\
+	echo "TARGET_CC=$(TARGET_CC)" ; \
+	echo "TARGET_CFLAGS=$(TARGET_CFLAGS)" ; \
+	echo "TARGET_ASFLAGS=$(TARGET_ASFLAGS)" ; \
+	echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(pkglibdir) -I$(includedir)" ; \
+	echo "STRIP=$(STRIP)" ; \
+	echo "OBJCONV=$(OBJCONV)" ; \
+	echo "TARGET_MODULE_FORMAT=$(TARGET_MODULE_FORMAT)" ; \
+	echo "TARGET_APPLE_CC=$(TARGET_APPLE_CC)" ; \
+	echo "COMMON_ASFLAGS=$(COMMON_ASFLAGS)" ; \
+	echo "COMMON_CFLAGS=$(COMMON_CFLAGS)" ; \
+	echo "COMMON_LDFLAGS=$(COMMON_LDFLAGS)"\
+	) > $@
+pkglib_BUILDDIR += config.h grub_script.tab.h
+
+all-local: $(PROGRAMS) $(PKGLIB) $(PKGDATA) $(SCRIPTS) $(INFOS) $(MKFILES)
+
+install: install-local
+
+install-local: all
+	$(SHELL) $(mkinstalldirs) $(DESTDIR)$(pkglibdir)
+	rm -f $(DESTDIR)$(pkglibdir)/*
+	@list='$(PKGLIB)'; \
+	for file in $$list; do \
+	  if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
+	  dest="`echo $$file | sed 's,.*/,,'`"; \
+	  $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(pkglibdir)/$$dest; \
+	done
+	$(SHELL) $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+	@list='$(PKGDATA)'; \
+	for file in $$list; do \
+	  if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
+	  dest="`echo $$file | sed 's,.*/,,'`"; \
+	  $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(pkgdatadir)/$$dest; \
+	done
+	$(SHELL) $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1
+	@list='$(bin_UTILITIES)'; for file in $$list; do \
+	  if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
+	  dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
+	  $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \
+	  $(HELP2MAN) --section=1 -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \
+	done
+	$(SHELL) $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8
+	@list='$(sbin_UTILITIES)'; for file in $$list; do \
+	  if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
+	  dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
+	  $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \
+	  $(HELP2MAN) --section=8 -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \
+	done
+	@list='$(bin_SCRIPTS)'; for file in $$list; do \
+	  if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
+	  dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
+	  $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \
+	  $(HELP2MAN) --section=1 -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \
+	done
+	@list='$(sbin_SCRIPTS)'; for file in $$list; do \
+	  if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
+	  dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
+	  $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \
+	  $(HELP2MAN) --section=8 -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \
+	done
+	$(SHELL) $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/grub.d
+	@list='$(grub-mkconfig_SCRIPTS)'; for file in $$list; do \
+	  if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
+	  dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
+	  $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(sysconfdir)/grub.d/$$dest; \
+	done
+	@list='$(grub-mkconfig_DATA)'; for file in $$list; do \
+	  if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
+	  dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
+	  $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(sysconfdir)/grub.d/$$dest; \
+	done
+	$(SHELL) $(mkinstalldirs) $(DESTDIR)$(libdir)/grub
+	@list='$(lib_SCRIPTS)'; \
+	for file in $$list; do \
+	  if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
+	  dest="`echo $$file | sed 's,.*/,,'`"; \
+	  $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(libdir)/grub/$$dest; \
+	done
+	$(SHELL) $(mkinstalldirs) $(DESTDIR)$(infodir)
+	@list='$(info_INFOS)'; \
+	for file in $$list; do \
+	  if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
+	  dest="`echo $$file | sed 's,.*/,,'`"; \
+	  $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(infodir); \
+	  if (install-info --version && \
+	       install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+	    install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$dest" || :; \
+	  fi; \
+	done
+
+install-strip:
+	$(MAKE) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" install
+
+uninstall:
+	@list='$(PKGLIB)'; \
+	for file in $$list; do \
+	  dest="`echo $$file | sed 's,.*/,,'`"; \
+	  rm -f $(DESTDIR)$(pkglibdir)/$$dest; \
+	done
+	@list='$(PKGDATA)'; \
+	for file in $$list; do \
+	  dest="`echo $$file | sed 's,.*/,,'`"; \
+	  rm -f $(DESTDIR)$(pkgdatadir)/$$dest; \
+	done
+	@list='$(bin_UTILITIES) $(bin_SCRIPTS)'; for file in $$list; do \
+	  dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
+	  rm -f $(DESTDIR)$(bindir)/$$dest; \
+	  rm -f $(DESTDIR)$(mandir)/man1/$$dest.1; \
+	done
+	@list='$(sbin_UTILITIES) $(sbin_SCRIPTS)'; for file in $$list; do \
+	  dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
+	  rm -f $(DESTDIR)$(sbindir)/$$dest; \
+	  rm -f $(DESTDIR)$(mandir)/man8/$$dest.8; \
+	done
+	@list='$(grub-mkconfig_SCRIPTS) $(grub-mkconfig_DATA)'; for file in $$list; do \
+	  dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
+	  rm -f $(DESTDIR)$(sysconfdir)/grub.d/$$dest; \
+	done
+	@list='$(lib_SCRIPTS)'; \
+	for file in $$list; do \
+	  dest="`echo $$file | sed 's,.*/,,'`"; \
+	  echo rm -f $(DESTDIR)$(libdir)/$$dest; \
+	  rm -f $(DESTDIR)$(libdir)/grub/$$dest; \
+	done
+	@list='$(info_INFOS)'; \
+	for file in $$list; do \
+	  dest="`echo $$file | sed 's,.*/,,'`"; \
+	  if (install-info --version && \
+	       install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+	    if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$dest"; then \
+	      :; \
+	    else \
+	      test ! -f "$(DESTDIR)$(infodir)/$$dest" || exit 1; \
+	    fi; \
+	  fi; \
+	  rm -f $(DESTDIR)$(infodir)/$$dest; \
+	done
+
+clean: $(CLEAN_IMAGE_TARGETS) $(CLEAN_MODULE_TARGETS) $(CLEAN_UTILITY_TARGETS)
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+mostlyclean: clean $(MOSTLYCLEAN_IMAGE_TARGETS) $(MOSTLYCLEAN_MODULE_TARGETS) $(MOSTLYCLEAN_UTILITY_TARGETS)
+	-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+distclean: mostlyclean
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+	-rm -rf $(srcdir)/autom4te.cache
+
+maintainer-clean: distclean
+	-test -z "$(MAINTAINER_CLEANFILES)" || rm -f $(MAINTAINER_CLEANFILES)
+
+info:
+
+dvi:
+
+distdir=$(PACKAGE_TARNAME)-$(PACKAGE_VERSION)
+
+DISTLIST: gendistlist.sh
+	$(SHELL) $(srcdir)/gendistlist.sh > $(srcdir)/DISTLIST
+
+distdir: DISTLIST
+	-chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir)
+	$(SHELL) $(mkinstalldirs) $(distdir)
+	for i in `cat $(srcdir)/DISTLIST`; do \
+	  dir=`echo "$$i" | sed 's:/[^/]*$$::'`; \
+	  if test -d $(srcdir)/$$dir; then \
+	    $(SHELL) $(mkinstalldirs) $(distdir)/$$dir; \
+	  fi; \
+	  cp -p $(srcdir)/$$i $(distdir)/$$i || exit 1; \
+	done
+	chmod -R a+r $(distdir)
+
+GZIP_ENV = --best
+
+dist: distdir
+	tar chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	-chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir)
+
+distcheck: dist
+	-chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir)
+	GZIP=$(GZIP_ENV) gzip -cd $(distdir).tar.gz | tar xf -
+	chmod -R a-w $(distdir)
+	chmod a+w $(distdir)
+	mkdir $(distdir)/=build
+	mkdir $(distdir)/=inst
+	chmod a-w $(distdir)
+	dc_instdir=`CDPATH=: && cd $(distdir)/=inst && pwd` \
+	  && cd $(distdir)/=build \
+	  && $(SHELL) ../configure --srcdir=.. --prefix=$$dc_instdir \
+	  && $(MAKE) all dvi check install && $(MAKE) uninstall \
+	  && (test `find $$dc_instdir -type f -print | wc -l` -le 1 \
+	     || (echo "Error: files left after uninstall" 1>&2; \
+	         exit 1)) \
+	  && $(MAKE) dist && $(MAKE) distclean \
+	  && rm -f $(distdir).tar.gz \
+	  && (test `find . -type f -print | wc -l` -eq 0 \
+	     || (echo "Error: files left after distclean" 1>&2; \
+	         exit 1))
+	-chmod -R a+w $(distdir) > /dev/null 2>&1; rm -rf $(distdir)
+	@echo "$(distdir).tar.gz is ready for distribution" | \
+	  sed 'h;s/./=/g;p;x;p;x'
+
+check:
+
+.SUFFIX:
+.SUFFIX: .c .o .S .d
+
+# Regenerate configure and Makefile automatically.
+$(srcdir)/configure: configure.ac aclocal.m4
+	cd $(srcdir) && autoconf
+
+$(srcdir)/config.h.in: stamp-h.in
+$(srcdir)/stamp-h.in: configure.ac aclocal.m4
+	cd $(srcdir) && autoheader
+	echo timestamp > $(srcdir)/stamp-h.in
+
+config.h: stamp-h
+stamp-h: config.h.in config.status
+	$(SHELL) ./config.status
+
+Makefile: Makefile.in config.status
+	$(SHELL) ./config.status
+
+config.status: configure
+	$(SHELL) ./config.status --recheck
+
+gensymlist.sh: gensymlist.sh.in config.status
+	$(SHELL) ./config.status
+
+genkernsyms.sh: genkernsyms.sh.in config.status
+	$(SHELL) ./config.status
+
+.PHONY: all install install-strip uninstall clean mostlyclean distclean
+.PHONY: maintainer-clean info dvi dist check
+
+# Prevent an overflow.
+.NOEXPORT:
+
+.DELETE_ON_ERROR:
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..7c29cc9
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,243 @@
+New in 1.97 - :
+
+* Add support for loading XNU (MacOS X kernel).
+
+* ACPI override support.
+
+* Integrated gptsync.
+
+* Password protection support.
+
+* Partition manipulation tool.
+
+* Add `keystatus' command.
+
+* Unicode fonts are now used by default.
+
+* Add `hdparm' command.
+
+* Add support for getting the current date and time from CMOS as variables.
+
+* Add `drivemap' command.
+
+* Add support for RAID levels 4,6 and 10.
+
+* update-grub is replaced by grub-mkconfig.
+
+* When booting from PXE, PXE can be used to load files.
+
+* High resolution timer support.
+
+* Image loaders now support IO buffering.
+
+* Add `crc' command.
+
+* Add Cygwin support.
+
+* Add x86_64 EFI support.
+
+* Use LZMA compression instead of LZO.
+
+* Support for saving the environment from and loading the environment
+  from a file.
+
+* Allow the UUID to be used as device name.
+
+* The `search' command can use UUIDs now.
+
+* Add support for IEEE 1275 on i386.
+
+* Create partmap.lst and use it to automatically load partition map
+  modules.
+
+* grub-mkconfig supports os-prober to add operating systems to the
+  boot menu.
+
+* The ATA driver supports devices bigger than 2 TiB.
+
+* Add support for the UDF, AFS and EXT4 filesystems.
+
+* The ISO9660 filesystem supports the Joliet extension
+
+* Add support for loading kernels of FreeBSD, NetBSD and OpenBSD.
+
+* Add new command `sleep'.
+
+* Support for direct access to AT keyboards.
+
+* New utility `grub-fstest'.
+
+New in 1.96 - 2008-02-03:
+
+* The license term is changed to GNU General Public License Version 3.
+
+* grub-emu is made optional.  Now you have to use
+  `--enable-grub-emu' to enable it.
+
+* Add Multiboot2 support.
+
+* grub-emu can access the host filesystem now.
+
+* Add support for the NTFS, cpio/tar and Reiserfs filesystems.
+
+* Add support for ATA/ATAPI.
+
+* Add update-grub script to generate grub.cfg.
+
+* Add grub-mkrescue script to generate floppy or ElTorito images
+  (i386-pc only).
+
+* Add support for background images in gfxterm (background_image command).
+
+* Add support for detection of 64-bit support in CPU (cpuid command).
+
+* GPT is now enabled in i386-pc target.
+
+* Add grub-install for EFI.
+
+* Ported to the following new platforms: Efika, coreboot (a.k.a. LinuxBIOS),
+  OLPC XO.
+
+* Add support for colored menu (menu_color_normal and menu_color_highlight
+  variables).
+
+* Fix support for loading Linux zImages (such as memtest86).
+
+New in 1.95 - 2006-10-15:
+
+* Number partitions from 1 instead of 0. For instance, the first
+  partition of "hd0" is now "hd0,1" but not "hd0,0".
+
+* grub-probefs is renamed to grub-probe, and supports printing a
+  guessed OS device name and a GRUB drive name.
+
+* RAID and LVM support is added.
+
+* New command, echo.
+
+* The disk API is changed to support 64-bit addressing.
+
+* A TGA loader is added for the video API.
+
+New in 1.94 - 2006-06-04:
+
+* Fix several serious bugs in HFS+.
+
+* Add experimental EFI support. Chainloading and Linux loading are
+  supported at the moment.
+
+* Add a new command "blocklist" to show a block list.
+
+* Use --with-platform to specify a boot environment. For now, efi,
+  ieee1275 and pc are supported.
+
+* Use the filename "kernel.elf" instead of "grubof" on ieee1275.
+
+* Install GRUB into pkglibdir instead of pkgdatadir.
+
+* Support environmental variables. You can export variables by the
+  command "export".
+
+* Remove the commands "default" and "timeout". They are now variables.
+
+* Add the commands "source" and "." to include a file.
+
+* Implement experimental Video API and a new terminal "gfxterm" based
+  on the Video API.
+
+
+New in 1.93 - 2006-03-10:
+
+* Add support for the HFS+ wrapper.
+
+* Major improvements to scripting support.
+
+* Menu entries are now scriptable.
+
+
+New in 1.92 - 2005-12-25:
+
+* Add support for GPT partition table format.
+
+* Add a new command "play" to play an audio file on PC.
+
+* Add support for Linux/ADFS partition table format.
+
+* Add support for BASH-like scripting.
+
+* Add support for Apple HFS+ filesystems.
+
+
+New in 1.91 - 2005-10-15:
+
+* Add support for LZO version 2.
+
+* Support completion in the entry editor.
+
+* Add VBE support.
+
+* New commands, "search", "vbetest" and "vbeinfo".
+
+* The option BOOT_IMAGE is passed to Linux.
+
+* Add support for automatic decompression for gzip.
+
+* Add support for terminfo and serial.
+
+* Add support for x86_64.
+
+* GRUB itself is a Multiboot-compliant kernel.
+
+* Add new filesystems: XFS, SFS, and AFFS.
+
+
+New in 1.90 - 2005-08-07:
+
+* Rename the project name PUPA to GRUB. Now this version is the
+  developmental version of GRUB officially.
+
+* The GRUB emulator ``grub-emu'' is added.
+
+* Add support for newworld Mac. This should work with other
+  PowerPC-based machines as well, if they use IEEE 1275
+  (Open Firmware).
+
+* Too many changes to describe. Look at ChangeLog for more details.
+
+
+New in 0.7:
+
+* Problems in cross-compiling PUPA are fixed.
+
+* Use -mrtd and -mregparm=3 to reduce the generated code sizes.	This
+  means that any missing prototypes could be fatal. Also, you must take
+  care when writing assembly code. See the comments at the beginning of
+  startup.S, for more details.
+
+* New utility, ``pupa-setup''. This sets up PUPA to make it bootable
+  from a real disk.
+
+* New commands, "prefix", "insmod", "rmmod" and "lsmod" are added into
+  the rescue mode to manipulate PUPA modules.
+
+* Linux support is added. Initrd is not support yet.
+
+* Reduce the size of a core image significantly by compressing a large
+  part of the core image and decompressing itself at boot time. The
+  currently used algorithm is LZO (more precisely, LZO1X-999). So you
+  have to install LZO to build PUPA. See
+  <http://www.oberhumer.com/opensource/lzo/>, for more information.
+
+
+New in 0.6 - 2002-12-27, Yoshinori K. Okuji:
+
+* The chainloader and the FAT filesystem are modularized.
+
+* The structure of the source tree is a bit changed.
+
+* Support for building loadable modules is added.
+
+* Some generic parts of pupa-mkimage are segregated.
+
+* Some documentation files are added, according to the GNU Coding
+  Standards.
diff --git a/README b/README
new file mode 100644
index 0000000..b6c7fd6
--- /dev/null
+++ b/README
@@ -0,0 +1,14 @@
+This is GRUB 2, the second version of the GRand Unified Bootloader.
+GRUB 2 is rewritten from scratch to make GNU GRUB cleaner, safer, more
+robust, more powerful, and more portable.
+
+See the file NEWS for a description of recent changes to GRUB 2.
+
+See the file INSTALL for instructions on how to build and install the
+GRUB 2 data and program files.
+
+Please visit the official web page of GRUB 2, for more information.
+The URL is <http://www.gnu.org/software/grub/grub.html>.
+
+For now, there is not much documentation yet. Please look at the GRUB
+Wiki <http://grub.enbug.org> for testing procedures.
diff --git a/THANKS b/THANKS
new file mode 100644
index 0000000..5ce1909
--- /dev/null
+++ b/THANKS
@@ -0,0 +1,37 @@
+GRUB 2 would not be what it is today without the invaluable help of
+everybody who was kind enough to spend time testing it and reporting
+bugs.
+
+The following people made especially gracious contributions of their
+time and energy in helping to track down bugs, add new features, and
+generally assist in the GRUB 2 maintainership process:
+
+Andrey Shuvikov <mr_hyro@yahoo.com>
+Bibo Mao <bibo.mao@intel.com>
+Guillem Jover <guillem@hadrons.org>
+Harley D. Eades III <hde@foobar-qux.org>
+Hitoshi Ozeki <h-ozeki@ck2.so-net.ne.jp>
+Hollis Blanchard <hollis@penguinppc.org>
+Jeroen Dekkers <jeroen@dekkers.cx>
+Johan Rydberg <jrydberg@gnu.org>
+Marco Gerards <marco@gnu.org>
+Michael Guntsche <mike@it-loops.com>
+NIIBE Yutaka <gniibe@m17n.org>
+Omniflux <omniflux@omniflux.com>
+Robert Bihlmeyer <robbe@orcus.priv.at>
+Roger Leigh <rleigh@whinlatter.ukfsn.org>
+Ruslan Nikolaev <nruslan@mail.com>
+Timothy Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
+Tomas Ebenlendr <ebik@ucw.cz>
+Tristan Gingold  <tristan.gingold@bull.net>
+Tsuneyoshi Yasuo <tuneyoshi@naic.co.jp>
+Vesa Jaaskelainen  <chaac@nic.fi>
+Vincent Guffens <guffens@inma.ucl.ac.be>
+Vincent Pelletier <subdino2004@yahoo.fr>
+Vladimir Serbinenko <phcoder@gmail.com>
+
+Also, we thank the projects GNU Automake and LZMA. Some code
+was stolen from them.
+
+This project was supported by Information-technology Promotion Agency,
+Japan.
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..6ec1521
--- /dev/null
+++ b/TODO
@@ -0,0 +1,13 @@
+
+Before working on improving GRUB, it's very important that you
+make contact with the core GRUB developers. Things herein might be
+slightly out of date or otherwise not easy to understand at first
+glance. So write to <grub-devel@gnu.org> first.
+
+For bug tracking, refer to:
+
+  http://savannah.gnu.org/bugs/?group=grub
+
+Our wiki also lists some areas that need work:
+
+  http://grub.enbug.org/
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..899eca4
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,460 @@
+dnl Redefine AC_LANG_PROGRAM with a "-Wstrict-prototypes -Werror"-friendly
+dnl version.  Patch submitted to bug-autoconf in 2009-09-16.
+m4_define([AC_LANG_PROGRAM(C)],
+[$1
+int
+main (void)
+{
+dnl Do *not* indent the following line: there may be CPP directives.
+dnl Don't move the `;' right after for the same reason.
+$2
+  ;
+  return 0;
+}])
+
+
+dnl Check whether target compiler is working
+AC_DEFUN(grub_PROG_TARGET_CC,
+[AC_MSG_CHECKING([whether target compiler is working])
+AC_CACHE_VAL(grub_cv_prog_target_cc,
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+asm (".globl start; start: nop");
+int main (void);
+]], [[]])],
+  		[grub_cv_prog_target_cc=yes],
+		[grub_cv_prog_target_cc=no])
+])
+AC_MSG_RESULT([$grub_cv_prog_target_cc])
+
+if test "x$grub_cv_prog_target_cc" = xno; then
+  AC_MSG_ERROR([cannot compile for the target])
+fi
+])
+
+
+dnl grub_ASM_USCORE checks if C symbols get an underscore after
+dnl compiling to assembler.
+dnl Written by Pavel Roskin. Based on grub_ASM_EXT_C written by
+dnl Erich Boleyn and modified by Yoshinori K. Okuji.
+AC_DEFUN(grub_ASM_USCORE,
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([if C symbols get an underscore after compilation])
+AC_CACHE_VAL(grub_cv_asm_uscore,
+[cat > conftest.c <<\EOF
+int func (int *);
+int
+func (int *list)
+{
+  *list = 0;
+  return *list;
+}
+EOF
+
+if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -S conftest.c]) && test -s conftest.s; then
+  true
+else
+  AC_MSG_ERROR([${CC-cc} failed to produce assembly code])
+fi
+
+if grep _func conftest.s >/dev/null 2>&1; then
+  grub_cv_asm_uscore=yes
+else
+  grub_cv_asm_uscore=no
+fi
+
+rm -f conftest*])
+
+if test "x$grub_cv_asm_uscore" = xyes; then
+  AC_DEFINE_UNQUOTED([HAVE_ASM_USCORE], $grub_cv_asm_uscore,
+    [Define if C symbols get an underscore after compilation])
+fi
+
+AC_MSG_RESULT([$grub_cv_asm_uscore])
+])
+
+
+dnl Some versions of `objcopy -O binary' vary their output depending
+dnl on the link address.
+AC_DEFUN(grub_PROG_OBJCOPY_ABSOLUTE,
+[AC_MSG_CHECKING([whether ${OBJCOPY} works for absolute addresses])
+AC_CACHE_VAL(grub_cv_prog_objcopy_absolute,
+[cat > conftest.c <<\EOF
+void cmain (void);
+void
+cmain (void)
+{
+   *((int *) 0x1000) = 2;
+}
+EOF
+
+if AC_TRY_EVAL(ac_compile) && test -s conftest.o; then :
+else
+  AC_MSG_ERROR([${CC-cc} cannot compile C source code])
+fi
+grub_cv_prog_objcopy_absolute=yes
+for link_addr in 2000 8000 7C00; do
+  if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
+  else
+    AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
+  fi
+  if AC_TRY_COMMAND([${OBJCOPY-objcopy} --only-section=.text -O binary conftest.exec conftest]); then :
+  else
+    AC_MSG_ERROR([${OBJCOPY-objcopy} cannot create binary files])
+  fi
+  if test ! -f conftest.old || AC_TRY_COMMAND([cmp -s conftest.old conftest]); then
+    mv -f conftest conftest.old
+  else
+    grub_cv_prog_objcopy_absolute=no
+    break
+  fi
+done
+rm -f conftest*])
+AC_MSG_RESULT([$grub_cv_prog_objcopy_absolute])
+
+if test "x$grub_cv_prog_objcopy_absolute" = xno; then
+  AC_MSG_ERROR([GRUB requires a working absolute objcopy; upgrade your binutils])
+fi
+])
+
+
+dnl Supply --build-id=none to ld if building modules.
+dnl This suppresses warnings from ld on some systems
+AC_DEFUN(grub_PROG_LD_BUILD_ID_NONE,
+[AC_MSG_CHECKING([whether linker accepts --build-id=none])
+AC_CACHE_VAL(grub_cv_prog_ld_build_id_none,
+[save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS -Wl,--build-id=none"
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+	       [grub_cv_prog_ld_build_id_none=yes],
+	       [grub_cv_prog_ld_build_id_none=no])
+LDFLAGS="$save_LDFLAGS"
+])
+AC_MSG_RESULT([$grub_cv_prog_ld_build_id_none])
+
+if test "x$grub_cv_prog_ld_build_id_none" = xyes; then
+  TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,--build-id=none"
+fi
+])
+
+
+dnl Mass confusion!
+dnl Older versions of GAS interpret `.code16' to mean ``generate 32-bit
+dnl instructions, but implicitly insert addr32 and data32 bytes so
+dnl that the code works in real mode''.
+dnl
+dnl Newer versions of GAS interpret `.code16' to mean ``generate 16-bit
+dnl instructions,'' which seems right.  This requires the programmer
+dnl to explicitly insert addr32 and data32 instructions when they want
+dnl them.
+dnl
+dnl We only support the newer versions, because the old versions cause
+dnl major pain, by requiring manual assembly to get 16-bit instructions into
+dnl asm files.
+AC_DEFUN(grub_I386_ASM_ADDR32,
+[AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([grub_I386_ASM_PREFIX_REQUIREMENT])
+AC_MSG_CHECKING([for .code16 addr32 assembler support])
+AC_CACHE_VAL(grub_cv_i386_asm_addr32,
+[cat > conftest.s.in <<\EOF
+	.code16
+l1:	@ADDR32@	movb	%al, l1
+EOF
+
+if test "x$grub_cv_i386_asm_prefix_requirement" = xyes; then
+  sed -e s/@ADDR32@/addr32/ < conftest.s.in > conftest.s
+else
+  sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s
+fi
+
+if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
+  grub_cv_i386_asm_addr32=yes
+else
+  grub_cv_i386_asm_addr32=no
+fi
+
+rm -f conftest*])
+
+AC_MSG_RESULT([$grub_cv_i386_asm_addr32])])
+
+dnl check if our compiler is apple cc
+dnl because it requires numerous workarounds
+AC_DEFUN(grub_apple_cc,
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([whether our compiler is apple cc])
+AC_CACHE_VAL(grub_cv_apple_cc,
+[if $CC -v 2>&1 | grep "Apple Inc." > /dev/null; then
+  grub_cv_apple_cc=yes
+else
+  grub_cv_apple_cc=no
+fi
+])
+
+AC_MSG_RESULT([$grub_cv_apple_cc])])
+
+dnl check if our target compiler is apple cc
+dnl because it requires numerous workarounds
+AC_DEFUN(grub_apple_target_cc,
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([whether our target compiler is apple cc])
+AC_CACHE_VAL(grub_cv_apple_target_cc,
+[if $CC -v 2>&1 | grep "Apple Inc." > /dev/null; then
+  grub_cv_apple_target_cc=yes
+else
+  grub_cv_apple_target_cc=no
+fi
+])
+
+AC_MSG_RESULT([$grub_cv_apple_target_cc])])
+
+
+dnl Later versions of GAS requires that addr32 and data32 prefixes
+dnl appear in the same lines as the instructions they modify, while
+dnl earlier versions requires that they appear in separate lines.
+AC_DEFUN(grub_I386_ASM_PREFIX_REQUIREMENT,
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING(dnl
+[whether addr32 must be in the same line as the instruction])
+AC_CACHE_VAL(grub_cv_i386_asm_prefix_requirement,
+[cat > conftest.s <<\EOF
+	.code16
+l1:	addr32	movb	%al, l1
+EOF
+
+if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
+  grub_cv_i386_asm_prefix_requirement=yes
+else
+  grub_cv_i386_asm_prefix_requirement=no
+fi
+
+rm -f conftest*])
+
+if test "x$grub_cv_i386_asm_prefix_requirement" = xyes; then
+  grub_tmp_addr32="addr32"
+  grub_tmp_data32="data32"
+else
+  grub_tmp_addr32="addr32;"
+  grub_tmp_data32="data32;"
+fi
+
+AC_DEFINE_UNQUOTED([ADDR32], $grub_tmp_addr32,
+  [Define it to \"addr32\" or \"addr32;\" to make GAS happy])
+AC_DEFINE_UNQUOTED([DATA32], $grub_tmp_data32,
+  [Define it to \"data32\" or \"data32;\" to make GAS happy])
+
+AC_MSG_RESULT([$grub_cv_i386_asm_prefix_requirement])])
+
+
+dnl Older versions of GAS require that absolute indirect calls/jumps are
+dnl not prefixed with `*', while later versions warn if not prefixed.
+AC_DEFUN(grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK,
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING(dnl
+[whether an absolute indirect call/jump must not be prefixed with an asterisk])
+AC_CACHE_VAL(grub_cv_i386_asm_absolute_without_asterisk,
+[cat > conftest.s <<\EOF
+	lcall	*(offset)
+offset:
+	.long	0
+	.word	0
+EOF
+
+if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
+  grub_cv_i386_asm_absolute_without_asterisk=no
+else
+  grub_cv_i386_asm_absolute_without_asterisk=yes
+fi
+
+rm -f conftest*])
+
+if test "x$grub_cv_i386_asm_absolute_without_asterisk" = xyes; then
+  AC_DEFINE([ABSOLUTE_WITHOUT_ASTERISK], 1,
+	    [Define it if GAS requires that absolute indirect calls/jumps are not prefixed with an asterisk])
+fi
+
+AC_MSG_RESULT([$grub_cv_i386_asm_absolute_without_asterisk])])
+
+
+dnl Check what symbol is defined as a bss start symbol.
+dnl Written by Michael Hohmoth and Yoshinori K. Okuji.
+AC_DEFUN(grub_CHECK_BSS_START_SYMBOL,
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([if __bss_start is defined by the compiler])
+AC_CACHE_VAL(grub_cv_check_uscore_uscore_bss_start_symbol,
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],
+		[[asm ("incl __bss_start")]])],
+		[grub_cv_check_uscore_uscore_bss_start_symbol=yes],
+		[grub_cv_check_uscore_uscore_bss_start_symbol=no])])
+
+AC_MSG_RESULT([$grub_cv_check_uscore_uscore_bss_start_symbol])
+
+AC_MSG_CHECKING([if edata is defined by the compiler])
+AC_CACHE_VAL(grub_cv_check_edata_symbol,
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],
+		[[asm ("incl edata")]])],
+		[grub_cv_check_edata_symbol=yes],
+		[grub_cv_check_edata_symbol=no])])
+
+AC_MSG_RESULT([$grub_cv_check_edata_symbol])
+
+AC_MSG_CHECKING([if _edata is defined by the compiler])
+AC_CACHE_VAL(grub_cv_check_uscore_edata_symbol,
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],
+		[[asm ("incl _edata")]])],
+		[grub_cv_check_uscore_edata_symbol=yes],
+		[grub_cv_check_uscore_edata_symbol=no])])
+
+AC_MSG_RESULT([$grub_cv_check_uscore_edata_symbol])
+
+AH_TEMPLATE([BSS_START_SYMBOL], [Define it to one of __bss_start, edata and _edata])
+
+if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" = xyes; then
+  AC_DEFINE([BSS_START_SYMBOL], [__bss_start])
+elif test "x$grub_cv_check_edata_symbol" = xyes; then
+  AC_DEFINE([BSS_START_SYMBOL], [edata])
+elif test "x$grub_cv_check_uscore_edata_symbol" = xyes; then
+  AC_DEFINE([BSS_START_SYMBOL], [_edata])
+else
+  AC_MSG_ERROR([none of __bss_start, edata or _edata is defined])
+fi
+])
+
+dnl Check what symbol is defined as an end symbol.
+dnl Written by Yoshinori K. Okuji.
+AC_DEFUN(grub_CHECK_END_SYMBOL,
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([if end is defined by the compiler])
+AC_CACHE_VAL(grub_cv_check_end_symbol,
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],
+		[[asm ("incl end")]])],
+		[grub_cv_check_end_symbol=yes],
+		[grub_cv_check_end_symbol=no])])
+
+AC_MSG_RESULT([$grub_cv_check_end_symbol])
+
+AC_MSG_CHECKING([if _end is defined by the compiler])
+AC_CACHE_VAL(grub_cv_check_uscore_end_symbol,
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],
+		[[asm ("incl _end")]])],
+		[grub_cv_check_uscore_end_symbol=yes],
+		[grub_cv_check_uscore_end_symbol=no])])
+
+AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol])
+
+AH_TEMPLATE([END_SYMBOL], [Define it to either end or _end])
+
+if test "x$grub_cv_check_end_symbol" = xyes; then
+  AC_DEFINE([END_SYMBOL], [end])
+elif test "x$grub_cv_check_uscore_end_symbol" = xyes; then
+  AC_DEFINE([END_SYMBOL], [_end])
+else
+  AC_MSG_ERROR([neither end nor _end is defined])
+fi
+])
+
+dnl Check if the C compiler generates calls to `__enable_execute_stack()'.
+AC_DEFUN(grub_CHECK_ENABLE_EXECUTE_STACK,[
+AC_MSG_CHECKING([whether `$CC' generates calls to `__enable_execute_stack()'])
+AC_LANG_CONFTEST([[
+void f (int (*p) (void));
+void g (int i)
+{
+  int nestedfunc (void) { return i; }
+  f (nestedfunc);
+}
+]])
+if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -S conftest.c]) && test -s conftest.s; then
+  true
+else
+  AC_MSG_ERROR([${CC-cc} failed to produce assembly code])
+fi
+if grep __enable_execute_stack conftest.s >/dev/null 2>&1; then
+  AC_DEFINE([NEED_ENABLE_EXECUTE_STACK], 1,
+	    [Define to 1 if GCC generates calls to __enable_execute_stack()])
+  AC_MSG_RESULT([yes])
+else
+  AC_MSG_RESULT([no])
+fi
+rm -f conftest*
+])
+
+
+dnl Check if the C compiler supports `-fstack-protector'.
+AC_DEFUN(grub_CHECK_STACK_PROTECTOR,[
+[# Smashing stack protector.
+ssp_possible=yes]
+AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector'])
+# Is this a reliable test case?
+AC_LANG_CONFTEST([[void foo (void) { volatile char a[8]; a[3]; }]])
+[# `$CC -c -o ...' might not be portable.  But, oh, well...  Is calling
+# `ac_compile' like this correct, after all?
+if eval "$ac_compile -S -fstack-protector -o conftest.s" 2> /dev/null; then]
+  AC_MSG_RESULT([yes])
+  [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'?
+  rm -f conftest.s
+else
+  ssp_possible=no]
+  AC_MSG_RESULT([no])
+[fi]
+])
+
+dnl Check if the C compiler supports `-mstack-arg-probe' (Cygwin).
+AC_DEFUN(grub_CHECK_STACK_ARG_PROBE,[
+[# Smashing stack arg probe.
+sap_possible=yes]
+AC_MSG_CHECKING([whether `$CC' accepts `-mstack-arg-probe'])
+AC_LANG_CONFTEST([[void foo (void) { volatile char a[8]; a[3]; }]])
+[if eval "$ac_compile -S -mstack-arg-probe -o conftest.s" 2> /dev/null; then]
+  AC_MSG_RESULT([yes])
+  [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'?
+  rm -f conftest.s
+else
+  sap_possible=no]
+  AC_MSG_RESULT([no])
+[fi]
+])
+
+dnl Check if ln can handle directories properly (mingw).
+AC_DEFUN(grub_CHECK_LINK_DIR,[
+AC_MSG_CHECKING([whether ln can handle directories properly])
+[mkdir testdir 2>/dev/null
+case $srcdir in
+[\\/$]* | ?:[\\/]* ) reldir=$srcdir/include/grub/util ;;
+    *) reldir=../$srcdir/include/grub/util ;;
+esac
+if ln -s $reldir testdir/util 2>/dev/null ; then]
+  AC_MSG_RESULT([yes])
+  [link_dir=yes
+else
+  link_dir=no]
+  AC_MSG_RESULT([no])
+[fi
+rm -rf testdir]
+])
+
+dnl Check if the C compiler supports `-fPIE'.
+AC_DEFUN(grub_CHECK_PIE,[
+[# Position independent executable.
+pie_possible=yes]
+AC_MSG_CHECKING([whether `$CC' has `-fPIE' as default])
+# Is this a reliable test case?
+AC_LANG_CONFTEST([[
+#ifdef __PIE__
+int main() {
+	return 0;
+}
+#else
+#error NO __PIE__ DEFINED
+#endif
+]])
+
+[# `$CC -c -o ...' might not be portable.  But, oh, well...  Is calling
+# `ac_compile' like this correct, after all?
+if eval "$ac_compile -S -o conftest.s" 2> /dev/null; then]
+  AC_MSG_RESULT([yes])
+  [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'?
+  rm -f conftest.s
+else
+  pie_possible=no]
+  AC_MSG_RESULT([no])
+[fi]
+])
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..6895de2
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,13 @@
+#! /bin/sh
+
+set -e
+
+autoconf
+autoheader
+echo timestamp > stamp-h.in
+for rmk in conf/*.rmk; do
+  ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'`
+done
+./gendistlist.sh > DISTLIST
+
+exit 0
diff --git a/boot/i386/pc/boot.S b/boot/i386/pc/boot.S
new file mode 100644
index 0000000..865326e
--- /dev/null
+++ b/boot/i386/pc/boot.S
@@ -0,0 +1,485 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+
+/*
+ *  defines for the code go here
+ */
+
+	/* Print message string */
+#define MSG(x)	movw $x, %si; call LOCAL(message)
+
+	.file	"boot.S"
+
+	.text
+
+	/* Tell GAS to generate 16-bit instructions so that this code works
+	   in real mode. */
+	.code16
+
+.globl _start, start;
+_start:
+start:
+	/*
+	 * _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00
+	 */
+
+	/*
+	 * Beginning of the sector is compatible with the FAT/HPFS BIOS
+	 * parameter block.
+	 */
+
+	jmp	LOCAL(after_BPB)
+	nop	/* do I care about this ??? */
+
+	/*
+	 * This space is for the BIOS parameter block!!!!  Don't change
+	 * the first jump, nor start the code anywhere but right after
+	 * this area.
+	 */
+
+	. = _start + GRUB_BOOT_MACHINE_BPB_START
+	. = _start + 4
+
+	/* scratch space */
+mode:
+	.byte	0
+disk_address_packet:
+sectors:
+	.long	0
+heads:
+	.long	0
+cylinders:
+	.word	0
+sector_start:
+	.byte	0
+head_start:
+	.byte	0
+cylinder_start:
+	.word	0
+	/* more space... */
+
+	. = _start + GRUB_BOOT_MACHINE_BPB_END
+
+	/*
+	 * End of BIOS parameter block.
+	 */
+
+kernel_address:
+	.word	GRUB_BOOT_MACHINE_KERNEL_ADDR
+
+	. = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR
+kernel_sector:
+	.long	1, 0
+
+	. = _start + GRUB_BOOT_MACHINE_BOOT_DRIVE
+boot_drive:
+	.byte 0xff	/* the disk to load kernel from */
+			/* 0xff means use the boot drive */
+
+LOCAL(after_BPB):
+
+/* general setup */
+	cli		/* we're not safe here! */
+
+        /*
+         * This is a workaround for buggy BIOSes which don't pass boot
+         * drive correctly. If GRUB is installed into a HDD, check if
+         * DL is masked correctly. If not, assume that the BIOS passed
+         * a bogus value and set DL to 0x80, since this is the only
+         * possible boot drive. If GRUB is installed into a floppy,
+         * this does nothing (only jump).
+         */
+	. = _start + GRUB_BOOT_MACHINE_DRIVE_CHECK
+boot_drive_check:
+        jmp     1f	/* grub-setup may overwrite this jump */
+        testb   $0x80, %dl
+        jnz     1f
+        movb    $0x80, %dl
+1:
+
+	/*
+	 * ljmp to the next instruction because some bogus BIOSes
+	 * jump to 07C0:0000 instead of 0000:7C00.
+	 */
+	ljmp	$0, $real_start
+
+real_start:
+
+	/* set up %ds and %ss as offset from 0 */
+	xorw	%ax, %ax
+	movw	%ax, %ds
+	movw	%ax, %ss
+
+	/* set up the REAL stack */
+	movw	$GRUB_BOOT_MACHINE_STACK_SEG, %sp
+
+	sti		/* we're safe again */
+
+	/*
+	 *  Check if we have a forced disk reference here
+	 */
+	movb   boot_drive, %al
+	cmpb	$0xff, %al
+	je	1f
+	movb	%al, %dl
+1:
+	/* save drive reference first thing! */
+	pushw	%dx
+
+	/* print a notification message on the screen */
+	MSG(notification_string)
+
+	/* set %si to the disk address packet */
+	movw	$disk_address_packet, %si
+
+	/* do not probe LBA if the drive is a floppy */
+	testb	$GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl
+	jz	LOCAL(chs_mode)
+
+	/* check if LBA is supported */
+	movb	$0x41, %ah
+	movw	$0x55aa, %bx
+	int	$0x13
+
+	/*
+	 *  %dl may have been clobbered by INT 13, AH=41H.
+	 *  This happens, for example, with AST BIOS 1.04.
+	 */
+	popw	%dx
+	pushw	%dx
+
+	/* use CHS if fails */
+	jc	LOCAL(chs_mode)
+	cmpw	$0xaa55, %bx
+	jne	LOCAL(chs_mode)
+
+	andw	$1, %cx
+	jz	LOCAL(chs_mode)
+
+lba_mode:
+	xorw	%ax, %ax
+	movw	%ax, 4(%si)
+
+	incw	%ax
+	/* set the mode to non-zero */
+	movb	%al, -1(%si)
+
+	/* the blocks */
+	movw	%ax, 2(%si)
+
+	/* the size and the reserved byte */
+	movw	$0x0010, (%si)
+
+	/* the absolute address */
+	movl	kernel_sector, %ebx
+	movl	%ebx, 8(%si)
+	movl	kernel_sector + 4, %ebx
+	movl	%ebx, 12(%si)
+
+	/* the segment of buffer address */
+	movw	$GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si)
+
+/*
+ * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
+ *	Call with	%ah = 0x42
+ *			%dl = drive number
+ *			%ds:%si = segment:offset of disk address packet
+ *	Return:
+ *			%al = 0x0 on success; err code on failure
+ */
+
+	movb	$0x42, %ah
+	int	$0x13
+
+	/* LBA read is not supported, so fallback to CHS.  */
+	jc	LOCAL(chs_mode)
+
+	movw	$GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
+	jmp	LOCAL(copy_buffer)
+
+LOCAL(chs_mode):
+	/*
+	 *  Determine the hard disk geometry from the BIOS!
+	 *  We do this first, so that LS-120 IDE floppies work correctly.
+	 */
+	movb	$8, %ah
+	int	$0x13
+	jnc	LOCAL(final_init)
+
+	/*
+	 *  The call failed, so maybe use the floppy probe instead.
+	 */
+	testb	$GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl
+	jz	LOCAL(floppy_probe)
+
+	/* Nope, we definitely have a hard disk, and we're screwed. */
+	jmp	LOCAL(hd_probe_error)
+
+LOCAL(final_init):
+	/* set the mode to zero */
+	movzbl	%dh, %eax
+	movb	%ah, -1(%si)
+
+	/* save number of heads */
+	incw	%ax
+	movl	%eax, 4(%si)
+
+	movzbw	%cl, %dx
+	shlw	$2, %dx
+	movb	%ch, %al
+	movb	%dh, %ah
+
+	/* save number of cylinders */
+	incw	%ax
+	movw	%ax, 8(%si)
+
+	movzbw	%dl, %ax
+	shrb	$2, %al
+
+	/* save number of sectors */
+	movl	%eax, (%si)
+
+setup_sectors:
+	/* load logical sector start (top half) */
+	movl	kernel_sector + 4, %eax
+
+	orl	%eax, %eax
+	jnz	LOCAL(geometry_error)
+
+	/* load logical sector start (bottom half) */
+	movl	kernel_sector, %eax
+
+	/* zero %edx */
+	xorl	%edx, %edx
+
+	/* divide by number of sectors */
+	divl	(%si)
+
+	/* save sector start */
+	movb	%dl, %cl
+
+	xorw	%dx, %dx	/* zero %edx */
+	divl	4(%si)		/* divide by number of heads */
+
+	/* do we need too many cylinders? */
+	cmpw	8(%si), %ax
+	jge	LOCAL(geometry_error)
+
+	/* normalize sector start (1-based) */
+	incb	%cl
+
+	/* low bits of cylinder start */
+	movb	%al, %ch
+
+	/* high bits of cylinder start */
+	xorb	%al, %al
+	shrw	$2, %ax
+	orb	%al, %cl
+
+	/* save head start */
+	movb	%dl, %al
+
+	/* restore %dl */
+	popw	%dx
+
+	/* head start */
+	movb	%al, %dh
+
+/*
+ * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+ *	Call with	%ah = 0x2
+ *			%al = number of sectors
+ *			%ch = cylinder
+ *			%cl = sector (bits 6-7 are high bits of "cylinder")
+ *			%dh = head
+ *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+ *			%es:%bx = segment:offset of buffer
+ *	Return:
+ *			%al = 0x0 on success; err code on failure
+ */
+
+	movw	$GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
+	movw	%bx, %es	/* load %es segment with disk buffer */
+
+	xorw	%bx, %bx	/* %bx = 0, put it at 0 in the segment */
+	movw	$0x0201, %ax	/* function 2 */
+	int	$0x13
+
+	jc	LOCAL(read_error)
+
+	movw	%es, %bx
+
+LOCAL(copy_buffer):
+	/*
+	 * We need to save %cx and %si because the startup code in
+	 * kernel uses them without initializing them.
+	 */
+	pusha
+	pushw	%ds
+
+	movw	$0x100, %cx
+	movw	%bx, %ds
+	xorw	%si, %si
+	movw	$GRUB_BOOT_MACHINE_KERNEL_ADDR, %di
+	movw	%si, %es
+
+	cld
+
+	rep
+	movsw
+
+	popw	%ds
+	popa
+
+	/* boot kernel */
+	jmp	*(kernel_address)
+
+/* END OF MAIN LOOP */
+
+/*
+ * BIOS Geometry translation error (past the end of the disk geometry!).
+ */
+LOCAL(geometry_error):
+	MSG(geometry_error_string)
+	jmp	LOCAL(general_error)
+
+/*
+ * Disk probe failure.
+ */
+LOCAL(hd_probe_error):
+	MSG(hd_probe_error_string)
+	jmp	LOCAL(general_error)
+
+/*
+ * Read error on the disk.
+ */
+LOCAL(read_error):
+	MSG(read_error_string)
+
+LOCAL(general_error):
+	MSG(general_error_string)
+
+/* go here when you need to stop the machine hard after an error condition */
+        /* tell the BIOS a boot failure, which may result in no effect */
+        int	$0x18
+LOCAL(stop):
+	jmp	LOCAL(stop)
+
+notification_string:	.asciz "GRUB "
+geometry_error_string:	.asciz "Geom"
+hd_probe_error_string:	.asciz "Hard Disk"
+read_error_string:	.asciz "Read"
+general_error_string:	.asciz " Error\r\n"
+
+/*
+ * message: write the string pointed to by %si
+ *
+ *   WARNING: trashes %si, %ax, and %bx
+ */
+
+	/*
+	 * Use BIOS "int 10H Function 0Eh" to write character in teletype mode
+	 *	%ah = 0xe	%al = character
+	 *	%bh = page	%bl = foreground color (graphics modes)
+	 */
+1:
+	movw	$0x0001, %bx
+	movb	$0xe, %ah
+	int	$0x10		/* display a byte */
+LOCAL(message):
+	lodsb
+	cmpb	$0, %al
+	jne	1b	/* if not end of string, jmp to display */
+	ret
+
+	/*
+	 *  Windows NT breaks compatibility by embedding a magic
+	 *  number here.
+	 */
+
+	. = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC
+nt_magic:
+	.long 0
+	.word 0
+
+	/*
+	 *  This is where an MBR would go if on a hard disk.  The code
+	 *  here isn't even referenced unless we're on a floppy.  Kinda
+	 *  sneaky, huh?
+	 */
+
+	. = _start + GRUB_BOOT_MACHINE_PART_START
+part_start:
+
+probe_values:
+	.byte	36, 18, 15, 9, 0
+
+LOCAL(floppy_probe):
+/*
+ *  Perform floppy probe.
+ */
+
+	movw	$probe_values - 1, %si
+
+LOCAL(probe_loop):
+	/* reset floppy controller INT 13h AH=0 */
+	xorw	%ax, %ax
+	int	$0x13
+
+	incw	%si
+	movb	(%si), %cl
+
+	/* if number of sectors is 0, display error and die */
+	cmpb	$0, %cl
+	jne	1f
+
+/*
+ * Floppy disk probe failure.
+ */
+	MSG(fd_probe_error_string)
+	jmp	LOCAL(general_error)
+
+/* "Floppy" */
+fd_probe_error_string:	.asciz "Floppy"
+
+1:
+	/* perform read */
+	movw	$GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
+	movw	$0x201, %ax
+	movb	$0, %ch
+	movb	$0, %dh
+	int	$0x13
+
+	/* if error, jump to "LOCAL(probe_loop)" */
+	jc	LOCAL(probe_loop)
+
+	/* %cl is already the correct value! */
+	movb	$1, %dh
+	movb	$79, %ch
+
+	jmp	LOCAL(final_init)
+
+	. = _start + GRUB_BOOT_MACHINE_PART_END
+
+/* the last 2 bytes in the sector 0 contain the signature */
+	.word	GRUB_BOOT_MACHINE_SIGNATURE
diff --git a/boot/i386/pc/cdboot.S b/boot/i386/pc/cdboot.S
new file mode 100644
index 0000000..ccc9d64
--- /dev/null
+++ b/boot/i386/pc/cdboot.S
@@ -0,0 +1,173 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+#include <multiboot.h>
+
+        .file   "cdboot.S"
+
+#define CODE_ADDR	0x6000
+#define DATA_ADDR	((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200)
+
+#define CDSEC_SHIFT	11
+#define CDBLK_LENG	16
+
+	.text
+
+        .code16
+
+        .globl  start, _start
+
+start:
+_start:
+	call	LOCAL(next)
+
+LOCAL(next):
+	jmp	1f
+
+	. = start + 8
+
+bi_pvd:
+	.long 0		/* LBA of primary volume descriptor.  */
+bi_file:
+	.long 0		/* LBA of boot file. */
+bi_length:
+	.long 0		/* Length of boot file. */
+bi_csum:
+	.long 0		/* Checksum of boot file */
+bi_reserved:
+	.space (10*4)	/* Reserved */
+
+1:
+	popw	%bx
+
+	/* Boot from CDROM.  */
+
+	xorw	%ax, %ax
+	movw	%ax, %ss
+	movw	$(CODE_ADDR), %sp
+	movw	%ax, %ds
+	movw	%ax, %es
+
+	movw	$(0x7C00 + err_noboot_msg - start), %si
+	movl	%cs: bi_length - LOCAL(next)(%bx), %ecx
+	orl	%ecx, %ecx
+	jz	LOCAL(fail)
+
+	addl	$((1 << CDSEC_SHIFT) - 1), %ecx
+	shrl	$CDSEC_SHIFT, %ecx
+
+	movl	%cs: bi_file - LOCAL(next)(%bx), %esi
+
+	call	LOCAL(read_cdrom)
+
+	ljmp	$(DATA_ADDR >> 4), $0
+
+/*
+ * Parameters:
+ *   esi: start sector
+ *   ecx: number of sectors
+ */
+LOCAL(read_cdrom):
+	xorl	%eax, %eax
+
+	/* Number of blocks to read.  */
+	pushw	$CDBLK_LENG
+
+	/* Block number.  */
+	pushl	%eax
+	pushl	%esi
+
+	/* Buffer address.  */
+	pushw	$((DATA_ADDR - 0x400)>> 4)
+	pushl	%eax
+	pushw	$0x10
+
+	xorl	%edi, %edi
+	movw	%sp, %si
+
+1:
+	movw	0x10(%si), %di
+	cmpl	%ecx, %edi
+	jbe	2f
+	movl	%ecx, %edi
+
+2:
+	mov	%di, 2(%si)
+
+	pushl	%ecx
+
+	movb	$0x42, %ah
+	int	$0x13
+
+	jnc	3f
+
+	movb	$0x42, %ah		/* Try again.  */
+	int	$0x13
+
+	jnc	3f
+
+2:
+	shrw	$1, %di			/* Reduce transfer size.  */
+	jz	LOCAL(cdrom_fail)
+	movw	%di, 0x10(%si)
+	movw	%di, 2(%si)
+	movb	$0x42, %ah
+	int	$0x13
+	jc	2b
+
+3:
+
+	movw	%di, %ax
+	shlw	$(CDSEC_SHIFT - 4), %ax
+	addw	%ax, 6(%si)
+	addl	%edi, 8(%si)
+
+	popl	%ecx
+	subl	%edi, %ecx
+	jnz	1b
+
+	addw	$0x12, %sp
+	ret
+
+LOCAL(cdrom_fail):
+	movw	$(0x7C00 + err_cdfail_msg - start), %si
+
+LOCAL(fail):
+	movb	$0x0e, %ah
+	xorw	%bx, %bx
+1:
+	lodsb	(%si), %al
+	int	$0x10
+	cmpb	$0, %al
+	jne	1b
+1:	jmp	1b
+
+err_noboot_msg:
+	.ascii	"no boot info\0"
+
+err_cdfail_msg:
+	.ascii	"cdrom read fails\0"
+
+	. = start + 0x1FF
+
+	.byte	0
diff --git a/boot/i386/pc/diskboot.S b/boot/i386/pc/diskboot.S
new file mode 100644
index 0000000..e5e4a4e
--- /dev/null
+++ b/boot/i386/pc/diskboot.S
@@ -0,0 +1,380 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2006,2007   Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/machine/boot.h>
+
+/*
+ *  defines for the code go here
+ */
+
+#define MSG(x)	movw $x, %si; call LOCAL(message)
+
+	.file	"diskboot.S"
+
+	.text
+
+	/* Tell GAS to generate 16-bit instructions so that this code works
+	   in real mode. */
+	.code16
+
+	.globl	start, _start
+start:
+_start:
+	/*
+	 * _start is loaded at 0x2000 and is jumped to with
+	 * CS:IP 0:0x2000 in kernel.
+	 */
+
+	/*
+	 * we continue to use the stack for boot.img and assume that
+	 * some registers are set to correct values. See boot.S
+	 * for more information.
+	 */
+
+	/* save drive reference first thing! */
+	pushw	%dx
+
+	/* print a notification message on the screen */
+	pushw	%si
+	MSG(notification_string)
+	popw	%si
+
+	/* this sets up for the first run through "bootloop" */
+	movw	$(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE), %di
+
+	/* save the sector number of the second sector in %ebp */
+	movl	(%di), %ebp
+
+        /* this is the loop for reading the rest of the kernel in */
+LOCAL(bootloop):
+
+	/* check the number of sectors to read */
+	cmpw	$0, 8(%di)
+
+	/* if zero, go to the start function */
+	je	LOCAL(bootit)
+
+LOCAL(setup_sectors):
+	/* check if we use LBA or CHS */
+	cmpb	$0, -1(%si)
+
+	/* use CHS if zero, LBA otherwise */
+	je	LOCAL(chs_mode)
+
+	/* load logical sector start */
+	movl	(%di), %ebx
+	movl	4(%di), %ecx
+
+	/* the maximum is limited to 0x7f because of Phoenix EDD */
+	xorl	%eax, %eax
+	movb	$0x7f, %al
+
+	/* how many do we really want to read? */
+	cmpw	%ax, 8(%di)	/* compare against total number of sectors */
+
+	/* which is greater? */
+	jg	1f
+
+	/* if less than, set to total */
+	movw	8(%di), %ax
+
+1:
+	/* subtract from total */
+	subw	%ax, 8(%di)
+
+	/* add into logical sector start */
+	addl	%eax, (%di)
+	adcl	$0, 4(%di)
+
+	/* set up disk address packet */
+
+	/* the size and the reserved byte */
+	movw	$0x0010, (%si)
+
+	/* the number of sectors */
+	movw	%ax, 2(%si)
+
+	/* the absolute address */
+	movl	%ebx, 8(%si)
+	movl	%ecx, 12(%si)
+
+	/* the segment of buffer address */
+	movw	$GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si)
+
+	/* save %ax from destruction! */
+	pushw	%ax
+
+	/* the offset of buffer address */
+	movw	$0, 4(%si)
+
+/*
+ * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
+ *	Call with	%ah = 0x42
+ *			%dl = drive number
+ *			%ds:%si = segment:offset of disk address packet
+ *	Return:
+ *			%al = 0x0 on success; err code on failure
+ */
+
+	movb	$0x42, %ah
+	int	$0x13
+
+	jc	LOCAL(read_error)
+
+	movw	$GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
+	jmp	LOCAL(copy_buffer)
+
+LOCAL(chs_mode):
+	/* load logical sector start (top half) */
+	movl	4(%di), %eax
+	orl	%eax, %eax
+	jnz	LOCAL(geometry_error)
+
+	/* load logical sector start (bottom half) */
+	movl	(%di), %eax
+
+	/* zero %edx */
+	xorl	%edx, %edx
+
+	/* divide by number of sectors */
+	divl	(%si)
+
+	/* save sector start */
+	movb	%dl, 10(%si)
+
+	xorl	%edx, %edx	/* zero %edx */
+	divl	4(%si)		/* divide by number of heads */
+
+	/* save head start */
+	movb	%dl, 11(%si)
+
+	/* save cylinder start */
+	movw	%ax, 12(%si)
+
+	/* do we need too many cylinders? */
+	cmpw	8(%si), %ax
+	jge	LOCAL(geometry_error)
+
+	/* determine the maximum sector length of this read */
+	movw	(%si), %ax	/* get number of sectors per track/head */
+
+	/* subtract sector start */
+	subb	10(%si), %al
+
+	/* how many do we really want to read? */
+	cmpw	%ax, 8(%di)	/* compare against total number of sectors */
+
+
+	/* which is greater? */
+	jg	2f
+
+	/* if less than, set to total */
+	movw	8(%di), %ax
+
+2:
+	/* subtract from total */
+	subw	%ax, 8(%di)
+
+	/* add into logical sector start */
+	addl	%eax, (%di)
+	adcl	$0, 4(%di)
+
+/*
+ *  This is the loop for taking care of BIOS geometry translation (ugh!)
+ */
+
+	/* get high bits of cylinder */
+	movb	13(%si), %dl
+
+	shlb	$6, %dl		/* shift left by 6 bits */
+	movb	10(%si), %cl	/* get sector */
+
+	incb	%cl		/* normalize sector (sectors go
+					from 1-N, not 0-(N-1) ) */
+	orb	%dl, %cl	/* composite together */
+	movb	12(%si), %ch	/* sector+hcyl in cl, cylinder in ch */
+
+	/* restore %dx */
+	popw	%dx
+	pushw	%dx
+
+	/* head number */
+	movb	11(%si), %dh
+
+	pushw	%ax	/* save %ax from destruction! */
+
+/*
+ * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+ *	Call with	%ah = 0x2
+ *			%al = number of sectors
+ *			%ch = cylinder
+ *			%cl = sector (bits 6-7 are high bits of "cylinder")
+ *			%dh = head
+ *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+ *			%es:%bx = segment:offset of buffer
+ *	Return:
+ *			%al = 0x0 on success; err code on failure
+ */
+
+	movw	$GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
+	movw	%bx, %es	/* load %es segment with disk buffer */
+
+	xorw	%bx, %bx	/* %bx = 0, put it at 0 in the segment */
+	movb	$0x2, %ah	/* function 2 */
+	int	$0x13
+
+	jc	LOCAL(read_error)
+
+	/* save source segment */
+	movw	%es, %bx
+
+LOCAL(copy_buffer):
+
+	/* load addresses for copy from disk buffer to destination */
+	movw	10(%di), %es	/* load destination segment */
+
+	/* restore %ax */
+	popw	%ax
+
+	/* determine the next possible destination address (presuming
+		512 byte sectors!) */
+	shlw	$5, %ax		/* shift %ax five bits to the left */
+	addw	%ax, 10(%di)	/* add the corrected value to the destination
+				   address for next time */
+
+	/* save addressing regs */
+	pusha
+	pushw	%ds
+
+	/* get the copy length */
+	shlw	$3, %ax
+	movw	%ax, %cx
+
+	xorw	%di, %di	/* zero offset of destination addresses */
+	xorw	%si, %si	/* zero offset of source addresses */
+	movw	%bx, %ds	/* restore the source segment */
+
+	cld		/* sets the copy direction to forward */
+
+	/* perform copy */
+	rep		/* sets a repeat */
+	movsw		/* this runs the actual copy */
+
+	/* restore addressing regs and print a dot with correct DS
+	   (MSG modifies SI, which is saved, and unused AX and BX) */
+	popw	%ds
+	MSG(notification_step)
+	popa
+
+	/* check if finished with this dataset */
+	cmpw	$0, 8(%di)
+	jne	LOCAL(setup_sectors)
+
+	/* update position to load from */
+	subw	$GRUB_BOOT_MACHINE_LIST_SIZE, %di
+
+	/* jump to bootloop */
+	jmp	LOCAL(bootloop)
+
+/* END OF MAIN LOOP */
+
+LOCAL(bootit):
+	/* print a newline */
+	MSG(notification_done)
+	popw	%dx	/* this makes sure %dl is our "boot" drive */
+	ljmp	$0, $(GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)
+
+
+/*
+ * BIOS Geometry translation error (past the end of the disk geometry!).
+ */
+LOCAL(geometry_error):
+	MSG(geometry_error_string)
+	jmp	LOCAL(general_error)
+
+/*
+ * Read error on the disk.
+ */
+LOCAL(read_error):
+	MSG(read_error_string)
+
+LOCAL(general_error):
+	MSG(general_error_string)
+
+/* go here when you need to stop the machine hard after an error condition */
+LOCAL(stop):	jmp	LOCAL(stop)
+
+notification_string:	.asciz "loading"
+
+notification_step:	.asciz "."
+notification_done:	.asciz "\r\n"
+
+geometry_error_string:	.asciz "Geom"
+read_error_string:	.asciz "Read"
+general_error_string:	.asciz " Error"
+
+/*
+ * message: write the string pointed to by %si
+ *
+ *   WARNING: trashes %si, %ax, and %bx
+ */
+
+	/*
+	 * Use BIOS "int 10H Function 0Eh" to write character in teletype mode
+	 *	%ah = 0xe	%al = character
+	 *	%bh = page	%bl = foreground color (graphics modes)
+	 */
+1:
+	movw	$0x0001, %bx
+	movb	$0xe, %ah
+	int	$0x10		/* display a byte */
+
+	incw	%si
+LOCAL(message):
+	movb	(%si), %al
+	cmpb	$0, %al
+	jne	1b	/* if not end of string, jmp to display */
+	ret
+
+/*
+ *  This area is an empty space between the main body of code below which
+ *  grows up (fixed after compilation, but between releases it may change
+ *  in size easily), and the lists of sectors to read, which grows down
+ *  from a fixed top location.
+ */
+
+	.word 0
+	.word 0
+
+	. = _start + 0x200 - GRUB_BOOT_MACHINE_LIST_SIZE
+
+        /* fill the first data listing with the default */
+blocklist_default_start:
+	/* this is the sector start parameter, in logical sectors from
+	   the start of the disk, sector 0 */
+	.long 2, 0
+blocklist_default_len:
+	/* this is the number of sectors to read the command "install"
+	   will fill this up */
+	.word 0
+blocklist_default_seg:
+	/* this is the segment of the starting address to load the data into */
+	.word (GRUB_BOOT_MACHINE_KERNEL_SEG + 0x20)
+
+firstlist:	/* this label has to be after the list data!!! */
diff --git a/boot/i386/pc/lnxboot.S b/boot/i386/pc/lnxboot.S
new file mode 100644
index 0000000..c51741d
--- /dev/null
+++ b/boot/i386/pc/lnxboot.S
@@ -0,0 +1,290 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+#include <multiboot.h>
+
+        .file   "lnxboot.S"
+
+#define CODE_ADDR	0x6000
+#define CODE_SECTORS	1
+#define DATA_ADDR	((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200)
+
+#define BLCK_LENG	0x4000
+
+	.text
+
+        .code16
+
+        .globl  start, _start
+
+data_start:
+	xorl	%ebp, %ebp
+	jmp	LOCAL(linux_next)
+
+	. = data_start + 0x1F1
+
+setup_sects:
+	.byte	CODE_SECTORS
+root_flags:
+	.word	0
+syssize:
+	.word	0
+swap_dev:
+	.word	0
+ram_size:
+	.word	0
+vid_mode:
+	.word	0
+root_dev:
+	.word	0
+boot_flag:
+	.word	0xAA55
+
+start:
+_start:
+
+	jmp LOCAL(linux_init)
+
+	.ascii	"HdrS"			/* Header signature.  */
+	.word	0x0203			/* Header version number.  */
+
+realmode_swtch:
+	.word	0, 0			/* default_switch, SETUPSEG.  */
+start_sys_seg:
+	.word	0x1000			/* Obsolete.  */
+version_ptr:
+	.word	0			/* Version string ptr.  */
+type_of_loader:
+	.byte	0			/* Filled in by boot loader.  */
+loadflags:
+	.byte	1			/* Please load high.  */
+setup_move_size:
+	.word	0			/* Unused.  */
+code32_start:
+	.long	0x100000		/* 32-bit start address.  */
+ramdisk_image:
+	.long	0			/* Loaded ramdisk image address.  */
+ramdisk_size:
+	.long	0			/* Size of loaded ramdisk.  */
+bootsect_kludge:
+	.word	0, 0
+heap_end_ptr:
+	.word	0
+pad1:
+	.word	0
+cmd_line_ptr:
+	.long	0			/* Command line.  */
+ramdisk_max:
+	.long	0xffffffff		/* Highest allowed ramdisk address.  */
+
+gdt:
+	.long	0, 0, 0, 0		/* Must be zero.  */
+	.word	0xffff			/* 64 K segment size.  */
+gdt_src1:
+	.byte	0, 0 ,0			/* Low 24 bits of source address.  */
+	.byte	0x93			/* Access rights.  */
+	.byte	0			/* Extended access rights.  */
+gdt_src2:
+	.byte	0			/* High 8 bits of source address.  */
+	.word	0xffff			/* 64 K segment size.  */
+gdt_dst1:
+	.byte	0, 0, 0			/* Low 24 bits of target address.  */
+	.byte	0x93			/* Access rights.  */
+	.byte	0			/* Extended access rights.  */
+gdt_dst2:
+	.byte	0			/* High 8 bits of source address.  */
+	.long	0, 0, 0, 0		/* More space for the BIOS.  */
+
+reg_edx:
+	.byte	0x80, 0, 0xFF, 0xFF
+
+data_leng:
+	.long	0
+
+LOCAL(linux_init):
+	movw	%cs:(reg_edx - start), %dx
+	movl	%cs:(code32_start - start), %ebp
+
+LOCAL(linux_next):
+
+	call	LOCAL(normalize)
+
+LOCAL(normalize):
+	popw	%bx
+	subw	$(LOCAL(normalize) - start), %bx
+	shrw	$4, %bx
+	movw	%cs, %ax
+	addw	%bx, %ax
+	pushw	%ax
+	pushw	$(real_code - start)
+	lret				/* Jump to real_code.  */
+
+real_code:
+	subw	$0x20, %ax
+	movw	%ax, %ds
+	movw	(setup_sects - data_start), %cx
+	shlw	$7, %cx
+
+	/* Setup stack.  */
+
+	xorw	%si, %si
+	movw	%si, %ss
+	movw	$(CODE_ADDR), %sp
+
+	/* Move itself to 0:CODE_ADDR.  */
+
+	cld
+	movw	%cs, %ax
+	movw	%ax, %ds
+	movw	$(CODE_ADDR >> 4), %ax
+	movw	%ax, %es
+	movw	%si, %di
+
+	rep
+	movsl
+	ljmp	$(CODE_ADDR >> 4), $(real_code_2  - start)
+
+real_code_2:
+
+	xchgl	%ebp, %esi
+	orl	%esi, %esi
+	jnz	1f
+	movw	%ds, %si
+	shll	$4, %esi
+	addl	%ebp, %esi
+1:
+
+	pushw	%es
+	popw	%ds
+
+	movl	$0x200, %ecx
+	addl	%ecx, %esi
+	movl	$DATA_ADDR, %edi
+
+	call	LOCAL(move_memory)
+
+	/* Check for multiboot signature.  */
+	cmpl	$MULTIBOOT_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END)
+	jz	1f
+
+	movl	(ramdisk_image - start), %esi
+	movl	(ramdisk_size - start), %ecx
+	movl	$(DATA_ADDR - 0x200), %edi
+	jmp	2f
+
+1:
+
+	movl	%ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx
+	addl	$(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx
+
+2:
+	call	LOCAL(move_memory)
+
+	movsbl	%dh, %eax
+	movl	%eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)
+	movsbl	(reg_edx + 2 - start), %eax
+	movl	%eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)
+
+	movb	$0xFF, %dh
+
+	ljmp	$(DATA_ADDR >> 4), $0
+
+/*
+ * Parameters:
+ *   esi: source address
+ *   edi: target address
+ *   ecx: number of bytes
+ */
+
+LOCAL(move_memory):
+	incl	%ecx
+	andb	$0xFE, %cl
+	pushw	%dx
+1:
+	pushl	%esi
+	pushl	%edi
+	pushl	%ecx
+	cmpl	$BLCK_LENG, %ecx
+	jbe	2f
+	movl	$BLCK_LENG, %ecx
+2:
+	pushl	%ecx
+
+	movl	%esi, %eax
+	movw	%si, (gdt_src1 - start)
+	shrl	$16, %eax
+	movb	%al, (gdt_src1 + 2 - start)
+	movb	%ah, (gdt_src2 - start)
+
+	movl	%edi, %eax
+	movw	%di, (gdt_dst1 - start)
+	shrl	$16, %eax
+	movb	%al, (gdt_dst1 + 2 - start)
+	movb	%ah, (gdt_dst2 - start)
+
+	movw	$(gdt - start), %si
+	movb	$0x87, %ah
+	shrw	$1, %cx
+
+	int	$0x15
+
+	popl	%eax
+	popl	%ecx
+	popl	%edi
+	popl	%esi
+
+	jnc	2f
+	movw	$(err_int15_msg - start), %si
+	jmp	LOCAL(fail)
+
+2:
+
+	addl	%eax, %esi
+	addl	%eax, %edi
+	subl	%eax, %ecx
+	jnz	1b
+
+
+	popw	%dx
+	ret
+
+/*
+ * Parameters:
+ *   si: message
+ */
+
+LOCAL(fail):
+	movb	$0x0e, %ah
+	xorw	%bx, %bx
+1:
+	lodsb	(%si), %al
+	int	$0x10
+	cmpb	$0, %al
+	jne	1b
+1:	jmp	1b
+
+err_int15_msg:
+	.ascii	"move memory fails\0"
+
+	. = _start + CODE_SECTORS * 512
diff --git a/boot/i386/pc/pxeboot.S b/boot/i386/pc/pxeboot.S
new file mode 100644
index 0000000..2fc53bc
--- /dev/null
+++ b/boot/i386/pc/pxeboot.S
@@ -0,0 +1,40 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2005,2007,2008   Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+	.file	"pxeboot.S"
+	.text
+
+	/* Start with the prehistoric environment... */
+	.code16
+
+	/* Let's go */
+.globl start, _start;
+_start:
+start:
+
+	/* Use drive number 0x7F for PXE */
+        movb	$0x7F, %dl
+
+	/* Jump to the real world */
+	ljmp	$0, $0x8200
+
+	/* This region is a junk. Do you say that this is wasteful?
+	   But I like that the memory layout of the body is consistent
+	   among different kernels rather than scamping just for 1.5KB. */
+	. = _start + 0x8200 - 0x7C00 - 0x200 - 1
+	.byte	0
diff --git a/boot/i386/qemu/boot.S b/boot/i386/qemu/boot.S
new file mode 100644
index 0000000..a93fe39
--- /dev/null
+++ b/boot/i386/qemu/boot.S
@@ -0,0 +1,67 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+
+	.text
+	.code16
+	.globl _start
+_start:
+	/* Disable interrupts.  */
+	cli
+
+	jmp	1f
+
+	. = _start + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR
+VARIABLE(grub_core_entry_addr)
+	.long	0
+1:
+
+	/* Process VGA rom.  */
+	call	$0xc000, $0x3
+
+	/* Set up %ds, %ss, and %es.  */
+	xorw	%ax, %ax
+	movw	%ax, %ds
+	movw	%ax, %ss
+	movw	%ax, %es
+
+	/* Set up the real mode stack.  */
+	movl	$GRUB_MEMORY_MACHINE_REAL_STACK, %esp
+
+	/* Transition to protected mode.  We use pushl to force generation
+	   of a flat return address.  */
+	pushl	$1f
+	DATA32	jmp real_to_prot
+	.code32
+1:
+	movl	grub_core_entry_addr, %edx
+	jmp	*%edx
+
+#include "../../../kern/i386/realmode.S"
+
+	/* Intel, in its infinite wisdom, decided to put the i8086 entry point
+	   *right here* and this is why we need this kludge.  */
+
+	. = GRUB_BOOT_MACHINE_SIZE - 16
+	jmp	_start
+	. = GRUB_BOOT_MACHINE_SIZE
diff --git a/boot/sparc64/ieee1275/boot.S b/boot/sparc64/ieee1275/boot.S
new file mode 100644
index 0000000..74f4ee0
--- /dev/null
+++ b/boot/sparc64/ieee1275/boot.S
@@ -0,0 +1,196 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+
+	.text
+	.align	4
+	.globl	_start
+_start:
+	/* OF CIF entry point arrives in %o4 */
+pic_base:
+	call	boot_continue
+	 mov	%o4, CIF_REG
+
+	. = _start + GRUB_BOOT_MACHINE_VER_MAJ
+boot_version:		.byte	GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
+
+	/* The offsets to these locations are defined by the
+	 * GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h,
+	 * and grub-setup uses this to patch these next three values as needed.
+	 *
+	 * The boot_path will be the OF device path of the partition where the
+	 * rest of the GRUB kernel image resides.  kernel_sector will be set to
+	 * the location of the first block of the GRUB kernel, and
+	 * kernel_address is the location where we should load that first block.
+	 *
+	 * After loading in that block we will execute it by jumping to the
+	 * load address plus the size of the prepended A.OUT header (32 bytes).
+	 */
+boot_path:
+	. = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR
+kernel_sector:		.xword 2
+kernel_address:		.word  GRUB_BOOT_MACHINE_KERNEL_ADDR
+
+prom_finddev_name:	.asciz "finddevice"
+prom_chosen_path:	.asciz "/chosen"
+prom_getprop_name:	.asciz "getprop"
+prom_stdout_name:	.asciz "stdout"
+prom_write_name:	.asciz "write"
+prom_bootpath_name:	.asciz "bootpath"
+prom_open_name:		.asciz "open"
+prom_seek_name:		.asciz "seek"
+prom_read_name:		.asciz "read"
+prom_exit_name:		.asciz "exit"
+grub_name:		.asciz "GRUB "
+#define GRUB_NAME_LEN	5
+
+	.align	4
+
+prom_open_error:
+	GET_ABS(prom_open_name, %o2)
+	call	console_write
+	 mov	4, %o3
+	/* fallthru */
+
+prom_error:
+	GET_ABS(prom_exit_name, %o0)
+	/* fallthru */
+
+	/* %o0: OF call name
+	 * %o1: input arg 1
+	 */
+prom_call_1_1:
+	mov	1, %g1
+	ba	prom_call
+	 mov	1, %o5
+
+	/* %o2: message string
+	 * %o3: message length
+	 */
+console_write:
+	GET_ABS(prom_write_name, %o0)
+	mov	STDOUT_NODE_REG, %o1
+	/* fallthru */
+
+	/* %o0: OF call name
+	 * %o1: input arg 1
+	 * %o2: input arg 2
+	 * %o3: input arg 3
+	 */
+prom_call_3_1:
+	mov	3, %g1
+	mov	1, %o5
+	/* fallthru */
+
+	/* %o0: OF call name
+	 * %g1: num inputs
+	 * %o5: num outputs
+	 * %o1-%o4: inputs
+	 */
+prom_call:
+	stx	%o0, [%l1 + 0x00]
+	stx	%g1, [%l1 + 0x08]
+	stx	%o5, [%l1 + 0x10]
+	stx	%o1, [%l1 + 0x18]
+	stx	%o2, [%l1 + 0x20]
+	stx	%o3, [%l1 + 0x28]
+	stx	%o4, [%l1 + 0x30]
+	jmpl	CIF_REG, %g0
+	 mov	%l1, %o0
+
+boot_continue:
+	mov	%o7, PIC_REG		/* PIC base */
+	sethi	%hi(SCRATCH_PAD), %l1	/* OF argument slots */
+
+	/* Find the /chosen node so we can fetch the stdout handle,
+	 * and thus perform console output.
+	 *
+	 * chosen_node = prom_finddevice("/chosen")
+	 */
+	GET_ABS(prom_finddev_name, %o0)
+	GET_ABS(prom_chosen_path, %o1)
+	call	prom_call_1_1
+	 clr	%o2
+
+	ldx	[%l1 + 0x20], CHOSEN_NODE_REG
+	brz	CHOSEN_NODE_REG, prom_error
+
+	/* getprop(chosen_node, "stdout", &buffer, buffer_size) */
+	 GET_ABS(prom_getprop_name, %o0)
+	mov	4, %g1
+	mov	1, %o5
+	mov	CHOSEN_NODE_REG, %o1
+	GET_ABS(prom_stdout_name, %o2)
+	add	%l1, 256, %o3
+	mov	1024, %o4
+	call	prom_call
+	 stx	%g1, [%l1 + 256]
+
+	lduw	[%l1 + 256], STDOUT_NODE_REG
+	brz,pn	STDOUT_NODE_REG, prom_error
+
+	/* write(stdout_node, "GRUB ", strlen("GRUB ")) */
+	 GET_ABS(grub_name, %o2)
+	call	console_write
+	 mov	GRUB_NAME_LEN, %o3
+
+	/* Open up the boot_path, and use that handle to read the
+	 * first block of the GRUB kernel image.
+	 *
+	 * bootdev_handle = open(boot_path)
+	 */
+	GET_ABS(prom_open_name, %o0)
+	GET_ABS(boot_path, %o1)
+	call	prom_call_1_1
+	 clr	%o2
+
+	ldx	[%l1 + 0x20], BOOTDEV_REG
+	brz,pn	BOOTDEV_REG, prom_open_error
+
+	/* Since we have 64-bit cells, the high cell of the seek offset
+	 * is zero and the low cell is the entire value.
+	 *
+	 * seek(bootdev, 0, *kernel_sector << 9)
+	 */
+	 GET_ABS(prom_seek_name, %o0)
+	mov	BOOTDEV_REG, %o1
+	clr	%o2
+	LDX_ABS(kernel_sector, 0x00, %o3)
+	call	prom_call_3_1
+	 sllx	%o3, 9, %o3
+
+	/* read(bootdev, *kernel_address, 512) */
+	GET_ABS(prom_read_name, %o0)
+	mov	BOOTDEV_REG, %o1
+	LDUW_ABS(kernel_address, 0x00, %o2)
+	call	prom_call_3_1
+	 mov	512, %o3
+
+	LDUW_ABS(kernel_address, 0x00, %o2)
+	jmpl	%o2, %o7
+	 nop
+
+1:	ba,a	1b
+
+	. = _start + GRUB_BOOT_MACHINE_CODE_END
+
+/* the last 4 bytes in the sector 0 contain the signature */
+	.word	GRUB_BOOT_MACHINE_SIGNATURE
diff --git a/boot/sparc64/ieee1275/diskboot.S b/boot/sparc64/ieee1275/diskboot.S
new file mode 100644
index 0000000..68ed0ee
--- /dev/null
+++ b/boot/sparc64/ieee1275/diskboot.S
@@ -0,0 +1,145 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+
+	.text
+	.align	4
+	.globl	_start
+_start:
+	/* First stage boot block jumps to us here.  */
+pic_base:
+	call	after_info_block
+	 mov	%o7, PIC_REG
+
+prom_write_name:		.asciz "write"
+prom_seek_name:			.asciz "seek"
+prom_read_name:			.asciz "read"
+prom_close_name:		.asciz "close"
+
+notification_string:		.asciz "Loading kernel"
+#define NOTIFICATION_STRING_LEN	14
+
+notification_step:		.asciz "."
+#define NOTIFICATION_STEP_LEN	1
+
+notification_done:		.asciz "\r\n"
+#define NOTIFICATION_DONE_LEN	2
+
+	.align	4
+
+	/* %o2: message string
+	 * %o3: message length
+	 */
+console_write:
+	GET_ABS(prom_write_name, %o0)
+	mov	STDOUT_NODE_REG, %o1
+	/* fallthru */
+
+	/* %o0: OF call name
+	 * %o1: input arg 1
+	 * %o2: input arg 2
+	 * %o3: input arg 3
+	 */
+prom_call_3_1:
+	mov	3, %g1
+	mov	1, %o5
+	/* fallthru */
+
+	/* %o0: OF call name
+	 * %g1: num inputs
+	 * %o5: num outputs
+	 * %o1-%o4: inputs
+	 */
+prom_call:
+	stx	%o0, [%l1 + 0x00]
+	stx	%g1, [%l1 + 0x08]
+	stx	%o5, [%l1 + 0x10]
+	stx	%o1, [%l1 + 0x18]
+	stx	%o2, [%l1 + 0x20]
+	stx	%o3, [%l1 + 0x28]
+	stx	%o4, [%l1 + 0x30]
+	jmpl	CIF_REG, %g0
+	 mov	%l1, %o0
+
+
+after_info_block:
+	sethi	%hi(SCRATCH_PAD), %l1	/* OF argument slots */
+
+	GET_ABS(notification_string, %o2)
+	call	console_write
+	 mov	NOTIFICATION_STRING_LEN, %o3
+
+	GET_ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE, %l2)
+	set	GRUB_BOOT_MACHINE_IMAGE_ADDRESS, %l3
+bootloop:
+	lduw	[%l2 + 0x08], %o0
+	brz	%o0, bootit
+	 lduw	[%l2 + 0x00], %o3
+	sllx	%o3, 32, %o3
+	lduw	[%l2 + 0x04], %o4
+	or	%o3, %o4, %o3
+	GET_ABS(prom_seek_name, %o0)
+	mov	BOOTDEV_REG, %o1
+	clr	%o2
+	call	prom_call_3_1
+	 sllx	%o3, 9, %o3
+
+	GET_ABS(prom_read_name, %o0)
+	mov	BOOTDEV_REG, %o1
+	lduw	[%l2 + 0x08], %o3
+	sllx	%o3, 9, %o3
+	mov	%l3, %o2
+	call	prom_call_3_1
+	 add	%l3, %o3, %l3
+
+	GET_ABS(notification_step, %o2)
+	call	console_write
+	 mov	NOTIFICATION_STEP_LEN, %o3
+
+	ba	bootloop
+	 sub	%l2, GRUB_BOOT_MACHINE_LIST_SIZE, %l2
+
+bootit:
+	GET_ABS(prom_close_name, %o0)
+	mov	1, %g1
+	mov	0, %o5
+	call	prom_call
+	 mov	BOOTDEV_REG, %o1
+
+	GET_ABS(notification_done, %o2)
+	call	console_write
+	 mov	NOTIFICATION_DONE_LEN, %o3
+	sethi	%hi(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o2
+	jmpl	%o2 + %lo(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o7
+	 mov	CIF_REG, %o0
+1:	ba,a	1b
+
+lastlist:
+	.word	0
+	.word	0
+
+	. = _start + (0x200 - GRUB_BOOT_MACHINE_LIST_SIZE)
+blocklist_default_start:
+	.word	0
+	.word	2
+blocklist_default_len:
+	.word	0
+firstlist:
diff --git a/bus/pci.c b/bus/pci.c
new file mode 100644
index 0000000..2c29c03
--- /dev/null
+++ b/bus/pci.c
@@ -0,0 +1,66 @@
+/* pci.c - Generic PCI interfaces.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/pci.h>
+
+grub_pci_address_t
+grub_pci_make_address (int bus, int device, int function, int reg)
+{
+  return (1 << 31) | (bus << 16) | (device << 11) | (function << 8) | (reg << 2);
+}
+
+void
+grub_pci_iterate (grub_pci_iteratefunc_t hook)
+{
+  int bus;
+  int dev;
+  int func;
+  grub_pci_address_t addr;
+  grub_pci_id_t id;
+  grub_uint32_t hdr;
+
+  for (bus = 0; bus < 256; bus++)
+    {
+      for (dev = 0; dev < 32; dev++)
+	{
+	  for (func = 0; func < 8; func++)
+	    {
+	      addr = grub_pci_make_address (bus, dev, func, 0);
+	      id = grub_pci_read (addr);
+
+	      /* Check if there is a device present.  */
+	      if (id >> 16 == 0xFFFF)
+		continue;
+
+	      if (hook (bus, dev, func, id))
+		return;
+
+	      /* Probe only func = 0 if the device if not multifunction */
+	      if (func == 0)
+		{
+		  addr = grub_pci_make_address (bus, dev, func, 3);
+		  hdr = grub_pci_read (addr);
+		  if (!(hdr & 0x800000))
+		    break;
+		}
+	    }
+	}
+    }
+}
diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c
new file mode 100644
index 0000000..32fb7cf
--- /dev/null
+++ b/bus/usb/ohci.c
@@ -0,0 +1,611 @@
+/* ohci.c - OHCI Support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/usbtrans.h>
+#include <grub/misc.h>
+#include <grub/pci.h>
+#include <grub/cpu/pci.h>
+#include <grub/i386/io.h>
+#include <grub/time.h>
+
+struct grub_ohci_hcca
+{
+  /* Pointers to Interrupt Endpoint Descriptors.  Not used by
+     GRUB.  */
+  grub_uint32_t inttable[32];
+
+  /* Current frame number.  */
+  grub_uint16_t framenumber;
+
+  grub_uint16_t pad;
+
+  /* List of completed TDs.  */
+  grub_uint32_t donehead;
+
+  grub_uint8_t reserved[116];
+} __attribute__((packed));
+
+/* OHCI Endpoint Descriptor.  */
+struct grub_ohci_ed
+{
+  grub_uint32_t target;
+  grub_uint32_t td_tail;
+  grub_uint32_t td_head;
+  grub_uint32_t next_ed;
+} __attribute__((packed));
+
+struct grub_ohci_td
+{
+  /* Information used to construct the TOKEN packet.  */
+  grub_uint32_t token;
+
+  grub_uint32_t buffer;
+  grub_uint32_t next_td;
+  grub_uint32_t buffer_end;
+} __attribute__((packed));
+
+typedef struct grub_ohci_td *grub_ohci_td_t;
+typedef struct grub_ohci_ed *grub_ohci_ed_t;
+
+struct grub_ohci
+{
+  volatile grub_uint32_t *iobase;
+  volatile struct grub_ohci_hcca *hcca;
+  struct grub_ohci *next;
+};
+
+static struct grub_ohci *ohci;
+
+typedef enum
+{
+  GRUB_OHCI_REG_REVISION = 0x00,
+  GRUB_OHCI_REG_CONTROL,
+  GRUB_OHCI_REG_CMDSTATUS,
+  GRUB_OHCI_REG_INTSTATUS,
+  GRUB_OHCI_REG_INTENA,
+  GRUB_OHCI_REG_INTDIS,
+  GRUB_OHCI_REG_HCCA,
+  GRUB_OHCI_REG_PERIODIC,
+  GRUB_OHCI_REG_CONTROLHEAD,
+  GRUB_OHCI_REG_CONTROLCURR,
+  GRUB_OHCI_REG_BULKHEAD,
+  GRUB_OHCI_REG_BULKCURR,
+  GRUB_OHCI_REG_DONEHEAD,
+  GRUB_OHCI_REG_FRAME_INTERVAL,
+  GRUB_OHCI_REG_RHUBA = 18,
+  GRUB_OHCI_REG_RHUBPORT = 21
+} grub_ohci_reg_t;
+
+static grub_uint32_t
+grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg)
+{
+  return grub_le_to_cpu32 (*(o->iobase + reg));
+}
+
+static void
+grub_ohci_writereg32 (struct grub_ohci *o,
+		      grub_ohci_reg_t reg, grub_uint32_t val)
+{
+  *(o->iobase + reg) = grub_cpu_to_le32 (val);
+}
+
+
+
+/* Iterate over all PCI devices.  Determine if a device is an OHCI
+   controller.  If this is the case, initialize it.  */
+static int NESTED_FUNC_ATTR
+grub_ohci_pci_iter (int bus, int device, int func,
+		    grub_pci_id_t pciid __attribute__((unused)))
+{
+  grub_uint32_t class_code;
+  grub_uint32_t class;
+  grub_uint32_t subclass;
+  grub_uint32_t interf;
+  grub_uint32_t base;
+  grub_pci_address_t addr;
+  struct grub_ohci *o;
+  grub_uint32_t revision;
+  grub_uint32_t frame_interval;
+
+  addr = grub_pci_make_address (bus, device, func, 2);
+  class_code = grub_pci_read (addr) >> 8;
+
+  interf = class_code & 0xFF;
+  subclass = (class_code >> 8) & 0xFF;
+  class = class_code >> 16;
+
+  /* If this is not an OHCI controller, just return.  */
+  if (class != 0x0c || subclass != 0x03 || interf != 0x10)
+    return 0;
+
+  /* Determine IO base address.  */
+  addr = grub_pci_make_address (bus, device, func, 4);
+  base = grub_pci_read (addr);
+
+#if 0
+  /* Stop if there is no IO space base address defined.  */
+  if (! (base & 1))
+    return 0;
+#endif
+
+  /* Allocate memory for the controller and register it.  */
+  o = grub_malloc (sizeof (*o));
+  if (! o)
+    return 1;
+
+  o->iobase = (grub_uint32_t *) base;
+
+  /* Reserve memory for the HCCA.  */
+  o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256);
+
+  grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x base=%p\n",
+ 		class, subclass, interf, o->iobase);
+
+  /* Check if the OHCI revision is actually 1.0 as supported.  */
+  revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION);
+  grub_dprintf ("ohci", "OHCI revision=0x%02x\n", revision & 0xFF);
+  if ((revision & 0xFF) != 0x10)
+    goto fail;
+
+  /* Backup the frame interval register.  */
+  frame_interval = grub_ohci_readreg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL);
+
+  /* Suspend the OHCI by issuing a reset.  */
+  grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic.  */
+  grub_millisleep (1);
+  grub_dprintf ("ohci", "OHCI reset\n");
+
+  /* Restore the frame interval register.  */
+  grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, frame_interval);
+
+  /* Setup the HCCA.  */
+  grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca);
+  grub_dprintf ("ohci", "OHCI HCCA\n");
+
+  /* Enable the OHCI.  */
+  grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
+			(2 << 6));
+  grub_dprintf ("ohci", "OHCI enable: 0x%02x\n",
+		(grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) >> 6) & 3);
+
+  /* Link to ohci now that initialisation is successful.  */
+  o->next = ohci;
+  ohci = o;
+
+  return 0;
+
+ fail:
+  if (o)
+    grub_free ((void *) o->hcca);
+  grub_free (o);
+
+  return 1;
+}
+
+
+static void
+grub_ohci_inithw (void)
+{
+  grub_pci_iterate (grub_ohci_pci_iter);
+}
+
+
+
+static int
+grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev))
+{
+  struct grub_ohci *o;
+  struct grub_usb_controller dev;
+
+  for (o = ohci; o; o = o->next)
+    {
+      dev.data = o;
+      if (hook (&dev))
+	return 1;
+    }
+
+  return 0;
+}
+
+static void
+grub_ohci_transaction (grub_ohci_td_t td,
+		       grub_transfer_type_t type, unsigned int toggle,
+		       grub_size_t size, char *data)
+{
+  grub_uint32_t token;
+  grub_uint32_t buffer;
+  grub_uint32_t buffer_end;
+
+  grub_dprintf ("ohci", "OHCI transaction td=%p type=%d, toggle=%d, size=%d\n",
+		td, type, toggle, size);
+
+  switch (type)
+    {
+    case GRUB_USB_TRANSFER_TYPE_SETUP:
+      token = 0 << 19;
+      break;
+    case GRUB_USB_TRANSFER_TYPE_IN:
+      token = 2 << 19;
+      break;
+    case GRUB_USB_TRANSFER_TYPE_OUT:
+      token = 1 << 19;
+      break;
+    default:
+      token = 0;
+      break;
+    }
+
+  /* Generate no interrupts.  */
+  token |= 7 << 21;
+
+  /* Set the token.  */
+  token |= toggle << 24;
+  token |= 1 << 25;
+
+  buffer = (grub_uint32_t) data;
+  buffer_end = buffer + size - 1;
+
+  td->token = grub_cpu_to_le32 (token);
+  td->buffer = grub_cpu_to_le32 (buffer);
+  td->next_td = 0;
+  td->buffer_end = grub_cpu_to_le32 (buffer_end);
+}
+
+static grub_usb_err_t
+grub_ohci_transfer (grub_usb_controller_t dev,
+		    grub_usb_transfer_t transfer)
+{
+  struct grub_ohci *o = (struct grub_ohci *) dev->data;
+  grub_ohci_ed_t ed;
+  grub_ohci_td_t td_list;
+  grub_uint32_t target;
+  grub_uint32_t td_tail;
+  grub_uint32_t td_head;
+  grub_uint32_t status;
+  grub_uint32_t control;
+  grub_usb_err_t err;
+  int i;
+
+  /* Allocate an Endpoint Descriptor.  */
+  ed = grub_memalign (16, sizeof (*ed));
+  if (! ed)
+    return GRUB_USB_ERR_INTERNAL;
+
+  td_list = grub_memalign (16, sizeof (*td_list) * (transfer->transcnt + 1));
+  if (! td_list)
+    {
+      grub_free ((void *) ed);
+      return GRUB_USB_ERR_INTERNAL;
+    }
+
+  grub_dprintf ("ohci", "alloc=%p\n", td_list);
+
+  /* Setup all Transfer Descriptors.  */
+  for (i = 0; i < transfer->transcnt; i++)
+    {
+      grub_usb_transaction_t tr = &transfer->transactions[i];
+
+      grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle,
+			     tr->size, tr->data);
+
+      td_list[i].next_td = grub_cpu_to_le32 (&td_list[i + 1]);
+    }
+
+  /* Setup the Endpoint Descriptor.  */
+
+  /* Set the device address.  */
+  target = transfer->devaddr;
+
+  /* Set the endpoint.  */
+  target |= transfer->endpoint << 7;
+
+  /* Set the device speed.  */
+  target |= (transfer->dev->speed == GRUB_USB_SPEED_LOW) << 13;
+
+  /* Set the maximum packet size.  */
+  target |= transfer->max << 16;
+
+  td_head = (grub_uint32_t) td_list;
+
+  td_tail = (grub_uint32_t) &td_list[transfer->transcnt];
+
+  ed->target = grub_cpu_to_le32 (target);
+  ed->td_head = grub_cpu_to_le32 (td_head);
+  ed->td_tail = grub_cpu_to_le32 (td_tail);
+  ed->next_ed = grub_cpu_to_le32 (0);
+
+  grub_dprintf ("ohci", "program OHCI\n");
+
+  /* Program the OHCI to actually transfer.  */
+  switch (transfer->type)
+    {
+    case GRUB_USB_TRANSACTION_TYPE_BULK:
+      {
+	grub_dprintf ("ohci", "add to bulk list\n");
+
+	status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
+	control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
+
+	/* Disable the Control and Bulk lists.  */
+	control &= ~(3 << 4);
+	grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+	/* Clear BulkListFilled.  */
+	status &= ~(1 << 2);
+	grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+
+	grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, (grub_uint32_t) ed);
+
+	/* Enable the Bulk list.  */
+	control |= 1 << 5;
+	grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+	/* Set BulkListFilled.  */
+	status |= 1 << 2;
+	grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+
+	break;
+      }
+
+    case GRUB_USB_TRANSACTION_TYPE_CONTROL:
+      {
+	grub_dprintf ("ohci", "add to control list\n");
+	status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
+	control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
+
+	/* Disable the Control and Bulk lists.  */
+	control &= ~(3 << 4);
+	grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+	/* Clear ControlListFilled.  */
+	status &= ~(1 << 1);
+	grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+
+	grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD,
+			      (grub_uint32_t) ed);
+	grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1,
+			      (grub_uint32_t) ed);
+
+	/* Enable the Control list.  */
+	control |= 1 << 4;
+	grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+	/* Set ControlListFilled.  */
+	status |= 1 << 1;
+	grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+	break;
+      }
+    }
+
+  grub_dprintf ("ohci", "wait for completion\n");
+  grub_dprintf ("ohci", "control=0x%02x status=0x%02x\n",
+		grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL),
+		grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS));
+
+  /* Wait until the transfer is completed or STALLs.  */
+  while ((ed->td_head & ~0xf) != (ed->td_tail & ~0xf))
+    {
+      grub_cpu_idle ();
+
+      grub_dprintf ("ohci", "head=0x%02x tail=0x%02x\n", ed->td_head, ed->td_tail);
+
+      /* Detected a STALL.  */
+      if (ed->td_head & 1)
+	break;
+    }
+
+  grub_dprintf ("ohci", "complete\n");
+
+/*   if (ed->td_head & 1) */
+/*     err = GRUB_USB_ERR_STALL; */
+/*   else if (ed->td */
+
+
+  if (ed->td_head & 1)
+    {
+      grub_uint8_t errcode;
+      grub_ohci_td_t tderr;
+
+      tderr = (grub_ohci_td_t) grub_ohci_readreg32 (o,
+						    GRUB_OHCI_REG_DONEHEAD);
+      errcode = tderr->token >> 28;
+
+      switch (errcode)
+	{
+	case 0:
+	  /* XXX: Should not happen!  */
+	  grub_error (GRUB_ERR_IO, "OHCI without reporting the reason");
+	  err = GRUB_USB_ERR_INTERNAL;
+	  break;
+
+	case 1:
+	  /* XXX: CRC error.  */
+	  err = GRUB_USB_ERR_TIMEOUT;
+	  break;
+
+	case 2:
+	  err = GRUB_USB_ERR_BITSTUFF;
+	  break;
+
+	case 3:
+	  /* XXX: Data Toggle error.  */
+	  err = GRUB_USB_ERR_DATA;
+	  break;
+
+	case 4:
+	  err = GRUB_USB_ERR_STALL;
+	  break;
+
+	case 5:
+	  /* XXX: Not responding.  */
+	  err = GRUB_USB_ERR_TIMEOUT;
+	  break;
+
+	case 6:
+	  /* XXX: PID Check bits failed.  */
+	  err = GRUB_USB_ERR_BABBLE;
+	  break;
+
+	case 7:
+	  /* XXX: PID unexpected failed.  */
+	  err = GRUB_USB_ERR_BABBLE;
+	  break;
+
+	case 8:
+	  /* XXX: Data overrun error.  */
+	  err = GRUB_USB_ERR_DATA;
+	  break;
+
+	case 9:
+	  /* XXX: Data underrun error.  */
+	  err = GRUB_USB_ERR_DATA;
+	  break;
+
+	case 10:
+	  /* XXX: Reserved.  */
+	  err = GRUB_USB_ERR_NAK;
+	  break;
+
+	case 11:
+	  /* XXX: Reserved.  */
+	  err = GRUB_USB_ERR_NAK;
+	  break;
+
+	case 12:
+	  /* XXX: Buffer overrun.  */
+	  err = GRUB_USB_ERR_DATA;
+	  break;
+
+	case 13:
+	  /* XXX: Buffer underrun.  */
+	  err = GRUB_USB_ERR_DATA;
+	  break;
+
+	default:
+	  err = GRUB_USB_ERR_NAK;
+	  break;
+	}
+    }
+  else
+    err = GRUB_USB_ERR_NONE;
+
+  /* Disable the Control and Bulk lists.  */
+  control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
+  control &= ~(3 << 4);
+  grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+  /* Clear BulkListFilled and ControlListFilled.  */
+  status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
+  status &= ~((1 << 2) | (1 << 3));
+  grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+
+  /* XXX */
+  grub_free (td_list);
+  grub_free (ed);
+
+  return err;
+}
+
+static grub_err_t
+grub_ohci_portstatus (grub_usb_controller_t dev,
+		      unsigned int port, unsigned int enable)
+{
+   struct grub_ohci *o = (struct grub_ohci *) dev->data;
+   grub_uint32_t status;
+
+   /* Reset the port.  */
+   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+   status |= (1 << 4); /* XXX: Magic.  */
+   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
+   grub_millisleep (100);
+
+   /* End the reset signaling.  */
+   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+   status |= (1 << 20); /* XXX: Magic.  */
+   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
+   grub_millisleep (10);
+
+   /* Enable the port.  */
+   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+   status |= (enable << 1); /* XXX: Magic.  */
+   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
+
+   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+   grub_dprintf ("ohci", "portstatus=0x%02x\n", status);
+
+   return GRUB_ERR_NONE;
+}
+
+static grub_usb_speed_t
+grub_ohci_detect_dev (grub_usb_controller_t dev, int port)
+{
+   struct grub_ohci *o = (struct grub_ohci *) dev->data;
+   grub_uint32_t status;
+
+   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+
+   grub_dprintf ("ohci", "detect_dev status=0x%02x\n", status);
+
+   if (! (status & 1))
+     return GRUB_USB_SPEED_NONE;
+   else if (status & (1 << 9))
+     return GRUB_USB_SPEED_LOW;
+   else
+     return GRUB_USB_SPEED_FULL;
+}
+
+static int
+grub_ohci_hubports (grub_usb_controller_t dev)
+{
+  struct grub_ohci *o = (struct grub_ohci *) dev->data;
+  grub_uint32_t portinfo;
+
+  portinfo = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA);
+
+  grub_dprintf ("ohci", "root hub ports=%d\n", portinfo & 0xFF);
+
+  /* The root hub has exactly two ports.  */
+  return portinfo & 0xFF;
+}
+
+
+
+static struct grub_usb_controller_dev usb_controller =
+{
+  .name = "ohci",
+  .iterate = grub_ohci_iterate,
+  .transfer = grub_ohci_transfer,
+  .hubports = grub_ohci_hubports,
+  .portstatus = grub_ohci_portstatus,
+  .detect_dev = grub_ohci_detect_dev
+};
+
+GRUB_MOD_INIT(ohci)
+{
+  grub_ohci_inithw ();
+  grub_usb_controller_dev_register (&usb_controller);
+}
+
+GRUB_MOD_FINI(ohci)
+{
+  grub_usb_controller_dev_unregister (&usb_controller);
+}
diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c
new file mode 100644
index 0000000..88ff5b3
--- /dev/null
+++ b/bus/usb/uhci.c
@@ -0,0 +1,676 @@
+/* uhci.c - UHCI Support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/usb.h>
+#include <grub/usbtrans.h>
+#include <grub/pci.h>
+#include <grub/cpu/pci.h>
+#include <grub/i386/io.h>
+#include <grub/time.h>
+
+#define GRUB_UHCI_IOMASK	(0x7FF << 5)
+
+typedef enum
+  {
+    GRUB_UHCI_REG_USBCMD = 0x00,
+    GRUB_UHCI_REG_FLBASEADD = 0x08,
+    GRUB_UHCI_REG_PORTSC1 = 0x10,
+    GRUB_UHCI_REG_PORTSC2 = 0x12
+  } grub_uhci_reg_t;
+
+#define GRUB_UHCI_LINK_TERMINATE	1
+#define GRUB_UHCI_LINK_QUEUE_HEAD	2
+
+
+/* UHCI Queue Head.  */
+struct grub_uhci_qh
+{
+  /* Queue head link pointer which points to the next queue head.  */
+  grub_uint32_t linkptr;
+
+  /* Queue element link pointer which points to the first data object
+     within the queue.  */
+  grub_uint32_t elinkptr;
+
+  /* Queue heads are aligned on 16 bytes, pad so a queue head is 16
+     bytes so we can store many in a 4K page.  */
+  grub_uint8_t pad[8];
+} __attribute__ ((packed));
+
+/* UHCI Transfer Descriptor.  */
+struct grub_uhci_td
+{
+  /* Pointer to the next TD in the list.  */
+  grub_uint32_t linkptr;
+
+  /* Control and status bits.  */
+  grub_uint32_t ctrl_status;
+
+  /* All information required to transfer the Token packet.  */
+  grub_uint32_t token;
+
+  /* A pointer to the data buffer, UHCI requires this pointer to be 32
+     bits.  */
+  grub_uint32_t buffer;
+
+  /* Another linkptr that is not overwritten by the Host Controller.
+     This is GRUB specific.  */
+  grub_uint32_t linkptr2;
+
+  /* 3 additional 32 bits words reserved for the Host Controller Driver.  */
+  grub_uint32_t data[3];
+} __attribute__ ((packed));
+
+typedef volatile struct grub_uhci_td *grub_uhci_td_t;
+typedef volatile struct grub_uhci_qh *grub_uhci_qh_t;
+
+struct grub_uhci
+{
+  int iobase;
+  grub_uint32_t *framelist;
+
+  /* 256 Queue Heads.  */
+  grub_uhci_qh_t qh;
+
+  /* 256 Transfer Descriptors.  */
+  grub_uhci_td_t td;
+
+  /* Free Transfer Descriptors.  */
+  grub_uhci_td_t tdfree;
+
+  struct grub_uhci *next;
+};
+
+static struct grub_uhci *uhci;
+
+static grub_uint16_t
+grub_uhci_readreg16 (struct grub_uhci *u, grub_uhci_reg_t reg)
+{
+  return grub_inw (u->iobase + reg);
+}
+
+#if 0
+static grub_uint32_t
+grub_uhci_readreg32 (struct grub_uhci *u, grub_uhci_reg_t reg)
+{
+  return grub_inl (u->iobase + reg);
+}
+#endif
+
+static void
+grub_uhci_writereg16 (struct grub_uhci *u,
+		      grub_uhci_reg_t reg, grub_uint16_t val)
+{
+  grub_outw (val, u->iobase + reg);
+}
+
+static void
+grub_uhci_writereg32 (struct grub_uhci *u,
+		    grub_uhci_reg_t reg, grub_uint32_t val)
+{
+  grub_outl (val, u->iobase + reg);
+}
+
+static grub_err_t
+grub_uhci_portstatus (grub_usb_controller_t dev,
+		      unsigned int port, unsigned int enable);
+
+
+/* Iterate over all PCI devices.  Determine if a device is an UHCI
+   controller.  If this is the case, initialize it.  */
+static int NESTED_FUNC_ATTR
+grub_uhci_pci_iter (int bus, int device, int func,
+		    grub_pci_id_t pciid __attribute__((unused)))
+{
+  grub_uint32_t class_code;
+  grub_uint32_t class;
+  grub_uint32_t subclass;
+  grub_uint32_t interf;
+  grub_uint32_t base;
+  grub_uint32_t fp;
+  grub_pci_address_t addr;
+  struct grub_uhci *u;
+  int i;
+
+  addr = grub_pci_make_address (bus, device, func, 2);
+  class_code = grub_pci_read (addr) >> 8;
+
+  interf = class_code & 0xFF;
+  subclass = (class_code >> 8) & 0xFF;
+  class = class_code >> 16;
+
+  /* If this is not an UHCI controller, just return.  */
+  if (class != 0x0c || subclass != 0x03 || interf != 0x00)
+    return 0;
+
+  /* Determine IO base address.  */
+  addr = grub_pci_make_address (bus, device, func, 8);
+  base = grub_pci_read (addr);
+  /* Stop if there is no IO space base address defined.  */
+  if (! (base & 1))
+    return 0;
+
+  /* Allocate memory for the controller and register it.  */
+  u = grub_zalloc (sizeof (*u));
+  if (! u)
+    return 1;
+
+  u->iobase = base & GRUB_UHCI_IOMASK;
+  grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x\n",
+		class, subclass, interf, u->iobase);
+
+  /* Reserve a page for the frame list.  */
+  u->framelist = grub_memalign (4096, 4096);
+  if (! u->framelist)
+    goto fail;
+
+  /* The framelist pointer of UHCI is only 32 bits, make sure this
+     code works on on 64 bits architectures.  */
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+  if ((grub_uint64_t) u->framelist >> 32)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		  "allocated frame list memory not <4GB");
+      goto fail;
+    }
+#endif
+
+  /* The QH pointer of UHCI is only 32 bits, make sure this
+     code works on on 64 bits architectures.  */
+  u->qh = (grub_uhci_qh_t) grub_memalign (4096, 4096);
+  if (! u->qh)
+    goto fail;
+
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+  if ((grub_uint64_t) u->qh >> 32)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "allocated QH memory not <4GB");
+      goto fail;
+    }
+#endif
+
+  /* The TD pointer of UHCI is only 32 bits, make sure this
+     code works on on 64 bits architectures.  */
+  u->td = (grub_uhci_td_t) grub_memalign (4096, 4096*2);
+  if (! u->td)
+    goto fail;
+
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+  if ((grub_uint64_t) u->td >> 32)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "allocated TD memory not <4GB");
+      goto fail;
+    }
+#endif
+
+  /* Link all Transfer Descriptors in a list of available Transfer
+     Descriptors.  */
+  for (i = 0; i < 256; i++)
+    u->td[i].linkptr = (grub_uint32_t) &u->td[i + 1];
+  u->td[255 - 1].linkptr = 0;
+  u->tdfree = u->td;
+
+  /* Make sure UHCI is disabled!  */
+  grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0);
+
+  /* Setup the frame list pointers.  Since no isochronous transfers
+     are and will be supported, they all point to the (same!) queue
+     head.  */
+  fp = (grub_uint32_t) u->qh & (~15);
+  /* Mark this as a queue head.  */
+  fp |= 2;
+  for (i = 0; i < 1024; i++)
+    u->framelist[i] = fp;
+  /* Program the framelist address into the UHCI controller.  */
+  grub_uhci_writereg32 (u, GRUB_UHCI_REG_FLBASEADD,
+			(grub_uint32_t) u->framelist);
+
+  /* Make the Queue Heads point to each other.  */
+  for (i = 0; i < 256; i++)
+    {
+      /* Point to the next QH.  */
+      u->qh[i].linkptr = (grub_uint32_t) (&u->qh[i + 1]) & (~15);
+
+      /* This is a QH.  */
+      u->qh[i].linkptr |= GRUB_UHCI_LINK_QUEUE_HEAD;
+
+      /* For the moment, do not point to a Transfer Descriptor.  These
+	 are set at transfer time, so just terminate it.  */
+      u->qh[i].elinkptr = 1;
+    }
+
+  /* The last Queue Head should terminate.  256 are too many QHs so
+     just use 50.  */
+  u->qh[50 - 1].linkptr = 1;
+
+  /* Enable UHCI again.  */
+  grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 1 | (1 << 7));
+
+  /* UHCI is initialized and ready for transfers.  */
+  grub_dprintf ("uhci", "UHCI initialized\n");
+
+
+#if 0
+  {
+    int i;
+    for (i = 0; i < 10; i++)
+      {
+	grub_uint16_t frnum;
+
+	frnum = grub_uhci_readreg16 (u, 6);
+	grub_dprintf ("uhci", "Framenum=%d\n", frnum);
+	grub_millisleep (100);
+      }
+  }
+#endif
+
+  /* Link to uhci now that initialisation is successful.  */
+  u->next = uhci;
+  uhci = u;
+
+  return 0;
+
+ fail:
+  if (u)
+    {
+      grub_free ((void *) u->qh);
+      grub_free (u->framelist);
+    }
+  grub_free (u);
+
+  return 1;
+}
+
+static void
+grub_uhci_inithw (void)
+{
+  grub_pci_iterate (grub_uhci_pci_iter);
+}
+
+static grub_uhci_td_t
+grub_alloc_td (struct grub_uhci *u)
+{
+  grub_uhci_td_t ret;
+
+  /* Check if there is a Transfer Descriptor available.  */
+  if (! u->tdfree)
+    return NULL;
+
+  ret = u->tdfree;
+  u->tdfree = (grub_uhci_td_t) u->tdfree->linkptr;
+
+  return ret;
+}
+
+static void
+grub_free_td (struct grub_uhci *u, grub_uhci_td_t td)
+{
+  td->linkptr = (grub_uint32_t) u->tdfree;
+  u->tdfree = td;
+}
+
+static void
+grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td)
+{
+  /* Free the TDs in this queue.  */
+  while (td)
+    {
+      grub_uhci_td_t tdprev;
+
+      /* Unlink the queue.  */
+      tdprev = td;
+      td = (grub_uhci_td_t) td->linkptr2;
+
+      /* Free the TD.  */
+      grub_free_td (u, tdprev);
+    }
+}
+
+static grub_uhci_qh_t
+grub_alloc_qh (struct grub_uhci *u,
+	       grub_transaction_type_t tr __attribute__((unused)))
+{
+  int i;
+  grub_uhci_qh_t qh;
+
+  /* Look for a Queue Head for this transfer.  Skip the first QH if
+     this is a Interrupt Transfer.  */
+#if 0
+  if (tr == GRUB_USB_TRANSACTION_TYPE_INTERRUPT)
+    i = 0;
+  else
+#endif
+    i = 1;
+
+  for (; i < 255; i++)
+    {
+      if (u->qh[i].elinkptr & 1)
+	break;
+    }
+  qh = &u->qh[i];
+  if (! (qh->elinkptr & 1))
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		  "no free queue heads available");
+      return NULL;
+    }
+
+  return qh;
+}
+
+static grub_uhci_td_t
+grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
+		       grub_transfer_type_t type, unsigned int addr,
+		       unsigned int toggle, grub_size_t size,
+		       char *data)
+{
+  grub_uhci_td_t td;
+  static const unsigned int tf[] = { 0x69, 0xE1, 0x2D };
+
+  /* XXX: Check if data is <4GB.  If it isn't, just copy stuff around.
+     This is only relevant for 64 bits architectures.  */
+
+  /* Grab a free Transfer Descriptor and initialize it.  */
+  td = grub_alloc_td (u);
+  if (! td)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		  "no transfer descriptors available for UHCI transfer");
+      return 0;
+    }
+
+  grub_dprintf ("uhci",
+		"transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=%p td=%p\n",
+		endp, type, addr, toggle, size, data, td);
+
+  /* Don't point to any TD, just terminate.  */
+  td->linkptr = 1;
+
+  /* Active!  Only retry a transfer 3 times.  */
+  td->ctrl_status = (1 << 23) | (3 << 27);
+
+  /* If zero bytes are transmitted, size is 0x7FF.  Otherwise size is
+     size-1.  */
+  if (size == 0)
+    size = 0x7FF;
+  else
+    size = size - 1;
+
+  /* Setup whatever is required for the token packet.  */
+  td->token = ((size << 21) | (toggle << 19) | (endp << 15)
+	       | (addr << 8) | tf[type]);
+
+  td->buffer = (grub_uint32_t) data;
+
+  return td;
+}
+
+static grub_usb_err_t
+grub_uhci_transfer (grub_usb_controller_t dev,
+		    grub_usb_transfer_t transfer)
+{
+  struct grub_uhci *u = (struct grub_uhci *) dev->data;
+  grub_uhci_qh_t qh;
+  grub_uhci_td_t td;
+  grub_uhci_td_t td_first = NULL;
+  grub_uhci_td_t td_prev = NULL;
+  grub_usb_err_t err = GRUB_USB_ERR_NONE;
+  int i;
+
+  /* Allocate a queue head for the transfer queue.  */
+  qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL);
+  if (! qh)
+    return grub_errno;
+
+  for (i = 0; i < transfer->transcnt; i++)
+    {
+      grub_usb_transaction_t tr = &transfer->transactions[i];
+
+      td = grub_uhci_transaction (u, transfer->endpoint, tr->pid,
+				  transfer->devaddr, tr->toggle,
+				  tr->size, tr->data);
+      if (! td)
+	{
+	  /* Terminate and free.  */
+	  td_prev->linkptr2 = 0;
+	  td_prev->linkptr = 1;
+
+	  if (td_first)
+	    grub_free_queue (u, td_first);
+
+	  return GRUB_USB_ERR_INTERNAL;
+	}
+
+      if (! td_first)
+	td_first = td;
+      else
+	{
+	  td_prev->linkptr2 = (grub_uint32_t) td;
+	  td_prev->linkptr = (grub_uint32_t) td;
+	  td_prev->linkptr |= 4;
+	}
+      td_prev = td;
+    }
+  td_prev->linkptr2 = 0;
+  td_prev->linkptr = 1;
+
+  grub_dprintf ("uhci", "setup transaction %d\n", transfer->type);
+
+  /* Link it into the queue and terminate.  Now the transaction can
+     take place.  */
+  qh->elinkptr = (grub_uint32_t) td_first;
+
+  grub_dprintf ("uhci", "initiate transaction\n");
+
+  /* Wait until either the transaction completed or an error
+     occurred.  */
+  for (;;)
+    {
+      grub_uhci_td_t errtd;
+
+      errtd = (grub_uhci_td_t) (qh->elinkptr & ~0x0f);
+
+      grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n",
+		    errtd->ctrl_status, errtd->buffer & (~15), errtd);
+
+      /* Check if the transaction completed.  */
+      if (qh->elinkptr & 1)
+	break;
+
+      grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status);
+
+      /* Check if the TD is not longer active.  */
+      if (! (errtd->ctrl_status & (1 << 23)))
+	{
+	  grub_dprintf ("uhci", ">>t status=0x%02x\n", errtd->ctrl_status);
+
+	  /* Check if the endpoint is stalled.  */
+	  if (errtd->ctrl_status & (1 << 22))
+	    err = GRUB_USB_ERR_STALL;
+
+	  /* Check if an error related to the data buffer occurred.  */
+	  if (errtd->ctrl_status & (1 << 21))
+	    err = GRUB_USB_ERR_DATA;
+
+	  /* Check if a babble error occurred.  */
+	  if (errtd->ctrl_status & (1 << 20))
+	    err = GRUB_USB_ERR_BABBLE;
+
+	  /* Check if a NAK occurred.  */
+	  if (errtd->ctrl_status & (1 << 19))
+	    err = GRUB_USB_ERR_NAK;
+
+	  /* Check if a timeout occurred.  */
+	  if (errtd->ctrl_status & (1 << 18))
+	    err = GRUB_USB_ERR_TIMEOUT;
+
+	  /* Check if a bitstuff error occurred.  */
+	  if (errtd->ctrl_status & (1 << 17))
+	    err = GRUB_USB_ERR_BITSTUFF;
+
+	  if (err)
+	    goto fail;
+
+	  /* Fall through, no errors occurred, so the QH might be
+	     updated.  */
+	  grub_dprintf ("uhci", "transaction fallthrough\n");
+	}
+    }
+
+  grub_dprintf ("uhci", "transaction complete\n");
+
+ fail:
+
+  grub_dprintf ("uhci", "transaction failed\n");
+
+  /* Place the QH back in the free list and deallocate the associated
+     TDs.  */
+  qh->elinkptr = 1;
+  grub_free_queue (u, td_first);
+
+  return err;
+}
+
+static int
+grub_uhci_iterate (int (*hook) (grub_usb_controller_t dev))
+{
+  struct grub_uhci *u;
+  struct grub_usb_controller dev;
+
+  for (u = uhci; u; u = u->next)
+    {
+      dev.data = u;
+      if (hook (&dev))
+	return 1;
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_uhci_portstatus (grub_usb_controller_t dev,
+		      unsigned int port, unsigned int enable)
+{
+  struct grub_uhci *u = (struct grub_uhci *) dev->data;
+  int reg;
+  unsigned int status;
+
+  grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port);
+
+  if (port == 0)
+    reg = GRUB_UHCI_REG_PORTSC1;
+  else if (port == 1)
+    reg = GRUB_UHCI_REG_PORTSC2;
+  else
+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+		       "UHCI Root Hub port does not exist");
+
+  status = grub_uhci_readreg16 (u, reg);
+  grub_dprintf ("uhci", "detect=0x%02x\n", status);
+
+  /* Reset the port.  */
+  grub_uhci_writereg16 (u, reg, enable << 9);
+
+  /* Wait for the reset to complete.  XXX: How long exactly?  */
+  grub_millisleep (10);
+  status = grub_uhci_readreg16 (u, reg);
+  grub_uhci_writereg16 (u, reg, status & ~(1 << 9));
+  grub_dprintf ("uhci", "reset completed\n");
+
+  /* Enable the port.  */
+  grub_uhci_writereg16 (u, reg, enable << 2);
+  grub_millisleep (10);
+
+  grub_dprintf ("uhci", "waiting for the port to be enabled\n");
+
+  while (! (grub_uhci_readreg16 (u, reg) & (1 << 2)));
+
+  status = grub_uhci_readreg16 (u, reg);
+  grub_dprintf ("uhci", ">3detect=0x%02x\n", status);
+
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_usb_speed_t
+grub_uhci_detect_dev (grub_usb_controller_t dev, int port)
+{
+  struct grub_uhci *u = (struct grub_uhci *) dev->data;
+  int reg;
+  unsigned int status;
+
+  if (port == 0)
+    reg = GRUB_UHCI_REG_PORTSC1;
+  else if (port == 1)
+    reg = GRUB_UHCI_REG_PORTSC2;
+  else
+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+		       "UHCI Root Hub port does not exist");
+
+  status = grub_uhci_readreg16 (u, reg);
+
+  grub_dprintf ("uhci", "detect=0x%02x port=%d\n", status, port);
+
+  if (! (status & 1))
+    return GRUB_USB_SPEED_NONE;
+  else if (status & (1 << 8))
+    return GRUB_USB_SPEED_LOW;
+  else
+    return GRUB_USB_SPEED_FULL;
+}
+
+static int
+grub_uhci_hubports (grub_usb_controller_t dev __attribute__((unused)))
+{
+  /* The root hub has exactly two ports.  */
+  return 2;
+}
+
+
+static struct grub_usb_controller_dev usb_controller =
+{
+  .name = "uhci",
+  .iterate = grub_uhci_iterate,
+  .transfer = grub_uhci_transfer,
+  .hubports = grub_uhci_hubports,
+  .portstatus = grub_uhci_portstatus,
+  .detect_dev = grub_uhci_detect_dev
+};
+
+GRUB_MOD_INIT(uhci)
+{
+  grub_uhci_inithw ();
+  grub_usb_controller_dev_register (&usb_controller);
+  grub_dprintf ("uhci", "registered\n");
+}
+
+GRUB_MOD_FINI(uhci)
+{
+  struct grub_uhci *u;
+
+  /* Disable all UHCI controllers.  */
+  for (u = uhci; u; u = u->next)
+    grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0);
+
+  /* Unregister the controller.  */
+  grub_usb_controller_dev_unregister (&usb_controller);
+}
diff --git a/bus/usb/usb.c b/bus/usb/usb.c
new file mode 100644
index 0000000..310b8cc
--- /dev/null
+++ b/bus/usb/usb.c
@@ -0,0 +1,263 @@
+/* usb.c - Generic USB interfaces.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/misc.h>
+
+static grub_usb_controller_dev_t grub_usb_list;
+
+void
+grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
+{
+  auto int iterate_hook (grub_usb_controller_t dev);
+
+  /* Iterate over all controllers found by the driver.  */
+  int iterate_hook (grub_usb_controller_t dev)
+    {
+      dev->dev = usb;
+
+      /* Enable the ports of the USB Root Hub.  */
+      grub_usb_root_hub (dev);
+
+      return 0;
+    }
+
+  usb->next = grub_usb_list;
+  grub_usb_list = usb;
+
+  if (usb->iterate)
+    usb->iterate (iterate_hook);
+}
+
+void
+grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb)
+{
+  grub_usb_controller_dev_t *p, q;
+
+  for (p = &grub_usb_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == usb)
+      {
+	*p = q->next;
+	break;
+      }
+}
+
+#if 0
+int
+grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev))
+{
+  grub_usb_controller_dev_t p;
+
+  auto int iterate_hook (grub_usb_controller_t dev);
+
+  int iterate_hook (grub_usb_controller_t dev)
+    {
+      dev->dev = p;
+      if (hook (dev))
+	return 1;
+      return 0;
+    }
+
+  /* Iterate over all controller drivers.  */
+  for (p = grub_usb_list; p; p = p->next)
+    {
+      /* Iterate over the busses of the controllers.  XXX: Actually, a
+	 hub driver should do this.  */
+      if (p->iterate (iterate_hook))
+	return 1;
+    }
+
+  return 0;
+}
+#endif
+
+
+grub_usb_err_t
+grub_usb_clear_halt (grub_usb_device_t dev, int endpoint)
+{
+  dev->toggle[endpoint] = 0;
+  return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
+				     | GRUB_USB_REQTYPE_STANDARD
+				     | GRUB_USB_REQTYPE_TARGET_ENDP),
+			       GRUB_USB_REQ_CLEAR_FEATURE,
+			       GRUB_USB_FEATURE_ENDP_HALT,
+			       endpoint, 0, 0);
+}
+
+grub_usb_err_t
+grub_usb_set_configuration (grub_usb_device_t dev, int configuration)
+{
+  int i;
+
+  for (i = 0; i < 16; i++)
+    dev->toggle[i] = 0;
+
+  return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
+				     | GRUB_USB_REQTYPE_STANDARD
+				     | GRUB_USB_REQTYPE_TARGET_DEV),
+			       GRUB_USB_REQ_SET_CONFIGURATION, configuration,
+			       0, 0, NULL);
+}
+
+grub_usb_err_t
+grub_usb_get_descriptor (grub_usb_device_t dev,
+			 grub_uint8_t type, grub_uint8_t index,
+			 grub_size_t size, char *data)
+{
+  return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
+				     | GRUB_USB_REQTYPE_STANDARD
+				     | GRUB_USB_REQTYPE_TARGET_DEV),
+			       GRUB_USB_REQ_GET_DESCRIPTOR,
+			       (type << 8) | index,
+			       0, size, data);
+}
+
+struct grub_usb_desc_endp *
+grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr)
+{
+  int i;
+
+  for (i = 0; i < usbdev->config[0].descconf->numif; i++)
+    {
+      struct grub_usb_desc_if *interf;
+      int j;
+
+      interf = usbdev->config[0].interf[i].descif;
+
+      for (j = 0; j < interf->endpointcnt; j++)
+	{
+	  struct grub_usb_desc_endp *endp;
+	  endp = &usbdev->config[0].interf[i].descendp[j];
+
+	  if (endp->endp_addr == addr)
+	    return endp;
+	}
+    }
+
+  return NULL;
+}
+
+grub_usb_err_t
+grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid,
+		     char **string)
+{
+  struct grub_usb_desc_str descstr;
+  struct grub_usb_desc_str *descstrp;
+  grub_usb_err_t err;
+
+  /* Only get the length.  */
+  err = grub_usb_control_msg (dev, 1 << 7,
+			      0x06, (3 << 8) | index,
+			      langid, 1, (char *) &descstr);
+  if (err)
+    return err;
+
+  descstrp = grub_malloc (descstr.length);
+  if (! descstrp)
+    return GRUB_USB_ERR_INTERNAL;
+  err = grub_usb_control_msg (dev, 1 << 7,
+			      0x06, (3 << 8) | index,
+			      langid, descstr.length, (char *) descstrp);
+
+  *string = grub_malloc (descstr.length / 2);
+  if (! *string)
+    {
+      grub_free (descstrp);
+      return GRUB_USB_ERR_INTERNAL;
+    }
+
+  grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1);
+  (*string)[descstr.length / 2 - 1] = '\0';
+  grub_free (descstrp);
+
+  return GRUB_USB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_device_initialize (grub_usb_device_t dev)
+{
+  struct grub_usb_desc_device *descdev;
+  struct grub_usb_desc_config config;
+  grub_usb_err_t err;
+  int i;
+
+  err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE,
+				 0, sizeof (struct grub_usb_desc_device),
+				 (char *) &dev->descdev);
+  if (err)
+    return err;
+  descdev = &dev->descdev;
+
+  for (i = 0; i < 8; i++)
+    dev->config[i].descconf = NULL;
+
+  for (i = 0; i < descdev->configcnt; i++)
+    {
+      int pos;
+      int currif;
+      char *data;
+
+      /* First just read the first 4 bytes of the configuration
+	 descriptor, after that it is known how many bytes really have
+	 to be read.  */
+      err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i, 4,
+				     (char *) &config);
+
+      data = grub_malloc (config.totallen);
+      if (! data)
+	{
+	  err = GRUB_USB_ERR_INTERNAL;
+	  goto fail;
+	}
+
+      dev->config[i].descconf = (struct grub_usb_desc_config *) data;
+      err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i,
+				     config.totallen, data);
+      if (err)
+	goto fail;
+
+      /* Skip the configuration descriptor.  */
+      pos = sizeof (struct grub_usb_desc_config);
+
+      /* Read all interfaces.  */
+      for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
+	{
+	  dev->config[i].interf[currif].descif
+	    = (struct grub_usb_desc_if *) &data[pos];
+	  pos += sizeof (struct grub_usb_desc_if);
+
+	  /* Point to the first endpoint.  */
+	  dev->config[i].interf[currif].descendp
+	    = (struct grub_usb_desc_endp *) &data[pos];
+	  pos += (sizeof (struct grub_usb_desc_endp)
+		  * dev->config[i].interf[currif].descif->endpointcnt);
+	}
+    }
+
+  return GRUB_USB_ERR_NONE;
+
+ fail:
+
+  for (i = 0; i < 8; i++)
+    grub_free (dev->config[i].descconf);
+
+  return err;
+}
diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c
new file mode 100644
index 0000000..6881ce0
--- /dev/null
+++ b/bus/usb/usbhub.c
@@ -0,0 +1,191 @@
+/* usb.c - USB Hub Support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/misc.h>
+
+/* USB Supports 127 devices, with device 0 as special case.  */
+static struct grub_usb_device *grub_usb_devs[128];
+
+/* Add a device that currently has device number 0 and resides on
+   CONTROLLER, the Hub reported that the device speed is SPEED.  */
+static grub_usb_device_t
+grub_usb_hub_add_dev (grub_usb_controller_t controller, grub_usb_speed_t speed)
+{
+  grub_usb_device_t dev;
+  int i;
+
+  dev = grub_zalloc (sizeof (struct grub_usb_device));
+  if (! dev)
+    return NULL;
+
+  dev->controller = *controller;
+  dev->speed = speed;
+
+  grub_usb_device_initialize (dev);
+
+  /* Assign a new address to the device.  */
+  for (i = 1; i < 128; i++)
+    {
+      if (! grub_usb_devs[i])
+	break;
+    }
+  if (grub_usb_devs[i])
+    {
+      grub_error (GRUB_ERR_IO, "Can't assign address to USB device");
+      return NULL;
+    }
+
+  grub_usb_control_msg (dev,
+			(GRUB_USB_REQTYPE_OUT
+			 | GRUB_USB_REQTYPE_STANDARD
+			 | GRUB_USB_REQTYPE_TARGET_DEV),
+			GRUB_USB_REQ_SET_ADDRESS,
+			i, 0, 0, NULL);
+  dev->addr = i;
+  dev->initialized = 1;
+  grub_usb_devs[i] = dev;
+
+  return dev;
+}
+
+
+static grub_err_t
+grub_usb_add_hub (grub_usb_device_t dev)
+{
+  struct grub_usb_usb_hubdesc hubdesc;
+  grub_err_t err;
+  int i;
+
+  grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
+			      | GRUB_USB_REQTYPE_CLASS
+			      | GRUB_USB_REQTYPE_TARGET_DEV),
+			GRUB_USB_REQ_GET_DESCRIPTOR,
+			(GRUB_USB_DESCRIPTOR_HUB << 8) | 0,
+			0, sizeof (hubdesc), (char *) &hubdesc);
+
+  /* Iterate over the Hub ports.  */
+  for (i = 1; i <= hubdesc.portcnt; i++)
+    {
+      grub_uint32_t status;
+
+      /* Get the port status.  */
+      err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
+					| GRUB_USB_REQTYPE_CLASS
+					| GRUB_USB_REQTYPE_TARGET_OTHER),
+				  GRUB_USB_REQ_HUB_GET_PORT_STATUS,
+				  0, i, sizeof (status), (char *) &status);
+
+      /* Just ignore the device if the Hub does not report the
+	 status.  */
+      if (err)
+	continue;
+
+      /* If connected, reset and enable the port.  */
+      if (status & GRUB_USB_HUB_STATUS_CONNECTED)
+	{
+	  grub_usb_speed_t speed;
+
+	  /* Determine the device speed.  */
+	  if (status & GRUB_USB_HUB_STATUS_LOWSPEED)
+	    speed = GRUB_USB_SPEED_LOW;
+	  else
+	    {
+	      if (status & GRUB_USB_HUB_STATUS_HIGHSPEED)
+		speed = GRUB_USB_SPEED_HIGH;
+	      else
+		speed = GRUB_USB_SPEED_FULL;
+	    }
+
+	  /* A device is actually connected to this port, not enable
+	     the port.  XXX: Why 0x03?  According to some docs it
+	     should be 0x0.  Check the specification!  */
+	  err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
+					    | GRUB_USB_REQTYPE_CLASS
+					    | GRUB_USB_REQTYPE_TARGET_OTHER),
+				      0x3, 0x4, i, 0, 0);
+
+	  /* If the Hub does not cooperate for this port, just skip
+	     the port.  */
+	  if (err)
+	    continue;
+
+	  /* Add the device and assign a device address to it.  */
+	  grub_usb_hub_add_dev (&dev->controller, speed);
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_root_hub (grub_usb_controller_t controller)
+{
+  grub_err_t err;
+  int ports;
+  int i;
+
+  /* Query the number of ports the root Hub has.  */
+  ports = controller->dev->hubports (controller);
+
+  for (i = 0; i < ports; i++)
+    {
+      grub_usb_speed_t speed = controller->dev->detect_dev (controller, i);
+
+      if (speed != GRUB_USB_SPEED_NONE)
+	{
+	  grub_usb_device_t dev;
+
+	  /* Enable the port.  */
+	  err = controller->dev->portstatus (controller, i, 1);
+	  if (err)
+	    continue;
+
+	  /* Enable the port and create a device.  */
+	  dev = grub_usb_hub_add_dev (controller, speed);
+	  if (! dev)
+	    continue;
+
+	  /* If the device is a Hub, scan it for more devices.  */
+	  if (dev->descdev.class == 0x09)
+	    grub_usb_add_hub (dev);
+	}
+    }
+
+  return GRUB_USB_ERR_NONE;
+}
+
+int
+grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
+{
+  int i;
+
+  for (i = 0; i < 128; i++)
+    {
+      if (grub_usb_devs[i])
+	{
+	  if (hook (grub_usb_devs[i]))
+	      return 1;
+	}
+    }
+
+  return 0;
+}
diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c
new file mode 100644
index 0000000..09e7af8
--- /dev/null
+++ b/bus/usb/usbtrans.c
@@ -0,0 +1,212 @@
+/* usbtrans.c - USB Transfers and Transactions.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/usb.h>
+#include <grub/usbtrans.h>
+
+grub_usb_err_t
+grub_usb_control_msg (grub_usb_device_t dev,
+		      grub_uint8_t reqtype,
+		      grub_uint8_t request,
+		      grub_uint16_t value,
+		      grub_uint16_t index,
+		      grub_size_t size, char *data)
+{
+  int i;
+  grub_usb_transfer_t transfer;
+  int datablocks;
+  struct grub_usb_packet_setup setupdata;
+  grub_usb_err_t err;
+  unsigned int max;
+
+  grub_dprintf ("usb",
+		"control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%d\n",
+		reqtype, request,  value, index, size);
+
+  /* Create a transfer.  */
+  transfer = grub_malloc (sizeof (struct grub_usb_transfer));
+  if (! transfer)
+    return grub_errno;
+
+  /* Determine the maximum packet size.  */
+  if (dev->initialized)
+    max = dev->descdev.maxsize0;
+  else
+    max = 64;
+
+  datablocks = (size + max - 1) / max;
+
+  /* XXX: Discriminate between different types of control
+     messages.  */
+  transfer->transcnt = datablocks + 2;
+  transfer->size = size; /* XXX ? */
+  transfer->endpoint = 0;
+  transfer->devaddr = dev->addr;
+  transfer->type = GRUB_USB_TRANSACTION_TYPE_CONTROL;
+  transfer->max = max;
+  transfer->dev = dev;
+
+  /* Allocate an array of transfer data structures.  */
+  transfer->transactions = grub_malloc (transfer->transcnt
+					* sizeof (struct grub_usb_transfer));
+  if (! transfer->transactions)
+    {
+      grub_free (transfer);
+      return grub_errno;
+    }
+
+  /* Build a Setup packet.  XXX: Endianness.  */
+  setupdata.reqtype = reqtype;
+  setupdata.request = request;
+  setupdata.value = value;
+  setupdata.index = index;
+  setupdata.length = size;
+  transfer->transactions[0].size = sizeof (setupdata);
+  transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP;
+  transfer->transactions[0].data = (char *) &setupdata;
+  transfer->transactions[0].toggle = 0;
+
+  /* Now the data...  XXX: Is this the right way to transfer control
+     transfers?  */
+  for (i = 0; i < datablocks; i++)
+    {
+      grub_usb_transaction_t tr = &transfer->transactions[i + 1];
+
+      tr->size = (size > max) ? max : size;
+      /* Use the right most bit as the data toggle.  Simple and
+	 effective.  */
+      tr->toggle = !(i & 1);
+      if (reqtype & 128)
+	tr->pid = GRUB_USB_TRANSFER_TYPE_IN;
+      else
+	tr->pid = GRUB_USB_TRANSFER_TYPE_OUT;
+      tr->data = &data[i * max];
+      size -= max;
+    }
+
+  /* End with an empty OUT transaction.  */
+  transfer->transactions[datablocks + 1].size = 0;
+  transfer->transactions[datablocks + 1].data = NULL;
+  if (reqtype & 128)
+    transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT;
+  else
+    transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_IN;
+
+  transfer->transactions[datablocks + 1].toggle = 1;
+
+  err = dev->controller.dev->transfer (&dev->controller, transfer);
+
+  grub_free (transfer->transactions);
+  grub_free (transfer);
+
+  return err;
+}
+
+static grub_usb_err_t
+grub_usb_bulk_readwrite (grub_usb_device_t dev,
+			 int endpoint, grub_size_t size, char *data,
+			 grub_transfer_type_t type)
+{
+  int i;
+  grub_usb_transfer_t transfer;
+  int datablocks;
+  unsigned int max;
+  grub_usb_err_t err;
+  int toggle = dev->toggle[endpoint];
+
+  /* Use the maximum packet size given in the endpoint descriptor.  */
+  if (dev->initialized)
+    {
+      struct grub_usb_desc_endp *endpdesc;
+      endpdesc = grub_usb_get_endpdescriptor (dev, 0);
+
+      if (endpdesc)
+	max = endpdesc->maxpacket;
+      else
+	max = 64;
+    }
+  else
+    max = 64;
+
+  /* Create a transfer.  */
+  transfer = grub_malloc (sizeof (struct grub_usb_transfer));
+  if (! transfer)
+    return grub_errno;
+
+  datablocks = ((size + max - 1) / max);
+  transfer->transcnt = datablocks;
+  transfer->size = size - 1;
+  transfer->endpoint = endpoint;
+  transfer->devaddr = dev->addr;
+  transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK;
+  transfer->max = max;
+  transfer->dev = dev;
+
+  /* Allocate an array of transfer data structures.  */
+  transfer->transactions = grub_malloc (transfer->transcnt
+					* sizeof (struct grub_usb_transfer));
+  if (! transfer->transactions)
+    {
+      grub_free (transfer);
+      return grub_errno;
+    }
+
+  /* Set up all transfers.  */
+  for (i = 0; i < datablocks; i++)
+    {
+      grub_usb_transaction_t tr = &transfer->transactions[i];
+
+      tr->size = (size > max) ? max : size;
+      /* XXX: Use the right most bit as the data toggle.  Simple and
+	 effective.  */
+      tr->toggle = toggle;
+      toggle = toggle ? 0 : 1;
+      tr->pid = type;
+      tr->data = &data[i * max];
+      size -= tr->size;
+    }
+
+  err = dev->controller.dev->transfer (&dev->controller, transfer);
+  grub_dprintf ("usb", "toggle=%d\n", toggle);
+  dev->toggle[endpoint] = toggle;
+
+  grub_free (transfer->transactions);
+  grub_free (transfer);
+
+  return err;
+}
+
+grub_usb_err_t
+grub_usb_bulk_write (grub_usb_device_t dev,
+		     int endpoint, grub_size_t size, char *data)
+{
+  return grub_usb_bulk_readwrite (dev, endpoint, size, data,
+				  GRUB_USB_TRANSFER_TYPE_OUT);
+}
+
+grub_usb_err_t
+grub_usb_bulk_read (grub_usb_device_t dev,
+		    int endpoint, grub_size_t size, char *data)
+{
+  return grub_usb_bulk_readwrite (dev, endpoint, size, data,
+				  GRUB_USB_TRANSFER_TYPE_IN);
+}
diff --git a/commands/acpi.c b/commands/acpi.c
new file mode 100644
index 0000000..e7cb9e6
--- /dev/null
+++ b/commands/acpi.c
@@ -0,0 +1,774 @@
+/* acpi.c - modify acpi tables. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/extcmd.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/acpi.h>
+#include <grub/mm.h>
+#include <grub/machine/machine.h>
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/efi.h>
+#include <grub/efi/api.h>
+#endif
+
+static const struct grub_arg_option options[] = {
+  {"exclude", 'x', 0,
+   "Don't load host tables specified by comma-separated list",
+   0, ARG_TYPE_STRING},
+  {"load-only", 'n', 0,
+   "Load only tables specified by comma-separated list", 0, ARG_TYPE_STRING},
+  {"v1", '1', 0, "Expose v1 tables", 0, ARG_TYPE_NONE},
+  {"v2", '2', 0, "Expose v2 and v3 tables", 0, ARG_TYPE_NONE},
+  {"oemid", 'o', 0, "Set OEMID of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING},
+  {"oemtable", 't', 0,
+   "Set OEMTABLE ID of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING},
+  {"oemtablerev", 'r', 0,
+   "Set OEMTABLE revision of RSDP, XSDT and RSDT", 0, ARG_TYPE_INT},
+  {"oemtablecreator", 'c', 0,
+   "Set creator field of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING},
+  {"oemtablecreatorrev", 'd', 0,
+   "Set creator revision of RSDP, XSDT and RSDT", 0, ARG_TYPE_INT},
+  {"no-ebda", 'e', 0, "Don't update EBDA. May fix failures or hangs on some"
+   " BIOSes but makes it ineffective with OS not receiving RSDP from GRUB",
+   0, ARG_TYPE_NONE},
+  {0, 0, 0, 0, 0, 0}
+};
+
+/* Simple checksum by summing all bytes. Used by ACPI and SMBIOS. */
+grub_uint8_t
+grub_byte_checksum (void *base, grub_size_t size)
+{
+  grub_uint8_t *ptr;
+  grub_uint8_t ret = 0;
+  for (ptr = (grub_uint8_t *) base; ptr < ((grub_uint8_t *) base) + size;
+       ptr++)
+    ret += *ptr;
+  return ret;
+}
+
+/* rev1 is 1 if ACPIv1 is to be generated, 0 otherwise.
+   rev2 contains the revision of ACPIv2+ to generate or 0 if none. */
+static int rev1, rev2;
+/* OEMID of RSDP, RSDT and XSDT. */
+static char root_oemid[6];
+/* OEMTABLE of the same tables. */
+static char root_oemtable[8];
+/* OEMREVISION of the same tables. */
+static grub_uint32_t root_oemrev;
+/* CreatorID of the same tables. */
+static char root_creator_id[4];
+/* CreatorRevision of the same tables. */
+static grub_uint32_t root_creator_rev;
+static struct grub_acpi_rsdp_v10 *rsdpv1_new = 0;
+static struct grub_acpi_rsdp_v20 *rsdpv2_new = 0;
+static char *playground = 0, *playground_ptr = 0;
+static int playground_size = 0;
+
+/* Linked list of ACPI tables. */
+struct efiemu_acpi_table
+{
+  void *addr;
+  grub_size_t size;
+  struct efiemu_acpi_table *next;
+};
+static struct efiemu_acpi_table *acpi_tables = 0;
+
+/* DSDT isn't in RSDT. So treat it specially. */
+static void *table_dsdt = 0;
+/* Pointer to recreated RSDT. */
+static void *rsdt_addr = 0;
+
+/* Allocation handles for different tables. */
+static grub_size_t dsdt_size = 0;
+
+/* Address of original FACS. */
+static grub_uint32_t facs_addr = 0;
+
+struct grub_acpi_rsdp_v20 *
+grub_acpi_get_rsdpv2 (void)
+{
+  if (rsdpv2_new)
+    return rsdpv2_new;
+  if (rsdpv1_new)
+    return 0;
+  return grub_machine_acpi_get_rsdpv2 ();
+}
+
+struct grub_acpi_rsdp_v10 *
+grub_acpi_get_rsdpv1 (void)
+{
+  if (rsdpv1_new)
+    return rsdpv1_new;
+  if (rsdpv2_new)
+    return 0;
+  return grub_machine_acpi_get_rsdpv1 ();
+}
+
+static inline int
+iszero (grub_uint8_t *reg, int size)
+{
+  int i;
+  for (i = 0; i < size; i++)
+    if (reg[i])
+      return 0;
+  return 1;
+}
+
+grub_err_t
+grub_acpi_create_ebda (void)
+{
+  int ebda_kb_len;
+  int ebda_len;
+  int mmapregion = 0;
+  grub_uint8_t *ebda, *v1inebda = 0, *v2inebda = 0;
+  grub_uint64_t highestlow = 0;
+  grub_uint8_t *targetebda, *target;
+  struct grub_acpi_rsdp_v10 *v1;
+  struct grub_acpi_rsdp_v20 *v2;
+  auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
+				       grub_uint32_t);
+  int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t size,
+				  grub_uint32_t type)
+  {
+    grub_uint64_t end = start + size;
+    if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+      return 0;
+    if (end > 0x100000)
+      end = 0x100000;
+    if (end > start + ebda_len
+	&& highestlow < ((end - ebda_len) & (~0xf)) )
+      highestlow = (end - ebda_len) & (~0xf);
+    return 0;
+  }
+
+  ebda = (grub_uint8_t *) UINT_TO_PTR ((*((grub_uint16_t *)0x40e)) << 4);
+  ebda_kb_len = *(grub_uint16_t *) ebda;
+  if (! ebda || ebda_kb_len > 16)
+    ebda_kb_len = 0;
+  ebda_len = (ebda_kb_len + 1) << 10;
+
+  /* FIXME: use low-memory mm allocation once it's available. */
+  grub_mmap_iterate (find_hook);
+  targetebda = (grub_uint8_t *) UINT_TO_PTR (highestlow);
+  grub_dprintf ("acpi", "creating ebda @%llx\n",
+		(unsigned long long) highestlow);
+  if (! highestlow)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		       "couldn't find space for the new EBDA");
+
+  mmapregion = grub_mmap_register (PTR_TO_UINT64 (targetebda), ebda_len,
+				   GRUB_MACHINE_MEMORY_RESERVED);
+  if (! mmapregion)
+    return grub_errno;
+
+  /* XXX: EBDA is unstandardized, so this implementation is heuristical. */
+  if (ebda_kb_len)
+    grub_memcpy (targetebda, ebda, 0x400);
+  else
+    grub_memset (targetebda, 0, 0x400);
+  *((grub_uint16_t *) targetebda) = ebda_kb_len + 1;
+  target = targetebda;
+
+  v1 = grub_acpi_get_rsdpv1 ();
+  v2 = grub_acpi_get_rsdpv2 ();
+  if (v2 && v2->length > 40)
+    v2 = 0;
+
+  /* First try to replace already existing rsdp. */
+  if (v2)
+    {
+      grub_dprintf ("acpi", "Scanning EBDA for old rsdpv2\n");
+      for (; target < targetebda + 0x400 - v2->length; target += 0x10)
+	if (grub_memcmp (target, "RSD PTR ", 8) == 0
+	    && grub_byte_checksum (target,
+				   sizeof (struct grub_acpi_rsdp_v10)) == 0
+	    && ((struct grub_acpi_rsdp_v10 *) target)->revision != 0
+	    && ((struct grub_acpi_rsdp_v20 *) target)->length <= v2->length)
+	  {
+	    grub_memcpy (target, v2, v2->length);
+	    grub_dprintf ("acpi", "Copying rsdpv2 to %p\n", target);
+	    v2inebda = target;
+	    target += v2->length;
+	    target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1);
+	    v2 = 0;
+	    break;
+	  }
+    }
+
+  if (v1)
+    {
+      grub_dprintf ("acpi", "Scanning EBDA for old rsdpv1\n");
+      for (; target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
+	   target += 0x10)
+	if (grub_memcmp (target, "RSD PTR ", 8) == 0
+	    && grub_byte_checksum (target,
+				   sizeof (struct grub_acpi_rsdp_v10)) == 0)
+	  {
+	    grub_memcpy (target, v1, sizeof (struct grub_acpi_rsdp_v10));
+	    grub_dprintf ("acpi", "Copying rsdpv2 to %p\n", target);
+	    v1inebda = target;
+	    target += sizeof (struct grub_acpi_rsdp_v10);
+	    target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1);
+	    v1 = 0;
+	    break;
+	  }
+    }
+
+  target = targetebda + 0x100;
+
+  /* Try contiguous zeros. */
+  if (v2)
+    {
+      grub_dprintf ("acpi", "Scanning EBDA for block of zeros\n");
+      for (; target < targetebda + 0x400 - v2->length; target += 0x10)
+	if (iszero (target, v2->length))
+	  {
+	    grub_dprintf ("acpi", "Copying rsdpv2 to %p\n", target);
+	    grub_memcpy (target, v2, v2->length);
+	    v2inebda = target;
+	    target += v2->length;
+	    target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1);
+	    v2 = 0;
+	    break;
+	  }
+    }
+
+  if (v1)
+    {
+      grub_dprintf ("acpi", "Scanning EBDA for block of zeros\n");
+      for (; target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
+	   target += 0x10)
+	if (iszero (target, sizeof (struct grub_acpi_rsdp_v10)))
+	  {
+	    grub_dprintf ("acpi", "Copying rsdpv1 to %p\n", target);
+	    grub_memcpy (target, v1, sizeof (struct grub_acpi_rsdp_v10));
+	    v1inebda = target;
+	    target += sizeof (struct grub_acpi_rsdp_v10);
+	    target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1);
+	    v1 = 0;
+	    break;
+	  }
+    }
+
+  if (v1 || v2)
+    {
+      grub_mmap_unregister (mmapregion);
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			 "Couldn't find suitable spot in EBDA");
+    }
+
+  /* Remove any other RSDT. */
+  for (target = targetebda;
+       target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
+       target += 0x10)
+    if (grub_memcmp (target, "RSD PTR ", 8) == 0
+	&& grub_byte_checksum (target,
+			       sizeof (struct grub_acpi_rsdp_v10)) == 0
+	&& target != v1inebda && target != v2inebda)
+      *target = 0;
+
+  grub_dprintf ("acpi", "Switching EBDA\n");
+  (*((grub_uint16_t *) 0x40e)) = ((long)targetebda) >> 4;
+  grub_dprintf ("acpi", "EBDA switched\n");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Create tables common to ACPIv1 and ACPIv2+ */
+static void
+setup_common_tables (void)
+{
+  struct efiemu_acpi_table *cur;
+  struct grub_acpi_table_header *rsdt;
+  grub_uint32_t *rsdt_entry;
+  int numoftables;
+
+  /* Treat DSDT. */
+  grub_memcpy (playground_ptr, table_dsdt, dsdt_size);
+  grub_free (table_dsdt);
+  table_dsdt = playground_ptr;
+  playground_ptr += dsdt_size;
+
+  /* Treat other tables. */
+  for (cur = acpi_tables; cur; cur = cur->next)
+    {
+      struct grub_acpi_fadt *fadt;
+
+      grub_memcpy (playground_ptr, cur->addr, cur->size);
+      grub_free (cur->addr);
+      cur->addr = playground_ptr;
+      playground_ptr += cur->size;
+
+      /* If it's FADT correct DSDT and FACS addresses. */
+      fadt = (struct grub_acpi_fadt *) cur->addr;
+      if (grub_memcmp (fadt->hdr.signature, "FACP", 4) == 0)
+	{
+	  fadt->dsdt_addr = PTR_TO_UINT32 (table_dsdt);
+	  fadt->facs_addr = facs_addr;
+
+	  /* Does a revision 2 exist at all? */
+	  if (fadt->hdr.revision >= 3)
+	    {
+	      fadt->dsdt_xaddr = PTR_TO_UINT64 (table_dsdt);
+	      fadt->facs_xaddr = facs_addr;
+	    }
+
+	  /* Recompute checksum. */
+	  fadt->hdr.checksum = 0;
+	  fadt->hdr.checksum = 1 + ~grub_byte_checksum (fadt, fadt->hdr.length);
+	}
+    }
+
+  /* Fill RSDT entries. */
+  numoftables = 0;
+  for (cur = acpi_tables; cur; cur = cur->next)
+    numoftables++;
+
+  rsdt_addr = rsdt = (struct grub_acpi_table_header *) playground_ptr;
+  playground_ptr += sizeof (struct grub_acpi_table_header) + 4 * numoftables;
+
+  rsdt_entry = (grub_uint32_t *)(rsdt + 1);
+
+  /* Fill RSDT header. */
+  grub_memcpy (&(rsdt->signature), "RSDT", 4);
+  rsdt->length = sizeof (struct grub_acpi_table_header) + 4 * numoftables;
+  rsdt->revision = 1;
+  grub_memcpy (&(rsdt->oemid), root_oemid, 6);
+  grub_memcpy (&(rsdt->oemtable), root_oemtable, 4);
+  rsdt->oemrev = root_oemrev;
+  grub_memcpy (&(rsdt->creator_id), root_creator_id, 6);
+  rsdt->creator_rev = root_creator_rev;
+
+  for (cur = acpi_tables; cur; cur = cur->next)
+    *(rsdt_entry++) = PTR_TO_UINT32 (cur->addr);
+
+  /* Recompute checksum. */
+  rsdt->checksum = 0;
+  rsdt->checksum = 1 + ~grub_byte_checksum (rsdt, rsdt->length);
+}
+
+/* Regenerate ACPIv1 RSDP */
+static void
+setv1table (void)
+{
+  /* Create RSDP. */
+  rsdpv1_new = (struct grub_acpi_rsdp_v10 *) playground_ptr;
+  playground_ptr += sizeof (struct grub_acpi_rsdp_v10);
+  grub_memcpy (&(rsdpv1_new->signature), "RSD PTR ", 8);
+  grub_memcpy (&(rsdpv1_new->oemid), root_oemid, sizeof  (rsdpv1_new->oemid));
+  rsdpv1_new->revision = 0;
+  rsdpv1_new->rsdt_addr = PTR_TO_UINT32 (rsdt_addr);
+  rsdpv1_new->checksum = 0;
+  rsdpv1_new->checksum = 1 + ~grub_byte_checksum (rsdpv1_new,
+						  sizeof (*rsdpv1_new));
+  grub_dprintf ("acpi", "Generated ACPIv1 tables\n");
+}
+
+static void
+setv2table (void)
+{
+  struct grub_acpi_table_header *xsdt;
+  struct efiemu_acpi_table *cur;
+  grub_uint64_t *xsdt_entry;
+  int numoftables;
+
+  numoftables = 0;
+  for (cur = acpi_tables; cur; cur = cur->next)
+    numoftables++;
+
+  /* Create XSDT. */
+  xsdt = (struct grub_acpi_table_header *) playground_ptr;
+  playground_ptr += sizeof (struct grub_acpi_table_header) + 8 * numoftables;
+
+  xsdt_entry = (grub_uint64_t *)(xsdt + 1);
+  for (cur = acpi_tables; cur; cur = cur->next)
+    *(xsdt_entry++) = PTR_TO_UINT64 (cur->addr);
+  grub_memcpy (&(xsdt->signature), "XSDT", 4);
+  xsdt->length = sizeof (struct grub_acpi_table_header) + 8 * numoftables;
+  xsdt->revision = 1;
+  grub_memcpy (&(xsdt->oemid), root_oemid, sizeof (xsdt->oemid));
+  grub_memcpy (&(xsdt->oemtable), root_oemtable, sizeof (xsdt->oemtable));
+  xsdt->oemrev = root_oemrev;
+  grub_memcpy (&(xsdt->creator_id), root_creator_id, sizeof (xsdt->creator_id));
+  xsdt->creator_rev = root_creator_rev;
+  xsdt->checksum = 0;
+  xsdt->checksum = 1 + ~grub_byte_checksum (xsdt, xsdt->length);
+
+  /* Create RSDPv2. */
+  rsdpv2_new = (struct grub_acpi_rsdp_v20 *) playground_ptr;
+  playground_ptr += sizeof (struct grub_acpi_rsdp_v20);
+  grub_memcpy (&(rsdpv2_new->rsdpv1.signature), "RSD PTR ",
+	       sizeof (rsdpv2_new->rsdpv1.signature));
+  grub_memcpy (&(rsdpv2_new->rsdpv1.oemid), root_oemid,
+	       sizeof (rsdpv2_new->rsdpv1.oemid));
+  rsdpv2_new->rsdpv1.revision = rev2;
+  rsdpv2_new->rsdpv1.rsdt_addr = PTR_TO_UINT32 (rsdt_addr);
+  rsdpv2_new->rsdpv1.checksum = 0;
+  rsdpv2_new->rsdpv1.checksum = 1 + ~grub_byte_checksum
+    (&(rsdpv2_new->rsdpv1), sizeof (rsdpv2_new->rsdpv1));
+  rsdpv2_new->length = sizeof (*rsdpv2_new);
+  rsdpv2_new->xsdt_addr = PTR_TO_UINT64 (xsdt);
+  rsdpv2_new->checksum = 0;
+  rsdpv2_new->checksum = 1 + ~grub_byte_checksum (rsdpv2_new,
+						  rsdpv2_new->length);
+  grub_dprintf ("acpi", "Generated ACPIv2 tables\n");
+}
+
+static void
+free_tables (void)
+{
+  struct efiemu_acpi_table *cur, *t;
+  if (table_dsdt)
+    grub_free (table_dsdt);
+  for (cur = acpi_tables; cur;)
+    {
+      t = cur;
+      grub_free (cur->addr);
+      cur = cur->next;
+      grub_free (t);
+    }
+  acpi_tables = 0;
+  table_dsdt = 0;
+}
+
+static grub_err_t
+grub_cmd_acpi (struct grub_extcmd *cmd,
+		      int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  struct grub_acpi_rsdp_v10 *rsdp;
+  struct efiemu_acpi_table *cur, *t;
+  grub_err_t err;
+  int i, mmapregion;
+  int numoftables;
+
+  /* Default values if no RSDP is found. */
+  rev1 = 1;
+  rev2 = 3;
+
+  facs_addr = 0;
+  playground = playground_ptr = 0;
+  playground_size = 0;
+
+  rsdp = (struct grub_acpi_rsdp_v10 *) grub_machine_acpi_get_rsdpv2 ();
+
+  if (! rsdp)
+    rsdp = grub_machine_acpi_get_rsdpv1 ();
+
+  if (rsdp)
+    {
+      grub_uint32_t *entry_ptr;
+      char *exclude = 0;
+      char *load_only = 0;
+      char *ptr;
+      /* RSDT consists of header and an array of 32-bit pointers. */
+      struct grub_acpi_table_header *rsdt;
+
+      exclude = state[0].set ? grub_strdup (state[0].arg) : 0;
+      if (exclude)
+	{
+	  for (ptr = exclude; *ptr; ptr++)
+	    *ptr = grub_tolower (*ptr);
+	}
+
+      load_only = state[1].set ? grub_strdup (state[1].arg) : 0;
+      if (load_only)
+	{
+	  for (ptr = load_only; *ptr; ptr++)
+	    *ptr = grub_tolower (*ptr);
+	}
+
+      /* Set revision variables to replicate the same version as host. */
+      rev1 = ! rsdp->revision;
+      rev2 = rsdp->revision;
+      rsdt = (struct grub_acpi_table_header *) UINT_TO_PTR (rsdp->rsdt_addr);
+      /* Load host tables. */
+      for (entry_ptr = (grub_uint32_t *) (rsdt + 1);
+	   entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt)
+					  + rsdt->length);
+	   entry_ptr++)
+	{
+	  char signature[5];
+	  struct efiemu_acpi_table *table;
+	  struct grub_acpi_table_header *curtable
+	    = (struct grub_acpi_table_header *) UINT_TO_PTR (*entry_ptr);
+	  signature[4] = 0;
+	  for (i = 0; i < 4;i++)
+	    signature[i] = grub_tolower (curtable->signature[i]);
+
+	  /* If it's FADT it contains addresses of DSDT and FACS. */
+	  if (grub_strcmp (signature, "facp") == 0)
+	    {
+	      struct grub_acpi_table_header *dsdt;
+	      struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *) curtable;
+
+	      /* Set root header variables to the same values
+		 as FACP by default. */
+	      grub_memcpy (&root_oemid, &(fadt->hdr.oemid),
+			   sizeof (root_oemid));
+	      grub_memcpy (&root_oemtable, &(fadt->hdr.oemtable),
+			   sizeof (root_oemtable));
+	      root_oemrev = fadt->hdr.oemrev;
+	      grub_memcpy (&root_creator_id, &(fadt->hdr.creator_id),
+			   sizeof (root_creator_id));
+	      root_creator_rev = fadt->hdr.creator_rev;
+
+	      /* Load DSDT if not excluded. */
+	      dsdt = (struct grub_acpi_table_header *)
+		UINT_TO_PTR (fadt->dsdt_addr);
+	      if (dsdt && (! exclude || ! grub_strword (exclude, "dsdt"))
+		  && (! load_only || grub_strword (load_only, "dsdt"))
+		  && dsdt->length >= sizeof (*dsdt))
+		{
+		  dsdt_size = dsdt->length;
+		  table_dsdt = grub_malloc (dsdt->length);
+		  if (! table_dsdt)
+		    {
+		      free_tables ();
+		      grub_free (exclude);
+		      grub_free (load_only);
+		      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+					 "Could allocate table");
+		    }
+		  grub_memcpy (table_dsdt, dsdt, dsdt->length);
+		}
+
+	      /* Save FACS address. FACS shouldn't be overridden. */
+	      facs_addr = fadt->facs_addr;
+	    }
+
+	  /* Skip excluded tables. */
+	  if (exclude && grub_strword (exclude, signature))
+	    continue;
+	  if (load_only && ! grub_strword (load_only, signature))
+	    continue;
+
+	  /* Sanity check. */
+	  if (curtable->length < sizeof (*curtable))
+	    continue;
+
+	  table = (struct efiemu_acpi_table *) grub_malloc
+	    (sizeof (struct efiemu_acpi_table));
+	  if (! table)
+	    {
+	      free_tables ();
+	      grub_free (exclude);
+	      grub_free (load_only);
+	      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+				 "Could allocate table structure");
+	    }
+	  table->size = curtable->length;
+	  table->addr = grub_malloc (table->size);
+	  playground_size += table->size;
+	  if (! table->addr)
+	    {
+	      free_tables ();
+	      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+				 "Could allocate table");
+	    }
+	  table->next = acpi_tables;
+	  acpi_tables = table;
+	  grub_memcpy (table->addr, curtable, table->size);
+	}
+      grub_free (exclude);
+      grub_free (load_only);
+    }
+
+  /* Does user specify versions to generate? */
+  if (state[2].set || state[3].set)
+    {
+      rev1 = state[2].set;
+      if (state[3].set)
+	rev2 = rev2 ? : 2;
+      else
+	rev2 = 0;
+    }
+
+  /* Does user override root header information? */
+  if (state[4].set)
+    grub_strncpy (root_oemid, state[4].arg, sizeof (root_oemid));
+  if (state[5].set)
+    grub_strncpy (root_oemtable, state[5].arg, sizeof (root_oemtable));
+  if (state[6].set)
+    root_oemrev = grub_strtoul (state[6].arg, 0, 0);
+  if (state[7].set)
+    grub_strncpy (root_creator_id, state[7].arg, sizeof (root_creator_id));
+  if (state[8].set)
+    root_creator_rev = grub_strtoul (state[8].arg, 0, 0);
+
+  /* Load user tables */
+  for (i = 0; i < argc; i++)
+    {
+      grub_file_t file;
+      grub_size_t size;
+      char *buf;
+
+      file = grub_gzfile_open (args[i], 1);
+      if (! file)
+	{
+	  free_tables ();
+	  return grub_error (GRUB_ERR_BAD_OS, "couldn't open file %s", args[i]);
+	}
+
+      size = grub_file_size (file);
+      if (size < sizeof (struct grub_acpi_table_header))
+	{
+	  grub_file_close (file);
+	  free_tables ();
+	  return grub_error (GRUB_ERR_BAD_OS, "file %s is too small", args[i]);
+	}
+
+      buf = (char *) grub_malloc (size);
+      if (! buf)
+	{
+	  grub_file_close (file);
+	  free_tables ();
+	  return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			     "couldn't read file %s", args[i]);
+	}
+
+      if (grub_file_read (file, buf, size) != (int) size)
+	{
+	  grub_file_close (file);
+	  free_tables ();
+	  return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[i]);
+	}
+      grub_file_close (file);
+
+      if (grub_memcmp (((struct grub_acpi_table_header *) buf)->signature,
+		       "DSDT", 4) == 0)
+	{
+	  grub_free (table_dsdt);
+	  table_dsdt = buf;
+	  dsdt_size = size;
+	}
+      else
+	{
+	  struct efiemu_acpi_table *table;
+	  table = (struct efiemu_acpi_table *) grub_malloc
+	    (sizeof (struct efiemu_acpi_table));
+	  if (! table)
+	    {
+	      free_tables ();
+	      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+				 "Could allocate table structure");
+	    }
+
+	  table->size = size;
+	  table->addr = buf;
+	  playground_size += table->size;
+
+	  table->next = acpi_tables;
+	  acpi_tables = table;
+	}
+    }
+
+  numoftables = 0;
+  for (cur = acpi_tables; cur; cur = cur->next)
+    numoftables++;
+
+  /* DSDT. */
+  playground_size += dsdt_size;
+  /* RSDT. */
+  playground_size += sizeof (struct grub_acpi_table_header) + 4 * numoftables;
+  /* RSDPv1. */
+  playground_size += sizeof (struct grub_acpi_rsdp_v10);
+  /* XSDT. */
+  playground_size += sizeof (struct grub_acpi_table_header) + 8 * numoftables;
+  /* RSDPv2. */
+  playground_size += sizeof (struct grub_acpi_rsdp_v20);
+
+  playground = playground_ptr
+    = grub_mmap_malign_and_register (1, playground_size, &mmapregion,
+				     GRUB_MACHINE_MEMORY_ACPI, 0);
+
+  if (! playground)
+    {
+      free_tables ();
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			 "Couldn't allocate space for ACPI tables");
+    }
+
+  setup_common_tables ();
+
+  /* Request space for RSDPv1. */
+  if (rev1)
+    setv1table ();
+
+  /* Request space for RSDPv2+ and XSDT. */
+  if (rev2)
+    setv2table ();
+
+  for (cur = acpi_tables; cur;)
+    {
+      t = cur;
+      cur = cur->next;
+      grub_free (t);
+    }
+  acpi_tables = 0;
+
+  if (! state[9].set && (err = grub_acpi_create_ebda ()))
+    {
+      rsdpv1_new = 0;
+      rsdpv2_new = 0;
+      grub_mmap_free_and_unregister (mmapregion);
+      return err;
+    }
+
+#ifdef GRUB_MACHINE_EFI
+  {
+    struct grub_efi_guid acpi = GRUB_EFI_ACPI_TABLE_GUID;
+    struct grub_efi_guid acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
+
+    grub_efi_system_table->boot_services->install_configuration_table
+      (&acpi20, grub_acpi_get_rsdpv2 ());
+    grub_efi_system_table->boot_services->install_configuration_table
+      (&acpi, grub_acpi_get_rsdpv1 ());
+  }
+#endif
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(acpi)
+{
+  cmd = grub_register_extcmd ("acpi", grub_cmd_acpi,
+			      GRUB_COMMAND_FLAG_BOTH,
+			      "acpi [-1|-2] [--exclude=table1,table2|"
+			      "--load-only=table1,table2] filename1 "
+			      " [filename2] [...]",
+			      "Load host acpi tables and tables "
+			      "specified by arguments",
+			      options);
+}
+
+GRUB_MOD_FINI(acpi)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/blocklist.c b/commands/blocklist.c
new file mode 100644
index 0000000..b457b7c
--- /dev/null
+++ b/commands/blocklist.c
@@ -0,0 +1,119 @@
+/* blocklist.c - print the block list of a file */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/command.h>
+
+static grub_err_t
+grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
+		    int argc, char **args)
+{
+  grub_file_t file;
+  char buf[GRUB_DISK_SECTOR_SIZE];
+  unsigned long start_sector = 0;
+  unsigned num_sectors = 0;
+  int num_entries = 0;
+  grub_disk_addr_t part_start = 0;
+  auto void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset,
+			    unsigned length);
+  auto void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
+			     unsigned offset, unsigned length);
+
+  void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset,
+		       unsigned length)
+    {
+      if (num_sectors > 0)
+	{
+	  if (start_sector + num_sectors == sector
+	      && offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
+	    {
+	      num_sectors++;
+	      return;
+	    }
+
+	  print_blocklist (start_sector, num_sectors, 0, 0);
+	  num_sectors = 0;
+	}
+
+      if (offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
+	{
+	  start_sector = sector;
+	  num_sectors++;
+	}
+      else
+	print_blocklist (sector, 0, offset, length);
+    }
+
+  void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
+			unsigned offset, unsigned length)
+    {
+      if (num_entries++)
+	grub_printf (",");
+
+      grub_printf ("%llu", (unsigned long long) (sector - part_start));
+      if (num > 0)
+	grub_printf ("+%u", num);
+      if (offset != 0 || length != 0)
+	grub_printf ("[%u-%u]", offset, offset + length);
+    }
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+
+  file = grub_file_open (args[0]);
+  if (! file)
+    return grub_errno;
+
+  if (! file->device->disk)
+    return grub_error (GRUB_ERR_BAD_DEVICE,
+		       "this command is available only for disk devices.");
+
+  if (file->device->disk->partition)
+    part_start = grub_partition_get_start (file->device->disk->partition);
+
+  file->read_hook = read_blocklist;
+
+  while (grub_file_read (file, buf, sizeof (buf)) > 0)
+    ;
+
+  if (num_sectors > 0)
+    print_blocklist (start_sector, num_sectors, 0, 0);
+
+  grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(blocklist)
+{
+  cmd = grub_register_command ("blocklist", grub_cmd_blocklist,
+			       "blocklist FILE", "Print a block list.");
+}
+
+GRUB_MOD_FINI(blocklist)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/boot.c b/commands/boot.c
new file mode 100644
index 0000000..e77b5ce
--- /dev/null
+++ b/commands/boot.c
@@ -0,0 +1,195 @@
+/* boot.c - command to boot an operating system */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/loader.h>
+#include <grub/kernel.h>
+#include <grub/mm.h>
+
+static grub_err_t (*grub_loader_boot_func) (void);
+static grub_err_t (*grub_loader_unload_func) (void);
+static int grub_loader_noreturn;
+
+struct grub_preboot_t
+{
+  grub_err_t (*preboot_func) (int);
+  grub_err_t (*preboot_rest_func) (void);
+  grub_loader_preboot_hook_prio_t prio;
+  struct grub_preboot_t *next;
+  struct grub_preboot_t *prev;
+};
+
+static int grub_loader_loaded;
+static struct grub_preboot_t *preboots_head = 0,
+  *preboots_tail = 0;
+
+int
+grub_loader_is_loaded (void)
+{
+  return grub_loader_loaded;
+}
+
+/* Register a preboot hook. */
+void *
+grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noreturn),
+				   grub_err_t (*preboot_rest_func) (void),
+				   grub_loader_preboot_hook_prio_t prio)
+{
+  struct grub_preboot_t *cur, *new_preboot;
+
+  if (! preboot_func && ! preboot_rest_func)
+    return 0;
+
+  new_preboot = (struct grub_preboot_t *)
+    grub_malloc (sizeof (struct grub_preboot_t));
+  if (! new_preboot)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "hook not added");
+      return 0;
+    }
+
+  new_preboot->preboot_func = preboot_func;
+  new_preboot->preboot_rest_func = preboot_rest_func;
+  new_preboot->prio = prio;
+
+  for (cur = preboots_head; cur && cur->prio > prio; cur = cur->next);
+
+  if (cur)
+    {
+      new_preboot->next = cur;
+      new_preboot->prev = cur->prev;
+      cur->prev = new_preboot;
+    }
+  else
+    {
+      new_preboot->next = 0;
+      new_preboot->prev = preboots_tail;
+      preboots_tail = new_preboot;
+    }
+  if (new_preboot->prev)
+    new_preboot->prev->next = new_preboot;
+  else
+    preboots_head = new_preboot;
+
+  return new_preboot;
+}
+
+void
+grub_loader_unregister_preboot_hook (void *hnd)
+{
+  struct grub_preboot_t *preb = hnd;
+
+  if (preb->next)
+    preb->next->prev = preb->prev;
+  else
+    preboots_tail = preb->prev;
+  if (preb->prev)
+    preb->prev->next = preb->next;
+  else
+    preboots_head = preb->next;
+
+  grub_free (preb);
+}
+
+void
+grub_loader_set (grub_err_t (*boot) (void),
+		 grub_err_t (*unload) (void),
+		 int noreturn)
+{
+  if (grub_loader_loaded && grub_loader_unload_func)
+    grub_loader_unload_func ();
+
+  grub_loader_boot_func = boot;
+  grub_loader_unload_func = unload;
+  grub_loader_noreturn = noreturn;
+
+  grub_loader_loaded = 1;
+}
+
+void
+grub_loader_unset(void)
+{
+  if (grub_loader_loaded && grub_loader_unload_func)
+    grub_loader_unload_func ();
+
+  grub_loader_boot_func = 0;
+  grub_loader_unload_func = 0;
+
+  grub_loader_loaded = 0;
+}
+
+grub_err_t
+grub_loader_boot (void)
+{
+  grub_err_t err = GRUB_ERR_NONE;
+  struct grub_preboot_t *cur;
+
+  if (! grub_loader_loaded)
+    return grub_error (GRUB_ERR_NO_KERNEL, "no loaded kernel");
+
+  if (grub_loader_noreturn)
+    grub_machine_fini ();
+
+  for (cur = preboots_head; cur; cur = cur->next)
+    {
+      err = cur->preboot_func (grub_loader_noreturn);
+      if (err)
+	{
+	  for (cur = cur->prev; cur; cur = cur->prev)
+	    cur->preboot_rest_func ();
+	  return err;
+	}
+    }
+  err = (grub_loader_boot_func) ();
+
+  for (cur = preboots_tail; cur; cur = cur->prev)
+    if (! err)
+      err = cur->preboot_rest_func ();
+    else
+      cur->preboot_rest_func ();
+
+  return err;
+}
+
+/* boot */
+static grub_err_t
+grub_cmd_boot (struct grub_command *cmd __attribute__ ((unused)),
+		    int argc __attribute__ ((unused)),
+		    char *argv[] __attribute__ ((unused)))
+{
+  return grub_loader_boot ();
+}
+
+
+
+static grub_command_t cmd_boot;
+
+GRUB_MOD_INIT(boot)
+{
+  cmd_boot =
+    grub_register_command ("boot", grub_cmd_boot,
+			   0, "boot an operating system");
+}
+
+GRUB_MOD_FINI(boot)
+{
+  grub_unregister_command (cmd_boot);
+}
diff --git a/commands/cat.c b/commands/cat.c
new file mode 100644
index 0000000..1a23743
--- /dev/null
+++ b/commands/cat.c
@@ -0,0 +1,87 @@
+/* cat.c - command to show the contents of a file  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/command.h>
+
+static grub_err_t
+grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)),
+	      int argc, char **args)
+
+{
+  grub_file_t file;
+  char buf[GRUB_DISK_SECTOR_SIZE];
+  grub_ssize_t size;
+  int key = 0;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  file = grub_gzfile_open (args[0], 1);
+  if (! file)
+    return 0;
+
+  while ((size = grub_file_read (file, buf, sizeof (buf))) > 0
+	 && key != GRUB_TERM_ESC)
+    {
+      int i;
+
+      for (i = 0; i < size; i++)
+	{
+	  unsigned char c = buf[i];
+
+	  if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
+	    grub_putchar (c);
+	  else
+	    {
+	      grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
+	      grub_printf ("<%x>", (int) c);
+	      grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
+	    }
+	}
+
+      while (grub_checkkey () >= 0 &&
+	     (key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != GRUB_TERM_ESC)
+	;
+    }
+
+  grub_putchar ('\n');
+  grub_refresh ();
+  grub_file_close (file);
+
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(cat)
+{
+  cmd = grub_register_command_p1 ("cat", grub_cmd_cat,
+				  "cat FILE", "Show the contents of a file.");
+}
+
+GRUB_MOD_FINI(cat)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/cmp.c b/commands/cmp.c
new file mode 100644
index 0000000..1258b1d
--- /dev/null
+++ b/commands/cmp.c
@@ -0,0 +1,118 @@
+/* cmd.c - command to cmp an operating system */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/gzio.h>
+#include <grub/command.h>
+
+#define BUFFER_SIZE 512
+
+static grub_err_t
+grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)),
+	      int argc, char **args)
+{
+  grub_ssize_t rd1, rd2;
+  grub_off_t pos;
+  grub_file_t file1 = 0;
+  grub_file_t file2 = 0;
+  char *buf1 = 0;
+  char *buf2 = 0;
+
+  if (argc != 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required");
+
+  grub_printf ("Compare `%s' and `%s':\n", args[0],
+	       args[1]);
+
+  file1 = grub_gzfile_open (args[0], 1);
+  file2 = grub_gzfile_open (args[1], 1);
+  if (! file1 || ! file2)
+    goto cleanup;
+
+  if (grub_file_size (file1) != grub_file_size (file2))
+    grub_printf ("Differ in size: %llu [%s], %llu [%s]\n",
+		 (unsigned long long) grub_file_size (file1), args[0],
+		 (unsigned long long) grub_file_size (file2), args[1]);
+  else
+    {
+      pos = 0;
+
+      buf1 = grub_malloc (BUFFER_SIZE);
+      buf2 = grub_malloc (BUFFER_SIZE);
+
+      if (! buf1 || ! buf2)
+        goto cleanup;
+
+      do
+	{
+	  int i;
+
+	  rd1 = grub_file_read (file1, buf1, BUFFER_SIZE);
+	  rd2 = grub_file_read (file2, buf2, BUFFER_SIZE);
+
+	  if (rd1 != rd2)
+	    goto cleanup;
+
+	  for (i = 0; i < rd2; i++)
+	    {
+	      if (buf1[i] != buf2[i])
+		{
+		  grub_printf ("Differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n",
+			       (unsigned long long) (i + pos), buf1[i], args[0],
+			       buf2[i], args[1]);
+		  goto cleanup;
+		}
+	    }
+	  pos += BUFFER_SIZE;
+
+	}
+      while (rd2);
+
+      grub_printf ("The files are identical.\n");
+    }
+
+cleanup:
+
+  if (buf1)
+    grub_free (buf1);
+  if (buf2)
+    grub_free (buf2);
+  if (file1)
+    grub_file_close (file1);
+  if (file2)
+    grub_file_close (file2);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(cmp)
+{
+  cmd = grub_register_command ("cmp", grub_cmd_cmp,
+			       "cmp FILE1 FILE2", "Compare two files.");
+}
+
+GRUB_MOD_FINI(cmp)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/configfile.c b/commands/configfile.c
new file mode 100644
index 0000000..8529322
--- /dev/null
+++ b/commands/configfile.c
@@ -0,0 +1,74 @@
+/* configfile.c - command to manually load config file  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/term.h>
+#include <grub/env.h>
+#include <grub/normal.h>
+#include <grub/command.h>
+
+static grub_err_t
+grub_cmd_source (grub_command_t cmd, int argc, char **args)
+{
+  int new_env;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  new_env = (cmd->name[0] == 'c');
+
+  if (new_env)
+    {
+      grub_cls ();
+      grub_env_context_open (1);
+    }
+
+  grub_normal_execute (args[0], 1, ! new_env);
+
+  if (new_env)
+    grub_env_context_close ();
+
+  return 0;
+}
+
+static grub_command_t cmd_configfile, cmd_source, cmd_dot;
+
+GRUB_MOD_INIT(configfile)
+{
+  cmd_configfile =
+    grub_register_command ("configfile", grub_cmd_source,
+			   "configfile FILE", "Load another config file.");
+  cmd_source =
+    grub_register_command ("source", grub_cmd_source,
+			   "source FILE",
+			   "Load another config file without changing context."
+			   );
+  cmd_dot =
+    grub_register_command (".", grub_cmd_source,
+			   ". FILE",
+			   "Load another config file without changing context."
+			   );
+}
+
+GRUB_MOD_FINI(configfile)
+{
+  grub_unregister_command (cmd_configfile);
+  grub_unregister_command (cmd_source);
+  grub_unregister_command (cmd_dot);
+}
diff --git a/commands/crc.c b/commands/crc.c
new file mode 100644
index 0000000..6b4b1d1
--- /dev/null
+++ b/commands/crc.c
@@ -0,0 +1,67 @@
+/* crc.c - command to calculate the crc32 checksum of a file  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/lib/crc.h>
+#include <grub/command.h>
+
+static grub_err_t
+grub_cmd_crc (grub_command_t cmd __attribute__ ((unused)),
+	      int argc, char **args)
+
+{
+  grub_file_t file;
+  char buf[GRUB_DISK_SECTOR_SIZE];
+  grub_ssize_t size;
+  grub_uint32_t crc;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  file = grub_file_open (args[0]);
+  if (! file)
+    return 0;
+
+  crc = 0;
+  while ((size = grub_file_read (file, buf, sizeof (buf))) > 0)
+    crc = grub_getcrc32 (crc, buf, size);
+
+  grub_file_close (file);
+
+  grub_printf ("%08x\n", crc);
+
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(crc)
+{
+  cmd = grub_register_command ("crc", grub_cmd_crc,
+			       "crc FILE",
+			       "Calculate the crc32 checksum of a file.");
+}
+
+GRUB_MOD_FINI(crc)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/date.c b/commands/date.c
new file mode 100644
index 0000000..1d60964
--- /dev/null
+++ b/commands/date.c
@@ -0,0 +1,145 @@
+/* date.c - command to display/set current datetime.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/datetime.h>
+#include <grub/command.h>
+
+#define GRUB_DATETIME_SET_YEAR		1
+#define GRUB_DATETIME_SET_MONTH		2
+#define GRUB_DATETIME_SET_DAY		4
+#define GRUB_DATETIME_SET_HOUR		8
+#define GRUB_DATETIME_SET_MINUTE	16
+#define GRUB_DATETIME_SET_SECOND	32
+
+static grub_err_t
+grub_cmd_date (grub_command_t cmd __attribute__ ((unused)),
+               int argc, char **args)
+{
+  struct grub_datetime datetime;
+  int limit[6][2] = {{1980, 2079}, {1, 12}, {1, 31}, {0, 23}, {0, 59}, {0, 59}};
+  int value[6], mask;
+
+  if (argc == 0)
+    {
+      if (grub_get_datetime (&datetime))
+        return grub_errno;
+
+      grub_printf ("%d-%02d-%02d %02d:%02d:%02d %s\n",
+                   datetime.year, datetime.month, datetime.day,
+                   datetime.hour, datetime.minute, datetime.second,
+                   grub_get_weekday_name (&datetime));
+
+      return 0;
+    }
+
+  grub_memset (&value, 0, sizeof (value));
+  mask = 0;
+
+  for (; argc; argc--, args++)
+    {
+      char *p, c;
+      int m1, ofs, n, cur_mask;
+
+      p = args[0];
+      m1 = grub_strtoul (p, &p, 10);
+
+      c = *p;
+      if (c == '-')
+        ofs = 0;
+      else if (c == ':')
+        ofs = 3;
+      else
+        goto fail;
+
+      value[ofs] = m1;
+      cur_mask = (1 << ofs);
+      mask &= ~(cur_mask * (1 + 2 + 4));
+
+      for (n = 1; (n < 3) && (*p); n++)
+        {
+          if (*p != c)
+            goto fail;
+
+          value[ofs + n] = grub_strtoul (p + 1, &p, 10);
+          cur_mask |= (1 << (ofs + n));
+        }
+
+      if (*p)
+        goto fail;
+
+      if ((ofs == 0) && (n == 2))
+        {
+          value[ofs + 2] = value[ofs + 1];
+          value[ofs + 1] = value[ofs];
+          ofs++;
+          cur_mask <<= 1;
+        }
+
+      for (; n; n--, ofs++)
+        if ((value [ofs] < limit[ofs][0]) ||
+            (value [ofs] > limit[ofs][1]))
+          goto fail;
+
+      mask |= cur_mask;
+    }
+
+  if (grub_get_datetime (&datetime))
+    return grub_errno;
+
+  if (mask & GRUB_DATETIME_SET_YEAR)
+    datetime.year = value[0];
+
+  if (mask & GRUB_DATETIME_SET_MONTH)
+    datetime.month = value[1];
+
+  if (mask & GRUB_DATETIME_SET_DAY)
+    datetime.day = value[2];
+
+  if (mask & GRUB_DATETIME_SET_HOUR)
+    datetime.hour = value[3];
+
+  if (mask & GRUB_DATETIME_SET_MINUTE)
+    datetime.minute = value[4];
+
+  if (mask & GRUB_DATETIME_SET_SECOND)
+    datetime.second = value[5];
+
+  return grub_set_datetime (&datetime);
+
+fail:
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid datetime");
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(date)
+{
+  cmd =
+    grub_register_command ("date", grub_cmd_date,
+			   "date [[year-]month-day] [hour:minute[:second]]",
+			   "Command to display/set current datetime.");
+}
+
+GRUB_MOD_FINI(date)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/echo.c b/commands/echo.c
new file mode 100644
index 0000000..69aa3be
--- /dev/null
+++ b/commands/echo.c
@@ -0,0 +1,123 @@
+/* echo.c - Command to display a line of text  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {0, 'n', 0, "do not output the trailing newline", 0, 0},
+    {0, 'e', 0, "enable interpretation of backslash escapes", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_err_t
+grub_cmd_echo (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  int newline = 1;
+  int i;
+
+  /* Check if `-n' was used.  */
+  if (state[0].set)
+    newline = 0;
+
+  for (i = 0; i < argc; i++)
+    {
+      char *arg = *args;
+      args++;
+
+      while (*arg)
+	{
+	  /* In case `-e' is used, parse backslashes.  */
+	  if (*arg == '\\' && state[1].set)
+	    {
+	      arg++;
+	      if (*arg == '\0')
+		break;
+
+	      switch (*arg)
+		{
+		case '\\':
+		  grub_printf ("\\");
+		  break;
+
+		case 'a':
+		  grub_printf ("\a");
+		  break;
+
+		case 'c':
+		  newline = 0;
+		  break;
+
+		case 'f':
+		  grub_printf ("\f");
+		  break;
+
+		case 'n':
+		  grub_printf ("\n");
+		  break;
+
+		case 'r':
+		  grub_printf ("\r");
+		  break;
+
+		case 't':
+		  grub_printf ("\t");
+		  break;
+
+		case 'v':
+		  grub_printf ("\v");
+		  break;
+		}
+	      arg++;
+	      continue;
+	    }
+
+	  /* This was not an escaped character, or escaping is not
+	     enabled.  */
+	  grub_printf ("%c", *arg);
+	  arg++;
+	}
+
+      /* If another argument follows, insert a space.  */
+      if (i != argc - 1)
+	grub_printf (" " );
+    }
+
+  if (newline)
+    grub_printf ("\n");
+
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(echo)
+{
+  cmd = grub_register_extcmd ("echo", grub_cmd_echo, GRUB_COMMAND_FLAG_BOTH,
+			      "echo [-e|-n] STRING", "Display a line of text.",
+			      options);
+}
+
+GRUB_MOD_FINI(echo)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/efi/acpi.c b/commands/efi/acpi.c
new file mode 100644
index 0000000..93a560d
--- /dev/null
+++ b/commands/efi/acpi.c
@@ -0,0 +1,59 @@
+/* acpi.c - get acpi tables. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/acpi.h>
+#include <grub/misc.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/api.h>
+
+struct grub_acpi_rsdp_v10 *
+grub_machine_acpi_get_rsdpv1 (void)
+{
+  unsigned i;
+  static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID;
+
+  for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
+    {
+      grub_efi_guid_t *guid =
+	&grub_efi_system_table->configuration_table[i].vendor_guid;
+
+      if (! grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_guid_t)))
+	return (struct grub_acpi_rsdp_v10 *)
+	  grub_efi_system_table->configuration_table[i].vendor_table;
+    }
+  return 0;
+}
+
+struct grub_acpi_rsdp_v20 *
+grub_machine_acpi_get_rsdpv2 (void)
+{
+  unsigned i;
+  static grub_efi_guid_t acpi20_guid = GRUB_EFI_ACPI_20_TABLE_GUID;
+
+  for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
+    {
+      grub_efi_guid_t *guid =
+	&grub_efi_system_table->configuration_table[i].vendor_guid;
+
+      if (! grub_memcmp (guid, &acpi20_guid, sizeof (grub_efi_guid_t)))
+	return (struct grub_acpi_rsdp_v20 *)
+	  grub_efi_system_table->configuration_table[i].vendor_table;
+    }
+  return 0;
+}
diff --git a/commands/efi/fixvideo.c b/commands/efi/fixvideo.c
new file mode 100644
index 0000000..f97d837
--- /dev/null
+++ b/commands/efi/fixvideo.c
@@ -0,0 +1,109 @@
+/* fixvideo.c - fix video problem in efi */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/pci.h>
+#include <grub/command.h>
+
+static struct grub_video_patch
+{
+  const char *name;
+  grub_uint32_t pci_id;
+  grub_uint32_t mmio_bar;
+  grub_uint32_t mmio_reg;
+  grub_uint32_t mmio_old;
+} video_patches[] =
+  {
+    {"Intel 945GM", 0x27a28086, 0, 0x71184, 0x1000000}, /* DSPBBASE  */
+    {"Intel 965GM", 0x2a028086, 0, 0x7119C, 0x1000000}, /* DSPBSURF  */
+    {0, 0, 0, 0, 0}
+  };
+
+static int NESTED_FUNC_ATTR
+scan_card (int bus, int dev, int func, grub_pci_id_t pciid)
+{
+  grub_pci_address_t addr;
+
+  addr = grub_pci_make_address (bus, dev, func, 2);
+  if (grub_pci_read_byte (addr + 3) == 0x3)
+    {
+      struct grub_video_patch *p = video_patches;
+
+      while (p->name)
+	{
+	  if (p->pci_id == pciid)
+	    {
+	      grub_target_addr_t base;
+
+	      grub_printf ("Found graphic card: %s\n", p->name);
+	      addr += 8 + p->mmio_bar * 4;
+	      base = grub_pci_read (addr);
+	      if ((! base) || (base & GRUB_PCI_ADDR_SPACE_IO) ||
+		  (base & GRUB_PCI_ADDR_MEM_PREFETCH))
+		grub_printf ("Invalid MMIO bar %d\n", p->mmio_bar);
+	      else
+		{
+		  base &= GRUB_PCI_ADDR_MEM_MASK;
+		  base += p->mmio_reg;
+
+		  if (*((volatile grub_uint32_t *) base) != p->mmio_old)
+		    grub_printf ("Old value don't match\n");
+		  else
+		    {
+		      *((volatile grub_uint32_t *) base) = 0;
+		      if (*((volatile grub_uint32_t *) base))
+			grub_printf ("Set MMIO fails\n");
+		    }
+		}
+
+	      return 1;
+	    }
+	  p++;
+	}
+
+      grub_printf ("Unknown graphic card: %x\n", pciid);
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_fixvideo (grub_command_t cmd __attribute__ ((unused)),
+		   int argc __attribute__ ((unused)),
+		   char *argv[] __attribute__ ((unused)))
+{
+  grub_pci_iterate (scan_card);
+  return 0;
+}
+
+static grub_command_t cmd_fixvideo;
+
+GRUB_MOD_INIT(fixvideo)
+{
+  cmd_fixvideo = grub_register_command ("fix_video", grub_cmd_fixvideo,
+					0, "Fix video problem.");
+
+}
+
+GRUB_MOD_FINI(fixvideo)
+{
+  grub_unregister_command (cmd_fixvideo);
+}
diff --git a/commands/efi/loadbios.c b/commands/efi/loadbios.c
new file mode 100644
index 0000000..9967bb1
--- /dev/null
+++ b/commands/efi/loadbios.c
@@ -0,0 +1,213 @@
+/* loadbios.c - command to load a bios dump  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/efi/efi.h>
+#include <grub/pci.h>
+#include <grub/command.h>
+
+static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID;
+static grub_efi_guid_t acpi2_guid = GRUB_EFI_ACPI_20_TABLE_GUID;
+static grub_efi_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID;
+
+#define EBDA_SEG_ADDR	0x40e
+#define LOW_MEM_ADDR	0x413
+#define FAKE_EBDA_SEG	0x9fc0
+
+#define BLANK_MEM	0xffffffff
+#define VBIOS_ADDR	0xc0000
+#define SBIOS_ADDR	0xf0000
+
+static int
+enable_rom_area (void)
+{
+  grub_pci_address_t addr;
+  grub_uint32_t *rom_ptr;
+
+  rom_ptr = (grub_uint32_t *) VBIOS_ADDR;
+  if (*rom_ptr != BLANK_MEM)
+    {
+      grub_printf ("ROM image present.\n");
+      return 0;
+    }
+
+  addr = grub_pci_make_address (0, 0, 0, 36);
+  grub_pci_write_byte (addr++, 0x30);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr, 0);
+
+  *rom_ptr = 0;
+  if (*rom_ptr != 0)
+    {
+      grub_printf ("Can\'t enable rom area.\n");
+      return 0;
+    }
+
+  return 1;
+}
+
+static void
+lock_rom_area (void)
+{
+  grub_pci_address_t addr;
+
+  addr = grub_pci_make_address (0, 0, 0, 36);
+  grub_pci_write_byte (addr++, 0x10);
+  grub_pci_write_byte (addr++, 0x11);
+  grub_pci_write_byte (addr++, 0x11);
+  grub_pci_write_byte (addr++, 0x11);
+  grub_pci_write_byte (addr, 0x11);
+}
+
+static void
+fake_bios_data (int use_rom)
+{
+  unsigned i;
+  void *acpi, *smbios;
+  grub_uint16_t *ebda_seg_ptr, *low_mem_ptr;
+
+  ebda_seg_ptr = (grub_uint16_t *) EBDA_SEG_ADDR;
+  low_mem_ptr = (grub_uint16_t *) LOW_MEM_ADDR;
+  if ((*ebda_seg_ptr) || (*low_mem_ptr))
+    return;
+
+  acpi = 0;
+  smbios = 0;
+  for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
+    {
+      grub_efi_guid_t *guid =
+	&grub_efi_system_table->configuration_table[i].vendor_guid;
+
+      if (! grub_memcmp (guid, &acpi2_guid, sizeof (grub_efi_guid_t)))
+	{
+	  acpi = grub_efi_system_table->configuration_table[i].vendor_table;
+	  grub_dprintf ("efi", "ACPI2: %p\n", acpi);
+	}
+      else if (! grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_guid_t)))
+	{
+	  void *t;
+
+	  t = grub_efi_system_table->configuration_table[i].vendor_table;
+	  if (! acpi)
+	    acpi = t;
+	  grub_dprintf ("efi", "ACPI: %p\n", t);
+	}
+      else if (! grub_memcmp (guid, &smbios_guid, sizeof (grub_efi_guid_t)))
+	{
+	  smbios = grub_efi_system_table->configuration_table[i].vendor_table;
+	  grub_dprintf ("efi", "SMBIOS: %p\n", smbios);
+	}
+    }
+
+  *ebda_seg_ptr = FAKE_EBDA_SEG;
+  *low_mem_ptr = (FAKE_EBDA_SEG >> 6);
+
+  *((grub_uint16_t *) (FAKE_EBDA_SEG << 4)) = 640 - *low_mem_ptr;
+
+  if (acpi)
+    grub_memcpy ((char *) ((FAKE_EBDA_SEG << 4) + 16), acpi, 1024 - 16);
+
+  if ((use_rom) && (smbios))
+    grub_memcpy ((char *) SBIOS_ADDR, (char *) smbios + 16, 16);
+}
+
+static grub_err_t
+grub_cmd_fakebios (struct grub_command *cmd __attribute__ ((unused)),
+		   int argc __attribute__ ((unused)),
+		   char *argv[] __attribute__ ((unused)))
+{
+  if (enable_rom_area ())
+    {
+      fake_bios_data (1);
+      lock_rom_area ();
+    }
+  else
+    fake_bios_data (0);
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)),
+		   int argc, char *argv[])
+{
+  grub_file_t file;
+  int size;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "No rom image specified");
+
+  if (argc > 1)
+    {
+      file = grub_file_open (argv[1]);
+      if (! file)
+	return grub_errno;
+
+      if (file->size != 4)
+	grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid int10 dump size");
+      else
+	grub_file_read (file, (void *) 0x40, 4);
+
+      grub_file_close (file);
+      if (grub_errno)
+	return grub_errno;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    return grub_errno;
+
+  size = file->size;
+  if ((size < 0x10000) || (size > 0x40000))
+    grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid bios dump size");
+  else if (enable_rom_area ())
+    {
+      grub_file_read (file, (void *) VBIOS_ADDR, size);
+      fake_bios_data (size <= 0x40000);
+      lock_rom_area ();
+    }
+
+  grub_file_close (file);
+  return grub_errno;
+}
+
+static grub_command_t cmd_fakebios, cmd_loadbios;
+
+GRUB_MOD_INIT(loadbios)
+{
+  cmd_fakebios = grub_register_command ("fakebios", grub_cmd_fakebios,
+					0, "fake bios.");
+
+  cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios,
+					"loadbios BIOS_DUMP [INT10_DUMP]",
+					"Load bios dump.");
+}
+
+GRUB_MOD_FINI(loadbios)
+{
+  grub_unregister_command (cmd_fakebios);
+  grub_unregister_command (cmd_loadbios);
+}
diff --git a/commands/extcmd.c b/commands/extcmd.c
new file mode 100644
index 0000000..16796fe
--- /dev/null
+++ b/commands/extcmd.c
@@ -0,0 +1,96 @@
+/* extcmd.c - support extended command */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/list.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+
+static grub_err_t
+grub_extcmd_dispatcher (struct grub_command *cmd,
+			int argc, char **args)
+{
+  int new_argc;
+  char **new_args;
+  struct grub_arg_option *parser;
+  struct grub_arg_list *state;
+  int maxargs = 0;
+  grub_err_t ret;
+  grub_extcmd_t ext;
+
+  ext = cmd->data;
+  parser = (struct grub_arg_option *) ext->options;
+  while (parser && (parser++)->doc)
+    maxargs++;
+
+  /* Set up the option state.  */
+  state = grub_zalloc (sizeof (struct grub_arg_list) * maxargs);
+
+  if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc))
+    {
+      ext->state = state;
+      ret = (ext->func) (ext, new_argc, new_args);
+      grub_free (new_args);
+    }
+  else
+    ret = grub_errno;
+
+  grub_free (state);
+
+  return ret;
+}
+
+grub_extcmd_t
+grub_register_extcmd (const char *name, grub_extcmd_func_t func,
+		      unsigned flags, const char *summary,
+		      const char *description,
+		      const struct grub_arg_option *parser)
+{
+  grub_extcmd_t ext;
+  grub_command_t cmd;
+
+  ext = (grub_extcmd_t) grub_malloc (sizeof (*ext));
+  if (! ext)
+    return 0;
+
+  cmd = grub_register_command_prio (name, grub_extcmd_dispatcher,
+				    summary, description, 1);
+  if (! cmd)
+    {
+      grub_free (ext);
+      return 0;
+    }
+
+  cmd->flags = (flags | GRUB_COMMAND_FLAG_EXTCMD);
+  cmd->data = ext;
+
+  ext->cmd = cmd;
+  ext->func = func;
+  ext->options = parser;
+  ext->data = 0;
+
+  return ext;
+}
+
+void
+grub_unregister_extcmd (grub_extcmd_t ext)
+{
+  grub_unregister_command (ext->cmd);
+  grub_free (ext);
+}
diff --git a/commands/gptsync.c b/commands/gptsync.c
new file mode 100644
index 0000000..a603746
--- /dev/null
+++ b/commands/gptsync.c
@@ -0,0 +1,255 @@
+/* gptsync.c - fill the mbr based on gpt entries  */
+/* XXX: I don't know what to do if sector size isn't 512 bytes */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/command.h>
+#include <grub/dl.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/msdos_partition.h>
+#include <grub/partition.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/fs.h>
+
+/* Convert a LBA address to a CHS address in the INT 13 format.  */
+/* Taken from grub1. */
+/* XXX: use hardcoded geometry of C = 1024, H = 255, S = 63.
+   Is it a problem?
+*/
+static void
+lba_to_chs (int lba, grub_uint8_t *cl, grub_uint8_t *ch,
+	    grub_uint8_t *dh)
+{
+  int cylinder, head, sector;
+  int sectors = 63, heads = 255, cylinders = 1024;
+
+  sector = lba % sectors + 1;
+  head = (lba / sectors) % heads;
+  cylinder = lba / (sectors * heads);
+
+  if (cylinder >= cylinders)
+    {
+      *cl = *ch = *dh = 0xff;
+      return;
+    }
+
+  *cl = sector | ((cylinder & 0x300) >> 2);
+  *ch = cylinder & 0xFF;
+  *dh = head;
+}
+
+static grub_err_t
+grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)),
+		  int argc, char **args)
+{
+  grub_device_t dev;
+  struct grub_msdos_partition_mbr mbr;
+  struct grub_partition *partition;
+  grub_disk_addr_t first_sector;
+  int numactive = 0;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+  if (argc > 4)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "only 3 partitions can be "
+		       "in hybrid MBR");
+
+  if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')')
+    {
+      args[0][grub_strlen (args[0]) - 1] = 0;
+      dev = grub_device_open (args[0] + 1);
+      args[0][grub_strlen (args[0])] = ')';
+    }
+  else
+    dev = grub_device_open (args[0]);
+
+  if (! dev)
+    return grub_errno;
+
+  if (! dev->disk)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk");
+    }
+
+  /* Read the protective MBR.  */
+  if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), &mbr))
+    {
+      grub_device_close (dev);
+      return grub_errno;
+    }
+
+  /* Check if it is valid.  */
+  if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
+    }
+
+  /* Make sure the MBR is a protective MBR and not a normal MBR.  */
+  if (mbr.entries[0].type != GRUB_PC_PARTITION_TYPE_GPT_DISK)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found");
+    }
+
+  int i;
+  first_sector = dev->disk->total_sectors;
+  for (i = 1; i < argc; i++)
+    {
+      char *separator, csep = 0;
+      grub_uint8_t type;
+      separator = grub_strchr (args[i], '+');
+      if (! separator)
+	separator = grub_strchr (args[i], '-');
+      if (separator)
+	{
+	  csep = *separator;
+	  *separator = 0;
+	}
+      partition = grub_partition_probe (dev->disk, args[i]);
+      if (separator)
+	*separator = csep;
+      if (! partition)
+	{
+	  grub_device_close (dev);
+	  return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such partition");
+	}
+
+      if (partition->start + partition->len > 0xffffffff)
+	{
+	  grub_device_close (dev);
+	  return grub_error (GRUB_ERR_OUT_OF_RANGE,
+			     "only partitions resding in the first 2TB "
+			     "can be presen in hybrid MBR");
+	}
+
+
+      if (first_sector > partition->start)
+	first_sector = partition->start;
+
+      if (separator && *(separator + 1))
+	type = grub_strtoul (separator + 1, 0, 0);
+      else
+	{
+	  grub_fs_t fs = 0;
+	  dev->disk->partition = partition;
+	  fs = grub_fs_probe (dev);
+
+	  /* Unknown filesystem isn't fatal. */
+	  if (grub_errno == GRUB_ERR_UNKNOWN_FS)
+	    {
+	      fs = 0;
+	      grub_errno = GRUB_ERR_NONE;
+	    }
+
+	  if (fs && grub_strcmp (fs->name, "ntfs") == 0)
+	    type = GRUB_PC_PARTITION_TYPE_NTFS;
+	  else if (fs && grub_strcmp (fs->name, "fat") == 0)
+	    /* FIXME: detect FAT16. */
+	    type = GRUB_PC_PARTITION_TYPE_FAT32_LBA;
+	  else if (fs && (grub_strcmp (fs->name, "hfsplus") == 0
+			  || grub_strcmp (fs->name, "hfs") == 0))
+	    type = GRUB_PC_PARTITION_TYPE_HFS;
+	  else
+	    /* FIXME: detect more types. */
+	    type = GRUB_PC_PARTITION_TYPE_EXT2FS;
+
+	  dev->disk->partition = 0;
+	}
+
+      mbr.entries[i].flag = (csep == '+') ? 0x80 : 0;
+      if (csep == '+')
+	{
+	  numactive++;
+	  if (numactive == 2)
+	    {
+	      grub_device_close (dev);
+	      return grub_error (GRUB_ERR_BAD_ARGUMENT,
+				 "only one partition can be active");
+	    }
+	}
+      mbr.entries[i].type = type;
+      mbr.entries[i].start = grub_cpu_to_le32 (partition->start);
+      lba_to_chs (partition->start,
+		  &(mbr.entries[i].start_sector),
+		  &(mbr.entries[i].start_cylinder),
+		  &(mbr.entries[i].start_head));
+      lba_to_chs (partition->start + partition->len - 1,
+		  &(mbr.entries[i].end_sector),
+		  &(mbr.entries[i].end_cylinder),
+		  &(mbr.entries[i].end_head));
+      mbr.entries[i].length = grub_cpu_to_le32 (partition->len);
+      grub_free (partition);
+    }
+  for (; i < 4; i++)
+    grub_memset (&(mbr.entries[i]), 0, sizeof (mbr.entries[i]));
+
+  /* The protective partition. */
+  if (first_sector > 0xffffffff)
+    first_sector = 0xffffffff;
+  else
+    first_sector--;
+  mbr.entries[0].flag = 0;
+  mbr.entries[0].type = GRUB_PC_PARTITION_TYPE_GPT_DISK;
+  mbr.entries[0].start = grub_cpu_to_le32 (1);
+  lba_to_chs (1,
+	      &(mbr.entries[0].start_sector),
+	      &(mbr.entries[0].start_cylinder),
+	      &(mbr.entries[0].start_head));
+  lba_to_chs (first_sector,
+	      &(mbr.entries[0].end_sector),
+	      &(mbr.entries[0].end_cylinder),
+	      &(mbr.entries[0].end_head));
+  mbr.entries[0].length = grub_cpu_to_le32 (first_sector);
+
+  mbr.signature = grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE);
+
+  if (grub_disk_write (dev->disk, 0, 0, sizeof (mbr), &mbr))
+    {
+      grub_device_close (dev);
+      return grub_errno;
+    }
+
+  grub_printf ("New MBR is written to '%s'\n", args[0]);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(gptsync)
+{
+  (void) mod;			/* To stop warning. */
+  cmd = grub_register_command ("gptsync", grub_cmd_gptsync,
+			       "gptsync DEVICE [PARTITION[+/-[TYPE]]] ...",
+			       "Fill hybrid MBR of GPT drive DEVICE. "
+			       "specified partitions will be a part "
+			       "of hybrid mbr. Up to 3 partitions are "
+			       "allowed. TYPE is an MBR type. "
+			       "+ means that partition is active. "
+			       "Only one partition can be active");
+}
+
+GRUB_MOD_FINI(gptsync)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/halt.c b/commands/halt.c
new file mode 100644
index 0000000..b902418
--- /dev/null
+++ b/commands/halt.c
@@ -0,0 +1,54 @@
+/* halt.c - command to halt the computer.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/machine/machine.h>
+#include <grub/command.h>
+
+#if defined(GRUB_MACHINE_IEEE1275)
+#include <grub/machine/kernel.h>
+#elif defined(GRUB_MACHINE_EFI)
+#include <grub/efi/efi.h>
+#else
+/* Platforms shipping standalone halt, such as coreboot.  */
+#include <grub/cpu/halt.h>
+#endif
+
+static grub_err_t
+grub_cmd_halt (grub_command_t cmd __attribute__ ((unused)),
+	       int argc __attribute__ ((unused)),
+	       char **args __attribute__ ((unused)))
+{
+  grub_halt ();
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(halt)
+{
+  cmd = grub_register_command ("halt", grub_cmd_halt,
+			       0, "halts the computer.  This command does not"
+			       " work on all firmware.");
+}
+
+GRUB_MOD_FINI(halt)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/handler.c b/commands/handler.c
new file mode 100644
index 0000000..2070c39
--- /dev/null
+++ b/commands/handler.c
@@ -0,0 +1,115 @@
+/* handler.c - commands to list or select handlers */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/handler.h>
+#include <grub/command.h>
+
+static grub_err_t
+grub_cmd_handler (struct grub_command *cmd,
+		  int argc, char **args)
+{
+  char *class_name;
+  void *curr_item = 0;
+  grub_handler_class_t head;
+
+  auto int list_item (grub_named_list_t item);
+  int list_item (grub_named_list_t item)
+    {
+      if (item == curr_item)
+	grub_putchar ('*');
+
+      grub_printf ("%s\n", item->name);
+
+      return 0;
+    }
+
+  class_name = (grub_strcmp (cmd->name, "handler")) ? (char *) cmd->name : 0;
+
+  head = grub_handler_class_list;
+  if ((argc == 0) && (class_name == 0))
+    {
+      grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_item);
+    }
+  else
+    {
+      grub_handler_class_t class;
+
+      if (class_name == 0)
+	{
+	  class_name = args[0];
+	  argc--;
+	  args++;
+	}
+
+      class = grub_named_list_find (GRUB_AS_NAMED_LIST (head), class_name);
+      if (! class)
+	return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
+
+      if (argc == 0)
+	{
+	  curr_item = class->cur_handler;
+	  grub_list_iterate (GRUB_AS_LIST (class->handler_list),
+			     (grub_list_hook_t) list_item);
+	}
+      else
+	{
+	  grub_handler_t handler;
+
+	  handler =
+	    grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list),
+				  args[0]);
+
+	  if (! handler)
+	    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
+
+	  grub_handler_set_current (class, handler);
+	}
+    }
+
+  return 0;
+}
+
+static grub_command_t cmd_handler, cmd_terminal_input, cmd_terminal_output;
+
+GRUB_MOD_INIT(handler)
+{
+  cmd_handler =
+    grub_register_command ("handler", grub_cmd_handler,
+			   "handler [class [handler]]",
+			   "List or select a handler");
+  cmd_terminal_input =
+    grub_register_command ("terminal_input", grub_cmd_handler,
+			   "terminal_input [handler]",
+			   "List or select a handler");
+  cmd_terminal_output =
+    grub_register_command ("terminal_output", grub_cmd_handler,
+			   "terminal_output [handler]",
+			   "List or select a handler");
+}
+
+GRUB_MOD_FINI(handler)
+{
+  grub_unregister_command (cmd_handler);
+  grub_unregister_command (cmd_terminal_input);
+  grub_unregister_command (cmd_terminal_output);
+}
diff --git a/commands/hdparm.c b/commands/hdparm.c
new file mode 100644
index 0000000..389954c
--- /dev/null
+++ b/commands/hdparm.c
@@ -0,0 +1,420 @@
+/* hdparm.c - command to get/set ATA disk parameters.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/ata.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/lib/hexdump.h>
+#include <grub/extcmd.h>
+
+static const struct grub_arg_option options[] = {
+  {"apm",             'B', 0, "set Advanced Power Management\n"
+			      "(1=low, ..., 254=high, 255=off)",
+			      0, ARG_TYPE_INT},
+  {"power",           'C', 0, "check power mode", 0, ARG_TYPE_NONE},
+  {"security-freeze", 'F', 0, "freeze ATA security settings until reset",
+			      0, ARG_TYPE_NONE},
+  {"health",          'H', 0, "check SMART health status", 0, ARG_TYPE_NONE},
+  {"aam",             'M', 0, "set Automatic Acoustic Management\n"
+			      "(0=off, 128=quiet, ..., 254=fast)",
+			      0, ARG_TYPE_INT},
+  {"standby-timeout", 'S', 0, "set standby timeout\n"
+			      "(0=off, 1=5s, 2=10s, ..., 240=20m, 241=30m, ...)",
+			      0, ARG_TYPE_INT},
+  {"standby",         'y', 0, "set drive to standby mode", 0, ARG_TYPE_NONE},
+  {"sleep",           'Y', 0, "set drive to sleep mode", 0, ARG_TYPE_NONE},
+  {"identify",        'i', 0, "print drive identity and settings",
+			      0, ARG_TYPE_NONE},
+  {"dumpid",          'I', 0, "dump contents of ATA IDENTIFY sector",
+			       0, ARG_TYPE_NONE},
+  {"smart",            -1, 0, "disable/enable SMART (0/1)", 0, ARG_TYPE_INT},
+  {"quiet",           'q', 0, "do not print messages", 0, ARG_TYPE_NONE},
+  {0, 0, 0, 0, 0, 0}
+};
+
+enum grub_ata_smart_commands
+  {
+    GRUB_ATA_FEAT_SMART_ENABLE  = 0xd8,
+    GRUB_ATA_FEAT_SMART_DISABLE = 0xd9,
+    GRUB_ATA_FEAT_SMART_STATUS  = 0xda,
+  };
+
+static int quiet = 0;
+
+static grub_err_t
+grub_hdparm_do_ata_cmd (grub_disk_t disk, grub_uint8_t cmd,
+			grub_uint8_t features, grub_uint8_t sectors,
+			void * buffer, int size)
+{
+  struct grub_disk_ata_pass_through_parms apt;
+  grub_memset (&apt, 0, sizeof (apt));
+
+  apt.taskfile[GRUB_ATA_REG_CMD] = cmd;
+  apt.taskfile[GRUB_ATA_REG_FEATURES] = features;
+  apt.taskfile[GRUB_ATA_REG_SECTORS] = sectors;
+  apt.buffer = buffer;
+  apt.size = size;
+
+  if (grub_disk_ata_pass_through (disk, &apt))
+    return grub_errno;
+
+  return GRUB_ERR_NONE;
+}
+
+static int
+grub_hdparm_do_check_powermode_cmd (grub_disk_t disk)
+{
+  struct grub_disk_ata_pass_through_parms apt;
+  grub_memset (&apt, 0, sizeof (apt));
+
+  apt.taskfile[GRUB_ATA_REG_CMD] = GRUB_ATA_CMD_CHECK_POWER_MODE;
+
+  if (grub_disk_ata_pass_through (disk, &apt))
+    return -1;
+
+  return apt.taskfile[GRUB_ATA_REG_SECTORS];
+}
+
+static int
+grub_hdparm_do_smart_cmd (grub_disk_t disk, grub_uint8_t features)
+{
+  struct grub_disk_ata_pass_through_parms apt;
+  grub_memset (&apt, 0, sizeof (apt));
+
+  apt.taskfile[GRUB_ATA_REG_CMD] = GRUB_ATA_CMD_SMART;
+  apt.taskfile[GRUB_ATA_REG_FEATURES] = features;
+  apt.taskfile[GRUB_ATA_REG_LBAMID]  = 0x4f;
+  apt.taskfile[GRUB_ATA_REG_LBAHIGH] = 0xc2;
+
+  if (grub_disk_ata_pass_through (disk, &apt))
+    return -1;
+
+  if (features == GRUB_ATA_FEAT_SMART_STATUS)
+    {
+      if (   apt.taskfile[GRUB_ATA_REG_LBAMID]  == 0x4f
+          && apt.taskfile[GRUB_ATA_REG_LBAHIGH] == 0xc2)
+	return 0; /* Good SMART status.  */
+      else if (   apt.taskfile[GRUB_ATA_REG_LBAMID]  == 0xf4
+	       && apt.taskfile[GRUB_ATA_REG_LBAHIGH] == 0x2c)
+	return 1; /* Bad SMART status.  */
+      else
+	return -1;
+    }
+  return 0;
+}
+
+static grub_err_t
+grub_hdparm_simple_cmd (const char * msg,
+			grub_disk_t disk, grub_uint8_t cmd)
+{
+  if (! quiet && msg)
+    grub_printf ("%s", msg);
+
+  grub_err_t err = grub_hdparm_do_ata_cmd (disk, cmd, 0, 0, NULL, 0);
+
+  if (! quiet && msg)
+    grub_printf ("%s\n", ! err ? "" : ": not supported");
+  return err;
+}
+
+static grub_err_t
+grub_hdparm_set_val_cmd (const char * msg, int val,
+			 grub_disk_t disk, grub_uint8_t cmd,
+			 grub_uint8_t features, grub_uint8_t sectors)
+{
+  if (! quiet && msg && *msg)
+    {
+      if (val >= 0)
+	grub_printf ("Set %s to %d", msg, val);
+      else
+	grub_printf ("Disable %s", msg);
+    }
+
+  grub_err_t err = grub_hdparm_do_ata_cmd (disk, cmd, features, sectors,
+					   NULL, 0);
+
+  if (! quiet && msg)
+    grub_printf ("%s\n", ! err ? "" : ": not supported");
+  return err;
+}
+
+static const char *
+le16_to_char (char *dest, const grub_uint16_t * src16, unsigned bytes)
+{
+  grub_uint16_t * dest16 = (grub_uint16_t *) dest;
+  unsigned i;
+  for (i = 0; i < bytes / 2; i++)
+    dest16[i] = grub_be_to_cpu16 (src16[i]);
+  return dest;
+}
+
+static void
+grub_hdparm_print_identify (const char * idbuf)
+{
+  const grub_uint16_t * idw = (const grub_uint16_t *) idbuf;
+
+  /* Print identity strings.  */
+  char tmp[40];
+  grub_printf ("Model:    \"%.40s\"\n", le16_to_char (tmp, &idw[27], 40));
+  grub_printf ("Firmware: \"%.8s\"\n",  le16_to_char (tmp, &idw[23], 8));
+  grub_printf ("Serial:   \"%.20s\"\n", le16_to_char (tmp, &idw[10], 20));
+
+  /* Print AAM, APM and SMART settings.  */
+  grub_uint16_t features1 = grub_le_to_cpu16 (idw[82]);
+  grub_uint16_t features2 = grub_le_to_cpu16 (idw[83]);
+  grub_uint16_t enabled1  = grub_le_to_cpu16 (idw[85]);
+  grub_uint16_t enabled2  = grub_le_to_cpu16 (idw[86]);
+
+  grub_printf ("Automatic Acoustic Management: ");
+  if (features2 & 0x0200)
+    {
+      if (enabled2 & 0x0200)
+	{
+	  grub_uint16_t aam = grub_le_to_cpu16 (idw[94]);
+	  grub_printf ("%u (128=quiet, ..., 254=fast, recommended=%u)\n",
+		       aam & 0xff, (aam >> 8) & 0xff);
+	}
+      else
+	grub_printf ("disabled\n");
+    }
+  else
+    grub_printf ("not supported\n");
+
+  grub_printf ("Advanced Power Management: ");
+  if (features2 & 0x0008)
+    {
+      if (enabled2 & 0x0008)
+	grub_printf ("%u (1=low, ..., 254=high)\n",
+		     grub_le_to_cpu16 (idw[91]) & 0xff);
+      else
+	grub_printf ("disabled\n");
+    }
+  else
+    grub_printf ("not supported\n");
+
+  grub_printf ("SMART Feature Set: ");
+  if (features1 & 0x0001)
+    grub_printf ("%sabled\n", (enabled1 & 0x0001 ? "en" : "dis"));
+  else
+    grub_printf ("not supported\n");
+
+  /* Print security settings.  */
+  grub_uint16_t security = grub_le_to_cpu16 (idw[128]);
+
+  grub_printf ("ATA Security: ");
+  if (security & 0x0001)
+    grub_printf ("%s, %s, %s, %s\n",
+		 (security & 0x0002 ? "ENABLED" : "disabled"),
+		 (security & 0x0004 ? "**LOCKED**"  : "not locked"),
+		 (security & 0x0008 ? "frozen" : "NOT FROZEN"),
+		 (security & 0x0010 ? "COUNT EXPIRED" : "count not expired"));
+  else
+    grub_printf ("not supported\n");
+}
+
+static void
+grub_hdparm_print_standby_tout (int timeout)
+{
+  if (timeout == 0)
+    grub_printf ("off");
+  else if (timeout <= 252 || timeout == 255)
+    {
+      int h = 0, m = 0 , s = 0;
+      if (timeout == 255)
+	{
+	  m = 21;
+	  s = 15;
+	}
+      else if (timeout == 252)
+	m = 21;
+      else if (timeout <= 240)
+	{
+	  s = timeout * 5;
+	  m = s / 60;
+	  s %= 60;
+	}
+      else
+	{
+	  m = (timeout - 240) * 30;
+	  h  = m / 60;
+	  m %= 60;
+	}
+      grub_printf ("%02d:%02d:%02d", h, m, s);
+    }
+  else
+    grub_printf ("invalid or vendor-specific");
+}
+
+static int get_int_arg (const struct grub_arg_list *state)
+{
+  return (state->set ? (int)grub_strtoul (state->arg, 0, 0) : -1);
+}
+
+static grub_err_t
+grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state????
+{
+  struct grub_arg_list *state = cmd->state;
+
+  /* Check command line.  */
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing device name argument");
+
+  grub_size_t len = grub_strlen (args[0]);
+  if (! (args[0][0] == '(' && args[0][len - 1] == ')'))
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "argument is not a device name");
+  args[0][len - 1] = 0;
+
+  if (! grub_disk_ata_pass_through)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "ATA pass through not available");
+
+  int i = 0;
+  int apm          = get_int_arg (&state[i++]);
+  int power        = state[i++].set;
+  int sec_freeze   = state[i++].set;
+  int health       = state[i++].set;
+  int aam          = get_int_arg (&state[i++]);
+  int standby_tout = get_int_arg (&state[i++]);
+  int standby_now  = state[i++].set;
+  int sleep_now    = state[i++].set;
+  int ident        = state[i++].set;
+  int dumpid       = state[i++].set;
+  int enable_smart = get_int_arg (&state[i++]);
+  quiet            = state[i++].set;
+
+  /* Open disk.  */
+  grub_disk_t disk = grub_disk_open (&args[0][1]);
+  if (! disk)
+    return grub_errno;
+
+  if (disk->partition)
+    {
+      grub_disk_close (disk);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "partition not allowed");
+    }
+
+  /* Change settings.  */
+  if (aam >= 0)
+    grub_hdparm_set_val_cmd ("Automatic Acoustic Management", (aam ? aam : -1),
+      disk, GRUB_ATA_CMD_SET_FEATURES, (aam ? 0x42 : 0xc2), aam);
+
+  if (apm >= 0)
+    grub_hdparm_set_val_cmd ("Advanced Power Management",
+      (apm != 255 ? apm : -1), disk, GRUB_ATA_CMD_SET_FEATURES,
+      (apm != 255 ? 0x05 : 0x85), (apm != 255 ? apm : 0));
+
+  if (standby_tout >= 0)
+    {
+      if (! quiet)
+	{
+	  grub_printf ("Set standby timeout to %d (", standby_tout);
+	  grub_hdparm_print_standby_tout (standby_tout);
+	  grub_printf (")");
+	}
+      /* The IDLE cmd sets disk to idle mode and configures standby timer.  */
+      grub_hdparm_set_val_cmd ("", -1, disk, GRUB_ATA_CMD_IDLE, 0, standby_tout);
+    }
+
+  if (enable_smart >= 0)
+    {
+      if (! quiet)
+	grub_printf ("%sable SMART operations", (enable_smart ? "En" : "Dis"));
+      int err = grub_hdparm_do_smart_cmd (disk, (enable_smart ?
+	          GRUB_ATA_FEAT_SMART_ENABLE : GRUB_ATA_FEAT_SMART_DISABLE));
+      if (! quiet)
+	grub_printf ("%s\n", err ? ": not supported" : "");
+    }
+
+  if (sec_freeze)
+    grub_hdparm_simple_cmd ("Freeze security settings", disk,
+                            GRUB_ATA_CMD_SECURITY_FREEZE_LOCK);
+
+  /* Print/dump IDENTIFY.  */
+  if (ident || dumpid)
+    {
+      char buf[GRUB_DISK_SECTOR_SIZE];
+      if (grub_hdparm_do_ata_cmd (disk, GRUB_ATA_CMD_IDENTIFY_DEVICE,
+          0, 0, buf, sizeof (buf)))
+	grub_printf ("Cannot read ATA IDENTIFY data\n");
+      else
+	{
+	  if (ident)
+	    grub_hdparm_print_identify (buf);
+	  if (dumpid)
+	    hexdump (0, buf, sizeof (buf));
+	}
+    }
+
+  /* Check power mode.  */
+  if (power)
+    {
+      grub_printf ("Disk power mode is: ");
+      int mode = grub_hdparm_do_check_powermode_cmd (disk);
+      if (mode < 0)
+        grub_printf ("unknown\n");
+      else
+	grub_printf ("%s (0x%02x)\n",
+		     (mode == 0xff ? "active/idle" :
+		      mode == 0x80 ? "idle" :
+		      mode == 0x00 ? "standby" : "unknown"), mode);
+    }
+
+  /* Check health.  */
+  int status = 0;
+  if (health)
+    {
+      if (! quiet)
+	grub_printf ("SMART status is: ");
+      int err = grub_hdparm_do_smart_cmd (disk, GRUB_ATA_FEAT_SMART_STATUS);
+      if (! quiet)
+	grub_printf ("%s\n", (err  < 0 ? "unknown" :
+	                      err == 0 ? "OK" : "*BAD*"));
+      status = (err > 0);
+    }
+
+  /* Change power mode.  */
+  if (standby_now)
+    grub_hdparm_simple_cmd ("Set disk to standby mode", disk,
+			    GRUB_ATA_CMD_STANDBY_IMMEDIATE);
+
+  if (sleep_now)
+    grub_hdparm_simple_cmd ("Set disk to sleep mode", disk,
+			    GRUB_ATA_CMD_SLEEP);
+
+  grub_disk_close (disk);
+
+  grub_errno = GRUB_ERR_NONE;
+  return status;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(hdparm)
+{
+  cmd = grub_register_extcmd ("hdparm", grub_cmd_hdparm,
+			      GRUB_COMMAND_FLAG_BOTH,
+			      "hdparm [OPTIONS] DISK",
+			      "Get/set ATA disk parameters.", options);
+}
+
+GRUB_MOD_FINI(hdparm)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/help.c b/commands/help.c
new file mode 100644
index 0000000..c18ec6b
--- /dev/null
+++ b/commands/help.c
@@ -0,0 +1,104 @@
+/* help.c - command to show a help text.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/extcmd.h>
+
+static grub_err_t
+grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
+	       char **args)
+{
+  int cnt = 0;
+  char *currarg;
+
+  auto int print_command_info (grub_command_t cmd);
+  auto int print_command_help (grub_command_t cmd);
+
+  int print_command_info (grub_command_t cmd)
+    {
+      if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) &&
+	  (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE))
+	{
+	  char description[GRUB_TERM_WIDTH / 2];
+	  int desclen = grub_strlen (cmd->summary);
+
+	  /* Make a string with a length of GRUB_TERM_WIDTH / 2 - 1 filled
+	     with the description followed by spaces.  */
+	  grub_memset (description, ' ', GRUB_TERM_WIDTH / 2 - 1);
+	  description[GRUB_TERM_WIDTH / 2 - 1] = '\0';
+	  grub_memcpy (description, cmd->summary,
+		       (desclen < GRUB_TERM_WIDTH / 2 - 1
+			? desclen : GRUB_TERM_WIDTH / 2 - 1));
+
+	  grub_printf ("%s%s", description, (cnt++) % 2 ? "\n" : " ");
+	}
+      return 0;
+    }
+
+  int print_command_help (grub_command_t cmd)
+    {
+      if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE)
+	{
+	  if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg)))
+	    {
+	      if (cnt++ > 0)
+		grub_printf ("\n\n");
+
+	      if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD)
+		grub_arg_show_help ((grub_extcmd_t) cmd->data);
+	      else
+		grub_printf ("Usage: %s\n%s\b", cmd->summary,
+			     cmd->description);
+	    }
+	}
+      return 0;
+    }
+
+  if (argc == 0)
+    grub_command_iterate (print_command_info);
+  else
+    {
+      int i;
+
+      for (i = 0; i < argc; i++)
+	{
+	  currarg = args[i];
+	  grub_command_iterate (print_command_help);
+	}
+    }
+
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(help)
+{
+  cmd = grub_register_extcmd ("help", grub_cmd_help,
+			      GRUB_COMMAND_FLAG_CMDLINE,
+			      "help [PATTERN ...]",
+			      "Show a help message.", 0);
+}
+
+GRUB_MOD_FINI(help)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/hexdump.c b/commands/hexdump.c
new file mode 100644
index 0000000..f59ba36
--- /dev/null
+++ b/commands/hexdump.c
@@ -0,0 +1,132 @@
+/* hexdump.c - command to dump the contents of a file or memory */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/lib/hexdump.h>
+#include <grub/extcmd.h>
+
+static const struct grub_arg_option options[] = {
+  {"skip", 's', 0, "skip offset bytes from the beginning of file.", 0,
+   ARG_TYPE_INT},
+  {"length", 'n', 0, "read only length bytes", 0, ARG_TYPE_INT},
+  {0, 0, 0, 0, 0, 0}
+};
+
+static grub_err_t
+grub_cmd_hexdump (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  char buf[GRUB_DISK_SECTOR_SIZE * 4];
+  grub_ssize_t size, length;
+  grub_addr_t skip;
+  int namelen;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  namelen = grub_strlen (args[0]);
+  skip = (state[0].set) ? grub_strtoul (state[0].arg, 0, 0) : 0;
+  length = (state[1].set) ? grub_strtoul (state[1].arg, 0, 0) : 256;
+
+  if (!grub_strcmp (args[0], "(mem)"))
+    hexdump (skip, (char *) skip, length);
+  else if ((args[0][0] == '(') && (args[0][namelen - 1] == ')'))
+    {
+      grub_disk_t disk;
+      grub_disk_addr_t sector;
+      grub_size_t ofs;
+
+      args[0][namelen - 1] = 0;
+      disk = grub_disk_open (&args[0][1]);
+      if (! disk)
+        return 0;
+
+      sector = (skip >> (GRUB_DISK_SECTOR_BITS + 2)) * 4;
+      ofs = skip & (GRUB_DISK_SECTOR_SIZE * 4 - 1);
+      while (length)
+        {
+          grub_size_t len;
+
+          len = length;
+          if (len > sizeof (buf))
+            len = sizeof (buf);
+
+          if (grub_disk_read (disk, sector, ofs, len, buf))
+            break;
+
+          hexdump (skip, buf, len);
+
+          ofs = 0;
+          skip += len;
+          length -= len;
+          sector += 4;
+        }
+
+      grub_disk_close (disk);
+    }
+  else
+    {
+      grub_file_t file;
+
+      file = grub_gzfile_open (args[0], 1);
+      if (! file)
+	return 0;
+
+      file->offset = skip;
+
+      while ((size = grub_file_read (file, buf, sizeof (buf))) > 0)
+	{
+	  unsigned long len;
+
+	  len = ((length) && (size > length)) ? length : size;
+	  hexdump (skip, buf, len);
+	  skip += len;
+	  if (length)
+	    {
+	      length -= len;
+	      if (!length)
+		break;
+	    }
+	}
+
+      grub_file_close (file);
+    }
+
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT (hexdump)
+{
+  cmd = grub_register_extcmd ("hexdump", grub_cmd_hexdump,
+			      GRUB_COMMAND_FLAG_BOTH,
+			      "hexdump [OPTIONS] FILE_OR_DEVICE",
+			      "Dump the contents of a file or memory.",
+			      options);
+}
+
+GRUB_MOD_FINI (hexdump)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/i386/cpuid.c b/commands/i386/cpuid.c
new file mode 100644
index 0000000..a8bbfe6
--- /dev/null
+++ b/commands/i386/cpuid.c
@@ -0,0 +1,97 @@
+/* cpuid.c - test for CPU features */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006, 2007, 2009  Free Software Foundation, Inc.
+ *  Based on gcc/gcc/config/i386/driver-i386.c
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/command.h>
+#include <grub/extcmd.h>
+#include <grub/i386/cpuid.h>
+
+#define cpuid(num,a,b,c,d) \
+  asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
+		: "=a" (a), "=r" (b), "=c" (c), "=d" (d)  \
+		: "0" (num))
+
+static const struct grub_arg_option options[] =
+  {
+    {"long-mode", 'l', 0, "check for long mode flag (default)", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+#define bit_LM (1 << 29)
+
+unsigned char grub_cpuid_has_longmode = 0;
+
+static grub_err_t
+grub_cmd_cpuid (grub_extcmd_t cmd __attribute__ ((unused)),
+		int argc __attribute__ ((unused)),
+		char **args __attribute__ ((unused)))
+{
+  return grub_cpuid_has_longmode ? GRUB_ERR_NONE
+    : grub_error (GRUB_ERR_TEST_FAILURE, "false");
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(cpuid)
+{
+#ifdef __x86_64__
+  /* grub-emu */
+  grub_cpuid_has_longmode = 1;
+#else
+  unsigned int eax, ebx, ecx, edx;
+  unsigned int max_level;
+  unsigned int ext_level;
+
+  /* See if we can use cpuid.  */
+  asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
+		"pushl %0; popfl; pushfl; popl %0; popfl"
+		: "=&r" (eax), "=&r" (ebx)
+		: "i" (0x00200000));
+  if (((eax ^ ebx) & 0x00200000) == 0)
+    goto done;
+
+  /* Check the highest input value for eax.  */
+  cpuid (0, eax, ebx, ecx, edx);
+  /* We only look at the first four characters.  */
+  max_level = eax;
+  if (max_level == 0)
+    goto done;
+
+  cpuid (0x80000000, eax, ebx, ecx, edx);
+  ext_level = eax;
+  if (ext_level < 0x80000000)
+    goto done;
+
+  cpuid (0x80000001, eax, ebx, ecx, edx);
+  grub_cpuid_has_longmode = !!(edx & bit_LM);
+done:
+#endif
+
+  cmd = grub_register_extcmd ("cpuid", grub_cmd_cpuid, GRUB_COMMAND_FLAG_BOTH,
+			      "cpuid [-l]", "Check for CPU features", options);
+}
+
+GRUB_MOD_FINI(cpuid)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/i386/pc/acpi.c b/commands/i386/pc/acpi.c
new file mode 100644
index 0000000..88e4f55
--- /dev/null
+++ b/commands/i386/pc/acpi.c
@@ -0,0 +1,81 @@
+/* acpi.c - get acpi tables. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/acpi.h>
+#include <grub/misc.h>
+
+struct grub_acpi_rsdp_v10 *
+grub_machine_acpi_get_rsdpv1 (void)
+{
+  int ebda_len;
+  grub_uint8_t *ebda, *ptr;
+
+  grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
+  ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
+  ebda_len = * (grub_uint16_t *) ebda;
+  if (! ebda_len)
+    return 0;
+  for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
+    if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
+	&& grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
+	&& ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
+      return (struct grub_acpi_rsdp_v10 *) ptr;
+
+  grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
+  for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
+       ptr += 16)
+    if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
+	&& grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
+	&& ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
+      return (struct grub_acpi_rsdp_v10 *) ptr;
+  return 0;
+}
+
+struct grub_acpi_rsdp_v20 *
+grub_machine_acpi_get_rsdpv2 (void)
+{
+  int ebda_len;
+  grub_uint8_t *ebda, *ptr;
+
+  grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
+  ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
+  ebda_len = * (grub_uint16_t *) ebda;
+  if (! ebda_len)
+    return 0;
+  for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
+    if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
+	&& grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
+	&& ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0
+	&& ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024
+	&& grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length)
+	== 0)
+      return (struct grub_acpi_rsdp_v20 *) ptr;
+
+  grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
+  for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
+       ptr += 16)
+    if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
+	&& grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
+	&& ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0
+	&& ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024
+	&& grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length)
+	== 0)
+      return (struct grub_acpi_rsdp_v20 *) ptr;
+  return 0;
+}
diff --git a/commands/i386/pc/drivemap.c b/commands/i386/pc/drivemap.c
new file mode 100644
index 0000000..52424c3
--- /dev/null
+++ b/commands/i386/pc/drivemap.c
@@ -0,0 +1,421 @@
+/* drivemap.c - command to manage the BIOS drive mappings.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/extcmd.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/loader.h>
+#include <grub/env.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/biosnum.h>
+
+
+/* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
+static grub_uint32_t *const int13slot = UINT_TO_PTR (4 * 0x13);
+
+/* Remember to update enum opt_idxs accordingly.  */
+static const struct grub_arg_option options[] = {
+  {"list", 'l', 0, "show the current mappings", 0, 0},
+  {"reset", 'r', 0, "reset all mappings to the default values", 0, 0},
+  {"swap", 's', 0, "perform both direct and reverse mappings", 0, 0},
+  {0, 0, 0, 0, 0, 0}
+};
+
+/* Remember to update options[] accordingly.  */
+enum opt_idxs
+{
+  OPTIDX_LIST = 0,
+  OPTIDX_RESET,
+  OPTIDX_SWAP,
+};
+
+/* Realmode far ptr (2 * 16b) to the previous INT13h handler.  */
+extern grub_uint32_t grub_drivemap_oldhandler;
+
+/* The type "void" is used for imported assembly labels, takes no storage and
+   serves just to take the address with &label.  */
+
+/* The assembly function to replace the old INT13h handler. It does not follow
+   any C callspecs and returns with IRET.  */
+extern const void grub_drivemap_handler;
+
+/* Start of the drive mappings area (space reserved at runtime).  */
+extern const void grub_drivemap_mapstart;
+
+typedef struct drivemap_node
+{
+  struct drivemap_node *next;
+  grub_uint8_t newdrive;
+  grub_uint8_t redirto;
+} drivemap_node_t;
+
+typedef struct __attribute__ ((packed)) int13map_node
+{
+  grub_uint8_t disknum;
+  grub_uint8_t mapto;
+} int13map_node_t;
+
+#define INT13H_OFFSET(x) \
+	(((grub_uint8_t *)(x)) - ((grub_uint8_t *)&grub_drivemap_handler))
+
+static drivemap_node_t *map_head;
+static void *drivemap_hook;
+static int drivemap_mmap;
+
+/* Puts the specified mapping into the table, replacing an existing mapping
+   for newdrive or adding a new one if required.  */
+static grub_err_t
+drivemap_set (grub_uint8_t newdrive, grub_uint8_t redirto)
+{
+  drivemap_node_t *mapping = 0;
+  drivemap_node_t *search = map_head;
+  while (search)
+    {
+      if (search->newdrive == newdrive)
+	{
+	  mapping = search;
+	  break;
+	}
+      search = search->next;
+    }
+
+  /* Check for pre-existing mappings to modify before creating a new one.  */
+  if (mapping)
+    mapping->redirto = redirto;
+  else
+    {
+      mapping = grub_malloc (sizeof (drivemap_node_t));
+      if (! mapping)
+	return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			   "cannot allocate map entry, not enough memory");
+      mapping->newdrive = newdrive;
+      mapping->redirto = redirto;
+      mapping->next = map_head;
+      map_head = mapping;
+    }
+  return GRUB_ERR_NONE;
+}
+
+/* Removes the mapping for newdrive from the table.  If there is no mapping,
+   then this function behaves like a no-op on the map.  */
+static void
+drivemap_remove (grub_uint8_t newdrive)
+{
+  drivemap_node_t *mapping = 0;
+  drivemap_node_t *search = map_head;
+  drivemap_node_t *previous = 0;
+
+  while (search)
+    {
+      if (search->newdrive == newdrive)
+	{
+	  mapping = search;
+	  break;
+	}
+      previous = search;
+      search = search->next;
+    }
+
+  if (mapping)
+    {
+      if (previous)
+	previous->next = mapping->next;
+      else
+	map_head = mapping->next;
+      grub_free (mapping);
+    }
+}
+
+/* Given a GRUB-like device name and a convenient location, stores the
+   related BIOS disk number.  Accepts devices like \((f|h)dN\), with
+   0 <= N < 128.  */
+static grub_err_t
+tryparse_diskstring (const char *str, grub_uint8_t *output)
+{
+  /* Skip opening paren in order to allow both (hd0) and hd0.  */
+  if (*str == '(')
+    str++;
+  if ((str[0] == 'f' || str[0] == 'h') && str[1] == 'd')
+    {
+      grub_uint8_t bios_num = (str[0] == 'h') ? 0x80 : 0x00;
+      unsigned long drivenum = grub_strtoul (str + 2, 0, 0);
+      if (grub_errno == GRUB_ERR_NONE && drivenum < 128)
+	{
+	  bios_num |= drivenum;
+	  if (output)
+	    *output = bios_num;
+	  return GRUB_ERR_NONE;
+	}
+    }
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "device format \"%s\" "
+		     "invalid: must be (f|h)dN, with 0 <= N < 128", str);
+}
+
+static grub_err_t
+list_mappings (void)
+{
+  /* Show: list mappings.  */
+  if (! map_head)
+    {
+      grub_printf ("No drives have been remapped\n");
+      return GRUB_ERR_NONE;
+    }
+
+  grub_printf ("OS disk #num ------> GRUB/BIOS device\n");
+  drivemap_node_t *curnode = map_head;
+  while (curnode)
+    {
+      grub_printf ("%cD #%-3u (0x%02x)       %cd%d\n",
+		   (curnode->newdrive & 0x80) ? 'H' : 'F',
+		   curnode->newdrive & 0x7F, curnode->newdrive,
+		   (curnode->redirto & 0x80) ? 'h' : 'f',
+		   curnode->redirto & 0x7F
+		   );
+      curnode = curnode->next;
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args)
+{
+  if (cmd->state[OPTIDX_LIST].set)
+    {
+      return list_mappings ();
+    }
+  else if (cmd->state[OPTIDX_RESET].set)
+    {
+      /* Reset: just delete all mappings, freeing their memory.  */
+      drivemap_node_t *curnode = map_head;
+      drivemap_node_t *prevnode = 0;
+      while (curnode)
+	{
+	  prevnode = curnode;
+	  curnode = curnode->next;
+	  grub_free (prevnode);
+	}
+      map_head = 0;
+      return GRUB_ERR_NONE;
+    }
+  else if (!cmd->state[OPTIDX_SWAP].set && argc == 0)
+    {
+      /* No arguments */
+      return list_mappings ();
+    }
+
+  /* Neither flag: put mapping.  */
+  grub_uint8_t mapfrom = 0;
+  grub_uint8_t mapto = 0xFF;
+  grub_err_t err;
+
+  if (argc != 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required");
+
+  err = tryparse_diskstring (args[0], &mapfrom);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  err = tryparse_diskstring (args[1], &mapto);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  if (mapto == mapfrom)
+    {
+      /* Reset to default.  */
+      grub_dprintf ("drivemap", "Removing mapping for %s (%02x)\n",
+		    args[0], mapfrom);
+      drivemap_remove (mapfrom);
+      return GRUB_ERR_NONE;
+    }
+  /* Set the mapping for the disk (overwrites any existing mapping).  */
+  grub_dprintf ("drivemap", "%s %s (%02x) = %s (%02x)\n",
+		cmd->state[OPTIDX_SWAP].set ? "Swapping" : "Mapping",
+		args[1], mapto, args[0], mapfrom);
+  err = drivemap_set (mapto, mapfrom);
+  /* If -s, perform the reverse mapping too (only if the first was OK).  */
+  if (cmd->state[OPTIDX_SWAP].set && err == GRUB_ERR_NONE)
+    err = drivemap_set (mapfrom, mapto);
+  return err;
+}
+
+/* Int13h handler installer - reserves conventional memory for the handler,
+   copies it over and sets the IVT entry for int13h.
+   This code rests on the assumption that GRUB does not activate any kind
+   of memory mapping apart from identity paging, since it accesses
+   realmode structures by their absolute addresses, like the IVT at 0;
+   and transforms a pmode pointer into a rmode seg:off far ptr.  */
+static grub_err_t
+install_int13_handler (int noret __attribute__ ((unused)))
+{
+  /* Size of the full int13 handler "bundle", including code and map.  */
+  grub_uint32_t total_size;
+  /* Base address of the space reserved for the handler bundle.  */
+  grub_uint8_t *handler_base = 0;
+  /* Address of the map within the deployed bundle.  */
+  int13map_node_t *handler_map;
+
+  int i;
+  int entries = 0;
+  drivemap_node_t *curentry = map_head;
+
+  /* Count entries to prepare a contiguous map block.  */
+  while (curentry)
+    {
+      entries++;
+      curentry = curentry->next;
+    }
+  if (entries == 0)
+    {
+      /* No need to install the int13h handler.  */
+      grub_dprintf ("drivemap", "No drives marked as remapped, not installing "
+		    "our int13h handler.\n");
+      return GRUB_ERR_NONE;
+    }
+
+  grub_dprintf ("drivemap", "Installing our int13h handler\n");
+
+  /* Save the pointer to the old handler.  */
+  grub_drivemap_oldhandler = *int13slot;
+  grub_dprintf ("drivemap", "Original int13 handler: %04x:%04x\n",
+		(grub_drivemap_oldhandler >> 16) & 0x0ffff,
+		grub_drivemap_oldhandler & 0x0ffff);
+
+  /* Find a rmode-segment-aligned zone in conventional memory big
+     enough to hold the handler and its data.  */
+  total_size = INT13H_OFFSET (&grub_drivemap_mapstart)
+    + (entries + 1) * sizeof (int13map_node_t);
+  grub_dprintf ("drivemap", "Payload is %u bytes long\n", total_size);
+  handler_base = grub_mmap_malign_and_register (16, total_size,
+						&drivemap_mmap,
+						GRUB_MACHINE_MEMORY_RESERVED,
+						GRUB_MMAP_MALLOC_LOW);
+  if (! handler_base)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not reserve "
+		       "memory for the int13h handler");
+
+  /* Copy int13h handler bundle to reserved area.  */
+  grub_dprintf ("drivemap", "Reserved memory at %p, copying handler\n",
+		handler_base);
+  grub_memcpy (handler_base, &grub_drivemap_handler,
+	       INT13H_OFFSET (&grub_drivemap_mapstart));
+
+  /* Copy the mappings to the reserved area.  */
+  curentry = map_head;
+  handler_map = (int13map_node_t *) (handler_base +
+				     INT13H_OFFSET (&grub_drivemap_mapstart));
+  grub_dprintf ("drivemap", "Target map at %p, copying mappings\n", handler_map);
+  for (i = 0; i < entries; ++i, curentry = curentry->next)
+    {
+      handler_map[i].disknum = curentry->newdrive;
+      handler_map[i].mapto = curentry->redirto;
+      grub_dprintf ("drivemap", "\t#%d: 0x%02x <- 0x%02x\n", i,
+		    handler_map[i].disknum, handler_map[i].mapto);
+    }
+  /* Signal end-of-map.  */
+  handler_map[i].disknum = 0;
+  handler_map[i].mapto = 0;
+  grub_dprintf ("drivemap", "\t#%d: 0x00 <- 0x00 (end)\n", i);
+
+  /* Install our function as the int13h handler in the IVT.  */
+  *int13slot = ((grub_uint32_t) handler_base) << 12;	/* Segment address.  */
+  grub_dprintf ("drivemap", "New int13 handler: %04x:%04x\n",
+		(*int13slot >> 16) & 0x0ffff, *int13slot & 0x0ffff);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+uninstall_int13_handler (void)
+{
+  if (! grub_drivemap_oldhandler)
+    return GRUB_ERR_NONE;
+
+  *int13slot = grub_drivemap_oldhandler;
+  grub_mmap_free_and_unregister (drivemap_mmap);
+  grub_drivemap_oldhandler = 0;
+  grub_dprintf ("drivemap", "Restored int13 handler: %04x:%04x\n",
+		(*int13slot >> 16) & 0x0ffff, *int13slot & 0x0ffff);
+
+  return GRUB_ERR_NONE;
+}
+
+static int
+grub_get_root_biosnumber_drivemap (void)
+{
+  char *biosnum;
+  int ret = -1;
+  grub_device_t dev;
+
+  biosnum = grub_env_get ("biosnum");
+
+  if (biosnum)
+    return grub_strtoul (biosnum, 0, 0);
+
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->dev 
+      && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID)
+    {
+      drivemap_node_t *curnode = map_head;
+      ret = (int) dev->disk->id;
+      while (curnode)
+	{
+	  if (curnode->redirto == ret)
+	    {
+	      ret = curnode->newdrive;
+	      break;
+	    }
+	  curnode = curnode->next;
+	}
+
+    }
+
+  if (dev)
+    grub_device_close (dev);
+
+  return ret;
+}
+
+static grub_extcmd_t cmd;
+static int (*grub_get_root_biosnumber_saved) (void);
+
+GRUB_MOD_INIT (drivemap)
+{
+  grub_get_root_biosnumber_saved = grub_get_root_biosnumber;
+  grub_get_root_biosnumber = grub_get_root_biosnumber_drivemap;
+  cmd = grub_register_extcmd ("drivemap", grub_cmd_drivemap,
+					GRUB_COMMAND_FLAG_BOTH,
+					"drivemap"
+					" -l | -r | [-s] grubdev osdisk",
+					"Manage the BIOS drive mappings",
+					options);
+  drivemap_hook =
+    grub_loader_register_preboot_hook (&install_int13_handler,
+				       &uninstall_int13_handler,
+				       GRUB_LOADER_PREBOOT_HOOK_PRIO_NORMAL);
+}
+
+GRUB_MOD_FINI (drivemap)
+{
+  grub_get_root_biosnumber = grub_get_root_biosnumber_saved;
+  grub_loader_unregister_preboot_hook (drivemap_hook);
+  drivemap_hook = 0;
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/i386/pc/drivemap_int13h.S b/commands/i386/pc/drivemap_int13h.S
new file mode 100644
index 0000000..4403496
--- /dev/null
+++ b/commands/i386/pc/drivemap_int13h.S
@@ -0,0 +1,119 @@
+/* drivemap_int13h.S - interrupt handler for the BIOS drive remapper */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+#define INT13H_OFFSET(x) ((x) - EXT_C(grub_drivemap_handler))
+
+.code16
+
+/* Copy starts here.  When deployed, this code must be segment-aligned.  */
+
+/* The replacement int13 handler.   Preserve all registers.  */
+FUNCTION(grub_drivemap_handler)
+	/* Save %dx for future restore. */
+	push	%dx
+	/* Push flags. Used to simulate interrupt with original flags. */
+	pushf
+
+	/* Map the drive number (always in DL).  */
+	push	%ax
+	push	%bx
+#ifdef APPLE_CC
+	grub_drivemap_mapstart_ofs = INT13H_OFFSET(EXT_C(grub_drivemap_mapstart))
+	movw	$grub_drivemap_mapstart_ofs, %bx
+#else
+	movw	$INT13H_OFFSET(EXT_C(grub_drivemap_mapstart)), %bx
+#endif
+
+more_remaining:
+	movw	%cs:(%bx), %ax
+	cmpb	%ah, %al
+	jz	not_found /* DRV=DST => map end - drive not remapped, keep DL.  */
+	inc	%bx
+	inc	%bx
+	cmpb	%dl, %al
+	jnz	more_remaining /* Not found, but more remaining, loop.  */
+	movb	%ah, %dl /* Found - drive remapped, modify DL.  */
+
+not_found:
+	pop	%bx
+	pop	%ax
+
+	/* If the call isn't ah=0x8 or ah=0x15 we must restore %dx.  */
+	cmpb	$0x8, %ah
+	jz	norestore
+	cmpb	$0x15, %ah
+	jz	norestore
+
+	/* Restore flags.  */
+	popf
+	pushf
+
+#ifdef APPLE_CC
+	grub_drivemap_oldhandler_ofs = INT13H_OFFSET (EXT_C (grub_drivemap_oldhandler))
+	lcall *%cs:grub_drivemap_oldhandler_ofs
+#else
+	lcall *%cs:INT13H_OFFSET (EXT_C (grub_drivemap_oldhandler))
+#endif
+
+	push	%bp
+	mov	%sp, %bp
+
+tail:
+	/* Save new flags below %esp so the caller will recieve new flags.  */
+	pushf
+	pop	%dx
+	mov	%dx, 8(%bp)
+
+	pop	%bp
+
+	/* Restore %dx.  */
+	pop	%dx
+	iret
+
+norestore:
+
+	/* Restore flags.  */
+	popf
+	pushf
+
+#ifdef APPLE_CC
+	lcall *%cs:grub_drivemap_oldhandler_ofs
+#else
+	lcall *%cs:INT13H_OFFSET (EXT_C (grub_drivemap_oldhandler))
+#endif
+
+	push	%bp
+	mov	%sp, %bp
+
+	/* Save %dx. So it won't be restored to original value.  */
+	mov	%dx, 2(%bp)
+
+	jmp tail
+
+/* Far pointer to the old handler.  Stored as a CS:IP in the style of real-mode
+   IVT entries (thus PI:SC in mem).  */
+VARIABLE(grub_drivemap_oldhandler)
+	.word 0x0, 0x0
+
+/* This label MUST be at the end of the copied block, since the installer code
+   reserves additional space for mappings at runtime and copies them over it.  */
+.align 2
+VARIABLE(grub_drivemap_mapstart)
diff --git a/commands/i386/pc/halt.c b/commands/i386/pc/halt.c
new file mode 100644
index 0000000..add8631
--- /dev/null
+++ b/commands/i386/pc/halt.c
@@ -0,0 +1,57 @@
+/* halt.c - command to halt the computer.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/machine/init.h>
+#include <grub/extcmd.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"no-apm", 'n', 0, "do not use APM to halt the computer", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_err_t
+grub_cmd_halt (grub_extcmd_t cmd,
+	       int argc __attribute__ ((unused)),
+	       char **args __attribute__ ((unused)))
+
+{
+  struct grub_arg_list *state = cmd->state;
+  int no_apm = 0;
+  if (state[0].set)
+    no_apm = 1;
+  grub_halt (no_apm);
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(halt)
+{
+  cmd = grub_register_extcmd ("halt", grub_cmd_halt, GRUB_COMMAND_FLAG_BOTH,
+			      "halt [-n]",
+			      "Halt the system, if possible using APM",
+			      options);
+}
+
+GRUB_MOD_FINI(halt)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/i386/pc/play.c b/commands/i386/pc/play.c
new file mode 100644
index 0000000..23150ea
--- /dev/null
+++ b/commands/i386/pc/play.c
@@ -0,0 +1,216 @@
+/* play.c - command to play a tune  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Lots of this file is borrowed from GNU/Hurd generic-speaker driver.  */
+
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/machine/time.h>
+#include <grub/cpu/io.h>
+#include <grub/command.h>
+
+#define BASE_TEMPO 120
+
+/* The speaker port.  */
+#define SPEAKER			0x61
+
+/* If 0, follow state of SPEAKER_DATA bit, otherwise enable output
+   from timer 2.  */
+#define SPEAKER_TMR2		0x01
+
+/* If SPEAKER_TMR2 is not set, this provides direct input into the
+   speaker.  Otherwise, this enables or disables the output from the
+   timer.  */
+#define SPEAKER_DATA		0x02
+
+/* The PIT channel value ports.  You can write to and read from them.
+   Do not mess with timer 0 or 1.  */
+#define PIT_COUNTER_0		0x40
+#define PIT_COUNTER_1		0x41
+#define PIT_COUNTER_2		0x42
+
+/* The frequency of the PIT clock.  */
+#define PIT_FREQUENCY		0x1234dd
+
+/* The PIT control port.  You can only write to it.  Do not mess with
+   timer 0 or 1.  */
+#define PIT_CTRL		0x43
+#define PIT_CTRL_SELECT_MASK	0xc0
+#define PIT_CTRL_SELECT_0	0x00
+#define PIT_CTRL_SELECT_1	0x40
+#define PIT_CTRL_SELECT_2	0x80
+
+/* Read and load control.  */
+#define PIT_CTRL_READLOAD_MASK	0x30
+#define PIT_CTRL_COUNTER_LATCH	0x00	/* Hold timer value until read.  */
+#define PIT_CTRL_READLOAD_LSB	0x10	/* Read/load the LSB.  */
+#define PIT_CTRL_READLOAD_MSB	0x20	/* Read/load the MSB.  */
+#define PIT_CTRL_READLOAD_WORD	0x30	/* Read/load the LSB then the MSB.  */
+
+/* Mode control.  */
+#define PIT_CTRL_MODE_MASK	0x0e
+
+/* Interrupt on terminal count.  Setting the mode sets output to low.
+   When counter is set and terminated, output is set to high.  */
+#define PIT_CTRL_INTR_ON_TERM	0x00
+
+/* Programmable one-shot.  When loading counter, output is set to
+   high.  When counter terminated, output is set to low.  Can be
+   triggered again from that point on by setting the gate pin to
+   high.  */
+#define PIT_CTRL_PROGR_ONE_SHOT	0x02
+
+/* Rate generator.  Output is low for one period of the counter, and
+   high for the other.  */
+#define PIT_CTRL_RATE_GEN	0x04
+
+/* Square wave generator.  Output is low for one half of the period,
+   and high for the other half.  */
+#define PIT_CTRL_SQUAREWAVE_GEN	0x06
+
+/* Software triggered strobe.  Setting the mode sets output to high.
+   When counter is set and terminated, output is set to low.  */
+#define PIT_CTRL_SOFTSTROBE	0x08
+
+/* Hardware triggered strobe.  Like software triggered strobe, but
+   only starts the counter when the gate pin is set to high.  */
+#define PIT_CTRL_HARDSTROBE	0x0a
+
+/* Count mode.  */
+#define PIT_CTRL_COUNT_MASK	0x01
+#define PIT_CTRL_COUNT_BINARY	0x00	/* 16-bit binary counter.  */
+#define PIT_CTRL_COUNT_BCD	0x01	/* 4-decade BCD counter.  */
+
+#define T_REST			((short) 0)
+#define T_FINE			((short) -1)
+
+struct note
+{
+  short pitch;
+  short duration;
+};
+
+static void
+beep_off (void)
+{
+  unsigned char status;
+
+  status = grub_inb (SPEAKER);
+  grub_outb (status & ~(SPEAKER_TMR2 | SPEAKER_DATA), SPEAKER);
+}
+
+static void
+beep_on (short pitch)
+{
+  unsigned char status;
+  unsigned int counter;
+
+  if (pitch < 20)
+    pitch = 20;
+  else if (pitch > 20000)
+    pitch = 20000;
+
+  counter = PIT_FREQUENCY / pitch;
+
+  /* Program timer 2.  */
+  grub_outb (PIT_CTRL_SELECT_2 | PIT_CTRL_READLOAD_WORD
+	| PIT_CTRL_SQUAREWAVE_GEN | PIT_CTRL_COUNT_BINARY, PIT_CTRL);
+  grub_outb (counter & 0xff, PIT_COUNTER_2);		/* LSB */
+  grub_outb ((counter >> 8) & 0xff, PIT_COUNTER_2);	/* MSB */
+
+  /* Start speaker.  */
+  status = grub_inb (SPEAKER);
+  grub_outb (status | SPEAKER_TMR2 | SPEAKER_DATA, SPEAKER);
+}
+
+static grub_err_t
+grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
+	       int argc, char **args)
+{
+  grub_file_t file;
+  struct note buf;
+  int tempo;
+  unsigned int to;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  file = grub_file_open (args[0]);
+  if (! file)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+
+  if (grub_file_read (file, &tempo, sizeof(tempo)) != sizeof(tempo))
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_FILE_READ_ERROR,
+                         "file doesn't even contains a full tempo record");
+    }
+
+  grub_dprintf ("play","tempo = %d\n", tempo);
+
+  while (grub_file_read (file, &buf,
+                         sizeof (struct note)) == sizeof (struct note)
+         && buf.pitch != T_FINE && grub_checkkey () < 0)
+    {
+
+      grub_dprintf ("play", "pitch = %d, duration = %d\n", buf.pitch,
+                    buf.duration);
+
+      switch (buf.pitch)
+        {
+          case T_REST:
+            beep_off ();
+            break;
+
+          default:
+            beep_on (buf.pitch);
+            break;
+        }
+
+      to = grub_get_rtc () + BASE_TEMPO * buf.duration / tempo;
+      while (((unsigned int) grub_get_rtc () <= to) && (grub_checkkey () < 0))
+        ;
+
+    }
+
+  beep_off ();
+
+  grub_file_close (file);
+
+  while (grub_checkkey () > 0)
+    grub_getkey ();
+
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(play)
+{
+  cmd = grub_register_command ("play", grub_cmd_play,
+			       "play FILE", "Play a tune");
+}
+
+GRUB_MOD_FINI(play)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/i386/pc/pxecmd.c b/commands/i386/pc/pxecmd.c
new file mode 100644
index 0000000..df53870
--- /dev/null
+++ b/commands/i386/pc/pxecmd.c
@@ -0,0 +1,99 @@
+/* pxe.c - command to control the pxe driver  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/machine/pxe.h>
+#include <grub/extcmd.h>
+
+static const struct grub_arg_option options[] =
+{
+    {"info", 'i', 0, "show PXE information.", 0, 0},
+    {"bsize", 'b', 0, "set PXE block size", 0, ARG_TYPE_INT},
+    {"unload", 'u', 0, "unload PXE stack.", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static void
+print_ip (grub_uint32_t ip)
+{
+  int i;
+
+  for (i = 0; i < 3; i++)
+    {
+      grub_printf ("%d.", ip & 0xFF);
+      ip >>= 8;
+    }
+  grub_printf ("%d", ip);
+}
+
+static grub_err_t
+grub_cmd_pxe (grub_extcmd_t cmd, int argc __attribute__ ((unused)),
+	      char **args __attribute__ ((unused)))
+{
+  struct grub_arg_list *state = cmd->state;
+
+  if (! grub_pxe_pxenv)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no pxe environment");
+
+  if (state[1].set)
+    {
+      int size;
+
+      size = grub_strtoul (state[1].arg, 0, 0);
+      if (size < GRUB_PXE_MIN_BLKSIZE)
+        size = GRUB_PXE_MIN_BLKSIZE;
+      else if (size > GRUB_PXE_MAX_BLKSIZE)
+        size = GRUB_PXE_MAX_BLKSIZE;
+
+      grub_pxe_blksize = size;
+    }
+
+  if (state[0].set)
+    {
+      grub_printf ("blksize : %d\n", grub_pxe_blksize);
+      grub_printf ("client ip  : ");
+      print_ip (grub_pxe_your_ip);
+      grub_printf ("\nserver ip  : ");
+      print_ip (grub_pxe_server_ip);
+      grub_printf ("\ngateway ip : ");
+      print_ip (grub_pxe_gateway_ip);
+      grub_printf ("\n");
+    }
+
+  if (state[2].set)
+    grub_pxe_unload ();
+
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(pxecmd)
+{
+  cmd = grub_register_extcmd ("pxe", grub_cmd_pxe, GRUB_COMMAND_FLAG_BOTH,
+			      "pxe [-i|-b|-u]",
+			      "Command to control the PXE device.", options);
+}
+
+GRUB_MOD_FINI(pxecmd)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/i386/pc/vbeinfo.c b/commands/i386/pc/vbeinfo.c
new file mode 100644
index 0000000..ee9f3c1
--- /dev/null
+++ b/commands/i386/pc/vbeinfo.c
@@ -0,0 +1,184 @@
+/* vbeinfo.c - command to list compatible VBE video modes.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/machine/init.h>
+#include <grub/machine/vbe.h>
+#include <grub/mm.h>
+#include <grub/command.h>
+
+static void *
+real2pm (grub_vbe_farptr_t ptr)
+{
+  return (void *) ((((unsigned long) ptr & 0xFFFF0000) >> 12UL)
+		   + ((unsigned long) ptr & 0x0000FFFF));
+}
+
+static grub_err_t
+grub_cmd_vbeinfo (grub_command_t cmd __attribute__ ((unused)),
+		  int argc __attribute__ ((unused)),
+		  char **args __attribute__ ((unused)))
+{
+  struct grub_vbe_info_block controller_info;
+  struct grub_vbe_mode_info_block mode_info_tmp;
+  grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
+  grub_uint16_t *video_mode_list;
+  grub_uint16_t *p;
+  grub_uint16_t *saved_video_mode_list;
+  grub_size_t video_mode_list_size;
+  grub_err_t err;
+  char *modevar;
+
+  err = grub_vbe_probe (&controller_info);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  grub_printf ("VBE info:   version: %d.%d  OEM software rev: %d.%d\n",
+	       controller_info.version >> 8,
+               controller_info.version & 0xFF,
+               controller_info.oem_software_rev >> 8,
+               controller_info.oem_software_rev & 0xFF);
+
+  /* The total_memory field is in 64 KiB units.  */
+  grub_printf ("            total memory: %d KiB\n",
+               (controller_info.total_memory << 16) / 1024);
+
+  /* Because the information on video modes is stored in a temporary place,
+     it is better to copy it to somewhere safe.  */
+  p = video_mode_list = real2pm (controller_info.video_mode_ptr);
+  while (*p++ != 0xFFFF)
+    ;
+
+  video_mode_list_size = (grub_addr_t) p - (grub_addr_t) video_mode_list;
+  saved_video_mode_list = grub_malloc (video_mode_list_size);
+  if (! saved_video_mode_list)
+    return grub_errno;
+
+  grub_memcpy (saved_video_mode_list, video_mode_list, video_mode_list_size);
+
+  grub_printf ("List of compatible video modes:\n");
+  grub_printf ("Legend: P=Packed pixel, D=Direct color, "
+	       "mask/pos=R/G/B/reserved\n");
+
+  /* Walk through all video modes listed.  */
+  for (p = saved_video_mode_list; *p != 0xFFFF; p++)
+    {
+      const char *memory_model = 0;
+      grub_uint32_t mode = (grub_uint32_t) *p;
+
+      err = grub_vbe_get_video_mode_info (mode, &mode_info_tmp);
+      if (err != GRUB_ERR_NONE)
+	{
+	  grub_errno = GRUB_ERR_NONE;
+	  continue;
+	}
+
+      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_SUPPORTED) == 0)
+	/* If not available, skip it.  */
+	continue;
+
+      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_RESERVED_1) == 0)
+	/* Not enough information.  */
+	continue;
+
+      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_COLOR) == 0)
+	/* Monochrome is unusable.  */
+	continue;
+
+      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_LFB_AVAIL) == 0)
+	/* We support only linear frame buffer modes.  */
+	continue;
+
+      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_GRAPHICS) == 0)
+	/* We allow only graphical modes.  */
+	continue;
+
+      switch (mode_info_tmp.memory_model)
+	{
+	case GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL:
+	  memory_model = "Packed";
+	  break;
+	case GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR:
+	  memory_model = "Direct";
+	  break;
+
+	default:
+	  break;
+	}
+
+      if (! memory_model)
+	continue;
+
+      grub_printf ("0x%03x:  %4d x %4d x %2d  %s",
+                   mode,
+                   mode_info_tmp.x_resolution,
+                   mode_info_tmp.y_resolution,
+                   mode_info_tmp.bits_per_pixel,
+                   memory_model);
+
+      /* Show mask and position details for direct color modes.  */
+      if (mode_info_tmp.memory_model == GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)
+        grub_printf (", mask: %d/%d/%d/%d  pos: %d/%d/%d/%d",
+                     mode_info_tmp.red_mask_size,
+                     mode_info_tmp.green_mask_size,
+                     mode_info_tmp.blue_mask_size,
+                     mode_info_tmp.rsvd_mask_size,
+                     mode_info_tmp.red_field_position,
+                     mode_info_tmp.green_field_position,
+                     mode_info_tmp.blue_field_position,
+                     mode_info_tmp.rsvd_field_position);
+      grub_printf ("\n");
+    }
+
+  grub_free (saved_video_mode_list);
+
+  /* Check existence of vbe_mode environment variable.  */
+  modevar = grub_env_get ("vbe_mode");
+
+  if (modevar != 0)
+    {
+      unsigned long value;
+
+      value = grub_strtoul (modevar, 0, 0);
+      if (grub_errno == GRUB_ERR_NONE)
+	use_mode = value;
+      else
+	grub_errno = GRUB_ERR_NONE;
+    }
+
+  grub_printf ("Configured VBE mode (vbe_mode) = 0x%03x\n", use_mode);
+
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(vbeinfo)
+{
+  cmd =
+    grub_register_command ("vbeinfo", grub_cmd_vbeinfo, 0,
+			   "List compatible VESA BIOS extension video modes.");
+}
+
+GRUB_MOD_FINI(vbeinfo)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/i386/pc/vbetest.c b/commands/i386/pc/vbetest.c
new file mode 100644
index 0000000..314320d
--- /dev/null
+++ b/commands/i386/pc/vbetest.c
@@ -0,0 +1,177 @@
+/* vbetest.c - command to test VESA BIOS Extension 2.0+ support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/machine/init.h>
+#include <grub/machine/vbe.h>
+#include <grub/err.h>
+
+static grub_err_t
+grub_cmd_vbetest (grub_command_t cmd __attribute__ ((unused)),
+		  int argc __attribute__ ((unused)),
+		  char **args __attribute__ ((unused)))
+{
+  grub_err_t err;
+  char *modevar;
+  struct grub_vbe_mode_info_block mode_info;
+  struct grub_vbe_info_block controller_info;
+  grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
+  grub_uint32_t old_mode;
+  grub_uint8_t *framebuffer = 0;
+  grub_uint32_t bytes_per_scan_line = 0;
+  unsigned char *ptr;
+  int i;
+
+  grub_printf ("Probing for VESA BIOS Extension ... ");
+
+  /* Check if VESA BIOS exists.  */
+  err = grub_vbe_probe (&controller_info);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  grub_printf ("found!\n");
+
+  /* Dump out controller information.  */
+  grub_printf ("VBE signature = %c%c%c%c\n",
+	       controller_info.signature[0],
+	       controller_info.signature[1],
+	       controller_info.signature[2],
+	       controller_info.signature[3]);
+
+  grub_printf ("VBE version = %d.%d\n",
+	       controller_info.version >> 8,
+	       controller_info.version & 0xFF);
+  grub_printf ("OEM string ptr = %08x\n",
+	       controller_info.oem_string_ptr);
+  grub_printf ("Total memory = %d\n",
+	       controller_info.total_memory);
+
+  err = grub_vbe_get_video_mode (&old_mode);
+  grub_printf ("Get video mode err = %04x\n", err);
+
+  if (err == GRUB_ERR_NONE)
+    grub_printf ("Old video mode = %04x\n", old_mode);
+  else
+    grub_errno = GRUB_ERR_NONE;
+
+  /* Check existence of vbe_mode environment variable.  */
+  modevar = grub_env_get ("vbe_mode");
+  if (modevar != 0)
+    {
+      unsigned long value;
+
+      value = grub_strtoul (modevar, 0, 0);
+      if (grub_errno == GRUB_ERR_NONE)
+	use_mode = value;
+      else
+	grub_errno = GRUB_ERR_NONE;
+    }
+
+  err = grub_vbe_get_video_mode_info (use_mode, &mode_info);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  /* Dump out details about the mode being tested.  */
+  grub_printf ("mode: 0x%03x\n",
+               use_mode);
+  grub_printf ("width : %d\n",
+               mode_info.x_resolution);
+  grub_printf ("height: %d\n",
+               mode_info.y_resolution);
+  grub_printf ("memory model: %02x\n",
+               mode_info.memory_model);
+  grub_printf ("bytes/scanline: %d\n",
+               mode_info.bytes_per_scan_line);
+  grub_printf ("bytes/scanline (lin): %d\n",
+               mode_info.lin_bytes_per_scan_line);
+  grub_printf ("base address: %08x\n",
+               mode_info.phys_base_addr);
+  grub_printf ("red mask/pos: %d/%d\n",
+               mode_info.red_mask_size,
+               mode_info.red_field_position);
+  grub_printf ("green mask/pos: %d/%d\n",
+               mode_info.green_mask_size,
+               mode_info.green_field_position);
+  grub_printf ("blue mask/pos: %d/%d\n",
+               mode_info.blue_mask_size,
+               mode_info.blue_field_position);
+
+  grub_printf ("Press any key to continue.\n");
+
+  grub_getkey ();
+
+  /* Setup GFX mode.  */
+  err = grub_vbe_set_video_mode (use_mode, &mode_info);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  /* Determine framebuffer address and how many bytes are in scan line.  */
+  framebuffer = (grub_uint8_t *) mode_info.phys_base_addr;
+  ptr = framebuffer;
+
+  if (controller_info.version >= 0x300)
+    {
+      bytes_per_scan_line = mode_info.lin_bytes_per_scan_line;
+    }
+  else
+    {
+      bytes_per_scan_line = mode_info.bytes_per_scan_line;
+    }
+
+  /* Draw some random data to screen.  */
+  for (i = 0; i < 256 * 256; i++)
+    {
+      ptr[i] = i & 0x0F;
+    }
+
+  /* Draw white line to screen.  */
+  for (i = 0; i < 100; i++)
+    {
+      ptr[mode_info.bytes_per_scan_line * 50 + i] = 0x0F;
+    }
+
+  /* Draw another white line to screen.  */
+  grub_memset (ptr + bytes_per_scan_line * 51, 0x0f, bytes_per_scan_line);
+
+  grub_getkey ();
+
+  grub_video_restore ();
+
+  /* Restore old video mode.  */
+  grub_vbe_set_video_mode (old_mode, 0);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(vbetest)
+{
+  cmd = grub_register_command ("vbetest", grub_cmd_vbetest,
+			       0, "Test VESA BIOS Extension 2.0+ support");
+}
+
+GRUB_MOD_FINI(vbetest)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/ieee1275/suspend.c b/commands/ieee1275/suspend.c
new file mode 100644
index 0000000..028dd3c
--- /dev/null
+++ b/commands/ieee1275/suspend.c
@@ -0,0 +1,48 @@
+/* suspend.c - command to suspend GRUB and return to Open Firmware  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/command.h>
+
+static grub_err_t
+grub_cmd_suspend (grub_command_t cmd __attribute__ ((unused)),
+		  int argc __attribute__ ((unused)),
+		  char **args __attribute__ ((unused)))
+{
+  grub_printf ("Run 'go' to resume GRUB.\n");
+  grub_ieee1275_enter ();
+  grub_cls ();
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(ieee1275_suspend)
+{
+  cmd = grub_register_command ("suspend", grub_cmd_suspend,
+			       0, "Return to Open Firmware prompt");
+}
+
+GRUB_MOD_FINI(ieee1275_suspend)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/keystatus.c b/commands/keystatus.c
new file mode 100644
index 0000000..28ceb2d
--- /dev/null
+++ b/commands/keystatus.c
@@ -0,0 +1,81 @@
+/* keystatus.c - Command to check key modifier status.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/term.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"shift", 's', 0, "check Shift key", 0, 0},
+    {"ctrl", 'c', 0, "check Control key", 0, 0},
+    {"alt", 'a', 0, "check Alt key", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+#define grub_cur_term_input	grub_term_get_current_input ()
+
+static grub_err_t
+grub_cmd_keystatus (grub_extcmd_t cmd,
+		    int argc __attribute__ ((unused)),
+		    char **args __attribute__ ((unused)))
+{
+  struct grub_arg_list *state = cmd->state;
+  int expect_mods = 0;
+  int mods;
+
+  if (state[0].set)
+    expect_mods |= GRUB_TERM_STATUS_SHIFT;
+  if (state[1].set)
+    expect_mods |= GRUB_TERM_STATUS_CTRL;
+  if (state[2].set)
+    expect_mods |= GRUB_TERM_STATUS_ALT;
+
+  /* Without arguments, just check whether getkeystatus is supported at
+     all.  */
+  if (!grub_cur_term_input->getkeystatus)
+    return grub_error (GRUB_ERR_TEST_FAILURE, "false");
+  grub_dprintf ("keystatus", "expect_mods: %d\n", expect_mods);
+  if (!expect_mods)
+    return 0;
+
+  mods = grub_getkeystatus ();
+  grub_dprintf ("keystatus", "mods: %d\n", mods);
+  if (mods >= 0 && (mods & expect_mods) != 0)
+    return 0;
+  else
+    return grub_error (GRUB_ERR_TEST_FAILURE, "false");
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(keystatus)
+{
+  cmd = grub_register_extcmd ("keystatus", grub_cmd_keystatus,
+			      GRUB_COMMAND_FLAG_BOTH,
+			      "keystatus [--shift] [--ctrl] [--alt]",
+			      "Check key modifier status",
+			      options);
+}
+
+GRUB_MOD_FINI(keystatus)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/loadenv.c b/commands/loadenv.c
new file mode 100644
index 0000000..c60eb83
--- /dev/null
+++ b/commands/loadenv.c
@@ -0,0 +1,409 @@
+/* loadenv.c - command to load/save environment variable.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/partition.h>
+#include <grub/lib/envblk.h>
+#include <grub/extcmd.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"file", 'f', 0, "specify filename", 0, ARG_TYPE_PATHNAME},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_file_t
+open_envblk_file (char *filename)
+{
+  grub_file_t file;
+
+  if (! filename)
+    {
+      char *prefix;
+
+      prefix = grub_env_get ("prefix");
+      if (prefix)
+        {
+          int len;
+
+          len = grub_strlen (prefix);
+          filename = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG));
+          if (! filename)
+            return 0;
+
+          grub_strcpy (filename, prefix);
+          filename[len] = '/';
+          grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG);
+          file = grub_file_open (filename);
+          grub_free (filename);
+          return file;
+        }
+      else
+        {
+          grub_error (GRUB_ERR_FILE_NOT_FOUND, "prefix is not found");
+          return 0;
+        }
+    }
+
+  return grub_file_open (filename);
+}
+
+static grub_envblk_t
+read_envblk_file (grub_file_t file)
+{
+  grub_off_t offset = 0;
+  char *buf;
+  grub_size_t size = grub_file_size (file);
+  grub_envblk_t envblk;
+
+  buf = grub_malloc (size);
+  if (! buf)
+    return 0;
+
+  while (size > 0)
+    {
+      grub_ssize_t ret;
+
+      ret = grub_file_read (file, buf + offset, size);
+      if (ret <= 0)
+        {
+          if (grub_errno == GRUB_ERR_NONE)
+            grub_error (GRUB_ERR_FILE_READ_ERROR, "cannot read");
+          grub_free (buf);
+          return 0;
+        }
+
+      size -= ret;
+      offset += ret;
+    }
+
+  envblk = grub_envblk_open (buf, offset);
+  if (! envblk)
+    {
+      grub_free (buf);
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
+      return 0;
+    }
+
+  return envblk;
+}
+
+static grub_err_t
+grub_cmd_load_env (grub_extcmd_t cmd,
+		   int argc __attribute__ ((unused)),
+		   char **args __attribute__ ((unused)))
+{
+  struct grub_arg_list *state = cmd->state;
+  grub_file_t file;
+  grub_envblk_t envblk;
+
+  auto int set_var (const char *name, const char *value);
+  int set_var (const char *name, const char *value)
+  {
+    grub_env_set (name, value);
+    return 0;
+  }
+
+  file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
+  if (! file)
+    return grub_errno;
+
+  envblk = read_envblk_file (file);
+  if (! envblk)
+    goto fail;
+
+  grub_envblk_iterate (envblk, set_var);
+  grub_envblk_close (envblk);
+
+ fail:
+  grub_file_close (file);
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_list_env (grub_extcmd_t cmd,
+		   int argc __attribute__ ((unused)),
+		   char **args __attribute__ ((unused)))
+{
+  struct grub_arg_list *state = cmd->state;
+  grub_file_t file;
+  grub_envblk_t envblk;
+
+  /* Print all variables in current context.  */
+  auto int print_var (const char *name, const char *value);
+  int print_var (const char *name, const char *value)
+    {
+      grub_printf ("%s=%s\n", name, value);
+      return 0;
+    }
+
+  file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
+  if (! file)
+    return grub_errno;
+
+  envblk = read_envblk_file (file);
+  if (! envblk)
+    goto fail;
+
+  grub_envblk_iterate (envblk, print_var);
+  grub_envblk_close (envblk);
+
+ fail:
+  grub_file_close (file);
+  return grub_errno;
+}
+
+/* Used to maintain a variable length of blocklists internally.  */
+struct blocklist
+{
+  grub_disk_addr_t sector;
+  unsigned offset;
+  unsigned length;
+  struct blocklist *next;
+};
+
+static void
+free_blocklists (struct blocklist *p)
+{
+  struct blocklist *q;
+
+  for (; p; p = q)
+    {
+      q = p->next;
+      grub_free (p);
+    }
+}
+
+static int
+check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
+                  grub_file_t file)
+{
+  grub_size_t total_length;
+  grub_size_t index;
+  grub_disk_t disk;
+  grub_disk_addr_t part_start;
+  struct blocklist *p;
+  char *buf;
+
+  /* Sanity checks.  */
+  total_length = 0;
+  for (p = blocklists; p; p = p->next)
+    {
+      struct blocklist *q;
+      for (q = p->next; q; q = q->next)
+        {
+          /* Check if any pair of blocks overlap.  */
+          if (p->sector == q->sector)
+            {
+              /* This might be actually valid, but it is unbelievable that
+                 any filesystem makes such a silly allocation.  */
+              grub_error (GRUB_ERR_BAD_FS, "malformed file");
+              return 0;
+            }
+        }
+
+      total_length += p->length;
+    }
+
+  if (total_length != grub_file_size (file))
+    {
+      /* Maybe sparse, unallocated sectors. No way in GRUB.  */
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "sparse file not allowed");
+      return 0;
+    }
+
+  /* One more sanity check. Re-read all sectors by blocklists, and compare
+     those with the data read via a file.  */
+  disk = file->device->disk;
+  if (disk->partition)
+    part_start = grub_partition_get_start (disk->partition);
+  else
+    part_start = 0;
+
+  buf = grub_envblk_buffer (envblk);
+  for (p = blocklists, index = 0; p; index += p->length, p = p->next)
+    {
+      char blockbuf[GRUB_DISK_SECTOR_SIZE];
+
+      if (grub_disk_read (disk, p->sector - part_start,
+                          p->offset, p->length, blockbuf))
+        return 0;
+
+      if (grub_memcmp (buf + index, blockbuf, p->length) != 0)
+        {
+          grub_error (GRUB_ERR_FILE_READ_ERROR, "invalid blocklist");
+          return 0;
+        }
+    }
+
+  return 1;
+}
+
+static int
+write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
+                  grub_file_t file)
+{
+  char *buf;
+  grub_disk_t disk;
+  grub_disk_addr_t part_start;
+  struct blocklist *p;
+  grub_size_t index;
+
+  buf = grub_envblk_buffer (envblk);
+  disk = file->device->disk;
+  if (disk->partition)
+    part_start = grub_partition_get_start (disk->partition);
+  else
+    part_start = 0;
+
+  index = 0;
+  for (p = blocklists; p; index += p->length, p = p->next)
+    {
+      if (grub_disk_write (disk, p->sector - part_start,
+                           p->offset, p->length, buf + index))
+        return 0;
+    }
+
+  return 1;
+}
+
+static grub_err_t
+grub_cmd_save_env (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  grub_file_t file;
+  grub_envblk_t envblk;
+  struct blocklist *head = 0;
+  struct blocklist *tail = 0;
+
+  /* Store blocklists in a linked list.  */
+  auto void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector,
+                                        unsigned offset,
+                                        unsigned length);
+  void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector,
+                                   unsigned offset, unsigned length)
+    {
+      struct blocklist *block;
+
+      if (offset + length > GRUB_DISK_SECTOR_SIZE)
+        /* Seemingly a bug.  */
+        return;
+
+      block = grub_malloc (sizeof (*block));
+      if (! block)
+        return;
+
+      block->sector = sector;
+      block->offset = offset;
+      block->length = length;
+
+      /* Slightly complicated, because the list should be FIFO.  */
+      block->next = 0;
+      if (tail)
+        tail->next = block;
+      tail = block;
+      if (! head)
+        head = block;
+    }
+
+  if (! argc)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "No variable is specified");
+
+  file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
+  if (! file)
+    return grub_errno;
+
+  if (! file->device->disk)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_BAD_DEVICE, "disk device required");
+    }
+
+  file->read_hook = read_hook;
+  envblk = read_envblk_file (file);
+  file->read_hook = 0;
+  if (! envblk)
+    goto fail;
+
+  if (! check_blocklists (envblk, head, file))
+    goto fail;
+
+  while (argc)
+    {
+      char *value;
+
+      value = grub_env_get (args[0]);
+      if (value)
+        {
+          if (! grub_envblk_set (envblk, args[0], value))
+            {
+              grub_error (GRUB_ERR_BAD_ARGUMENT, "environment block too small");
+              goto fail;
+            }
+        }
+
+      argc--;
+      args++;
+    }
+
+  write_blocklists (envblk, head, file);
+
+ fail:
+  if (envblk)
+    grub_envblk_close (envblk);
+  free_blocklists (head);
+  grub_file_close (file);
+  return grub_errno;
+}
+
+static grub_extcmd_t cmd_load, cmd_list, cmd_save;
+
+GRUB_MOD_INIT(loadenv)
+{
+  cmd_load =
+    grub_register_extcmd ("load_env", grub_cmd_load_env,
+			  GRUB_COMMAND_FLAG_BOTH,
+			  "load_env [-f FILE]",
+			  "Load variables from environment block file.",
+			  options);
+  cmd_list =
+    grub_register_extcmd ("list_env", grub_cmd_list_env,
+			  GRUB_COMMAND_FLAG_BOTH,
+			  "list_env [-f FILE]",
+			  "List variables from environment block file.",
+			  options);
+  cmd_save =
+    grub_register_extcmd ("save_env", grub_cmd_save_env,
+			  GRUB_COMMAND_FLAG_BOTH,
+			  "save_env [-f FILE] variable_name [...]",
+			  "Save variables to environment block file.",
+			  options);
+}
+
+GRUB_MOD_FINI(loadenv)
+{
+  grub_unregister_extcmd (cmd_load);
+  grub_unregister_extcmd (cmd_list);
+  grub_unregister_extcmd (cmd_save);
+}
diff --git a/commands/ls.c b/commands/ls.c
new file mode 100644
index 0000000..15b4c6b
--- /dev/null
+++ b/commands/ls.c
@@ -0,0 +1,270 @@
+/* ls.c - command to list files and devices */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/device.h>
+#include <grub/term.h>
+#include <grub/partition.h>
+#include <grub/file.h>
+#include <grub/normal.h>
+#include <grub/extcmd.h>
+#include <grub/datetime.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"long", 'l', 0, "show a long list with more detailed information", 0, 0},
+    {"human-readable", 'h', 0, "print sizes in a human readable format", 0, 0},
+    {"all", 'a', 0, "list all files", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'};
+
+static grub_err_t
+grub_ls_list_devices (int longlist)
+{
+  auto int grub_ls_print_devices (const char *name);
+  int grub_ls_print_devices (const char *name)
+    {
+      if (longlist)
+	grub_normal_print_device_info (name);
+      else
+	grub_printf ("(%s) ", name);
+
+      return 0;
+    }
+
+  grub_device_iterate (grub_ls_print_devices);
+  grub_putchar ('\n');
+  grub_refresh ();
+
+  return 0;
+}
+
+static grub_err_t
+grub_ls_list_files (char *dirname, int longlist, int all, int human)
+{
+  char *device_name;
+  grub_fs_t fs;
+  const char *path;
+  grub_device_t dev;
+
+  auto int print_files (const char *filename,
+			const struct grub_dirhook_info *info);
+  auto int print_files_long (const char *filename,
+			     const struct grub_dirhook_info *info);
+
+  int print_files (const char *filename, const struct grub_dirhook_info *info)
+    {
+      if (all || filename[0] != '.')
+	grub_printf ("%s%s ", filename, info->dir ? "/" : "");
+
+      return 0;
+    }
+
+  int print_files_long (const char *filename,
+			const struct grub_dirhook_info *info)
+    {
+      char pathname[grub_strlen (dirname) + grub_strlen (filename) + 1];
+
+      if ((! all) && (filename[0] == '.'))
+	return 0;
+
+      if (! info->dir)
+	{
+	  grub_file_t file;
+
+	  if (dirname[grub_strlen (dirname) - 1] == '/')
+	    grub_sprintf (pathname, "%s%s", dirname, filename);
+	  else
+	    grub_sprintf (pathname, "%s/%s", dirname, filename);
+
+	  /* XXX: For ext2fs symlinks are detected as files while they
+	     should be reported as directories.  */
+	  file = grub_file_open (pathname);
+	  if (! file)
+	    {
+	      grub_errno = 0;
+	      return 0;
+	    }
+
+	  if (! human)
+	    grub_printf ("%-12llu", (unsigned long long) file->size);
+	  else
+	    {
+	      grub_uint64_t fsize = file->size * 100ULL;
+	      int fsz = file->size;
+	      int units = 0;
+	      char buf[20];
+
+	      while (fsz / 1024)
+		{
+		  fsize = (fsize + 512) / 1024;
+		  fsz /= 1024;
+		  units++;
+		}
+
+	      if (units)
+		{
+		  grub_uint32_t whole, fraction;
+
+		  whole = grub_divmod64 (fsize, 100, &fraction);
+		  grub_sprintf (buf, "%u.%02u%c", whole, fraction,
+				grub_human_sizes[units]);
+		  grub_printf ("%-12s", buf);
+		}
+	      else
+		grub_printf ("%-12llu", (unsigned long long) file->size);
+
+	    }
+	  grub_file_close (file);
+	}
+      else
+	grub_printf ("%-12s", "DIR");
+
+      if (info->mtimeset)
+	{
+	  struct grub_datetime datetime;
+	  grub_unixtime2datetime (info->mtime, &datetime);
+	  if (human)
+	    grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ",
+			 datetime.year, datetime.month, datetime.day,
+			 datetime.hour, datetime.minute,
+			 datetime.second,
+			 grub_get_weekday_name (&datetime));
+	  else
+	    grub_printf (" %04d%02d%02d%02d%02d%02d ",
+			 datetime.year, datetime.month,
+			 datetime.day, datetime.hour,
+			 datetime.minute, datetime.second);
+	}
+      grub_printf ("%s%s\n", filename, info->dir ? "/" : "");
+
+      return 0;
+    }
+
+  device_name = grub_file_get_device_name (dirname);
+  dev = grub_device_open (device_name);
+  if (! dev)
+    goto fail;
+
+  fs = grub_fs_probe (dev);
+  path = grub_strchr (dirname, ')');
+  if (! path)
+    path = dirname;
+  else
+    path++;
+
+  if (! path && ! device_name)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
+      goto fail;
+    }
+
+  if (! *path)
+    {
+      if (grub_errno == GRUB_ERR_UNKNOWN_FS)
+	grub_errno = GRUB_ERR_NONE;
+
+      grub_normal_print_device_info (device_name);
+    }
+  else if (fs)
+    {
+      if (longlist)
+	(fs->dir) (dev, path, print_files_long);
+      else
+	(fs->dir) (dev, path, print_files);
+
+      if (grub_errno == GRUB_ERR_BAD_FILE_TYPE
+	  && path[grub_strlen (path) - 1] != '/')
+	{
+	  /* PATH might be a regular file.  */
+	  char *p;
+	  grub_file_t file;
+	  struct grub_dirhook_info info;
+	  grub_errno = 0;
+
+	  file = grub_file_open (dirname);
+	  if (! file)
+	    goto fail;
+
+	  grub_file_close (file);
+
+	  p = grub_strrchr (dirname, '/') + 1;
+	  dirname = grub_strndup (dirname, p - dirname);
+	  if (! dirname)
+	    goto fail;
+
+	  all = 1;
+	  grub_memset (&info, 0, sizeof (info));
+	  if (longlist)
+	    print_files_long (p, &info);
+	  else
+	    print_files (p, &info);
+
+	  grub_free (dirname);
+	}
+
+      if (grub_errno == GRUB_ERR_NONE)
+	grub_putchar ('\n');
+
+      grub_refresh ();
+    }
+
+ fail:
+  if (dev)
+    grub_device_close (dev);
+
+  grub_free (device_name);
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_ls (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+
+  if (argc == 0)
+    grub_ls_list_devices (state[0].set);
+  else
+    grub_ls_list_files (args[0], state[0].set, state[2].set,
+			state[1].set);
+
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(ls)
+{
+  cmd = grub_register_extcmd ("ls", grub_cmd_ls, GRUB_COMMAND_FLAG_BOTH,
+			      "ls [-l|-h|-a] [FILE]",
+			      "List devices and files.", options);
+}
+
+GRUB_MOD_FINI(ls)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/lsmmap.c b/commands/lsmmap.c
new file mode 100644
index 0000000..09f141e
--- /dev/null
+++ b/commands/lsmmap.c
@@ -0,0 +1,52 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+
+static grub_err_t
+grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)),
+		 int argc __attribute__ ((unused)), char **args __attribute__ ((unused)))
+
+{
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n",
+		   (long long) addr, (long long) size, type);
+      return 0;
+    }
+  grub_machine_mmap_iterate (hook);
+
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(lsmmap)
+{
+  cmd = grub_register_command ("lsmmap", grub_cmd_lsmmap,
+			       0, "List memory map provided by firmware.");
+}
+
+GRUB_MOD_FINI(lsmmap)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/lspci.c b/commands/lspci.c
new file mode 100644
index 0000000..5b3360a
--- /dev/null
+++ b/commands/lspci.c
@@ -0,0 +1,168 @@
+/* lspci.c - List PCI devices.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/pci.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+
+struct grub_pci_classname
+{
+  int class;
+  int subclass;
+  char *desc;
+};
+
+static const struct grub_pci_classname grub_pci_classes[] =
+  {
+    { 0, 0, "" },
+    { 1, 0, "SCSI Controller" },
+    { 1, 1, "IDE Controller" },
+    { 1, 2, "Floppy Controller" },
+    { 1, 3, "IPI Controller" },
+    { 1, 4, "RAID Controller" },
+    { 1, 6, "SATA Controller" },
+    { 1, 0x80, "Mass storage Controller" },
+    { 2, 0, "Ethernet Controller" },
+    { 2, 1, "Token Ring Controller" },
+    { 2, 2, "FDDI Controller" },
+    { 2, 3, "ATM Controller" },
+    { 2, 4, "ISDN Controller" },
+    { 2, 0x80, "Network controller" },
+    { 3, 0, "VGA Controller" },
+    { 3, 1, "XGA Controller" },
+    { 3, 2, "3D Controller" },
+    { 3, 0x80, "Display Controller" },
+    { 4, 0, "Multimedia Video Device" },
+    { 4, 1, "Multimedia Audio Device" },
+    { 4, 2, "Multimedia Telephony Device" },
+    { 4, 0x80, "Multimedia device" },
+    { 5, 0, "RAM Controller" },
+    { 5, 1, "Flash Memory Controller" },
+    { 5, 0x80, "Memory Controller" },
+    { 6, 0, "Host Bridge" },
+    { 6, 1, "ISA Bridge" },
+    { 6, 2, "EISA Bride" },
+    { 6, 3, "MCA Bridge" },
+    { 6, 4, "PCI-PCI Bridge" },
+    { 6, 5, "PCMCIA Bridge" },
+    { 6, 6, "NuBus Bridge" },
+    { 6, 7, "CardBus Bridge" },
+    { 6, 8, "Raceway Bridge" },
+    { 6, 0x80, "Unknown Bridge" },
+    { 7, 0x80, "Communication controller" },
+    { 8, 0x80, "System hardware" },
+    { 9, 0, "Keyboard Controller" },
+    { 9, 1, "Digitizer" },
+    { 9, 2, "Mouse Controller" },
+    { 9, 3, "Scanner Controller" },
+    { 9, 4, "Gameport Controller" },
+    { 9, 0x80, "Unknown Input Device" },
+    { 10, 0, "Generic Docking Station" },
+    { 10, 0x80, "Unknown Docking Station" },
+    { 11, 0, "80386 Processor" },
+    { 11, 1, "80486 Processor" },
+    { 11, 2, "Pentium Processor" },
+    { 11, 0x10, "Alpha Processor" },
+    { 11, 0x20, "PowerPC Processor" },
+    { 11, 0x30, "MIPS Processor" },
+    { 11, 0x40, "Co-Processor" },
+    { 11, 0x80, "Unknown Processor" },
+    { 12, 0x80, "Serial Bus Controller" },
+    { 13, 0x80, "Wireless Controller" },
+    { 14, 0, "I2O" },
+    { 15, 0, "IrDA Controller" },
+    { 15, 1, "Consumer IR" },
+    { 15, 0x10, "RF-Controller" },
+    { 15, 0x80, "Satellite Communication Controller" },
+    { 16, 0, "Network Decryption" },
+    { 16, 1, "Entertainment Decryption" },
+    { 16, 0x80, "Unknown Decryption Controller" },
+    { 17, 0, "Digital IO Module" },
+    { 17, 0x80, "Unknown Data Input System" },
+    { 0, 0, 0 },
+  };
+
+static const char *
+grub_pci_get_class (int class, int subclass)
+{
+  const struct grub_pci_classname *curr = grub_pci_classes;
+
+  while (curr->desc)
+    {
+      if (curr->class == class && curr->subclass == subclass)
+	return curr->desc;
+      curr++;
+    }
+
+  return 0;
+}
+
+static int NESTED_FUNC_ATTR
+grub_lspci_iter (int bus, int dev, int func, grub_pci_id_t pciid)
+{
+  grub_uint32_t class;
+  const char *sclass;
+  grub_pci_address_t addr;
+
+  grub_printf ("%02x:%02x.%x %04x:%04x", bus, dev, func, pciid & 0xFFFF,
+	       pciid >> 16);
+  addr = grub_pci_make_address (bus, dev, func, 2);
+  class = grub_pci_read (addr);
+
+  /* Lookup the class name, if there isn't a specific one,
+     retry with 0x80 to get the generic class name.  */
+  sclass = grub_pci_get_class (class >> 24, (class >> 16) & 0xFF);
+  if (! sclass)
+    sclass = grub_pci_get_class (class >> 24, 0x80);
+  if (! sclass)
+    sclass = "";
+
+  grub_printf (" [%04x] %s", (class >> 16) & 0xffff, sclass);
+
+  grub_uint8_t pi = (class >> 8) & 0xff;
+  if (pi)
+    grub_printf (" [PI %02x]", pi);
+
+  grub_printf ("\n");
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_lspci (grub_command_t cmd __attribute__ ((unused)),
+		int argc __attribute__ ((unused)),
+		char **args __attribute__ ((unused)))
+{
+  grub_pci_iterate (grub_lspci_iter);
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(pci)
+{
+  cmd = grub_register_command ("lspci", grub_cmd_lspci,
+			       0, "List PCI devices");
+}
+
+GRUB_MOD_FINI(pci)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/memrw.c b/commands/memrw.c
new file mode 100644
index 0000000..adffb7f
--- /dev/null
+++ b/commands/memrw.c
@@ -0,0 +1,100 @@
+/* memrw.c - command to read / write physical memory  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+
+static grub_command_t cmd_read_byte, cmd_read_word, cmd_read_dword;
+static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword;
+
+static grub_err_t
+grub_cmd_read (grub_command_t cmd, int argc, char **argv)
+{
+  grub_target_addr_t addr;
+  grub_uint32_t value;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments");
+
+  addr = grub_strtoul (argv[0], 0, 0);
+  if (cmd->name[5] == 'd')
+    value = *((grub_uint32_t *) addr);
+  else if (cmd->name[5] == 'w')
+    value = *((grub_uint16_t *) addr);
+  else
+    value = *((grub_uint8_t *) addr);
+
+  grub_printf ("0x%x\n", value);
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_write (grub_command_t cmd, int argc, char **argv)
+{
+  grub_target_addr_t addr;
+  grub_uint32_t value;
+
+  if (argc != 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments");
+
+  addr = grub_strtoul (argv[0], 0, 0);
+  value = grub_strtoul (argv[1], 0, 0);
+  if (cmd->name[6] == 'd')
+    *((grub_uint32_t *) addr) = value;
+  else if (cmd->name[6] == 'w')
+    *((grub_uint16_t *) addr) = (grub_uint16_t) value;
+  else
+    *((grub_uint8_t *) addr) = (grub_uint8_t) value;
+
+  return 0;
+}
+
+GRUB_MOD_INIT(memrw)
+{
+  cmd_read_byte =
+    grub_register_command ("read_byte", grub_cmd_read,
+			   "read_byte ADDR", "read byte.");
+  cmd_read_word =
+    grub_register_command ("read_word", grub_cmd_read,
+			   "read_word ADDR", "read word.");
+  cmd_read_dword =
+    grub_register_command ("read_dword", grub_cmd_read,
+			   "read_dword ADDR", "read dword.");
+  cmd_write_byte =
+    grub_register_command ("write_byte", grub_cmd_write,
+			   "write_byte ADDR VALUE", "write byte.");
+  cmd_write_word =
+    grub_register_command ("write_word", grub_cmd_write,
+			   "write_word ADDR VALUE", "write word.");
+  cmd_write_dword =
+    grub_register_command ("write_dword", grub_cmd_write,
+			   "write_dword ADDR VALUE", "write dword.");
+}
+
+GRUB_MOD_FINI(memrw)
+{
+  grub_unregister_command (cmd_read_byte);
+  grub_unregister_command (cmd_read_word);
+  grub_unregister_command (cmd_read_dword);
+  grub_unregister_command (cmd_write_byte);
+  grub_unregister_command (cmd_write_word);
+  grub_unregister_command (cmd_write_dword);
+}
diff --git a/commands/minicmd.c b/commands/minicmd.c
new file mode 100644
index 0000000..b314388
--- /dev/null
+++ b/commands/minicmd.c
@@ -0,0 +1,376 @@
+/* minicmd.c - commands for the rescue mode */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/term.h>
+#include <grub/loader.h>
+#include <grub/command.h>
+
+/* cat FILE */
+static grub_err_t
+grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
+		   int argc, char *argv[])
+{
+  grub_file_t file;
+  char buf[GRUB_DISK_SECTOR_SIZE];
+  grub_ssize_t size;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    return grub_errno;
+
+  while ((size = grub_file_read (file, buf, sizeof (buf))) > 0)
+    {
+      int i;
+
+      for (i = 0; i < size; i++)
+	{
+	  unsigned char c = buf[i];
+
+	  if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
+	    grub_putchar (c);
+	  else
+	    {
+	      grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
+	      grub_printf ("<%x>", (int) c);
+	      grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
+	    }
+	}
+    }
+
+  grub_putchar ('\n');
+  grub_refresh ();
+  grub_file_close (file);
+
+  return 0;
+}
+
+/* help */
+static grub_err_t
+grub_mini_cmd_help (struct grub_command *cmd __attribute__ ((unused)),
+		    int argc __attribute__ ((unused)),
+		    char *argv[] __attribute__ ((unused)))
+{
+  grub_command_t p;
+
+  for (p = grub_command_list; p; p = p->next)
+    grub_printf ("%s (%d%c)\t%s\n", p->name,
+		 p->prio & GRUB_PRIO_LIST_PRIO_MASK,
+		 (p->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) ? '+' : '-',
+		 p->description);
+
+  return 0;
+}
+
+#if 0
+static void
+grub_rescue_cmd_info (void)
+{
+  extern void grub_disk_cache_get_performance (unsigned long *,
+					       unsigned long *);
+  unsigned long hits, misses;
+
+  grub_disk_cache_get_performance (&hits, &misses);
+  grub_printf ("Disk cache: hits = %u, misses = %u ", hits, misses);
+  if (hits + misses)
+    {
+      unsigned long ratio = hits * 10000 / (hits + misses);
+      grub_printf ("(%u.%u%%)\n", ratio / 100, ratio % 100);
+    }
+  else
+    grub_printf ("(N/A)\n");
+}
+#endif
+
+/* root [DEVICE] */
+static grub_err_t
+grub_mini_cmd_root (struct grub_command *cmd __attribute__ ((unused)),
+		    int argc, char *argv[])
+{
+  grub_device_t dev;
+  grub_fs_t fs;
+
+  if (argc > 0)
+    {
+      char *device_name = grub_file_get_device_name (argv[0]);
+      if (! device_name)
+	return grub_errno;
+
+      grub_env_set ("root", device_name);
+      grub_free (device_name);
+    }
+
+  dev = grub_device_open (0);
+  if (! dev)
+    return grub_errno;
+
+  fs = grub_fs_probe (dev);
+  if (grub_errno == GRUB_ERR_UNKNOWN_FS)
+    grub_errno = GRUB_ERR_NONE;
+
+  grub_printf ("(%s): Filesystem is %s.\n",
+	       grub_env_get ("root"), fs ? fs->name : "unknown");
+
+  grub_device_close (dev);
+
+  return 0;
+}
+
+#if 0
+static void
+grub_rescue_cmd_testload (int argc, char *argv[])
+{
+  grub_file_t file;
+  char *buf;
+  grub_ssize_t size;
+  grub_ssize_t pos;
+  auto void read_func (unsigned long sector, unsigned offset, unsigned len);
+
+  void read_func (unsigned long sector __attribute__ ((unused)),
+		  unsigned offset __attribute__ ((unused)),
+		  unsigned len __attribute__ ((unused)))
+    {
+      grub_putchar ('.');
+      grub_refresh ();
+    }
+
+  if (argc < 1)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+      return;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    return;
+
+  size = grub_file_size (file) & ~(GRUB_DISK_SECTOR_SIZE - 1);
+  if (size == 0)
+    {
+      grub_file_close (file);
+      return;
+    }
+
+  buf = grub_malloc (size);
+  if (! buf)
+    goto fail;
+
+  grub_printf ("Reading %s sequentially", argv[0]);
+  file->read_hook = read_func;
+  if (grub_file_read (file, buf, size) != size)
+    goto fail;
+  grub_printf (" Done.\n");
+
+  /* Read sequentially again.  */
+  grub_printf ("Reading %s sequentially again", argv[0]);
+  if (grub_file_seek (file, 0) < 0)
+    goto fail;
+
+  for (pos = 0; pos < size; pos += GRUB_DISK_SECTOR_SIZE)
+    {
+      char sector[GRUB_DISK_SECTOR_SIZE];
+
+      if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE)
+	  != GRUB_DISK_SECTOR_SIZE)
+	goto fail;
+
+      if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0)
+	{
+	  grub_printf ("\nDiffers in %d\n", pos);
+	  goto fail;
+	}
+    }
+  grub_printf (" Done.\n");
+
+  /* Read backwards and compare.  */
+  grub_printf ("Reading %s backwards", argv[0]);
+  pos = size;
+  while (pos > 0)
+    {
+      char sector[GRUB_DISK_SECTOR_SIZE];
+
+      pos -= GRUB_DISK_SECTOR_SIZE;
+
+      if (grub_file_seek (file, pos) < 0)
+	goto fail;
+
+      if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE)
+	  != GRUB_DISK_SECTOR_SIZE)
+	goto fail;
+
+      if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0)
+	{
+	  int i;
+
+	  grub_printf ("\nDiffers in %d\n", pos);
+
+	  for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i++)
+	    grub_putchar (buf[pos + i]);
+
+	  if (i)
+	    grub_refresh ();
+
+	  goto fail;
+	}
+    }
+  grub_printf (" Done.\n");
+
+ fail:
+
+  grub_file_close (file);
+  grub_free (buf);
+}
+#endif
+
+/* dump ADDRESS [SIZE] */
+static grub_err_t
+grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)),
+		    int argc, char *argv[])
+{
+  grub_uint8_t *addr;
+  grub_size_t size = 4;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no address specified");
+
+  addr = (grub_uint8_t *) grub_strtoul (argv[0], 0, 0);
+  if (grub_errno)
+    return grub_errno;
+
+  if (argc > 1)
+    size = (grub_size_t) grub_strtoul (argv[1], 0, 0);
+
+  while (size--)
+    {
+      grub_printf ("%x%x ", *addr >> 4, *addr & 0xf);
+      addr++;
+    }
+
+  return 0;
+}
+
+/* rmmod MODULE */
+static grub_err_t
+grub_mini_cmd_rmmod (struct grub_command *cmd __attribute__ ((unused)),
+		     int argc, char *argv[])
+{
+  grub_dl_t mod;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
+
+  mod = grub_dl_get (argv[0]);
+  if (! mod)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such module");
+
+  if (grub_dl_unref (mod) <= 0)
+    grub_dl_unload (mod);
+
+  return 0;
+}
+
+/* lsmod */
+static grub_err_t
+grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
+		     int argc __attribute__ ((unused)),
+		     char *argv[] __attribute__ ((unused)))
+{
+  auto int print_module (grub_dl_t mod);
+
+  int print_module (grub_dl_t mod)
+    {
+      grub_dl_dep_t dep;
+
+      grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count);
+      for (dep = mod->dep; dep; dep = dep->next)
+	{
+	  if (dep != mod->dep)
+	    grub_putchar (',');
+
+	  grub_printf ("%s", dep->mod->name);
+	}
+      grub_putchar ('\n');
+      grub_refresh ();
+
+      return 0;
+    }
+
+  grub_printf ("Name\tRef Count\tDependencies\n");
+  grub_dl_iterate (print_module);
+
+  return 0;
+}
+
+/* exit */
+static grub_err_t
+grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
+		    int argc __attribute__ ((unused)),
+		    char *argv[] __attribute__ ((unused)))
+{
+  grub_exit ();
+  return 0;
+}
+
+static grub_command_t cmd_cat, cmd_help, cmd_root;
+static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit;
+
+GRUB_MOD_INIT(minicmd)
+{
+  cmd_cat =
+    grub_register_command ("cat", grub_mini_cmd_cat,
+			   "cat FILE", "show the contents of a file");
+  cmd_help =
+    grub_register_command ("help", grub_mini_cmd_help,
+			   0, "show this message");
+  cmd_root =
+    grub_register_command ("root", grub_mini_cmd_root,
+			   "root [DEVICE]", "set the root device");
+  cmd_dump =
+    grub_register_command ("dump", grub_mini_cmd_dump,
+			   "dump ADDR", "dump memory");
+  cmd_rmmod =
+    grub_register_command ("rmmod", grub_mini_cmd_rmmod,
+			   "rmmod MODULE", "remove a module");
+  cmd_lsmod =
+    grub_register_command ("lsmod", grub_mini_cmd_lsmod,
+			   0, "show loaded modules");
+  cmd_exit =
+    grub_register_command ("exit", grub_mini_cmd_exit,
+			   0, "exit from GRUB");
+}
+
+GRUB_MOD_FINI(minicmd)
+{
+  grub_unregister_command (cmd_cat);
+  grub_unregister_command (cmd_help);
+  grub_unregister_command (cmd_root);
+  grub_unregister_command (cmd_dump);
+  grub_unregister_command (cmd_rmmod);
+  grub_unregister_command (cmd_lsmod);
+  grub_unregister_command (cmd_exit);
+}
diff --git a/commands/parttool.c b/commands/parttool.c
new file mode 100644
index 0000000..8c985fc
--- /dev/null
+++ b/commands/parttool.c
@@ -0,0 +1,332 @@
+/* parttool.c - common dispatcher and parser for partition operations */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  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 <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/parttool.h>
+#include <grub/command.h>
+
+static struct grub_parttool *parts = 0;
+static int curhandle = 0;
+static grub_dl_t mymod;
+static char helpmsg[] =
+  "perform COMMANDS on partition.\n"
+  "Use \"parttool PARTITION help\" for the list "
+  "of available commands";
+
+int
+grub_parttool_register(const char *part_name,
+		       const grub_parttool_function_t func,
+		       const struct grub_parttool_argdesc *args)
+{
+  struct grub_parttool *cur;
+  int nargs = 0;
+
+  if (! parts)
+    grub_dl_ref (mymod);
+
+  cur = (struct grub_parttool *) grub_malloc (sizeof (struct grub_parttool));
+  cur->next = parts;
+  cur->name = grub_strdup (part_name);
+  cur->handle = curhandle++;
+  for (nargs = 0; args[nargs].name != 0; nargs++);
+  cur->nargs = nargs;
+  cur->args = (struct grub_parttool_argdesc *)
+    grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc));
+  grub_memcpy (cur->args, args,
+	       (nargs + 1) * sizeof (struct grub_parttool_argdesc));
+
+  cur->func = func;
+  parts = cur;
+  return cur->handle;
+}
+
+void
+grub_parttool_unregister (int handle)
+{
+  struct grub_parttool *prev = 0, *cur, *t;
+  for (cur = parts; cur; )
+    if (cur->handle == handle)
+      {
+	grub_free (cur->args);
+	grub_free (cur->name);
+	if (prev)
+	  prev->next = cur->next;
+	else
+	  parts = cur->next;
+	t = cur;
+	cur = cur->next;
+	grub_free (t);
+      }
+    else
+      {
+	prev = cur;
+	cur = cur->next;
+      }
+  if (! parts)
+    grub_dl_unref (mymod);
+}
+
+static grub_err_t
+grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
+		   int argc, char **args)
+{
+  grub_device_t dev;
+  struct grub_parttool *cur, *ptool;
+  int *parsed;
+  int i, j;
+  grub_err_t err = GRUB_ERR_NONE;
+
+  auto grub_err_t show_help (void);
+  grub_err_t show_help (void)
+  {
+    int found = 0;
+    for (cur = parts; cur; cur = cur->next)
+      if (grub_strcmp (dev->disk->partition->partmap->name, cur->name) == 0)
+	{
+	  struct grub_parttool_argdesc *curarg;
+	  found = 1;
+	  for (curarg = cur->args; curarg->name; curarg++)
+	    {
+	      int spacing = 20;
+
+	      spacing -= grub_strlen (curarg->name);
+	      grub_printf ("%s", curarg->name);
+
+	      switch (curarg->type)
+		{
+		case GRUB_PARTTOOL_ARG_BOOL:
+		  grub_printf ("+/-");
+		  spacing -= 3;
+		  break;
+
+		case GRUB_PARTTOOL_ARG_VAL:
+		  grub_printf ("=VAL");
+		  spacing -= 4;
+		  break;
+
+		    case GRUB_PARTTOOL_ARG_END:
+		      break;
+		}
+	      while (spacing-- > 0)
+		grub_printf (" ");
+	      grub_printf ("%s\n", curarg->desc);
+	    }
+	}
+    if (! found)
+      grub_printf ("Sorry no parttool is available for %s\n",
+		   dev->disk->partition->partmap->name);
+    return GRUB_ERR_NONE;
+  }
+
+  if (argc < 1)
+    {
+      grub_printf ("%s\n", helpmsg);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments");
+    }
+
+  if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')')
+    {
+      args[0][grub_strlen (args[0]) - 1] = 0;
+      dev = grub_device_open (args[0] + 1);
+      args[0][grub_strlen (args[0]) - 1] = ')';
+    }
+  else
+    dev = grub_device_open (args[0]);
+
+  if (! dev)
+    return grub_errno;
+
+  if (! dev->disk)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk");
+    }
+
+  if (! dev->disk->partition)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a partition");
+    }
+
+  /* Load modules. */
+#ifndef GRUB_UTIL
+  {
+    const char *prefix;
+    prefix = grub_env_get ("prefix");
+    if (prefix)
+      {
+	char *filename;
+
+	filename = grub_malloc (grub_strlen (prefix) + sizeof ("/parttool.lst"));
+	if (filename)
+	  {
+	    grub_file_t file;
+
+	    grub_sprintf (filename, "%s/parttool.lst", prefix);
+	    file = grub_file_open (filename);
+	    if (file)
+	      {
+		char *buf = 0;
+		for (;; grub_free(buf))
+		  {
+		    char *p, *name;
+
+		    buf = grub_file_getline (file);
+
+		    if (! buf)
+		      break;
+
+		    name = buf;
+
+		    if (! grub_isgraph (name[0]))
+		      continue;
+
+		    p = grub_strchr (name, ':');
+		    if (! p)
+		      continue;
+
+		    *p = '\0';
+		    while (*++p == ' ')
+		      ;
+
+		    if (! grub_isgraph (*p))
+		      continue;
+
+		    if (grub_strcmp (name, dev->disk->partition->partmap->name)
+			!= 0)
+		      continue;
+
+		    grub_dl_load (p);
+		  }
+
+		grub_file_close (file);
+	      }
+
+	    grub_free (filename);
+	  }
+      }
+    /* Ignore errors.  */
+    grub_errno = GRUB_ERR_NONE;
+  }
+#endif
+
+  if (argc == 1)
+    return show_help ();
+
+  for (i = 1; i < argc; i++)
+    if (grub_strcmp (args[i], "help") == 0)
+      return show_help ();
+
+  parsed = (int *) grub_zalloc (argc * sizeof (int));
+
+  for (i = 1; i < argc; i++)
+    if (! parsed[i])
+      {
+	struct grub_parttool_argdesc *curarg;
+	struct grub_parttool_args *pargs;
+	for (cur = parts; cur; cur = cur->next)
+	  if (grub_strcmp (dev->disk->partition->partmap->name, cur->name) == 0)
+	    {
+	      for (curarg = cur->args; curarg->name; curarg++)
+		if (grub_strncmp (curarg->name, args[i],
+				  grub_strlen (curarg->name)) == 0
+		    && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
+			 && (args[i][grub_strlen (curarg->name)] == '+'
+			     || args[i][grub_strlen (curarg->name)] == '-'
+			     || args[i][grub_strlen (curarg->name)] == 0))
+			|| (curarg->type == GRUB_PARTTOOL_ARG_VAL
+			    && args[i][grub_strlen (curarg->name)] == '=')))
+
+		  break;
+	      if (curarg->name)
+		break;
+	    }
+	if (! cur)
+	  return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised argument %s",
+			     args[i]);
+	ptool = cur;
+	pargs = (struct grub_parttool_args *)
+	  grub_zalloc (ptool->nargs * sizeof (struct grub_parttool_args));
+	for (j = i; j < argc; j++)
+	  if (! parsed[j])
+	    {
+	      for (curarg = ptool->args; curarg->name; curarg++)
+		if (grub_strncmp (curarg->name, args[i],
+				   grub_strlen (curarg->name)) == 0
+		    && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
+			 && (args[j][grub_strlen (curarg->name)] == '+'
+			     || args[j][grub_strlen (curarg->name)] == '-'
+			     || args[j][grub_strlen (curarg->name)] == 0))
+			|| (curarg->type == GRUB_PARTTOOL_ARG_VAL
+			    && args[j][grub_strlen (curarg->name)] == '=')))
+		  {
+		    parsed[j] = 1;
+		    pargs[curarg - ptool->args].set = 1;
+		    switch (curarg->type)
+		      {
+		      case GRUB_PARTTOOL_ARG_BOOL:
+			pargs[curarg - ptool->args].bool
+			  = (args[j][grub_strlen (curarg->name)] != '-');
+			break;
+
+		      case GRUB_PARTTOOL_ARG_VAL:
+			pargs[curarg - ptool->args].str
+			  = (args[j] + grub_strlen (curarg->name) + 1);
+			break;
+
+		      case GRUB_PARTTOOL_ARG_END:
+			break;
+		      }
+		  }
+	    }
+
+	err = ptool->func (dev, pargs);
+	grub_free (pargs);
+	if (err)
+	  break;
+      }
+
+  grub_free (parsed);
+  grub_device_close (dev);
+  return err;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(parttool)
+{
+  mymod = mod;
+  cmd = grub_register_command ("parttool", grub_cmd_parttool,
+			       "parttool PARTITION COMMANDS",
+			       helpmsg);
+}
+
+GRUB_MOD_FINI(parttool)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/password.c b/commands/password.c
new file mode 100644
index 0000000..0e04879
--- /dev/null
+++ b/commands/password.c
@@ -0,0 +1,86 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/auth.h>
+#include <grub/list.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+
+static grub_dl_t my_mod;
+
+static grub_err_t
+check_password (const char *user,
+		void *password)
+{
+  char entered[1024];
+
+  grub_memset (entered, 0, sizeof (entered));
+
+  if (!GRUB_GET_PASSWORD (entered, sizeof (entered) - 1))
+    return GRUB_ACCESS_DENIED;
+
+  if (grub_auth_strcmp (entered, password) != 0)
+    return GRUB_ACCESS_DENIED;
+
+  grub_auth_authenticate (user);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
+		   int argc, char **args)
+{
+  grub_err_t err;
+  char *pass;
+
+  if (argc != 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two arguments expected.");
+
+  pass = grub_strdup (args[1]);
+  if (!pass)
+    return grub_errno;
+
+  err = grub_auth_register_authentication (args[0], check_password, pass);
+  if (err)
+    {
+      grub_free (pass);
+      return err;
+    }
+  grub_dl_ref (my_mod);
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(password)
+{
+  my_mod = mod;
+  cmd = grub_register_command ("password", grub_cmd_password,
+			       "password USER PASSWORD",
+			       "Set user password (plaintext). "
+			       "Unrecommended and insecure.");
+}
+
+GRUB_MOD_FINI(password)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/probe.c b/commands/probe.c
new file mode 100644
index 0000000..fabdb2a
--- /dev/null
+++ b/commands/probe.c
@@ -0,0 +1,160 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/net.h>
+#include <grub/fs.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/extcmd.h>
+
+static const struct grub_arg_option options[] = 
+  {
+    {"set",             's', GRUB_ARG_OPTION_OPTIONAL,
+     "set a variable to return value", "VAR", ARG_TYPE_STRING},
+    {"driver",		'd', 0, "determine driver", 0, 0},
+    {"partmap",		'p', 0, "determine partition map type", 0, 0},
+    {"fs",		'f', 0, "determine filesystem type", 0, 0},
+    {"fs-uuid",		'u', 0, "determine filesystem UUID", 0, 0},
+    {"label",		'l', 0, "determine filesystem label", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_err_t
+grub_cmd_probe (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  grub_device_t dev;
+  grub_fs_t fs;
+  char *ptr;
+  grub_err_t err;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+
+  ptr = args[0] + grub_strlen (args[0]) - 1;
+  if (args[0][0] == '(' && *ptr == ')')
+    {
+      *ptr = 0;
+      dev = grub_device_open (args[0] + 1);
+      *ptr = ')';
+    }
+  else
+    dev = grub_device_open (args[0]);
+  if (! dev)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "couldn't open device");
+
+  if (state[1].set)
+    {
+      const char *val = "none";
+      if (dev->net)
+	val = dev->net->dev->name;
+      if (dev->disk)
+	val = dev->disk->dev->name;
+      if (state[0].set)
+	grub_env_set (state[0].arg, val);
+      else
+	grub_printf ("%s", val);
+      return GRUB_ERR_NONE;
+    }
+  if (state[2].set)
+    {
+      const char *val = "none";
+      if (dev->disk && dev->disk->partition)
+	val = dev->disk->partition->partmap->name;
+      if (state[0].set)
+	grub_env_set (state[0].arg, val);
+      else
+	grub_printf ("%s", val);
+      return GRUB_ERR_NONE;
+    }
+  fs = grub_fs_probe (dev);
+  if (! fs)
+    return grub_error (GRUB_ERR_UNKNOWN_FS, "unrecognised fs");
+  if (state[3].set)
+    {
+      if (state[0].set)
+	grub_env_set (state[0].arg, fs->name);
+      else
+	grub_printf ("%s", fs->name);
+      return GRUB_ERR_NONE;
+    }
+  if (state[4].set)
+    {
+      char *uuid;
+      if (! fs->uuid)
+	return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+			   "uuid for this FS isn't supported yet");
+      err = fs->uuid (dev, &uuid);
+      if (err)
+	return err;
+      if (! uuid)
+	return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+			   "uuid for this FS isn't supported yet");
+
+      if (state[0].set)
+	grub_env_set (state[0].arg, uuid);
+      else
+	grub_printf ("%s", uuid);
+      grub_free (uuid);
+      return GRUB_ERR_NONE;
+    }
+  if (state[5].set)
+    {
+      char *label;
+      if (! fs->label)
+	return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+			   "label for this FS isn't supported yet");
+      err = fs->label (dev, &label);
+      if (err)
+	return err;
+      if (! label)
+	return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+			   "uuid for this FS isn't supported yet");
+
+      if (state[0].set)
+	grub_env_set (state[0].arg, label);
+      else
+	grub_printf ("%s", label);
+      grub_free (label);
+      return GRUB_ERR_NONE;
+    }
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised target");
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT (probe)
+{
+  cmd = grub_register_extcmd ("probe", grub_cmd_probe, GRUB_COMMAND_FLAG_BOTH,
+			      "probe [DEVICE]",
+			      "Retrieve device info.", options);
+}
+
+GRUB_MOD_FINI (probe)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/read.c b/commands/read.c
new file mode 100644
index 0000000..82b30b4
--- /dev/null
+++ b/commands/read.c
@@ -0,0 +1,89 @@
+/* read.c - Command to read variables from user.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/command.h>
+
+static char *
+grub_getline (void)
+{
+  int i;
+  char *line;
+  char *tmp;
+  char c;
+
+  i = 0;
+  line = grub_malloc (1 + i + sizeof('\0'));
+  if (! line)
+    return NULL;
+
+  while (1)
+    {
+      c = grub_getkey ();
+      if ((c == '\n') || (c == '\r'))
+	break;
+
+      line[i] = c;
+      if (grub_isprint (c))
+	grub_putchar (c);
+      i++;
+      tmp = grub_realloc (line, 1 + i + sizeof('\0'));
+      if (! tmp)
+	{
+	  grub_free (line);
+	  return NULL;
+	}
+      line = tmp;
+    }
+  line[i] = '\0';
+
+  return line;
+}
+
+static grub_err_t
+grub_cmd_read (grub_command_t cmd UNUSED, int argc, char **args)
+{
+  char *line = grub_getline ();
+  if (! line)
+    return grub_errno;
+  if (argc > 0)
+    grub_env_set (args[0], line);
+
+  grub_free (line);
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(read)
+{
+  cmd = grub_register_command ("read", grub_cmd_read,
+			       "read [ENVVAR]",
+			       "Set variable with user input");
+}
+
+GRUB_MOD_FINI(read)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/reboot.c b/commands/reboot.c
new file mode 100644
index 0000000..11bceeb
--- /dev/null
+++ b/commands/reboot.c
@@ -0,0 +1,56 @@
+/* reboot.c - command to reboot the computer.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/machine/machine.h>
+#include <grub/command.h>
+
+#if defined(GRUB_MACHINE_IEEE1275)
+#include <grub/machine/kernel.h>
+#elif defined(GRUB_MACHINE_EFI)
+#include <grub/efi/efi.h>
+#elif defined(GRUB_MACHINE_PCBIOS)
+#include <grub/machine/init.h>
+#else
+/* Platforms shipping standalone reboot, such as coreboot.  */
+#include <grub/cpu/reboot.h>
+#endif
+
+
+static grub_err_t
+grub_cmd_reboot (grub_command_t cmd __attribute__ ((unused)),
+		 int argc __attribute__ ((unused)),
+		 char **args __attribute__ ((unused)))
+{
+  grub_reboot ();
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(reboot)
+{
+  cmd = grub_register_command ("reboot", grub_cmd_reboot,
+			       0, "Reboot the computer");
+}
+
+GRUB_MOD_FINI(reboot)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/search.c b/commands/search.c
new file mode 100644
index 0000000..0cfd0eb
--- /dev/null
+++ b/commands/search.c
@@ -0,0 +1,200 @@
+/* search.c - search devices based on a file or a filesystem label */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/device.h>
+#include <grub/file.h>
+#include <grub/env.h>
+#include <grub/extcmd.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"file",		'f', 0, "search devices by a file", 0, 0},
+    {"label",		'l', 0, "search devices by a filesystem label", 0, 0},
+    {"fs-uuid",		'u', 0, "search devices by a filesystem UUID", 0, 0},
+    {"set",		's', GRUB_ARG_OPTION_OPTIONAL, "set a variable to the first device found", "VAR", ARG_TYPE_STRING},
+    {"no-floppy",	'n', 0, "do not probe any floppy drive", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+enum options
+  {
+    SEARCH_FILE,
+    SEARCH_LABEL,
+    SEARCH_FS_UUID,
+    SEARCH_SET,
+    SEARCH_NO_FLOPPY,
+ };
+
+static void
+search_fs (const char *key, const char *var, int no_floppy, enum options type)
+{
+  int count = 0;
+  char *buf = NULL;
+  grub_fs_autoload_hook_t saved_autoload;
+
+  auto int iterate_device (const char *name);
+  int iterate_device (const char *name)
+  {
+    int found = 0;
+
+    /* Skip floppy drives when requested.  */
+    if (no_floppy &&
+	name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
+      return 0;
+
+    if (type == SEARCH_FILE)
+      {
+	grub_size_t len;
+	char *p;
+	grub_file_t file;
+
+	len = grub_strlen (name) + 2 + grub_strlen (key) + 1;
+	p = grub_realloc (buf, len);
+	if (! p)
+	  return 1;
+
+	buf = p;
+	grub_sprintf (buf, "(%s)%s", name, key);
+
+	file = grub_file_open (buf);
+	if (file)
+	  {
+	    found = 1;
+	    grub_file_close (file);
+	  }
+      }
+    else
+      {
+	/* type is SEARCH_FS_UUID or SEARCH_LABEL */
+	grub_device_t dev;
+	grub_fs_t fs;
+	int (*compare_fn) (const char *, const char *);
+	char *quid;
+
+	dev = grub_device_open (name);
+	if (dev)
+	  {
+	    fs = grub_fs_probe (dev);
+	    compare_fn =
+	      (type == SEARCH_FS_UUID) ? grub_strcasecmp : grub_strcmp;
+
+	    if (fs && ((type == SEARCH_FS_UUID) ? fs->uuid : fs->label))
+	      {
+		if (type == SEARCH_FS_UUID)
+		  fs->uuid (dev, &quid);
+		else
+		  fs->label (dev, &quid);
+
+		if (grub_errno == GRUB_ERR_NONE && quid)
+		  {
+		    if (compare_fn (quid, key) == 0)
+		      found = 1;
+
+		    grub_free (quid);
+		  }
+	      }
+
+	    grub_device_close (dev);
+	  }
+      }
+
+    if (found)
+      {
+	count++;
+	if (var)
+	  grub_env_set (var, name);
+	else
+	  grub_printf (" %s", name);
+      }
+
+    grub_errno = GRUB_ERR_NONE;
+    return (found && var);
+  }
+
+  /* First try without autoloading if we're setting variable. */
+  if (var)
+    {
+      saved_autoload = grub_fs_autoload_hook;
+      grub_fs_autoload_hook = 0;
+      grub_device_iterate (iterate_device);
+
+      /* Restore autoload hook.  */
+      grub_fs_autoload_hook = saved_autoload;
+
+      /* Retry with autoload if nothing found.  */
+      if (grub_errno == GRUB_ERR_NONE && count == 0)
+	grub_device_iterate (iterate_device);
+    }
+  else
+    grub_device_iterate (iterate_device);
+
+  grub_free (buf);
+
+  if (grub_errno == GRUB_ERR_NONE && count == 0)
+    grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key);
+}
+
+static grub_err_t
+grub_cmd_search (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  const char *var = 0;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_INVALID_COMMAND, "no argument specified");
+
+  if (state[SEARCH_SET].set)
+    var = state[SEARCH_SET].arg ? state[SEARCH_SET].arg : "root";
+
+  if (state[SEARCH_LABEL].set)
+    search_fs (args[0], var, state[SEARCH_NO_FLOPPY].set, SEARCH_LABEL);
+  else if (state[SEARCH_FS_UUID].set)
+    search_fs (args[0], var, state[SEARCH_NO_FLOPPY].set, SEARCH_FS_UUID);
+  else if (state[SEARCH_FILE].set)
+    search_fs (args[0], var, state[SEARCH_NO_FLOPPY].set, SEARCH_FILE);
+  else
+    return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type");
+
+  return grub_errno;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(search)
+{
+  cmd =
+    grub_register_extcmd ("search", grub_cmd_search,
+			  GRUB_COMMAND_FLAG_BOTH,
+			  "search [-f|-l|-u|-s|-n] NAME",
+			  "Search devices by file, filesystem label or filesystem UUID."
+			  " If --set is specified, the first device found is"
+			  " set to a variable. If no variable name is"
+			  " specified, \"root\" is used.",
+			  options);
+}
+
+GRUB_MOD_FINI(search)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/sleep.c b/commands/sleep.c
new file mode 100644
index 0000000..c9d5333
--- /dev/null
+++ b/commands/sleep.c
@@ -0,0 +1,116 @@
+/* sleep.c - Command to wait a specified number of seconds.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/term.h>
+#include <grub/time.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/machine/time.h>
+#include <grub/extcmd.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"verbose", 'v', 0, "verbose countdown", 0, 0},
+    {"interruptible", 'i', 0, "interruptible with ESC", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_uint8_t x, y;
+
+static void
+do_print (int n)
+{
+  grub_gotoxy (x, y);
+  /* NOTE: Do not remove the trailing space characters.
+     They are required to clear the line.  */
+  grub_printf ("%d    ", n);
+}
+
+/* Based on grub_millisleep() from kern/generic/millisleep.c.  */
+static int
+grub_interruptible_millisleep (grub_uint32_t ms)
+{
+  grub_uint64_t start;
+
+  start = grub_get_time_ms ();
+
+  while (grub_get_time_ms () - start < ms)
+    if (grub_checkkey () >= 0 &&
+	GRUB_TERM_ASCII_CHAR (grub_getkey ()) == GRUB_TERM_ESC)
+      return 1;
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_sleep (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  grub_uint16_t xy;
+  int n;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand");
+
+  n = grub_strtoul (args[0], 0, 10);
+
+  if (n == 0)
+    {
+      /* Either `0' or broken input.  */
+      return 0;
+    }
+
+  xy = grub_getxy ();
+  x = xy >> 8;
+  y = xy & 0xff;
+
+  for (; n; n--)
+    {
+      if (state[0].set)
+	do_print (n);
+
+      if (state[1].set)
+	{
+	  if (grub_interruptible_millisleep (1000))
+	    return 1;
+	}
+      else
+	grub_millisleep (1000);
+    }
+  if (state[0].set)
+    do_print (0);
+
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(sleep)
+{
+  cmd = grub_register_extcmd ("sleep", grub_cmd_sleep, GRUB_COMMAND_FLAG_BOTH,
+			      "sleep NUMBER_OF_SECONDS",
+			      "Wait for a specified number of seconds",
+			      options);
+}
+
+GRUB_MOD_FINI(sleep)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/commands/test.c b/commands/test.c
new file mode 100644
index 0000000..9c813c8
--- /dev/null
+++ b/commands/test.c
@@ -0,0 +1,432 @@
+/* test.c -- The test command..  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/fs.h>
+#include <grub/device.h>
+#include <grub/file.h>
+#include <grub/command.h>
+
+/* A simple implementation for signed numbers. */
+static int
+grub_strtosl (char *arg, char **end, int base)
+{
+  if (arg[0] == '-')
+    return -grub_strtoul (arg + 1, end, base);
+  return grub_strtoul (arg, end, base);
+}
+
+/* Parse a test expression starting from *argn. */
+static int
+test_parse (char **args, int *argn, int argc)
+{
+  int ret = 0, discard = 0, invert = 0;
+  int file_exists;
+  struct grub_dirhook_info file_info;
+
+  auto void update_val (int val);
+  auto void get_fileinfo (char *pathname);
+
+  /* Take care of discarding and inverting. */
+  void update_val (int val)
+  {
+    if (! discard)
+      ret = invert ? ! val : val;
+    invert = discard = 0;
+  }
+
+  /* Check if file exists and fetch its information. */
+  void get_fileinfo (char *path)
+  {
+    char *filename, *pathname;
+    char *device_name;
+    grub_fs_t fs;
+    grub_device_t dev;
+
+    /* A hook for iterating directories. */
+    auto int find_file (const char *cur_filename,
+			const struct grub_dirhook_info *info);
+    int find_file (const char *cur_filename,
+		   const struct grub_dirhook_info *info)
+    {
+      if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename)
+	   : grub_strcmp (cur_filename, filename)) == 0)
+	{
+	  file_info = *info;
+	  file_exists = 1;
+	  return 1;
+	}
+      return 0;
+    }
+
+    file_exists = 0;
+    device_name = grub_file_get_device_name (path);
+    dev = grub_device_open (device_name);
+    if (! dev)
+      {
+	grub_free (device_name);
+	return;
+      }
+
+    fs = grub_fs_probe (dev);
+    if (! fs)
+      {
+	grub_free (device_name);
+	grub_device_close (dev);
+	return;
+      }
+
+    pathname = grub_strchr (path, ')');
+    if (! pathname)
+      pathname = path;
+    else
+      pathname++;
+
+    /* Remove trailing '/'. */
+    while (*pathname && pathname[grub_strlen (pathname) - 1] == '/')
+      pathname[grub_strlen (pathname) - 1] = 0;
+
+    /* Split into path and filename. */
+    filename = grub_strrchr (pathname, '/');
+    if (! filename)
+      {
+	path = grub_strdup ("/");
+	filename = pathname;
+      }
+    else
+      {
+	filename++;
+	path = grub_strdup (pathname);
+	path[filename - pathname] = 0;
+      }
+
+    /* It's the whole device. */
+    if (! *pathname)
+      {
+	file_exists = 1;
+	grub_memset (&file_info, 0, sizeof (file_info));
+	/* Root is always a directory. */
+	file_info.dir = 1;
+
+	/* Fetch writing time. */
+	file_info.mtimeset = 0;
+	if (fs->mtime)
+	  {
+	    if (! fs->mtime (dev, &file_info.mtime))
+	      file_info.mtimeset = 1;
+	    grub_errno = GRUB_ERR_NONE;
+	  }
+      }
+    else
+      (fs->dir) (dev, path, find_file);
+
+    grub_device_close (dev);
+    grub_free (path);
+    grub_free (device_name);
+  }
+
+  /* Here we have the real parsing. */
+  while (*argn < argc)
+    {
+      /* First try 3 argument tests. */
+      if (*argn + 2 < argc)
+	{
+	  /* String tests. */
+	  if (grub_strcmp (args[*argn + 1], "=") == 0
+	      || grub_strcmp (args[*argn + 1], "==") == 0)
+	    {
+	      update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0);
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  if (grub_strcmp (args[*argn + 1], "!=") == 0)
+	    {
+	      update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0);
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  /* GRUB extension: lexicographical sorting. */
+	  if (grub_strcmp (args[*argn + 1], "<") == 0)
+	    {
+	      update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0);
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  if (grub_strcmp (args[*argn + 1], "<=") == 0)
+	    {
+	      update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0);
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  if (grub_strcmp (args[*argn + 1], ">") == 0)
+	    {
+	      update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0);
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  if (grub_strcmp (args[*argn + 1], ">=") == 0)
+	    {
+	      update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0);
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  /* Number tests. */
+	  if (grub_strcmp (args[*argn + 1], "-eq") == 0)
+	    {
+	      update_val (grub_strtosl (args[*argn], 0, 0)
+			  == grub_strtosl (args[*argn + 2], 0, 0));
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  if (grub_strcmp (args[*argn + 1], "-ge") == 0)
+	    {
+	      update_val (grub_strtosl (args[*argn], 0, 0)
+			  >= grub_strtosl (args[*argn + 2], 0, 0));
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  if (grub_strcmp (args[*argn + 1], "-gt") == 0)
+	    {
+	      update_val (grub_strtosl (args[*argn], 0, 0)
+			  > grub_strtosl (args[*argn + 2], 0, 0));
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  if (grub_strcmp (args[*argn + 1], "-le") == 0)
+	    {
+	      update_val (grub_strtosl (args[*argn], 0, 0)
+		      <= grub_strtosl (args[*argn + 2], 0, 0));
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  if (grub_strcmp (args[*argn + 1], "-lt") == 0)
+	    {
+	      update_val (grub_strtosl (args[*argn], 0, 0)
+			  < grub_strtosl (args[*argn + 2], 0, 0));
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  if (grub_strcmp (args[*argn + 1], "-ne") == 0)
+	    {
+	      update_val (grub_strtosl (args[*argn], 0, 0)
+			  != grub_strtosl (args[*argn + 2], 0, 0));
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  /* GRUB extension: compare numbers skipping prefixes.
+	     Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */
+	  if (grub_strcmp (args[*argn + 1], "-pgt") == 0
+	      || grub_strcmp (args[*argn + 1], "-plt") == 0)
+	    {
+	      int i;
+	      /* Skip common prefix. */
+	      for (i = 0; args[*argn][i] == args[*argn + 2][i]
+		     && args[*argn][i]; i++);
+
+	      /* Go the digits back. */
+	      i--;
+	      while (grub_isdigit (args[*argn][i]) && i > 0)
+		i--;
+	      i++;
+
+	      if (grub_strcmp (args[*argn + 1], "-pgt") == 0)
+		update_val (grub_strtoul (args[*argn] + i, 0, 0)
+			    > grub_strtoul (args[*argn + 2] + i, 0, 0));
+	      else
+		update_val (grub_strtoul (args[*argn] + i, 0, 0)
+			    < grub_strtoul (args[*argn + 2] + i, 0, 0));
+	      (*argn) += 3;
+	      continue;
+	    }
+
+	  /* -nt and -ot tests. GRUB extension: when doing -?t<bias> bias
+	     will be added to the first mtime. */
+	  if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0
+	      || grub_memcmp (args[*argn + 1], "-ot", 3) == 0)
+	    {
+	      struct grub_dirhook_info file1;
+	      int file1exists;
+	      int bias = 0;
+
+	      /* Fetch fileinfo. */
+	      get_fileinfo (args[*argn]);
+	      file1 = file_info;
+	      file1exists = file_exists;
+	      get_fileinfo (args[*argn + 2]);
+
+	      if (args[*argn + 1][3])
+		bias = grub_strtosl (args[*argn + 1] + 3, 0, 0);
+
+	      if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0)
+		update_val ((file1exists && ! file_exists)
+			    || (file1.mtimeset && file_info.mtimeset
+				&& file1.mtime + bias > file_info.mtime));
+	      else
+		update_val ((! file1exists && file_exists)
+			    || (file1.mtimeset && file_info.mtimeset
+				&& file1.mtime + bias < file_info.mtime));
+	      (*argn) += 3;
+	      continue;
+	    }
+	}
+
+      /* Two-argument tests. */
+      if (*argn + 1 < argc)
+	{
+	  /* File tests. */
+	  if (grub_strcmp (args[*argn], "-d") == 0)
+	    {
+	      get_fileinfo (args[*argn + 1]);
+	      update_val (file_exists && file_info.dir);
+	      (*argn) += 2;
+	      return ret;
+	    }
+
+	  if (grub_strcmp (args[*argn], "-e") == 0)
+	    {
+	      get_fileinfo (args[*argn + 1]);
+	      update_val (file_exists);
+	      (*argn) += 2;
+	      return ret;
+	    }
+
+	  if (grub_strcmp (args[*argn], "-f") == 0)
+	    {
+	      get_fileinfo (args[*argn + 1]);
+	      /* FIXME: check for other types. */
+	      update_val (file_exists && ! file_info.dir);
+	      (*argn) += 2;
+	      return ret;
+	    }
+
+	  if (grub_strcmp (args[*argn], "-s") == 0)
+	    {
+	      grub_file_t file;
+	      file = grub_file_open (args[*argn + 1]);
+	      update_val (file && (grub_file_size (file) != 0));
+	      if (file)
+		grub_file_close (file);
+	      grub_errno = GRUB_ERR_NONE;
+	      (*argn) += 2;
+	      return ret;
+	    }
+
+	  /* String tests. */
+	  if (grub_strcmp (args[*argn], "-n") == 0)
+	    {
+	      update_val (args[*argn + 1][0]);
+
+	      (*argn) += 2;
+	      continue;
+	    }
+	  if (grub_strcmp (args[*argn], "-z") == 0)
+	    {
+	      update_val (! args[*argn + 1][0]);
+	      (*argn) += 2;
+	      continue;
+	    }
+	}
+
+      /* Special modifiers. */
+
+      /* End of expression. return to parent. */
+      if (grub_strcmp (args[*argn], ")") == 0)
+	{
+	  (*argn)++;
+	  return ret;
+	}
+      /* Recursively invoke if parenthesis. */
+      if (grub_strcmp (args[*argn], "(") == 0)
+	{
+	  (*argn)++;
+	  update_val (test_parse (args, argn, argc));
+	  continue;
+	}
+
+      if (grub_strcmp (args[*argn], "!") == 0)
+	{
+	  invert = ! invert;
+	  (*argn)++;
+	  continue;
+	}
+      if (grub_strcmp (args[*argn], "-a") == 0)
+	{
+	  /* If current value is 0 second value is to be discarded. */
+	  discard = ! ret;
+	  (*argn)++;
+	  continue;
+	}
+      if (grub_strcmp (args[*argn], "-o") == 0)
+	{
+	  /* If current value is 1 second value is to be discarded. */
+	  discard = ret;
+	  (*argn)++;
+	  continue;
+	}
+
+      /* No test found. Interpret if as just a string. */
+      update_val (args[*argn][0]);
+      (*argn)++;
+    }
+  return ret;
+}
+
+static grub_err_t
+grub_cmd_test (grub_command_t cmd __attribute__ ((unused)),
+	       int argc, char **args)
+{
+  int argn = 0;
+
+  if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0)
+    argc--;
+
+  return test_parse (args, &argn, argc) ? GRUB_ERR_NONE
+    : grub_error (GRUB_ERR_TEST_FAILURE, "false");
+}
+
+static grub_command_t cmd_1, cmd_2;
+
+GRUB_MOD_INIT(test)
+{
+  cmd_1 = grub_register_command ("[", grub_cmd_test,
+				 "[ EXPRESSION ]", "Evaluate an expression");
+  cmd_2 = grub_register_command ("test", grub_cmd_test,
+				 "test EXPRESSION", "Evaluate an expression");
+}
+
+GRUB_MOD_FINI(test)
+{
+  grub_unregister_command (cmd_1);
+  grub_unregister_command (cmd_2);
+}
diff --git a/commands/true.c b/commands/true.c
new file mode 100644
index 0000000..16ca315
--- /dev/null
+++ b/commands/true.c
@@ -0,0 +1,56 @@
+/* true.c - true and false commands.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/command.h>
+
+static grub_err_t
+grub_cmd_true (struct grub_command *cmd __attribute__ ((unused)),
+	       int argc __attribute__ ((unused)),
+	       char *argv[] __attribute__ ((unused)))
+{
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_false (struct grub_command *cmd __attribute__ ((unused)),
+		int argc __attribute__ ((unused)),
+		char *argv[] __attribute__ ((unused)))
+{
+  return grub_error (GRUB_ERR_TEST_FAILURE, "false");
+}
+
+static grub_command_t cmd_true, cmd_false;
+
+
+GRUB_MOD_INIT(true)
+{
+  cmd_true =
+    grub_register_command ("true", grub_cmd_true,
+			   0, "do nothing, successfully");
+  cmd_false =
+    grub_register_command ("false", grub_cmd_false,
+			   0, "do nothing, unsuccessfully");
+}
+
+GRUB_MOD_FINI(true)
+{
+  grub_unregister_command (cmd_true);
+  grub_unregister_command (cmd_false);
+}
diff --git a/commands/usbtest.c b/commands/usbtest.c
new file mode 100644
index 0000000..018c1a2
--- /dev/null
+++ b/commands/usbtest.c
@@ -0,0 +1,161 @@
+/* usbtest.c - test module for USB */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/usb.h>
+#include <grub/command.h>
+
+static const char *usb_classes[] =
+  {
+    "",
+    "Audio",
+    "Communication Interface",
+    "HID",
+    "",
+    "Physical",
+    "Image",
+    "Printer",
+    "Mass Storage",
+    "Hub",
+    "Data Interface",
+    "Smart Card",
+    "Content Security",
+    "Video"
+  };
+
+static const char *usb_endp_type[] =
+  {
+    "Control",
+    "Isochronous",
+    "Bulk",
+    "Interrupt"
+  };
+
+static const char *usb_devspeed[] =
+  {
+    "",
+    "Low",
+    "Full",
+    "High"
+  };
+
+static void
+usb_print_str (const char *description, grub_usb_device_t dev, int idx)
+{
+  char *name;
+  /* XXX: LANGID  */
+
+  if (! idx)
+    return;
+
+  grub_usb_get_string (dev, idx, 0x0409, &name);
+  grub_printf ("%s: `%s'\n", description, name);
+  grub_free (name);
+}
+
+static int
+usb_iterate (grub_usb_device_t dev)
+{
+  struct grub_usb_desc_device *descdev;
+  int i;
+
+  descdev = &dev->descdev;
+
+  usb_print_str ("Product", dev, descdev->strprod);
+  usb_print_str ("Vendor", dev, descdev->strvendor);
+  usb_print_str ("Serial", dev, descdev->strserial);
+
+  if (descdev->class > 0 && descdev->class <= 0x0E)
+    grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n",
+		 descdev->class, usb_classes[descdev->class],
+		 descdev->subclass, descdev->protocol);
+  grub_printf ("USB version %d.%d, VendorID: 0x%02x, ProductID: 0x%02x, #conf: %d\n",
+	       descdev->usbrel >> 8, (descdev->usbrel >> 4) & 0x0F,
+	       descdev->vendorid, descdev->prodid, descdev->configcnt);
+
+  grub_printf ("%s speed device\n", usb_devspeed[dev->speed]);
+
+  for (i = 0; i < descdev->configcnt; i++)
+    {
+      struct grub_usb_desc_config *config;
+
+      config = dev->config[i].descconf;
+      usb_print_str ("Configuration:", dev, config->strconfig);
+    }
+
+  for (i = 0; i < dev->config[0].descconf->numif; i++)
+    {
+      int j;
+      struct grub_usb_desc_if *interf;
+      interf = dev->config[0].interf[i].descif;
+
+      grub_printf ("Interface #%d: #Endpoints: %d   ",
+		   i, interf->endpointcnt);
+      if (interf->class > 0 && interf->class <= 0x0E)
+	grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n",
+		     interf->class, usb_classes[interf->class],
+		     interf->subclass, interf->protocol);
+
+      usb_print_str ("Interface", dev, interf->strif);
+
+      for (j = 0; j < interf->endpointcnt; j++)
+	{
+	  struct grub_usb_desc_endp *endp;
+	  endp = &dev->config[0].interf[i].descendp[j];
+
+	  grub_printf ("Endpoint #%d: %s, max packed size: %d, transfer type: %s, latency: %d\n",
+		       endp->endp_addr & 15,
+		       (endp->endp_addr & 128) ? "IN" : "OUT",
+		       endp->maxpacket, usb_endp_type[endp->attrib & 3],
+		       endp->interval);
+	}
+    }
+
+  grub_printf("\n");
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)),
+		  int argc __attribute__ ((unused)),
+		  char **args __attribute__ ((unused)))
+{
+  grub_printf ("USB devices:\n\n");
+  grub_usb_iterate (usb_iterate);
+
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(usbtest)
+{
+  cmd = grub_register_command ("usb", grub_cmd_usbtest,
+			       0, "Test USB support");
+}
+
+GRUB_MOD_FINI(usbtest)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/videotest.c b/commands/videotest.c
new file mode 100644
index 0000000..6fe4b9b
--- /dev/null
+++ b/commands/videotest.c
@@ -0,0 +1,187 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/video.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/font.h>
+#include <grub/term.h>
+#include <grub/command.h>
+
+static grub_err_t
+grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
+                    int argc __attribute__ ((unused)),
+                    char **args __attribute__ ((unused)))
+{
+  if (grub_video_set_mode ("1024x768;800x600;640x480", 0) != GRUB_ERR_NONE)
+    return grub_errno;
+
+  grub_video_color_t color;
+  unsigned int x;
+  unsigned int y;
+  unsigned int width;
+  unsigned int height;
+  int i;
+  grub_font_t sansbig;
+  grub_font_t sans;
+  grub_font_t sanssmall;
+  grub_font_t fixed;
+  struct grub_font_glyph *glyph;
+  struct grub_video_render_target *text_layer;
+  grub_video_color_t palette[16];
+  const char *str;
+  int texty;
+
+  grub_video_get_viewport (&x, &y, &width, &height);
+
+  grub_video_create_render_target (&text_layer, width, height,
+                                   GRUB_VIDEO_MODE_TYPE_RGB
+                                   | GRUB_VIDEO_MODE_TYPE_ALPHA);
+
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+  color = grub_video_map_rgb (0, 0, 0);
+  grub_video_fill_rect (color, 0, 0, width, height);
+
+  color = grub_video_map_rgb (255, 0, 0);
+  grub_video_fill_rect (color, 0, 0, 100, 100);
+
+  color = grub_video_map_rgb (0, 255, 255);
+  grub_video_fill_rect (color, 100, 100, 100, 100);
+
+  sansbig = grub_font_get ("Helvetica Bold 24");
+  sans = grub_font_get ("Helvetica Bold 14");
+  sanssmall = grub_font_get ("Helvetica 8");
+  fixed = grub_font_get ("Fixed 20");
+  if (! sansbig || ! sans || ! sanssmall || ! fixed)
+    return grub_error (GRUB_ERR_BAD_FONT, "No font loaded.");
+
+  glyph = grub_font_get_glyph (fixed, '*');
+  grub_font_draw_glyph (glyph, color, 200 ,0);
+
+  grub_video_set_viewport (x + 150, y + 150,
+                           width - 150 * 2, height - 150 * 2);
+  color = grub_video_map_rgb (77, 33, 77);
+  grub_video_fill_rect (color, 0, 0, width, height);
+
+  grub_video_set_active_render_target (text_layer);
+
+  color = grub_video_map_rgb (255, 255, 255);
+
+  texty = 32;
+  grub_font_draw_string ("The quick brown fox jumped over the lazy dog.",
+                         sans, color, 16, texty);
+  texty += grub_font_get_descent (sans) + grub_font_get_leading (sans);
+
+  texty += grub_font_get_ascent (fixed);
+  grub_font_draw_string ("The quick brown fox jumped over the lazy dog.",
+                         fixed, color, 16, texty);
+  texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed);
+
+  /* To convert Unicode characters into UTF-8 for this test, the following
+     command is useful:
+       echo -ne '\x00\x00\x26\x3A' | iconv -f UTF-32BE -t UTF-8 | od -t x1
+     This converts the Unicode character U+263A to UTF-8.  */
+
+  /* Characters used:
+     Code point  Description                    UTF-8 encoding
+     ----------- ------------------------------ --------------
+     U+263A      unfilled smiley face           E2 98 BA
+     U+00A1      inverted exclamation point     C2 A1
+     U+00A3      British pound currency symbol  C2 A3
+     U+03C4      Greek tau                      CF 84
+     U+00E4      lowercase letter a with umlaut C3 A4
+     U+2124      set 'Z' symbol (integers)      E2 84 A4
+     U+2287      subset symbol                  E2 8A 87
+     U+211D      set 'R' symbol (real numbers)  E2 84 9D  */
+
+  str =
+    "Unicode test: happy\xE2\x98\xBA \xC2\xA3 5.00"
+    " \xC2\xA1\xCF\x84\xC3\xA4u! "
+    " \xE2\x84\xA4\xE2\x8A\x87\xE2\x84\x9D";
+  color = grub_video_map_rgb (128, 128, 255);
+
+  /* All characters in the string exist in the 'Fixed 20' (10x20) font.  */
+  texty += grub_font_get_ascent(fixed);
+  grub_font_draw_string (str, fixed, color, 16, texty);
+  texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed);
+
+  /* Some character don't exist in the Helvetica font, so the font engine
+     will fall back to using glyphs from another font that does contain them.
+     TODO The font engine should be smart about selecting a replacement font
+     and prioritize fonts with similar sizes.  */
+
+  texty += grub_font_get_ascent(sansbig);
+  grub_font_draw_string (str, sansbig, color, 16, texty);
+  texty += grub_font_get_descent (sansbig) + grub_font_get_leading (sansbig);
+
+  texty += grub_font_get_ascent(sans);
+  grub_font_draw_string (str, sans, color, 16, texty);
+  texty += grub_font_get_descent (sans) + grub_font_get_leading (sans);
+
+  texty += grub_font_get_ascent(sanssmall);
+  grub_font_draw_string (str, sanssmall, color, 16, texty);
+  texty += (grub_font_get_descent (sanssmall)
+            + grub_font_get_leading (sanssmall));
+
+  glyph = grub_font_get_glyph (fixed, '*');
+
+  for (i = 0; i < 16; i++)
+    {
+      color = grub_video_map_color (i);
+      palette[i] = color;
+      grub_font_draw_glyph (glyph, color, 16 + i * 16, 220);
+    }
+
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+  for (i = 0; i < 255; i++)
+    {
+      color = grub_video_map_rgb (i, 33, 77);
+      grub_video_fill_rect (color, 0, 0, width, height);
+      grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0,
+                                     0, 0, width, height);
+    }
+
+  grub_getkey ();
+
+  grub_video_delete_render_target (text_layer);
+
+  grub_video_restore ();
+
+  for (i = 0; i < 16; i++)
+    grub_printf("color %d: %08x\n", i, palette[i]);
+
+  grub_errno = GRUB_ERR_NONE;
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(videotest)
+{
+  cmd = grub_register_command ("videotest", grub_cmd_videotest,
+			       0, "Test video subsystem");
+}
+
+GRUB_MOD_FINI(videotest)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/commands/xnu_uuid.c b/commands/xnu_uuid.c
new file mode 100644
index 0000000..06e88e5
--- /dev/null
+++ b/commands/xnu_uuid.c
@@ -0,0 +1,388 @@
+/* xnu_uuid.c - transform 64-bit serial number 
+   to 128-bit uuid suitable for xnu. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1995,1996,1998,1999,2001,2002,
+ *                2003, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/fs.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/command.h>
+
+struct tohash
+{
+  grub_uint8_t prefix[16];
+  grub_uint64_t serial;
+} __attribute__ ((packed));
+
+/* This prefix is used by xnu and boot-132 to hash 
+   together with volume serial. */
+static grub_uint8_t hash_prefix[16] 
+  = {0xB3, 0xE2, 0x0F, 0x39, 0xF2, 0x92, 0x11, 0xD6, 
+     0x97, 0xA4, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC};
+
+#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
+
+typedef struct {
+  grub_uint32_t A,B,C,D;	  /* chaining variables */
+  grub_uint32_t  nblocks;
+  grub_uint8_t buf[64];
+  int  count;
+} MD5_CONTEXT;
+
+static void
+md5_init( void *context )
+{
+  MD5_CONTEXT *ctx = context;
+
+  ctx->A = 0x67452301;
+  ctx->B = 0xefcdab89;
+  ctx->C = 0x98badcfe;
+  ctx->D = 0x10325476;
+
+  ctx->nblocks = 0;
+  ctx->count = 0;
+}
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+   and defined in the RFC 1321.  The first function is a little bit optimized
+   (as found in Colin Plumbs public domain implementation).  */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+
+/****************
+ * transform n*64 grub_uint8_ts
+ */
+static void
+transform ( MD5_CONTEXT *ctx, const unsigned char *data )
+{
+  grub_uint32_t correct_words[16];
+  register grub_uint32_t A = ctx->A;
+  register grub_uint32_t B = ctx->B;
+  register grub_uint32_t C = ctx->C;
+  register grub_uint32_t D = ctx->D;
+  grub_uint32_t *cwp = correct_words;
+
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+  {
+    int i;
+    const grub_uint32_t *p = (const grub_uint32_t *) data;
+
+    for (i = 0; i < 16; i++)
+      correct_words[i] = grub_le_to_cpu32 (p[i]);
+  }
+#else
+  grub_memcpy (correct_words, data, 64);
+#endif
+
+#define OP(a, b, c, d, s, T) \
+  do			         	   \
+  {					   \
+    a += FF (b, c, d) + (*cwp++) + T;    \
+    a = rol(a, s);			   \
+    a += b;				   \
+  }					   \
+  while (0)
+
+  /* Before we start, one word about the strange constants.
+     They are defined in RFC 1321 as
+
+     T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+     */
+
+  /* Round 1.  */
+  OP (A, B, C, D,  7, 0xd76aa478);
+  OP (D, A, B, C, 12, 0xe8c7b756);
+  OP (C, D, A, B, 17, 0x242070db);
+  OP (B, C, D, A, 22, 0xc1bdceee);
+  OP (A, B, C, D,  7, 0xf57c0faf);
+  OP (D, A, B, C, 12, 0x4787c62a);
+  OP (C, D, A, B, 17, 0xa8304613);
+  OP (B, C, D, A, 22, 0xfd469501);
+  OP (A, B, C, D,  7, 0x698098d8);
+  OP (D, A, B, C, 12, 0x8b44f7af);
+  OP (C, D, A, B, 17, 0xffff5bb1);
+  OP (B, C, D, A, 22, 0x895cd7be);
+  OP (A, B, C, D,  7, 0x6b901122);
+  OP (D, A, B, C, 12, 0xfd987193);
+  OP (C, D, A, B, 17, 0xa679438e);
+  OP (B, C, D, A, 22, 0x49b40821);
+
+#undef OP
+#define OP(f, a, b, c, d, k, s, T)  \
+  do								      \
+  { 							      \
+    a += f (b, c, d) + correct_words[k] + T;		      \
+    a = rol(a, s);						      \
+    a += b; 						      \
+  } 							      \
+  while (0)
+
+  /* Round 2.  */
+  OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
+  OP (FG, D, A, B, C,  6,  9, 0xc040b340);
+  OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+  OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
+  OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
+  OP (FG, D, A, B, C, 10,  9, 0x02441453);
+  OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+  OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
+  OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
+  OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
+  OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
+  OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
+  OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
+  OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
+  OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
+  OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+  /* Round 3.  */
+  OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
+  OP (FH, D, A, B, C,  8, 11, 0x8771f681);
+  OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+  OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+  OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
+  OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
+  OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
+  OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+  OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
+  OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
+  OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
+  OP (FH, B, C, D, A,  6, 23, 0x04881d05);
+  OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
+  OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+  OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+  OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
+
+  /* Round 4.  */
+  OP (FI, A, B, C, D,  0,  6, 0xf4292244);
+  OP (FI, D, A, B, C,  7, 10, 0x432aff97);
+  OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+  OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
+  OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
+  OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
+  OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+  OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
+  OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
+  OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+  OP (FI, C, D, A, B,  6, 15, 0xa3014314);
+  OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+  OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
+  OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+  OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
+  OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
+
+  /* Put checksum in context given as argument.  */
+  ctx->A += A;
+  ctx->B += B;
+  ctx->C += C;
+  ctx->D += D;
+}
+
+/* The routine updates the message-digest context to
+ * account for the presence of each of the characters inBuf[0..inLen-1]
+ * in the message whose digest is being computed.
+ */
+static void
+md5_write( void *context, const void *inbuf_arg , grub_size_t inlen)
+{
+  const unsigned char *inbuf = inbuf_arg;
+  MD5_CONTEXT *hd = context;
+
+  if( hd->count == 64 )  /* flush the buffer */
+  {
+    transform( hd, hd->buf );
+    //      _gcry_burn_stack (80+6*sizeof(void*));
+    hd->count = 0;
+    hd->nblocks++;
+  }
+  if( !inbuf )
+    return;
+
+  if( hd->count )
+  {
+    for( ; inlen && hd->count < 64; inlen-- )
+      hd->buf[hd->count++] = *inbuf++;
+    md5_write( hd, NULL, 0 );
+    if( !inlen )
+      return;
+  }
+  //  _gcry_burn_stack (80+6*sizeof(void*));
+
+  while( inlen >= 64 ) 
+  {
+    transform( hd, inbuf );
+    hd->count = 0;
+    hd->nblocks++;
+    inlen -= 64;
+    inbuf += 64;
+  }
+  for( ; inlen && hd->count < 64; inlen-- )
+    hd->buf[hd->count++] = *inbuf++;
+
+}
+
+
+
+/* The routine final terminates the message-digest computation and
+ * ends with the desired message digest in mdContext->digest[0...15].
+ * The handle is prepared for a new MD5 cycle.
+ * Returns 16 grub_uint8_ts representing the digest.
+ */
+static void
+md5_final( void *context)
+{
+  MD5_CONTEXT *hd = context;
+  grub_uint32_t t, msb, lsb;
+  grub_uint32_t *p;
+
+  md5_write(hd, NULL, 0); /* flush */;
+
+  t = hd->nblocks;
+  /* multiply by 64 to make a grub_uint8_t count */
+  lsb = t << 6;
+  msb = t >> 26;
+  /* add the count */
+  t = lsb;
+  if( (lsb += hd->count) < t )
+    msb++;
+  /* multiply by 8 to make a bit count */
+  t = lsb;
+  lsb <<= 3;
+  msb <<= 3;
+  msb |= t >> 29;
+
+  if( hd->count < 56 )  /* enough room */
+  {
+    hd->buf[hd->count++] = 0x80; /* pad */
+    while( hd->count < 56 )
+      hd->buf[hd->count++] = 0;  /* pad */
+  }
+  else  /* need one extra block */
+  {
+    hd->buf[hd->count++] = 0x80; /* pad character */
+    while( hd->count < 64 )
+      hd->buf[hd->count++] = 0;
+    md5_write(hd, NULL, 0);  /* flush */;
+    grub_memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+  }
+  /* append the 64 bit count */
+  hd->buf[56] = lsb	   ;
+  hd->buf[57] = lsb >>  8;
+  hd->buf[58] = lsb >> 16;
+  hd->buf[59] = lsb >> 24;
+  hd->buf[60] = msb	   ;
+  hd->buf[61] = msb >>  8;
+  hd->buf[62] = msb >> 16;
+  hd->buf[63] = msb >> 24;
+  transform( hd, hd->buf );
+  //  _gcry_burn_stack (80+6*sizeof(void*));
+
+  p = (grub_uint32_t *) hd->buf;
+#define X(a) do { *p = grub_le_to_cpu32 (hd->a); p++; } while (0)
+  X(A);
+  X(B);
+  X(C);
+  X(D);
+#undef X
+
+}
+
+/**
+ * GRUB2 Crypto Interface
+ * Written by Michael Gorven
+ */
+static grub_err_t
+md5 (const char *in, grub_size_t insize, char *out)
+{
+  MD5_CONTEXT hd;
+
+  md5_init (&hd);
+  md5_write (&hd, in, insize);
+  md5_final (&hd);
+  grub_memcpy (out, hd.buf, 16);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)),
+		   int argc, char **args)
+{
+  struct tohash hashme;
+  grub_uint8_t xnu_uuid[16];
+  char uuid_string[sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
+  char *ptr;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "UUID required");
+
+  hashme.serial = grub_cpu_to_be64 (grub_strtoull (args[0], 0, 16));
+  grub_memcpy (hashme.prefix, hash_prefix, sizeof (hashme.prefix));
+
+  md5 ((char *) &hashme, sizeof (hashme), (char *) xnu_uuid);
+  grub_sprintf (uuid_string,
+		"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		(unsigned int) xnu_uuid[0], (unsigned int) xnu_uuid[1],
+		(unsigned int) xnu_uuid[2], (unsigned int) xnu_uuid[3],
+		(unsigned int) xnu_uuid[4], (unsigned int) xnu_uuid[5],
+		(unsigned int) ((xnu_uuid[6] & 0xf) | 0x30),
+		(unsigned int) xnu_uuid[7],
+		(unsigned int) ((xnu_uuid[8] & 0x3f) | 0x80),
+		(unsigned int) xnu_uuid[9],
+		(unsigned int) xnu_uuid[10], (unsigned int) xnu_uuid[11],
+		(unsigned int) xnu_uuid[12], (unsigned int) xnu_uuid[13],
+		(unsigned int) xnu_uuid[14], (unsigned int) xnu_uuid[15]);
+  for (ptr = uuid_string; *ptr; ptr++)
+    *ptr = grub_toupper (*ptr);
+  if (argc == 1)
+    grub_printf ("%s", uuid_string);
+  if (argc > 1)
+    grub_env_set (args[1], uuid_string);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd;
+
+
+GRUB_MOD_INIT (xnu_uuid)
+{
+  cmd = grub_register_command ("xnu_uuid", grub_cmd_xnu_uuid,
+			       "xnu_uuid GRUBUUID [VARNAME]",
+			       "Transform 64-bit UUID to format "
+			       "suitable for xnu.");
+}
+
+GRUB_MOD_FINI (xnu_uuid)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/conf/common.mk b/conf/common.mk
new file mode 100644
index 0000000..45532e4
--- /dev/null
+++ b/conf/common.mk
@@ -0,0 +1,9205 @@
+# -*- makefile -*-
+# Generated by genmk.rb, please don't edit!
+
+# For grub-mkelfimage.
+bin_UTILITIES += grub-mkelfimage
+grub_mkelfimage_SOURCES = util/elf/grub-mkimage.c util/misc.c \
+	util/resolve.c
+
+clean-utility-grub-mkelfimage.1:
+	rm -f grub-mkelfimage$(EXEEXT) grub_mkelfimage-util_elf_grub_mkimage.o grub_mkelfimage-util_misc.o grub_mkelfimage-util_resolve.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkelfimage.1
+
+mostlyclean-utility-grub-mkelfimage.1:
+	rm -f grub_mkelfimage-util_elf_grub_mkimage.d grub_mkelfimage-util_misc.d grub_mkelfimage-util_resolve.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkelfimage.1
+
+grub_mkelfimage_OBJECTS += grub_mkelfimage-util_elf_grub_mkimage.o grub_mkelfimage-util_misc.o grub_mkelfimage-util_resolve.o
+
+grub_mkelfimage-util_elf_grub_mkimage.o: util/elf/grub-mkimage.c $(util/elf/grub-mkimage.c_DEPENDENCIES)
+	$(CC) -Iutil/elf -I$(srcdir)/util/elf $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkelfimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkelfimage-util_elf_grub_mkimage.d
+
+grub_mkelfimage-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkelfimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkelfimage-util_misc.d
+
+grub_mkelfimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkelfimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkelfimage-util_resolve.d
+
+util/elf/grub-mkimage.c_DEPENDENCIES = Makefile
+
+# For grub-probe.
+sbin_UTILITIES += grub-probe
+util/grub-probe.c_DEPENDENCIES = grub_probe_init.h
+grub_probe_SOURCES = util/grub-probe.c	\
+	util/hostdisk.c	util/misc.c util/getroot.c		\
+	kern/device.c kern/disk.c kern/err.c kern/misc.c	\
+	kern/parser.c kern/partition.c kern/file.c		\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c	\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c		\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c	\
+	fs/befs.c fs/befs_be.c fs/tar.c		\
+	\
+	partmap/msdos.c partmap/apple.c partmap/sun.c partmap/gpt.c\
+	kern/fs.c kern/env.c fs/fshelp.c			\
+	disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c
+
+clean-utility-grub-probe.1:
+	rm -f grub-probe$(EXEEXT) grub_probe-util_grub_probe.o grub_probe-util_hostdisk.o grub_probe-util_misc.o grub_probe-util_getroot.o grub_probe-kern_device.o grub_probe-kern_disk.o grub_probe-kern_err.o grub_probe-kern_misc.o grub_probe-kern_parser.o grub_probe-kern_partition.o grub_probe-kern_file.o grub_probe-fs_affs.o grub_probe-fs_cpio.o grub_probe-fs_fat.o grub_probe-fs_ext2.o grub_probe-fs_hfs.o grub_probe-fs_hfsplus.o grub_probe-fs_iso9660.o grub_probe-fs_udf.o grub_probe-fs_jfs.o grub_probe-fs_minix.o grub_probe-fs_ntfs.o grub_probe-fs_ntfscomp.o grub_probe-fs_reiserfs.o grub_probe-fs_sfs.o grub_probe-fs_ufs.o grub_probe-fs_ufs2.o grub_probe-fs_xfs.o grub_probe-fs_afs.o grub_probe-fs_afs_be.o grub_probe-fs_befs.o grub_probe-fs_befs_be.o grub_probe-fs_tar.o grub_probe-partmap_msdos.o grub_probe-partmap_apple.o grub_probe-partmap_sun.o grub_probe-partmap_gpt.o grub_probe-kern_fs.o grub_probe-kern_env.o grub_probe-fs_fshelp.o grub_probe-disk_raid.o grub_probe-disk_mdraid_linux.o grub_probe-disk_lvm.o grub_probe-grub_probe_init.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-probe.1
+
+mostlyclean-utility-grub-probe.1:
+	rm -f grub_probe-util_grub_probe.d grub_probe-util_hostdisk.d grub_probe-util_misc.d grub_probe-util_getroot.d grub_probe-kern_device.d grub_probe-kern_disk.d grub_probe-kern_err.d grub_probe-kern_misc.d grub_probe-kern_parser.d grub_probe-kern_partition.d grub_probe-kern_file.d grub_probe-fs_affs.d grub_probe-fs_cpio.d grub_probe-fs_fat.d grub_probe-fs_ext2.d grub_probe-fs_hfs.d grub_probe-fs_hfsplus.d grub_probe-fs_iso9660.d grub_probe-fs_udf.d grub_probe-fs_jfs.d grub_probe-fs_minix.d grub_probe-fs_ntfs.d grub_probe-fs_ntfscomp.d grub_probe-fs_reiserfs.d grub_probe-fs_sfs.d grub_probe-fs_ufs.d grub_probe-fs_ufs2.d grub_probe-fs_xfs.d grub_probe-fs_afs.d grub_probe-fs_afs_be.d grub_probe-fs_befs.d grub_probe-fs_befs_be.d grub_probe-fs_tar.d grub_probe-partmap_msdos.d grub_probe-partmap_apple.d grub_probe-partmap_sun.d grub_probe-partmap_gpt.d grub_probe-kern_fs.d grub_probe-kern_env.d grub_probe-fs_fshelp.d grub_probe-disk_raid.d grub_probe-disk_mdraid_linux.d grub_probe-disk_lvm.d grub_probe-grub_probe_init.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-probe.1
+
+grub_probe_OBJECTS += grub_probe-util_grub_probe.o grub_probe-util_hostdisk.o grub_probe-util_misc.o grub_probe-util_getroot.o grub_probe-kern_device.o grub_probe-kern_disk.o grub_probe-kern_err.o grub_probe-kern_misc.o grub_probe-kern_parser.o grub_probe-kern_partition.o grub_probe-kern_file.o grub_probe-fs_affs.o grub_probe-fs_cpio.o grub_probe-fs_fat.o grub_probe-fs_ext2.o grub_probe-fs_hfs.o grub_probe-fs_hfsplus.o grub_probe-fs_iso9660.o grub_probe-fs_udf.o grub_probe-fs_jfs.o grub_probe-fs_minix.o grub_probe-fs_ntfs.o grub_probe-fs_ntfscomp.o grub_probe-fs_reiserfs.o grub_probe-fs_sfs.o grub_probe-fs_ufs.o grub_probe-fs_ufs2.o grub_probe-fs_xfs.o grub_probe-fs_afs.o grub_probe-fs_afs_be.o grub_probe-fs_befs.o grub_probe-fs_befs_be.o grub_probe-fs_tar.o grub_probe-partmap_msdos.o grub_probe-partmap_apple.o grub_probe-partmap_sun.o grub_probe-partmap_gpt.o grub_probe-kern_fs.o grub_probe-kern_env.o grub_probe-fs_fshelp.o grub_probe-disk_raid.o grub_probe-disk_mdraid_linux.o grub_probe-disk_lvm.o grub_probe-grub_probe_init.o
+
+grub_probe-util_grub_probe.o: util/grub-probe.c $(util/grub-probe.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-util_grub_probe.d
+
+grub_probe-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-util_hostdisk.d
+
+grub_probe-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-util_misc.d
+
+grub_probe-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-util_getroot.d
+
+grub_probe-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-kern_device.d
+
+grub_probe-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-kern_disk.d
+
+grub_probe-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-kern_err.d
+
+grub_probe-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-kern_misc.d
+
+grub_probe-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-kern_parser.d
+
+grub_probe-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-kern_partition.d
+
+grub_probe-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-kern_file.d
+
+grub_probe-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_affs.d
+
+grub_probe-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_cpio.d
+
+grub_probe-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_fat.d
+
+grub_probe-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_ext2.d
+
+grub_probe-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_hfs.d
+
+grub_probe-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_hfsplus.d
+
+grub_probe-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_iso9660.d
+
+grub_probe-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_udf.d
+
+grub_probe-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_jfs.d
+
+grub_probe-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_minix.d
+
+grub_probe-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_ntfs.d
+
+grub_probe-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_ntfscomp.d
+
+grub_probe-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_reiserfs.d
+
+grub_probe-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_sfs.d
+
+grub_probe-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_ufs.d
+
+grub_probe-fs_ufs2.o: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_ufs2.d
+
+grub_probe-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_xfs.d
+
+grub_probe-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_afs.d
+
+grub_probe-fs_afs_be.o: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_afs_be.d
+
+grub_probe-fs_befs.o: fs/befs.c $(fs/befs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_befs.d
+
+grub_probe-fs_befs_be.o: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_befs_be.d
+
+grub_probe-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_tar.d
+
+grub_probe-partmap_msdos.o: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-partmap_msdos.d
+
+grub_probe-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-partmap_apple.d
+
+grub_probe-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-partmap_sun.d
+
+grub_probe-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-partmap_gpt.d
+
+grub_probe-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-kern_fs.d
+
+grub_probe-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-kern_env.d
+
+grub_probe-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-fs_fshelp.d
+
+grub_probe-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-disk_raid.d
+
+grub_probe-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-disk_mdraid_linux.d
+
+grub_probe-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-disk_lvm.d
+
+grub_probe-grub_probe_init.o: grub_probe_init.c $(grub_probe_init.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $<
+-include grub_probe-grub_probe_init.d
+
+
+ifeq ($(enable_grub_fstest), yes)
+bin_UTILITIES += grub-fstest
+endif
+
+# For grub-fstest.
+util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h
+grub_fstest_SOURCES = util/grub-fstest.c util/hostfs.c util/misc.c 	\
+	kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c	\
+	disk/host.c disk/loopback.c kern/list.c kern/command.c		\
+	lib/arg.c commands/extcmd.c normal/datetime.c normal/misc.c	\
+	lib/hexdump.c lib/crc.c commands/blocklist.c commands/ls.c 	\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c 	\
+	fs/befs_be.c fs/tar.c			\
+	\
+	kern/partition.c partmap/msdos.c partmap/apple.c partmap/sun.c	\
+	partmap/gpt.c							\
+	kern/fs.c kern/env.c fs/fshelp.c disk/raid.c			\
+	disk/raid5_recover.c disk/raid6_recover.c 			\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c 		\
+	grub_fstest_init.c
+
+clean-utility-grub-fstest.1:
+	rm -f grub-fstest$(EXEEXT) grub_fstest-util_grub_fstest.o grub_fstest-util_hostfs.o grub_fstest-util_misc.o grub_fstest-kern_file.o grub_fstest-kern_device.o grub_fstest-kern_disk.o grub_fstest-kern_err.o grub_fstest-kern_misc.o grub_fstest-disk_host.o grub_fstest-disk_loopback.o grub_fstest-kern_list.o grub_fstest-kern_command.o grub_fstest-lib_arg.o grub_fstest-commands_extcmd.o grub_fstest-normal_datetime.o grub_fstest-normal_misc.o grub_fstest-lib_hexdump.o grub_fstest-lib_crc.o grub_fstest-commands_blocklist.o grub_fstest-commands_ls.o grub_fstest-fs_affs.o grub_fstest-fs_cpio.o grub_fstest-fs_fat.o grub_fstest-fs_ext2.o grub_fstest-fs_hfs.o grub_fstest-fs_hfsplus.o grub_fstest-fs_iso9660.o grub_fstest-fs_udf.o grub_fstest-fs_jfs.o grub_fstest-fs_minix.o grub_fstest-fs_ntfs.o grub_fstest-fs_ntfscomp.o grub_fstest-fs_reiserfs.o grub_fstest-fs_sfs.o grub_fstest-fs_ufs.o grub_fstest-fs_ufs2.o grub_fstest-fs_xfs.o grub_fstest-fs_afs.o grub_fstest-fs_afs_be.o grub_fstest-fs_befs.o grub_fstest-fs_befs_be.o grub_fstest-fs_tar.o grub_fstest-kern_partition.o grub_fstest-partmap_msdos.o grub_fstest-partmap_apple.o grub_fstest-partmap_sun.o grub_fstest-partmap_gpt.o grub_fstest-kern_fs.o grub_fstest-kern_env.o grub_fstest-fs_fshelp.o grub_fstest-disk_raid.o grub_fstest-disk_raid5_recover.o grub_fstest-disk_raid6_recover.o grub_fstest-disk_mdraid_linux.o grub_fstest-disk_dmraid_nvidia.o grub_fstest-disk_lvm.o grub_fstest-grub_fstest_init.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-fstest.1
+
+mostlyclean-utility-grub-fstest.1:
+	rm -f grub_fstest-util_grub_fstest.d grub_fstest-util_hostfs.d grub_fstest-util_misc.d grub_fstest-kern_file.d grub_fstest-kern_device.d grub_fstest-kern_disk.d grub_fstest-kern_err.d grub_fstest-kern_misc.d grub_fstest-disk_host.d grub_fstest-disk_loopback.d grub_fstest-kern_list.d grub_fstest-kern_command.d grub_fstest-lib_arg.d grub_fstest-commands_extcmd.d grub_fstest-normal_datetime.d grub_fstest-normal_misc.d grub_fstest-lib_hexdump.d grub_fstest-lib_crc.d grub_fstest-commands_blocklist.d grub_fstest-commands_ls.d grub_fstest-fs_affs.d grub_fstest-fs_cpio.d grub_fstest-fs_fat.d grub_fstest-fs_ext2.d grub_fstest-fs_hfs.d grub_fstest-fs_hfsplus.d grub_fstest-fs_iso9660.d grub_fstest-fs_udf.d grub_fstest-fs_jfs.d grub_fstest-fs_minix.d grub_fstest-fs_ntfs.d grub_fstest-fs_ntfscomp.d grub_fstest-fs_reiserfs.d grub_fstest-fs_sfs.d grub_fstest-fs_ufs.d grub_fstest-fs_ufs2.d grub_fstest-fs_xfs.d grub_fstest-fs_afs.d grub_fstest-fs_afs_be.d grub_fstest-fs_befs.d grub_fstest-fs_befs_be.d grub_fstest-fs_tar.d grub_fstest-kern_partition.d grub_fstest-partmap_msdos.d grub_fstest-partmap_apple.d grub_fstest-partmap_sun.d grub_fstest-partmap_gpt.d grub_fstest-kern_fs.d grub_fstest-kern_env.d grub_fstest-fs_fshelp.d grub_fstest-disk_raid.d grub_fstest-disk_raid5_recover.d grub_fstest-disk_raid6_recover.d grub_fstest-disk_mdraid_linux.d grub_fstest-disk_dmraid_nvidia.d grub_fstest-disk_lvm.d grub_fstest-grub_fstest_init.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-fstest.1
+
+grub_fstest_OBJECTS += grub_fstest-util_grub_fstest.o grub_fstest-util_hostfs.o grub_fstest-util_misc.o grub_fstest-kern_file.o grub_fstest-kern_device.o grub_fstest-kern_disk.o grub_fstest-kern_err.o grub_fstest-kern_misc.o grub_fstest-disk_host.o grub_fstest-disk_loopback.o grub_fstest-kern_list.o grub_fstest-kern_command.o grub_fstest-lib_arg.o grub_fstest-commands_extcmd.o grub_fstest-normal_datetime.o grub_fstest-normal_misc.o grub_fstest-lib_hexdump.o grub_fstest-lib_crc.o grub_fstest-commands_blocklist.o grub_fstest-commands_ls.o grub_fstest-fs_affs.o grub_fstest-fs_cpio.o grub_fstest-fs_fat.o grub_fstest-fs_ext2.o grub_fstest-fs_hfs.o grub_fstest-fs_hfsplus.o grub_fstest-fs_iso9660.o grub_fstest-fs_udf.o grub_fstest-fs_jfs.o grub_fstest-fs_minix.o grub_fstest-fs_ntfs.o grub_fstest-fs_ntfscomp.o grub_fstest-fs_reiserfs.o grub_fstest-fs_sfs.o grub_fstest-fs_ufs.o grub_fstest-fs_ufs2.o grub_fstest-fs_xfs.o grub_fstest-fs_afs.o grub_fstest-fs_afs_be.o grub_fstest-fs_befs.o grub_fstest-fs_befs_be.o grub_fstest-fs_tar.o grub_fstest-kern_partition.o grub_fstest-partmap_msdos.o grub_fstest-partmap_apple.o grub_fstest-partmap_sun.o grub_fstest-partmap_gpt.o grub_fstest-kern_fs.o grub_fstest-kern_env.o grub_fstest-fs_fshelp.o grub_fstest-disk_raid.o grub_fstest-disk_raid5_recover.o grub_fstest-disk_raid6_recover.o grub_fstest-disk_mdraid_linux.o grub_fstest-disk_dmraid_nvidia.o grub_fstest-disk_lvm.o grub_fstest-grub_fstest_init.o
+
+grub_fstest-util_grub_fstest.o: util/grub-fstest.c $(util/grub-fstest.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-util_grub_fstest.d
+
+grub_fstest-util_hostfs.o: util/hostfs.c $(util/hostfs.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-util_hostfs.d
+
+grub_fstest-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-util_misc.d
+
+grub_fstest-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-kern_file.d
+
+grub_fstest-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-kern_device.d
+
+grub_fstest-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-kern_disk.d
+
+grub_fstest-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-kern_err.d
+
+grub_fstest-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-kern_misc.d
+
+grub_fstest-disk_host.o: disk/host.c $(disk/host.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-disk_host.d
+
+grub_fstest-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-disk_loopback.d
+
+grub_fstest-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-kern_list.d
+
+grub_fstest-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-kern_command.d
+
+grub_fstest-lib_arg.o: lib/arg.c $(lib/arg.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-lib_arg.d
+
+grub_fstest-commands_extcmd.o: commands/extcmd.c $(commands/extcmd.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-commands_extcmd.d
+
+grub_fstest-normal_datetime.o: normal/datetime.c $(normal/datetime.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-normal_datetime.d
+
+grub_fstest-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-normal_misc.d
+
+grub_fstest-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-lib_hexdump.d
+
+grub_fstest-lib_crc.o: lib/crc.c $(lib/crc.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-lib_crc.d
+
+grub_fstest-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-commands_blocklist.d
+
+grub_fstest-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-commands_ls.d
+
+grub_fstest-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_affs.d
+
+grub_fstest-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_cpio.d
+
+grub_fstest-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_fat.d
+
+grub_fstest-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_ext2.d
+
+grub_fstest-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_hfs.d
+
+grub_fstest-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_hfsplus.d
+
+grub_fstest-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_iso9660.d
+
+grub_fstest-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_udf.d
+
+grub_fstest-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_jfs.d
+
+grub_fstest-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_minix.d
+
+grub_fstest-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_ntfs.d
+
+grub_fstest-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_ntfscomp.d
+
+grub_fstest-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_reiserfs.d
+
+grub_fstest-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_sfs.d
+
+grub_fstest-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_ufs.d
+
+grub_fstest-fs_ufs2.o: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_ufs2.d
+
+grub_fstest-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_xfs.d
+
+grub_fstest-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_afs.d
+
+grub_fstest-fs_afs_be.o: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_afs_be.d
+
+grub_fstest-fs_befs.o: fs/befs.c $(fs/befs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_befs.d
+
+grub_fstest-fs_befs_be.o: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_befs_be.d
+
+grub_fstest-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_tar.d
+
+grub_fstest-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-kern_partition.d
+
+grub_fstest-partmap_msdos.o: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-partmap_msdos.d
+
+grub_fstest-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-partmap_apple.d
+
+grub_fstest-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-partmap_sun.d
+
+grub_fstest-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-partmap_gpt.d
+
+grub_fstest-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-kern_fs.d
+
+grub_fstest-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-kern_env.d
+
+grub_fstest-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-fs_fshelp.d
+
+grub_fstest-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-disk_raid.d
+
+grub_fstest-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-disk_raid5_recover.d
+
+grub_fstest-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-disk_raid6_recover.d
+
+grub_fstest-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-disk_mdraid_linux.d
+
+grub_fstest-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-disk_dmraid_nvidia.d
+
+grub_fstest-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-disk_lvm.d
+
+grub_fstest-grub_fstest_init.o: grub_fstest_init.c $(grub_fstest_init.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $<
+-include grub_fstest-grub_fstest_init.d
+
+
+# For grub-mkfont.
+ifeq ($(enable_grub_mkfont), yes)
+bin_UTILITIES += grub-mkfont
+grub_mkfont_SOURCES = util/grub-mkfont.c util/misc.c
+
+clean-utility-grub-mkfont.1:
+	rm -f grub-mkfont$(EXEEXT) grub_mkfont-util_grub_mkfont.o grub_mkfont-util_misc.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkfont.1
+
+mostlyclean-utility-grub-mkfont.1:
+	rm -f grub_mkfont-util_grub_mkfont.d grub_mkfont-util_misc.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkfont.1
+
+grub_mkfont_OBJECTS += grub_mkfont-util_grub_mkfont.o grub_mkfont-util_misc.o
+
+grub_mkfont-util_grub_mkfont.o: util/grub-mkfont.c $(util/grub-mkfont.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkfont_CFLAGS) -MD -c -o $@ $<
+-include grub_mkfont-util_grub_mkfont.d
+
+grub_mkfont-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkfont_CFLAGS) -MD -c -o $@ $<
+-include grub_mkfont-util_misc.d
+
+grub_mkfont_CFLAGS = $(freetype_cflags)
+grub_mkfont_LDFLAGS = $(freetype_libs)
+endif
+
+# For the parser.
+grub_script.tab.c grub_script.tab.h: script/sh/parser.y
+	$(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/sh/parser.y
+DISTCLEANFILES += grub_script.tab.c grub_script.tab.h
+
+# For grub-emu.
+grub_emu_init.lst: geninit.sh $(filter-out grub_emu_init.c,$(grub_emu_SOURCES))
+	rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
+DISTCLEANFILES += grub_emu_init.lst
+
+grub_emu_init.h: grub_emu_init.lst $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) geninitheader.sh
+	rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
+DISTCLEANFILES += grub_emu_init.h
+
+grub_emu_init.c: grub_emu_init.lst $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) geninit.sh grub_emu_init.h
+	rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
+DISTCLEANFILES += grub_emu_init.c
+
+# For grub-probe.
+grub_probe_init.lst: geninit.sh $(filter-out grub_probe_init.c,$(grub_probe_SOURCES))
+	rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
+DISTCLEANFILES += grub_probe_init.lst
+
+grub_probe_init.h: grub_probe_init.lst $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) geninitheader.sh
+	rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
+DISTCLEANFILES += grub_probe_init.h
+
+grub_probe_init.c: grub_probe_init.lst $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) geninit.sh grub_probe_init.h
+	rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
+DISTCLEANFILES += grub_probe_init.c
+
+# For grub-setup.
+grub_setup_init.lst: geninit.sh $(filter-out grub_setup_init.c,$(grub_setup_SOURCES))
+	rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
+DISTCLEANFILES += grub_setup_init.lst
+
+grub_setup_init.h: grub_setup_init.lst $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) geninitheader.sh
+	rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
+DISTCLEANFILES += grub_setup_init.h
+
+grub_setup_init.c: grub_setup_init.lst $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) geninit.sh grub_setup_init.h
+	rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
+DISTCLEANFILES += grub_setup_init.c
+
+# For grub-fstest.
+grub_fstest_init.lst: geninit.sh $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES))
+	rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
+DISTCLEANFILES += grub_fstest_init.lst
+
+grub_fstest_init.h: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) geninitheader.sh
+	rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
+DISTCLEANFILES += grub_fstest_init.h
+
+grub_fstest_init.c: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) geninit.sh grub_fstest_init.h
+	rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
+DISTCLEANFILES += grub_fstest_init.c
+
+# for grub-editenv
+bin_UTILITIES += grub-editenv
+grub_editenv_SOURCES = util/grub-editenv.c lib/envblk.c util/misc.c kern/misc.c kern/err.c
+
+clean-utility-grub-editenv.1:
+	rm -f grub-editenv$(EXEEXT) grub_editenv-util_grub_editenv.o grub_editenv-lib_envblk.o grub_editenv-util_misc.o grub_editenv-kern_misc.o grub_editenv-kern_err.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-editenv.1
+
+mostlyclean-utility-grub-editenv.1:
+	rm -f grub_editenv-util_grub_editenv.d grub_editenv-lib_envblk.d grub_editenv-util_misc.d grub_editenv-kern_misc.d grub_editenv-kern_err.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-editenv.1
+
+grub_editenv_OBJECTS += grub_editenv-util_grub_editenv.o grub_editenv-lib_envblk.o grub_editenv-util_misc.o grub_editenv-kern_misc.o grub_editenv-kern_err.o
+
+grub_editenv-util_grub_editenv.o: util/grub-editenv.c $(util/grub-editenv.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_editenv_CFLAGS) -MD -c -o $@ $<
+-include grub_editenv-util_grub_editenv.d
+
+grub_editenv-lib_envblk.o: lib/envblk.c $(lib/envblk.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_editenv_CFLAGS) -MD -c -o $@ $<
+-include grub_editenv-lib_envblk.d
+
+grub_editenv-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_editenv_CFLAGS) -MD -c -o $@ $<
+-include grub_editenv-util_misc.d
+
+grub_editenv-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_editenv_CFLAGS) -MD -c -o $@ $<
+-include grub_editenv-kern_misc.d
+
+grub_editenv-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_editenv_CFLAGS) -MD -c -o $@ $<
+-include grub_editenv-kern_err.d
+
+CLEANFILES += grub-editenv
+
+# Needed for genmk.rb to work
+ifeq (0,1)
+bin_UTILITIES += grub-macho2img grub-pe2elf
+endif
+
+grub_pe2elf_SOURCES = util/grub-pe2elf.c util/misc.c
+
+clean-utility-grub-pe2elf.1:
+	rm -f grub-pe2elf$(EXEEXT) grub_pe2elf-util_grub_pe2elf.o grub_pe2elf-util_misc.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-pe2elf.1
+
+mostlyclean-utility-grub-pe2elf.1:
+	rm -f grub_pe2elf-util_grub_pe2elf.d grub_pe2elf-util_misc.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-pe2elf.1
+
+grub_pe2elf_OBJECTS += grub_pe2elf-util_grub_pe2elf.o grub_pe2elf-util_misc.o
+
+grub_pe2elf-util_grub_pe2elf.o: util/grub-pe2elf.c $(util/grub-pe2elf.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_pe2elf_CFLAGS) -MD -c -o $@ $<
+-include grub_pe2elf-util_grub_pe2elf.d
+
+grub_pe2elf-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_pe2elf_CFLAGS) -MD -c -o $@ $<
+-include grub_pe2elf-util_misc.d
+
+CLEANFILES += grub-pe2elf
+
+grub_macho2img_SOURCES = util/grub-macho2img.c
+
+clean-utility-grub-macho2img.1:
+	rm -f grub-macho2img$(EXEEXT) grub_macho2img-util_grub_macho2img.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-macho2img.1
+
+mostlyclean-utility-grub-macho2img.1:
+	rm -f grub_macho2img-util_grub_macho2img.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-macho2img.1
+
+grub_macho2img_OBJECTS += grub_macho2img-util_grub_macho2img.o
+
+grub_macho2img-util_grub_macho2img.o: util/grub-macho2img.c $(util/grub-macho2img.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_macho2img_CFLAGS) -MD -c -o $@ $<
+-include grub_macho2img-util_grub_macho2img.d
+
+CLEANFILES += grub-macho2img
+
+# For grub-mkconfig
+grub-mkconfig: util/grub-mkconfig.in config.status
+	./config.status --file=$@:$<
+	chmod +x $@
+sbin_SCRIPTS += grub-mkconfig
+CLEANFILES += grub-mkconfig
+
+grub-mkconfig_lib: util/grub-mkconfig_lib.in config.status
+	./config.status --file=$@:$<
+	chmod +x $@
+lib_SCRIPTS += grub-mkconfig_lib
+CLEANFILES += grub-mkconfig_lib
+
+update-grub_lib: util/update-grub_lib.in config.status
+	./config.status --file=$@:$<
+	chmod +x $@
+lib_SCRIPTS += update-grub_lib
+CLEANFILES += update-grub_lib
+
+%: util/grub.d/%.in config.status
+	./config.status --file=$@:$<
+	chmod +x $@
+grub-mkconfig_SCRIPTS = 00_header 30_os-prober 40_custom
+ifneq (, $(host_kernel))
+grub-mkconfig_SCRIPTS += 10_$(host_kernel)
+endif
+
+CLEANFILES += $(grub-mkconfig_SCRIPTS)
+
+grub-mkconfig_DATA += util/grub.d/README
+
+# Filing systems.
+pkglib_MODULES += fshelp.mod fat.mod ufs1.mod ufs2.mod ext2.mod ntfs.mod \
+	ntfscomp.mod minix.mod hfs.mod jfs.mod iso9660.mod xfs.mod	\
+	affs.mod sfs.mod hfsplus.mod reiserfs.mod cpio.mod tar.mod	\
+	udf.mod	afs.mod afs_be.mod befs.mod befs_be.mod
+
+# For fshelp.mod.
+fshelp_mod_SOURCES = fs/fshelp.c
+
+clean-module-fshelp.mod.1:
+	rm -f fshelp.mod mod-fshelp.o mod-fshelp.c pre-fshelp.o fshelp_mod-fs_fshelp.o und-fshelp.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fshelp.mod.1
+
+ifneq ($(fshelp_mod_EXPORTS),no)
+clean-module-fshelp.mod-symbol.1:
+	rm -f def-fshelp.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fshelp.mod-symbol.1
+DEFSYMFILES += def-fshelp.lst
+endif
+mostlyclean-module-fshelp.mod.1:
+	rm -f fshelp_mod-fs_fshelp.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-fshelp.mod.1
+UNDSYMFILES += und-fshelp.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+fshelp.mod: pre-fshelp.o mod-fshelp.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(fshelp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-fshelp.o mod-fshelp.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+fshelp.mod: pre-fshelp.o mod-fshelp.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(fshelp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-fshelp.o mod-fshelp.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-fshelp.o: $(fshelp_mod_DEPENDENCIES) fshelp_mod-fs_fshelp.o
+	-rm -f $@
+	$(TARGET_CC) $(fshelp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ fshelp_mod-fs_fshelp.o
+
+mod-fshelp.o: mod-fshelp.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -c -o $@ $<
+
+mod-fshelp.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'fshelp' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(fshelp_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-fshelp.lst: pre-fshelp.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fshelp/' > $@
+else
+def-fshelp.lst: pre-fshelp.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 fshelp/' > $@
+endif
+endif
+
+und-fshelp.lst: pre-fshelp.o
+	echo 'fshelp' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+fshelp_mod-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -MD -c -o $@ $<
+-include fshelp_mod-fs_fshelp.d
+
+clean-module-fshelp_mod-fs_fshelp-extra.1:
+	rm -f cmd-fshelp_mod-fs_fshelp.lst fs-fshelp_mod-fs_fshelp.lst partmap-fshelp_mod-fs_fshelp.lst handler-fshelp_mod-fs_fshelp.lst parttool-fshelp_mod-fs_fshelp.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fshelp_mod-fs_fshelp-extra.1
+
+COMMANDFILES += cmd-fshelp_mod-fs_fshelp.lst
+FSFILES += fs-fshelp_mod-fs_fshelp.lst
+PARTTOOLFILES += parttool-fshelp_mod-fs_fshelp.lst
+PARTMAPFILES += partmap-fshelp_mod-fs_fshelp.lst
+HANDLERFILES += handler-fshelp_mod-fs_fshelp.lst
+
+cmd-fshelp_mod-fs_fshelp.lst: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh fshelp > $@ || (rm -f $@; exit 1)
+
+fs-fshelp_mod-fs_fshelp.lst: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh fshelp > $@ || (rm -f $@; exit 1)
+
+parttool-fshelp_mod-fs_fshelp.lst: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh fshelp > $@ || (rm -f $@; exit 1)
+
+partmap-fshelp_mod-fs_fshelp.lst: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh fshelp > $@ || (rm -f $@; exit 1)
+
+handler-fshelp_mod-fs_fshelp.lst: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh fshelp > $@ || (rm -f $@; exit 1)
+
+fshelp_mod_CFLAGS = $(COMMON_CFLAGS)
+fshelp_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For fat.mod.
+fat_mod_SOURCES = fs/fat.c
+
+clean-module-fat.mod.1:
+	rm -f fat.mod mod-fat.o mod-fat.c pre-fat.o fat_mod-fs_fat.o und-fat.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fat.mod.1
+
+ifneq ($(fat_mod_EXPORTS),no)
+clean-module-fat.mod-symbol.1:
+	rm -f def-fat.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fat.mod-symbol.1
+DEFSYMFILES += def-fat.lst
+endif
+mostlyclean-module-fat.mod.1:
+	rm -f fat_mod-fs_fat.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-fat.mod.1
+UNDSYMFILES += und-fat.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+fat.mod: pre-fat.o mod-fat.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(fat_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-fat.o mod-fat.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+fat.mod: pre-fat.o mod-fat.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(fat_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-fat.o mod-fat.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-fat.o: $(fat_mod_DEPENDENCIES) fat_mod-fs_fat.o
+	-rm -f $@
+	$(TARGET_CC) $(fat_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ fat_mod-fs_fat.o
+
+mod-fat.o: mod-fat.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -c -o $@ $<
+
+mod-fat.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'fat' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(fat_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-fat.lst: pre-fat.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fat/' > $@
+else
+def-fat.lst: pre-fat.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 fat/' > $@
+endif
+endif
+
+und-fat.lst: pre-fat.o
+	echo 'fat' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+fat_mod-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -MD -c -o $@ $<
+-include fat_mod-fs_fat.d
+
+clean-module-fat_mod-fs_fat-extra.1:
+	rm -f cmd-fat_mod-fs_fat.lst fs-fat_mod-fs_fat.lst partmap-fat_mod-fs_fat.lst handler-fat_mod-fs_fat.lst parttool-fat_mod-fs_fat.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fat_mod-fs_fat-extra.1
+
+COMMANDFILES += cmd-fat_mod-fs_fat.lst
+FSFILES += fs-fat_mod-fs_fat.lst
+PARTTOOLFILES += parttool-fat_mod-fs_fat.lst
+PARTMAPFILES += partmap-fat_mod-fs_fat.lst
+HANDLERFILES += handler-fat_mod-fs_fat.lst
+
+cmd-fat_mod-fs_fat.lst: fs/fat.c $(fs/fat.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh fat > $@ || (rm -f $@; exit 1)
+
+fs-fat_mod-fs_fat.lst: fs/fat.c $(fs/fat.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh fat > $@ || (rm -f $@; exit 1)
+
+parttool-fat_mod-fs_fat.lst: fs/fat.c $(fs/fat.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh fat > $@ || (rm -f $@; exit 1)
+
+partmap-fat_mod-fs_fat.lst: fs/fat.c $(fs/fat.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh fat > $@ || (rm -f $@; exit 1)
+
+handler-fat_mod-fs_fat.lst: fs/fat.c $(fs/fat.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh fat > $@ || (rm -f $@; exit 1)
+
+fat_mod_CFLAGS = $(COMMON_CFLAGS)
+fat_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ufs1.mod.
+ufs1_mod_SOURCES = fs/ufs.c
+
+clean-module-ufs1.mod.1:
+	rm -f ufs1.mod mod-ufs1.o mod-ufs1.c pre-ufs1.o ufs1_mod-fs_ufs.o und-ufs1.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ufs1.mod.1
+
+ifneq ($(ufs1_mod_EXPORTS),no)
+clean-module-ufs1.mod-symbol.1:
+	rm -f def-ufs1.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ufs1.mod-symbol.1
+DEFSYMFILES += def-ufs1.lst
+endif
+mostlyclean-module-ufs1.mod.1:
+	rm -f ufs1_mod-fs_ufs.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-ufs1.mod.1
+UNDSYMFILES += und-ufs1.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+ufs1.mod: pre-ufs1.o mod-ufs1.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(ufs1_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-ufs1.o mod-ufs1.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+ufs1.mod: pre-ufs1.o mod-ufs1.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(ufs1_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-ufs1.o mod-ufs1.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-ufs1.o: $(ufs1_mod_DEPENDENCIES) ufs1_mod-fs_ufs.o
+	-rm -f $@
+	$(TARGET_CC) $(ufs1_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ufs1_mod-fs_ufs.o
+
+mod-ufs1.o: mod-ufs1.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ufs1_mod_CFLAGS) -c -o $@ $<
+
+mod-ufs1.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'ufs1' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(ufs1_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-ufs1.lst: pre-ufs1.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ufs1/' > $@
+else
+def-ufs1.lst: pre-ufs1.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 ufs1/' > $@
+endif
+endif
+
+und-ufs1.lst: pre-ufs1.o
+	echo 'ufs1' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+ufs1_mod-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ufs1_mod_CFLAGS) -MD -c -o $@ $<
+-include ufs1_mod-fs_ufs.d
+
+clean-module-ufs1_mod-fs_ufs-extra.1:
+	rm -f cmd-ufs1_mod-fs_ufs.lst fs-ufs1_mod-fs_ufs.lst partmap-ufs1_mod-fs_ufs.lst handler-ufs1_mod-fs_ufs.lst parttool-ufs1_mod-fs_ufs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ufs1_mod-fs_ufs-extra.1
+
+COMMANDFILES += cmd-ufs1_mod-fs_ufs.lst
+FSFILES += fs-ufs1_mod-fs_ufs.lst
+PARTTOOLFILES += parttool-ufs1_mod-fs_ufs.lst
+PARTMAPFILES += partmap-ufs1_mod-fs_ufs.lst
+HANDLERFILES += handler-ufs1_mod-fs_ufs.lst
+
+cmd-ufs1_mod-fs_ufs.lst: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ufs1_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh ufs1 > $@ || (rm -f $@; exit 1)
+
+fs-ufs1_mod-fs_ufs.lst: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ufs1_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh ufs1 > $@ || (rm -f $@; exit 1)
+
+parttool-ufs1_mod-fs_ufs.lst: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ufs1_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh ufs1 > $@ || (rm -f $@; exit 1)
+
+partmap-ufs1_mod-fs_ufs.lst: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ufs1_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh ufs1 > $@ || (rm -f $@; exit 1)
+
+handler-ufs1_mod-fs_ufs.lst: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ufs1_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh ufs1 > $@ || (rm -f $@; exit 1)
+
+ufs1_mod_CFLAGS = $(COMMON_CFLAGS)
+ufs1_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ufs2.mod.
+ufs2_mod_SOURCES = fs/ufs2.c
+
+clean-module-ufs2.mod.1:
+	rm -f ufs2.mod mod-ufs2.o mod-ufs2.c pre-ufs2.o ufs2_mod-fs_ufs2.o und-ufs2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ufs2.mod.1
+
+ifneq ($(ufs2_mod_EXPORTS),no)
+clean-module-ufs2.mod-symbol.1:
+	rm -f def-ufs2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ufs2.mod-symbol.1
+DEFSYMFILES += def-ufs2.lst
+endif
+mostlyclean-module-ufs2.mod.1:
+	rm -f ufs2_mod-fs_ufs2.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-ufs2.mod.1
+UNDSYMFILES += und-ufs2.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+ufs2.mod: pre-ufs2.o mod-ufs2.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(ufs2_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-ufs2.o mod-ufs2.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+ufs2.mod: pre-ufs2.o mod-ufs2.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(ufs2_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-ufs2.o mod-ufs2.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-ufs2.o: $(ufs2_mod_DEPENDENCIES) ufs2_mod-fs_ufs2.o
+	-rm -f $@
+	$(TARGET_CC) $(ufs2_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ufs2_mod-fs_ufs2.o
+
+mod-ufs2.o: mod-ufs2.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ufs2_mod_CFLAGS) -c -o $@ $<
+
+mod-ufs2.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'ufs2' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(ufs2_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-ufs2.lst: pre-ufs2.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ufs2/' > $@
+else
+def-ufs2.lst: pre-ufs2.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 ufs2/' > $@
+endif
+endif
+
+und-ufs2.lst: pre-ufs2.o
+	echo 'ufs2' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+ufs2_mod-fs_ufs2.o: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ufs2_mod_CFLAGS) -MD -c -o $@ $<
+-include ufs2_mod-fs_ufs2.d
+
+clean-module-ufs2_mod-fs_ufs2-extra.1:
+	rm -f cmd-ufs2_mod-fs_ufs2.lst fs-ufs2_mod-fs_ufs2.lst partmap-ufs2_mod-fs_ufs2.lst handler-ufs2_mod-fs_ufs2.lst parttool-ufs2_mod-fs_ufs2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ufs2_mod-fs_ufs2-extra.1
+
+COMMANDFILES += cmd-ufs2_mod-fs_ufs2.lst
+FSFILES += fs-ufs2_mod-fs_ufs2.lst
+PARTTOOLFILES += parttool-ufs2_mod-fs_ufs2.lst
+PARTMAPFILES += partmap-ufs2_mod-fs_ufs2.lst
+HANDLERFILES += handler-ufs2_mod-fs_ufs2.lst
+
+cmd-ufs2_mod-fs_ufs2.lst: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ufs2_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh ufs2 > $@ || (rm -f $@; exit 1)
+
+fs-ufs2_mod-fs_ufs2.lst: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ufs2_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh ufs2 > $@ || (rm -f $@; exit 1)
+
+parttool-ufs2_mod-fs_ufs2.lst: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ufs2_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh ufs2 > $@ || (rm -f $@; exit 1)
+
+partmap-ufs2_mod-fs_ufs2.lst: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ufs2_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh ufs2 > $@ || (rm -f $@; exit 1)
+
+handler-ufs2_mod-fs_ufs2.lst: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ufs2_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh ufs2 > $@ || (rm -f $@; exit 1)
+
+ufs2_mod_CFLAGS = $(COMMON_CFLAGS)
+ufs2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ext2.mod.
+ext2_mod_SOURCES = fs/ext2.c
+
+clean-module-ext2.mod.1:
+	rm -f ext2.mod mod-ext2.o mod-ext2.c pre-ext2.o ext2_mod-fs_ext2.o und-ext2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ext2.mod.1
+
+ifneq ($(ext2_mod_EXPORTS),no)
+clean-module-ext2.mod-symbol.1:
+	rm -f def-ext2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ext2.mod-symbol.1
+DEFSYMFILES += def-ext2.lst
+endif
+mostlyclean-module-ext2.mod.1:
+	rm -f ext2_mod-fs_ext2.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-ext2.mod.1
+UNDSYMFILES += und-ext2.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+ext2.mod: pre-ext2.o mod-ext2.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(ext2_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-ext2.o mod-ext2.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+ext2.mod: pre-ext2.o mod-ext2.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(ext2_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-ext2.o mod-ext2.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-ext2.o: $(ext2_mod_DEPENDENCIES) ext2_mod-fs_ext2.o
+	-rm -f $@
+	$(TARGET_CC) $(ext2_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ext2_mod-fs_ext2.o
+
+mod-ext2.o: mod-ext2.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -c -o $@ $<
+
+mod-ext2.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'ext2' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(ext2_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-ext2.lst: pre-ext2.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ext2/' > $@
+else
+def-ext2.lst: pre-ext2.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 ext2/' > $@
+endif
+endif
+
+und-ext2.lst: pre-ext2.o
+	echo 'ext2' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+ext2_mod-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -MD -c -o $@ $<
+-include ext2_mod-fs_ext2.d
+
+clean-module-ext2_mod-fs_ext2-extra.1:
+	rm -f cmd-ext2_mod-fs_ext2.lst fs-ext2_mod-fs_ext2.lst partmap-ext2_mod-fs_ext2.lst handler-ext2_mod-fs_ext2.lst parttool-ext2_mod-fs_ext2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ext2_mod-fs_ext2-extra.1
+
+COMMANDFILES += cmd-ext2_mod-fs_ext2.lst
+FSFILES += fs-ext2_mod-fs_ext2.lst
+PARTTOOLFILES += parttool-ext2_mod-fs_ext2.lst
+PARTMAPFILES += partmap-ext2_mod-fs_ext2.lst
+HANDLERFILES += handler-ext2_mod-fs_ext2.lst
+
+cmd-ext2_mod-fs_ext2.lst: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh ext2 > $@ || (rm -f $@; exit 1)
+
+fs-ext2_mod-fs_ext2.lst: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh ext2 > $@ || (rm -f $@; exit 1)
+
+parttool-ext2_mod-fs_ext2.lst: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh ext2 > $@ || (rm -f $@; exit 1)
+
+partmap-ext2_mod-fs_ext2.lst: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh ext2 > $@ || (rm -f $@; exit 1)
+
+handler-ext2_mod-fs_ext2.lst: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh ext2 > $@ || (rm -f $@; exit 1)
+
+ext2_mod_CFLAGS = $(COMMON_CFLAGS)
+ext2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ntfs.mod.
+ntfs_mod_SOURCES = fs/ntfs.c
+
+clean-module-ntfs.mod.1:
+	rm -f ntfs.mod mod-ntfs.o mod-ntfs.c pre-ntfs.o ntfs_mod-fs_ntfs.o und-ntfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ntfs.mod.1
+
+ifneq ($(ntfs_mod_EXPORTS),no)
+clean-module-ntfs.mod-symbol.1:
+	rm -f def-ntfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ntfs.mod-symbol.1
+DEFSYMFILES += def-ntfs.lst
+endif
+mostlyclean-module-ntfs.mod.1:
+	rm -f ntfs_mod-fs_ntfs.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-ntfs.mod.1
+UNDSYMFILES += und-ntfs.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+ntfs.mod: pre-ntfs.o mod-ntfs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(ntfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-ntfs.o mod-ntfs.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+ntfs.mod: pre-ntfs.o mod-ntfs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(ntfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-ntfs.o mod-ntfs.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-ntfs.o: $(ntfs_mod_DEPENDENCIES) ntfs_mod-fs_ntfs.o
+	-rm -f $@
+	$(TARGET_CC) $(ntfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ntfs_mod-fs_ntfs.o
+
+mod-ntfs.o: mod-ntfs.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ntfs_mod_CFLAGS) -c -o $@ $<
+
+mod-ntfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'ntfs' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(ntfs_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-ntfs.lst: pre-ntfs.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ntfs/' > $@
+else
+def-ntfs.lst: pre-ntfs.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 ntfs/' > $@
+endif
+endif
+
+und-ntfs.lst: pre-ntfs.o
+	echo 'ntfs' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+ntfs_mod-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ntfs_mod_CFLAGS) -MD -c -o $@ $<
+-include ntfs_mod-fs_ntfs.d
+
+clean-module-ntfs_mod-fs_ntfs-extra.1:
+	rm -f cmd-ntfs_mod-fs_ntfs.lst fs-ntfs_mod-fs_ntfs.lst partmap-ntfs_mod-fs_ntfs.lst handler-ntfs_mod-fs_ntfs.lst parttool-ntfs_mod-fs_ntfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ntfs_mod-fs_ntfs-extra.1
+
+COMMANDFILES += cmd-ntfs_mod-fs_ntfs.lst
+FSFILES += fs-ntfs_mod-fs_ntfs.lst
+PARTTOOLFILES += parttool-ntfs_mod-fs_ntfs.lst
+PARTMAPFILES += partmap-ntfs_mod-fs_ntfs.lst
+HANDLERFILES += handler-ntfs_mod-fs_ntfs.lst
+
+cmd-ntfs_mod-fs_ntfs.lst: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ntfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh ntfs > $@ || (rm -f $@; exit 1)
+
+fs-ntfs_mod-fs_ntfs.lst: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ntfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh ntfs > $@ || (rm -f $@; exit 1)
+
+parttool-ntfs_mod-fs_ntfs.lst: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ntfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh ntfs > $@ || (rm -f $@; exit 1)
+
+partmap-ntfs_mod-fs_ntfs.lst: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ntfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh ntfs > $@ || (rm -f $@; exit 1)
+
+handler-ntfs_mod-fs_ntfs.lst: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ntfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh ntfs > $@ || (rm -f $@; exit 1)
+
+ntfs_mod_CFLAGS = $(COMMON_CFLAGS)
+ntfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ntfscomp.mod.
+ntfscomp_mod_SOURCES = fs/ntfscomp.c
+
+clean-module-ntfscomp.mod.1:
+	rm -f ntfscomp.mod mod-ntfscomp.o mod-ntfscomp.c pre-ntfscomp.o ntfscomp_mod-fs_ntfscomp.o und-ntfscomp.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ntfscomp.mod.1
+
+ifneq ($(ntfscomp_mod_EXPORTS),no)
+clean-module-ntfscomp.mod-symbol.1:
+	rm -f def-ntfscomp.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ntfscomp.mod-symbol.1
+DEFSYMFILES += def-ntfscomp.lst
+endif
+mostlyclean-module-ntfscomp.mod.1:
+	rm -f ntfscomp_mod-fs_ntfscomp.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-ntfscomp.mod.1
+UNDSYMFILES += und-ntfscomp.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+ntfscomp.mod: pre-ntfscomp.o mod-ntfscomp.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(ntfscomp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-ntfscomp.o mod-ntfscomp.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+ntfscomp.mod: pre-ntfscomp.o mod-ntfscomp.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(ntfscomp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-ntfscomp.o mod-ntfscomp.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-ntfscomp.o: $(ntfscomp_mod_DEPENDENCIES) ntfscomp_mod-fs_ntfscomp.o
+	-rm -f $@
+	$(TARGET_CC) $(ntfscomp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ntfscomp_mod-fs_ntfscomp.o
+
+mod-ntfscomp.o: mod-ntfscomp.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ntfscomp_mod_CFLAGS) -c -o $@ $<
+
+mod-ntfscomp.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'ntfscomp' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(ntfscomp_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-ntfscomp.lst: pre-ntfscomp.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ntfscomp/' > $@
+else
+def-ntfscomp.lst: pre-ntfscomp.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 ntfscomp/' > $@
+endif
+endif
+
+und-ntfscomp.lst: pre-ntfscomp.o
+	echo 'ntfscomp' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+ntfscomp_mod-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ntfscomp_mod_CFLAGS) -MD -c -o $@ $<
+-include ntfscomp_mod-fs_ntfscomp.d
+
+clean-module-ntfscomp_mod-fs_ntfscomp-extra.1:
+	rm -f cmd-ntfscomp_mod-fs_ntfscomp.lst fs-ntfscomp_mod-fs_ntfscomp.lst partmap-ntfscomp_mod-fs_ntfscomp.lst handler-ntfscomp_mod-fs_ntfscomp.lst parttool-ntfscomp_mod-fs_ntfscomp.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ntfscomp_mod-fs_ntfscomp-extra.1
+
+COMMANDFILES += cmd-ntfscomp_mod-fs_ntfscomp.lst
+FSFILES += fs-ntfscomp_mod-fs_ntfscomp.lst
+PARTTOOLFILES += parttool-ntfscomp_mod-fs_ntfscomp.lst
+PARTMAPFILES += partmap-ntfscomp_mod-fs_ntfscomp.lst
+HANDLERFILES += handler-ntfscomp_mod-fs_ntfscomp.lst
+
+cmd-ntfscomp_mod-fs_ntfscomp.lst: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ntfscomp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh ntfscomp > $@ || (rm -f $@; exit 1)
+
+fs-ntfscomp_mod-fs_ntfscomp.lst: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ntfscomp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh ntfscomp > $@ || (rm -f $@; exit 1)
+
+parttool-ntfscomp_mod-fs_ntfscomp.lst: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ntfscomp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh ntfscomp > $@ || (rm -f $@; exit 1)
+
+partmap-ntfscomp_mod-fs_ntfscomp.lst: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ntfscomp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh ntfscomp > $@ || (rm -f $@; exit 1)
+
+handler-ntfscomp_mod-fs_ntfscomp.lst: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ntfscomp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh ntfscomp > $@ || (rm -f $@; exit 1)
+
+ntfscomp_mod_CFLAGS = $(COMMON_CFLAGS)
+ntfscomp_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For minix.mod.
+minix_mod_SOURCES = fs/minix.c
+
+clean-module-minix.mod.1:
+	rm -f minix.mod mod-minix.o mod-minix.c pre-minix.o minix_mod-fs_minix.o und-minix.lst
+
+CLEAN_MODULE_TARGETS += clean-module-minix.mod.1
+
+ifneq ($(minix_mod_EXPORTS),no)
+clean-module-minix.mod-symbol.1:
+	rm -f def-minix.lst
+
+CLEAN_MODULE_TARGETS += clean-module-minix.mod-symbol.1
+DEFSYMFILES += def-minix.lst
+endif
+mostlyclean-module-minix.mod.1:
+	rm -f minix_mod-fs_minix.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-minix.mod.1
+UNDSYMFILES += und-minix.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+minix.mod: pre-minix.o mod-minix.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(minix_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-minix.o mod-minix.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+minix.mod: pre-minix.o mod-minix.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(minix_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-minix.o mod-minix.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-minix.o: $(minix_mod_DEPENDENCIES) minix_mod-fs_minix.o
+	-rm -f $@
+	$(TARGET_CC) $(minix_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ minix_mod-fs_minix.o
+
+mod-minix.o: mod-minix.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -c -o $@ $<
+
+mod-minix.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'minix' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(minix_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-minix.lst: pre-minix.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 minix/' > $@
+else
+def-minix.lst: pre-minix.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 minix/' > $@
+endif
+endif
+
+und-minix.lst: pre-minix.o
+	echo 'minix' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+minix_mod-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -MD -c -o $@ $<
+-include minix_mod-fs_minix.d
+
+clean-module-minix_mod-fs_minix-extra.1:
+	rm -f cmd-minix_mod-fs_minix.lst fs-minix_mod-fs_minix.lst partmap-minix_mod-fs_minix.lst handler-minix_mod-fs_minix.lst parttool-minix_mod-fs_minix.lst
+
+CLEAN_MODULE_TARGETS += clean-module-minix_mod-fs_minix-extra.1
+
+COMMANDFILES += cmd-minix_mod-fs_minix.lst
+FSFILES += fs-minix_mod-fs_minix.lst
+PARTTOOLFILES += parttool-minix_mod-fs_minix.lst
+PARTMAPFILES += partmap-minix_mod-fs_minix.lst
+HANDLERFILES += handler-minix_mod-fs_minix.lst
+
+cmd-minix_mod-fs_minix.lst: fs/minix.c $(fs/minix.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh minix > $@ || (rm -f $@; exit 1)
+
+fs-minix_mod-fs_minix.lst: fs/minix.c $(fs/minix.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh minix > $@ || (rm -f $@; exit 1)
+
+parttool-minix_mod-fs_minix.lst: fs/minix.c $(fs/minix.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh minix > $@ || (rm -f $@; exit 1)
+
+partmap-minix_mod-fs_minix.lst: fs/minix.c $(fs/minix.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh minix > $@ || (rm -f $@; exit 1)
+
+handler-minix_mod-fs_minix.lst: fs/minix.c $(fs/minix.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh minix > $@ || (rm -f $@; exit 1)
+
+minix_mod_CFLAGS = $(COMMON_CFLAGS)
+minix_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hfs.mod.
+hfs_mod_SOURCES = fs/hfs.c
+
+clean-module-hfs.mod.1:
+	rm -f hfs.mod mod-hfs.o mod-hfs.c pre-hfs.o hfs_mod-fs_hfs.o und-hfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hfs.mod.1
+
+ifneq ($(hfs_mod_EXPORTS),no)
+clean-module-hfs.mod-symbol.1:
+	rm -f def-hfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hfs.mod-symbol.1
+DEFSYMFILES += def-hfs.lst
+endif
+mostlyclean-module-hfs.mod.1:
+	rm -f hfs_mod-fs_hfs.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-hfs.mod.1
+UNDSYMFILES += und-hfs.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+hfs.mod: pre-hfs.o mod-hfs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(hfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-hfs.o mod-hfs.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+hfs.mod: pre-hfs.o mod-hfs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(hfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-hfs.o mod-hfs.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-hfs.o: $(hfs_mod_DEPENDENCIES) hfs_mod-fs_hfs.o
+	-rm -f $@
+	$(TARGET_CC) $(hfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ hfs_mod-fs_hfs.o
+
+mod-hfs.o: mod-hfs.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -c -o $@ $<
+
+mod-hfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'hfs' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(hfs_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-hfs.lst: pre-hfs.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 hfs/' > $@
+else
+def-hfs.lst: pre-hfs.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 hfs/' > $@
+endif
+endif
+
+und-hfs.lst: pre-hfs.o
+	echo 'hfs' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+hfs_mod-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -MD -c -o $@ $<
+-include hfs_mod-fs_hfs.d
+
+clean-module-hfs_mod-fs_hfs-extra.1:
+	rm -f cmd-hfs_mod-fs_hfs.lst fs-hfs_mod-fs_hfs.lst partmap-hfs_mod-fs_hfs.lst handler-hfs_mod-fs_hfs.lst parttool-hfs_mod-fs_hfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hfs_mod-fs_hfs-extra.1
+
+COMMANDFILES += cmd-hfs_mod-fs_hfs.lst
+FSFILES += fs-hfs_mod-fs_hfs.lst
+PARTTOOLFILES += parttool-hfs_mod-fs_hfs.lst
+PARTMAPFILES += partmap-hfs_mod-fs_hfs.lst
+HANDLERFILES += handler-hfs_mod-fs_hfs.lst
+
+cmd-hfs_mod-fs_hfs.lst: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh hfs > $@ || (rm -f $@; exit 1)
+
+fs-hfs_mod-fs_hfs.lst: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh hfs > $@ || (rm -f $@; exit 1)
+
+parttool-hfs_mod-fs_hfs.lst: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh hfs > $@ || (rm -f $@; exit 1)
+
+partmap-hfs_mod-fs_hfs.lst: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh hfs > $@ || (rm -f $@; exit 1)
+
+handler-hfs_mod-fs_hfs.lst: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh hfs > $@ || (rm -f $@; exit 1)
+
+hfs_mod_CFLAGS = $(COMMON_CFLAGS)
+hfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For jfs.mod.
+jfs_mod_SOURCES = fs/jfs.c
+
+clean-module-jfs.mod.1:
+	rm -f jfs.mod mod-jfs.o mod-jfs.c pre-jfs.o jfs_mod-fs_jfs.o und-jfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-jfs.mod.1
+
+ifneq ($(jfs_mod_EXPORTS),no)
+clean-module-jfs.mod-symbol.1:
+	rm -f def-jfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-jfs.mod-symbol.1
+DEFSYMFILES += def-jfs.lst
+endif
+mostlyclean-module-jfs.mod.1:
+	rm -f jfs_mod-fs_jfs.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-jfs.mod.1
+UNDSYMFILES += und-jfs.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+jfs.mod: pre-jfs.o mod-jfs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(jfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-jfs.o mod-jfs.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+jfs.mod: pre-jfs.o mod-jfs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(jfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-jfs.o mod-jfs.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-jfs.o: $(jfs_mod_DEPENDENCIES) jfs_mod-fs_jfs.o
+	-rm -f $@
+	$(TARGET_CC) $(jfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ jfs_mod-fs_jfs.o
+
+mod-jfs.o: mod-jfs.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -c -o $@ $<
+
+mod-jfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'jfs' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(jfs_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-jfs.lst: pre-jfs.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 jfs/' > $@
+else
+def-jfs.lst: pre-jfs.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 jfs/' > $@
+endif
+endif
+
+und-jfs.lst: pre-jfs.o
+	echo 'jfs' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+jfs_mod-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -MD -c -o $@ $<
+-include jfs_mod-fs_jfs.d
+
+clean-module-jfs_mod-fs_jfs-extra.1:
+	rm -f cmd-jfs_mod-fs_jfs.lst fs-jfs_mod-fs_jfs.lst partmap-jfs_mod-fs_jfs.lst handler-jfs_mod-fs_jfs.lst parttool-jfs_mod-fs_jfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-jfs_mod-fs_jfs-extra.1
+
+COMMANDFILES += cmd-jfs_mod-fs_jfs.lst
+FSFILES += fs-jfs_mod-fs_jfs.lst
+PARTTOOLFILES += parttool-jfs_mod-fs_jfs.lst
+PARTMAPFILES += partmap-jfs_mod-fs_jfs.lst
+HANDLERFILES += handler-jfs_mod-fs_jfs.lst
+
+cmd-jfs_mod-fs_jfs.lst: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh jfs > $@ || (rm -f $@; exit 1)
+
+fs-jfs_mod-fs_jfs.lst: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh jfs > $@ || (rm -f $@; exit 1)
+
+parttool-jfs_mod-fs_jfs.lst: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh jfs > $@ || (rm -f $@; exit 1)
+
+partmap-jfs_mod-fs_jfs.lst: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh jfs > $@ || (rm -f $@; exit 1)
+
+handler-jfs_mod-fs_jfs.lst: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh jfs > $@ || (rm -f $@; exit 1)
+
+jfs_mod_CFLAGS = $(COMMON_CFLAGS)
+jfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For iso9660.mod.
+iso9660_mod_SOURCES = fs/iso9660.c
+
+clean-module-iso9660.mod.1:
+	rm -f iso9660.mod mod-iso9660.o mod-iso9660.c pre-iso9660.o iso9660_mod-fs_iso9660.o und-iso9660.lst
+
+CLEAN_MODULE_TARGETS += clean-module-iso9660.mod.1
+
+ifneq ($(iso9660_mod_EXPORTS),no)
+clean-module-iso9660.mod-symbol.1:
+	rm -f def-iso9660.lst
+
+CLEAN_MODULE_TARGETS += clean-module-iso9660.mod-symbol.1
+DEFSYMFILES += def-iso9660.lst
+endif
+mostlyclean-module-iso9660.mod.1:
+	rm -f iso9660_mod-fs_iso9660.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-iso9660.mod.1
+UNDSYMFILES += und-iso9660.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+iso9660.mod: pre-iso9660.o mod-iso9660.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(iso9660_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-iso9660.o mod-iso9660.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+iso9660.mod: pre-iso9660.o mod-iso9660.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(iso9660_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-iso9660.o mod-iso9660.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-iso9660.o: $(iso9660_mod_DEPENDENCIES) iso9660_mod-fs_iso9660.o
+	-rm -f $@
+	$(TARGET_CC) $(iso9660_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ iso9660_mod-fs_iso9660.o
+
+mod-iso9660.o: mod-iso9660.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(iso9660_mod_CFLAGS) -c -o $@ $<
+
+mod-iso9660.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'iso9660' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(iso9660_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-iso9660.lst: pre-iso9660.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 iso9660/' > $@
+else
+def-iso9660.lst: pre-iso9660.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 iso9660/' > $@
+endif
+endif
+
+und-iso9660.lst: pre-iso9660.o
+	echo 'iso9660' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+iso9660_mod-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(iso9660_mod_CFLAGS) -MD -c -o $@ $<
+-include iso9660_mod-fs_iso9660.d
+
+clean-module-iso9660_mod-fs_iso9660-extra.1:
+	rm -f cmd-iso9660_mod-fs_iso9660.lst fs-iso9660_mod-fs_iso9660.lst partmap-iso9660_mod-fs_iso9660.lst handler-iso9660_mod-fs_iso9660.lst parttool-iso9660_mod-fs_iso9660.lst
+
+CLEAN_MODULE_TARGETS += clean-module-iso9660_mod-fs_iso9660-extra.1
+
+COMMANDFILES += cmd-iso9660_mod-fs_iso9660.lst
+FSFILES += fs-iso9660_mod-fs_iso9660.lst
+PARTTOOLFILES += parttool-iso9660_mod-fs_iso9660.lst
+PARTMAPFILES += partmap-iso9660_mod-fs_iso9660.lst
+HANDLERFILES += handler-iso9660_mod-fs_iso9660.lst
+
+cmd-iso9660_mod-fs_iso9660.lst: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(iso9660_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh iso9660 > $@ || (rm -f $@; exit 1)
+
+fs-iso9660_mod-fs_iso9660.lst: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(iso9660_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh iso9660 > $@ || (rm -f $@; exit 1)
+
+parttool-iso9660_mod-fs_iso9660.lst: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(iso9660_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh iso9660 > $@ || (rm -f $@; exit 1)
+
+partmap-iso9660_mod-fs_iso9660.lst: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(iso9660_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh iso9660 > $@ || (rm -f $@; exit 1)
+
+handler-iso9660_mod-fs_iso9660.lst: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(iso9660_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh iso9660 > $@ || (rm -f $@; exit 1)
+
+iso9660_mod_CFLAGS = $(COMMON_CFLAGS)
+iso9660_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For xfs.mod.
+xfs_mod_SOURCES = fs/xfs.c
+
+clean-module-xfs.mod.1:
+	rm -f xfs.mod mod-xfs.o mod-xfs.c pre-xfs.o xfs_mod-fs_xfs.o und-xfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xfs.mod.1
+
+ifneq ($(xfs_mod_EXPORTS),no)
+clean-module-xfs.mod-symbol.1:
+	rm -f def-xfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xfs.mod-symbol.1
+DEFSYMFILES += def-xfs.lst
+endif
+mostlyclean-module-xfs.mod.1:
+	rm -f xfs_mod-fs_xfs.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-xfs.mod.1
+UNDSYMFILES += und-xfs.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+xfs.mod: pre-xfs.o mod-xfs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(xfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-xfs.o mod-xfs.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+xfs.mod: pre-xfs.o mod-xfs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(xfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-xfs.o mod-xfs.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-xfs.o: $(xfs_mod_DEPENDENCIES) xfs_mod-fs_xfs.o
+	-rm -f $@
+	$(TARGET_CC) $(xfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ xfs_mod-fs_xfs.o
+
+mod-xfs.o: mod-xfs.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -c -o $@ $<
+
+mod-xfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'xfs' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(xfs_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-xfs.lst: pre-xfs.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 xfs/' > $@
+else
+def-xfs.lst: pre-xfs.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 xfs/' > $@
+endif
+endif
+
+und-xfs.lst: pre-xfs.o
+	echo 'xfs' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+xfs_mod-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -MD -c -o $@ $<
+-include xfs_mod-fs_xfs.d
+
+clean-module-xfs_mod-fs_xfs-extra.1:
+	rm -f cmd-xfs_mod-fs_xfs.lst fs-xfs_mod-fs_xfs.lst partmap-xfs_mod-fs_xfs.lst handler-xfs_mod-fs_xfs.lst parttool-xfs_mod-fs_xfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xfs_mod-fs_xfs-extra.1
+
+COMMANDFILES += cmd-xfs_mod-fs_xfs.lst
+FSFILES += fs-xfs_mod-fs_xfs.lst
+PARTTOOLFILES += parttool-xfs_mod-fs_xfs.lst
+PARTMAPFILES += partmap-xfs_mod-fs_xfs.lst
+HANDLERFILES += handler-xfs_mod-fs_xfs.lst
+
+cmd-xfs_mod-fs_xfs.lst: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xfs > $@ || (rm -f $@; exit 1)
+
+fs-xfs_mod-fs_xfs.lst: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xfs > $@ || (rm -f $@; exit 1)
+
+parttool-xfs_mod-fs_xfs.lst: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xfs > $@ || (rm -f $@; exit 1)
+
+partmap-xfs_mod-fs_xfs.lst: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xfs > $@ || (rm -f $@; exit 1)
+
+handler-xfs_mod-fs_xfs.lst: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xfs > $@ || (rm -f $@; exit 1)
+
+xfs_mod_CFLAGS = $(COMMON_CFLAGS)
+xfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For affs.mod.
+affs_mod_SOURCES = fs/affs.c
+
+clean-module-affs.mod.1:
+	rm -f affs.mod mod-affs.o mod-affs.c pre-affs.o affs_mod-fs_affs.o und-affs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-affs.mod.1
+
+ifneq ($(affs_mod_EXPORTS),no)
+clean-module-affs.mod-symbol.1:
+	rm -f def-affs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-affs.mod-symbol.1
+DEFSYMFILES += def-affs.lst
+endif
+mostlyclean-module-affs.mod.1:
+	rm -f affs_mod-fs_affs.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-affs.mod.1
+UNDSYMFILES += und-affs.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+affs.mod: pre-affs.o mod-affs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(affs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-affs.o mod-affs.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+affs.mod: pre-affs.o mod-affs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(affs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-affs.o mod-affs.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-affs.o: $(affs_mod_DEPENDENCIES) affs_mod-fs_affs.o
+	-rm -f $@
+	$(TARGET_CC) $(affs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ affs_mod-fs_affs.o
+
+mod-affs.o: mod-affs.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -c -o $@ $<
+
+mod-affs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'affs' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(affs_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-affs.lst: pre-affs.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 affs/' > $@
+else
+def-affs.lst: pre-affs.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 affs/' > $@
+endif
+endif
+
+und-affs.lst: pre-affs.o
+	echo 'affs' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+affs_mod-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -MD -c -o $@ $<
+-include affs_mod-fs_affs.d
+
+clean-module-affs_mod-fs_affs-extra.1:
+	rm -f cmd-affs_mod-fs_affs.lst fs-affs_mod-fs_affs.lst partmap-affs_mod-fs_affs.lst handler-affs_mod-fs_affs.lst parttool-affs_mod-fs_affs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-affs_mod-fs_affs-extra.1
+
+COMMANDFILES += cmd-affs_mod-fs_affs.lst
+FSFILES += fs-affs_mod-fs_affs.lst
+PARTTOOLFILES += parttool-affs_mod-fs_affs.lst
+PARTMAPFILES += partmap-affs_mod-fs_affs.lst
+HANDLERFILES += handler-affs_mod-fs_affs.lst
+
+cmd-affs_mod-fs_affs.lst: fs/affs.c $(fs/affs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh affs > $@ || (rm -f $@; exit 1)
+
+fs-affs_mod-fs_affs.lst: fs/affs.c $(fs/affs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh affs > $@ || (rm -f $@; exit 1)
+
+parttool-affs_mod-fs_affs.lst: fs/affs.c $(fs/affs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh affs > $@ || (rm -f $@; exit 1)
+
+partmap-affs_mod-fs_affs.lst: fs/affs.c $(fs/affs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh affs > $@ || (rm -f $@; exit 1)
+
+handler-affs_mod-fs_affs.lst: fs/affs.c $(fs/affs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh affs > $@ || (rm -f $@; exit 1)
+
+affs_mod_CFLAGS = $(COMMON_CFLAGS)
+affs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For sfs.mod.
+sfs_mod_SOURCES = fs/sfs.c
+
+clean-module-sfs.mod.1:
+	rm -f sfs.mod mod-sfs.o mod-sfs.c pre-sfs.o sfs_mod-fs_sfs.o und-sfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sfs.mod.1
+
+ifneq ($(sfs_mod_EXPORTS),no)
+clean-module-sfs.mod-symbol.1:
+	rm -f def-sfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sfs.mod-symbol.1
+DEFSYMFILES += def-sfs.lst
+endif
+mostlyclean-module-sfs.mod.1:
+	rm -f sfs_mod-fs_sfs.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-sfs.mod.1
+UNDSYMFILES += und-sfs.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+sfs.mod: pre-sfs.o mod-sfs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(sfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-sfs.o mod-sfs.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+sfs.mod: pre-sfs.o mod-sfs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(sfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-sfs.o mod-sfs.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-sfs.o: $(sfs_mod_DEPENDENCIES) sfs_mod-fs_sfs.o
+	-rm -f $@
+	$(TARGET_CC) $(sfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ sfs_mod-fs_sfs.o
+
+mod-sfs.o: mod-sfs.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -c -o $@ $<
+
+mod-sfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'sfs' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(sfs_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-sfs.lst: pre-sfs.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 sfs/' > $@
+else
+def-sfs.lst: pre-sfs.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 sfs/' > $@
+endif
+endif
+
+und-sfs.lst: pre-sfs.o
+	echo 'sfs' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+sfs_mod-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -MD -c -o $@ $<
+-include sfs_mod-fs_sfs.d
+
+clean-module-sfs_mod-fs_sfs-extra.1:
+	rm -f cmd-sfs_mod-fs_sfs.lst fs-sfs_mod-fs_sfs.lst partmap-sfs_mod-fs_sfs.lst handler-sfs_mod-fs_sfs.lst parttool-sfs_mod-fs_sfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sfs_mod-fs_sfs-extra.1
+
+COMMANDFILES += cmd-sfs_mod-fs_sfs.lst
+FSFILES += fs-sfs_mod-fs_sfs.lst
+PARTTOOLFILES += parttool-sfs_mod-fs_sfs.lst
+PARTMAPFILES += partmap-sfs_mod-fs_sfs.lst
+HANDLERFILES += handler-sfs_mod-fs_sfs.lst
+
+cmd-sfs_mod-fs_sfs.lst: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh sfs > $@ || (rm -f $@; exit 1)
+
+fs-sfs_mod-fs_sfs.lst: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh sfs > $@ || (rm -f $@; exit 1)
+
+parttool-sfs_mod-fs_sfs.lst: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh sfs > $@ || (rm -f $@; exit 1)
+
+partmap-sfs_mod-fs_sfs.lst: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh sfs > $@ || (rm -f $@; exit 1)
+
+handler-sfs_mod-fs_sfs.lst: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh sfs > $@ || (rm -f $@; exit 1)
+
+sfs_mod_CFLAGS = $(COMMON_CFLAGS)
+sfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hfsplus.mod.
+hfsplus_mod_SOURCES = fs/hfsplus.c
+
+clean-module-hfsplus.mod.1:
+	rm -f hfsplus.mod mod-hfsplus.o mod-hfsplus.c pre-hfsplus.o hfsplus_mod-fs_hfsplus.o und-hfsplus.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hfsplus.mod.1
+
+ifneq ($(hfsplus_mod_EXPORTS),no)
+clean-module-hfsplus.mod-symbol.1:
+	rm -f def-hfsplus.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hfsplus.mod-symbol.1
+DEFSYMFILES += def-hfsplus.lst
+endif
+mostlyclean-module-hfsplus.mod.1:
+	rm -f hfsplus_mod-fs_hfsplus.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-hfsplus.mod.1
+UNDSYMFILES += und-hfsplus.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+hfsplus.mod: pre-hfsplus.o mod-hfsplus.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(hfsplus_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-hfsplus.o mod-hfsplus.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+hfsplus.mod: pre-hfsplus.o mod-hfsplus.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(hfsplus_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-hfsplus.o mod-hfsplus.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-hfsplus.o: $(hfsplus_mod_DEPENDENCIES) hfsplus_mod-fs_hfsplus.o
+	-rm -f $@
+	$(TARGET_CC) $(hfsplus_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ hfsplus_mod-fs_hfsplus.o
+
+mod-hfsplus.o: mod-hfsplus.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfsplus_mod_CFLAGS) -c -o $@ $<
+
+mod-hfsplus.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'hfsplus' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(hfsplus_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-hfsplus.lst: pre-hfsplus.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 hfsplus/' > $@
+else
+def-hfsplus.lst: pre-hfsplus.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 hfsplus/' > $@
+endif
+endif
+
+und-hfsplus.lst: pre-hfsplus.o
+	echo 'hfsplus' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+hfsplus_mod-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hfsplus_mod_CFLAGS) -MD -c -o $@ $<
+-include hfsplus_mod-fs_hfsplus.d
+
+clean-module-hfsplus_mod-fs_hfsplus-extra.1:
+	rm -f cmd-hfsplus_mod-fs_hfsplus.lst fs-hfsplus_mod-fs_hfsplus.lst partmap-hfsplus_mod-fs_hfsplus.lst handler-hfsplus_mod-fs_hfsplus.lst parttool-hfsplus_mod-fs_hfsplus.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hfsplus_mod-fs_hfsplus-extra.1
+
+COMMANDFILES += cmd-hfsplus_mod-fs_hfsplus.lst
+FSFILES += fs-hfsplus_mod-fs_hfsplus.lst
+PARTTOOLFILES += parttool-hfsplus_mod-fs_hfsplus.lst
+PARTMAPFILES += partmap-hfsplus_mod-fs_hfsplus.lst
+HANDLERFILES += handler-hfsplus_mod-fs_hfsplus.lst
+
+cmd-hfsplus_mod-fs_hfsplus.lst: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hfsplus_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh hfsplus > $@ || (rm -f $@; exit 1)
+
+fs-hfsplus_mod-fs_hfsplus.lst: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hfsplus_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh hfsplus > $@ || (rm -f $@; exit 1)
+
+parttool-hfsplus_mod-fs_hfsplus.lst: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hfsplus_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh hfsplus > $@ || (rm -f $@; exit 1)
+
+partmap-hfsplus_mod-fs_hfsplus.lst: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hfsplus_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh hfsplus > $@ || (rm -f $@; exit 1)
+
+handler-hfsplus_mod-fs_hfsplus.lst: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hfsplus_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh hfsplus > $@ || (rm -f $@; exit 1)
+
+hfsplus_mod_CFLAGS = $(COMMON_CFLAGS)
+hfsplus_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reiserfs.mod.
+reiserfs_mod_SOURCES = fs/reiserfs.c
+
+clean-module-reiserfs.mod.1:
+	rm -f reiserfs.mod mod-reiserfs.o mod-reiserfs.c pre-reiserfs.o reiserfs_mod-fs_reiserfs.o und-reiserfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reiserfs.mod.1
+
+ifneq ($(reiserfs_mod_EXPORTS),no)
+clean-module-reiserfs.mod-symbol.1:
+	rm -f def-reiserfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reiserfs.mod-symbol.1
+DEFSYMFILES += def-reiserfs.lst
+endif
+mostlyclean-module-reiserfs.mod.1:
+	rm -f reiserfs_mod-fs_reiserfs.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-reiserfs.mod.1
+UNDSYMFILES += und-reiserfs.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+reiserfs.mod: pre-reiserfs.o mod-reiserfs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(reiserfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-reiserfs.o mod-reiserfs.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+reiserfs.mod: pre-reiserfs.o mod-reiserfs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(reiserfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-reiserfs.o mod-reiserfs.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-reiserfs.o: $(reiserfs_mod_DEPENDENCIES) reiserfs_mod-fs_reiserfs.o
+	-rm -f $@
+	$(TARGET_CC) $(reiserfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reiserfs_mod-fs_reiserfs.o
+
+mod-reiserfs.o: mod-reiserfs.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reiserfs_mod_CFLAGS) -c -o $@ $<
+
+mod-reiserfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'reiserfs' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(reiserfs_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-reiserfs.lst: pre-reiserfs.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reiserfs/' > $@
+else
+def-reiserfs.lst: pre-reiserfs.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 reiserfs/' > $@
+endif
+endif
+
+und-reiserfs.lst: pre-reiserfs.o
+	echo 'reiserfs' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+reiserfs_mod-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reiserfs_mod_CFLAGS) -MD -c -o $@ $<
+-include reiserfs_mod-fs_reiserfs.d
+
+clean-module-reiserfs_mod-fs_reiserfs-extra.1:
+	rm -f cmd-reiserfs_mod-fs_reiserfs.lst fs-reiserfs_mod-fs_reiserfs.lst partmap-reiserfs_mod-fs_reiserfs.lst handler-reiserfs_mod-fs_reiserfs.lst parttool-reiserfs_mod-fs_reiserfs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reiserfs_mod-fs_reiserfs-extra.1
+
+COMMANDFILES += cmd-reiserfs_mod-fs_reiserfs.lst
+FSFILES += fs-reiserfs_mod-fs_reiserfs.lst
+PARTTOOLFILES += parttool-reiserfs_mod-fs_reiserfs.lst
+PARTMAPFILES += partmap-reiserfs_mod-fs_reiserfs.lst
+HANDLERFILES += handler-reiserfs_mod-fs_reiserfs.lst
+
+cmd-reiserfs_mod-fs_reiserfs.lst: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reiserfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh reiserfs > $@ || (rm -f $@; exit 1)
+
+fs-reiserfs_mod-fs_reiserfs.lst: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reiserfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh reiserfs > $@ || (rm -f $@; exit 1)
+
+parttool-reiserfs_mod-fs_reiserfs.lst: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reiserfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh reiserfs > $@ || (rm -f $@; exit 1)
+
+partmap-reiserfs_mod-fs_reiserfs.lst: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reiserfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh reiserfs > $@ || (rm -f $@; exit 1)
+
+handler-reiserfs_mod-fs_reiserfs.lst: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reiserfs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh reiserfs > $@ || (rm -f $@; exit 1)
+
+reiserfs_mod_CFLAGS = $(COMMON_CFLAGS)
+reiserfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For cpio.mod.
+cpio_mod_SOURCES = fs/cpio.c
+
+clean-module-cpio.mod.1:
+	rm -f cpio.mod mod-cpio.o mod-cpio.c pre-cpio.o cpio_mod-fs_cpio.o und-cpio.lst
+
+CLEAN_MODULE_TARGETS += clean-module-cpio.mod.1
+
+ifneq ($(cpio_mod_EXPORTS),no)
+clean-module-cpio.mod-symbol.1:
+	rm -f def-cpio.lst
+
+CLEAN_MODULE_TARGETS += clean-module-cpio.mod-symbol.1
+DEFSYMFILES += def-cpio.lst
+endif
+mostlyclean-module-cpio.mod.1:
+	rm -f cpio_mod-fs_cpio.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-cpio.mod.1
+UNDSYMFILES += und-cpio.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+cpio.mod: pre-cpio.o mod-cpio.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(cpio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-cpio.o mod-cpio.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+cpio.mod: pre-cpio.o mod-cpio.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(cpio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-cpio.o mod-cpio.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-cpio.o: $(cpio_mod_DEPENDENCIES) cpio_mod-fs_cpio.o
+	-rm -f $@
+	$(TARGET_CC) $(cpio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ cpio_mod-fs_cpio.o
+
+mod-cpio.o: mod-cpio.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cpio_mod_CFLAGS) -c -o $@ $<
+
+mod-cpio.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'cpio' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(cpio_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-cpio.lst: pre-cpio.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 cpio/' > $@
+else
+def-cpio.lst: pre-cpio.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 cpio/' > $@
+endif
+endif
+
+und-cpio.lst: pre-cpio.o
+	echo 'cpio' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+cpio_mod-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cpio_mod_CFLAGS) -MD -c -o $@ $<
+-include cpio_mod-fs_cpio.d
+
+clean-module-cpio_mod-fs_cpio-extra.1:
+	rm -f cmd-cpio_mod-fs_cpio.lst fs-cpio_mod-fs_cpio.lst partmap-cpio_mod-fs_cpio.lst handler-cpio_mod-fs_cpio.lst parttool-cpio_mod-fs_cpio.lst
+
+CLEAN_MODULE_TARGETS += clean-module-cpio_mod-fs_cpio-extra.1
+
+COMMANDFILES += cmd-cpio_mod-fs_cpio.lst
+FSFILES += fs-cpio_mod-fs_cpio.lst
+PARTTOOLFILES += parttool-cpio_mod-fs_cpio.lst
+PARTMAPFILES += partmap-cpio_mod-fs_cpio.lst
+HANDLERFILES += handler-cpio_mod-fs_cpio.lst
+
+cmd-cpio_mod-fs_cpio.lst: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cpio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh cpio > $@ || (rm -f $@; exit 1)
+
+fs-cpio_mod-fs_cpio.lst: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cpio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh cpio > $@ || (rm -f $@; exit 1)
+
+parttool-cpio_mod-fs_cpio.lst: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cpio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh cpio > $@ || (rm -f $@; exit 1)
+
+partmap-cpio_mod-fs_cpio.lst: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cpio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh cpio > $@ || (rm -f $@; exit 1)
+
+handler-cpio_mod-fs_cpio.lst: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cpio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh cpio > $@ || (rm -f $@; exit 1)
+
+cpio_mod_CFLAGS = $(COMMON_CFLAGS)
+cpio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For tar.mod.
+tar_mod_SOURCES = fs/tar.c
+
+clean-module-tar.mod.1:
+	rm -f tar.mod mod-tar.o mod-tar.c pre-tar.o tar_mod-fs_tar.o und-tar.lst
+
+CLEAN_MODULE_TARGETS += clean-module-tar.mod.1
+
+ifneq ($(tar_mod_EXPORTS),no)
+clean-module-tar.mod-symbol.1:
+	rm -f def-tar.lst
+
+CLEAN_MODULE_TARGETS += clean-module-tar.mod-symbol.1
+DEFSYMFILES += def-tar.lst
+endif
+mostlyclean-module-tar.mod.1:
+	rm -f tar_mod-fs_tar.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-tar.mod.1
+UNDSYMFILES += und-tar.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+tar.mod: pre-tar.o mod-tar.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(tar_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-tar.o mod-tar.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+tar.mod: pre-tar.o mod-tar.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(tar_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-tar.o mod-tar.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-tar.o: $(tar_mod_DEPENDENCIES) tar_mod-fs_tar.o
+	-rm -f $@
+	$(TARGET_CC) $(tar_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ tar_mod-fs_tar.o
+
+mod-tar.o: mod-tar.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tar_mod_CFLAGS) -c -o $@ $<
+
+mod-tar.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'tar' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(tar_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-tar.lst: pre-tar.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 tar/' > $@
+else
+def-tar.lst: pre-tar.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 tar/' > $@
+endif
+endif
+
+und-tar.lst: pre-tar.o
+	echo 'tar' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+tar_mod-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(tar_mod_CFLAGS) -MD -c -o $@ $<
+-include tar_mod-fs_tar.d
+
+clean-module-tar_mod-fs_tar-extra.1:
+	rm -f cmd-tar_mod-fs_tar.lst fs-tar_mod-fs_tar.lst partmap-tar_mod-fs_tar.lst handler-tar_mod-fs_tar.lst parttool-tar_mod-fs_tar.lst
+
+CLEAN_MODULE_TARGETS += clean-module-tar_mod-fs_tar-extra.1
+
+COMMANDFILES += cmd-tar_mod-fs_tar.lst
+FSFILES += fs-tar_mod-fs_tar.lst
+PARTTOOLFILES += parttool-tar_mod-fs_tar.lst
+PARTMAPFILES += partmap-tar_mod-fs_tar.lst
+HANDLERFILES += handler-tar_mod-fs_tar.lst
+
+cmd-tar_mod-fs_tar.lst: fs/tar.c $(fs/tar.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(tar_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh tar > $@ || (rm -f $@; exit 1)
+
+fs-tar_mod-fs_tar.lst: fs/tar.c $(fs/tar.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(tar_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh tar > $@ || (rm -f $@; exit 1)
+
+parttool-tar_mod-fs_tar.lst: fs/tar.c $(fs/tar.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(tar_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh tar > $@ || (rm -f $@; exit 1)
+
+partmap-tar_mod-fs_tar.lst: fs/tar.c $(fs/tar.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(tar_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh tar > $@ || (rm -f $@; exit 1)
+
+handler-tar_mod-fs_tar.lst: fs/tar.c $(fs/tar.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(tar_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh tar > $@ || (rm -f $@; exit 1)
+
+tar_mod_CFLAGS = $(COMMON_CFLAGS)
+tar_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For udf.mod.
+udf_mod_SOURCES = fs/udf.c
+
+clean-module-udf.mod.1:
+	rm -f udf.mod mod-udf.o mod-udf.c pre-udf.o udf_mod-fs_udf.o und-udf.lst
+
+CLEAN_MODULE_TARGETS += clean-module-udf.mod.1
+
+ifneq ($(udf_mod_EXPORTS),no)
+clean-module-udf.mod-symbol.1:
+	rm -f def-udf.lst
+
+CLEAN_MODULE_TARGETS += clean-module-udf.mod-symbol.1
+DEFSYMFILES += def-udf.lst
+endif
+mostlyclean-module-udf.mod.1:
+	rm -f udf_mod-fs_udf.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-udf.mod.1
+UNDSYMFILES += und-udf.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+udf.mod: pre-udf.o mod-udf.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(udf_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-udf.o mod-udf.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+udf.mod: pre-udf.o mod-udf.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(udf_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-udf.o mod-udf.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-udf.o: $(udf_mod_DEPENDENCIES) udf_mod-fs_udf.o
+	-rm -f $@
+	$(TARGET_CC) $(udf_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ udf_mod-fs_udf.o
+
+mod-udf.o: mod-udf.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(udf_mod_CFLAGS) -c -o $@ $<
+
+mod-udf.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'udf' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(udf_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-udf.lst: pre-udf.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 udf/' > $@
+else
+def-udf.lst: pre-udf.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 udf/' > $@
+endif
+endif
+
+und-udf.lst: pre-udf.o
+	echo 'udf' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+udf_mod-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(udf_mod_CFLAGS) -MD -c -o $@ $<
+-include udf_mod-fs_udf.d
+
+clean-module-udf_mod-fs_udf-extra.1:
+	rm -f cmd-udf_mod-fs_udf.lst fs-udf_mod-fs_udf.lst partmap-udf_mod-fs_udf.lst handler-udf_mod-fs_udf.lst parttool-udf_mod-fs_udf.lst
+
+CLEAN_MODULE_TARGETS += clean-module-udf_mod-fs_udf-extra.1
+
+COMMANDFILES += cmd-udf_mod-fs_udf.lst
+FSFILES += fs-udf_mod-fs_udf.lst
+PARTTOOLFILES += parttool-udf_mod-fs_udf.lst
+PARTMAPFILES += partmap-udf_mod-fs_udf.lst
+HANDLERFILES += handler-udf_mod-fs_udf.lst
+
+cmd-udf_mod-fs_udf.lst: fs/udf.c $(fs/udf.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(udf_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh udf > $@ || (rm -f $@; exit 1)
+
+fs-udf_mod-fs_udf.lst: fs/udf.c $(fs/udf.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(udf_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh udf > $@ || (rm -f $@; exit 1)
+
+parttool-udf_mod-fs_udf.lst: fs/udf.c $(fs/udf.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(udf_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh udf > $@ || (rm -f $@; exit 1)
+
+partmap-udf_mod-fs_udf.lst: fs/udf.c $(fs/udf.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(udf_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh udf > $@ || (rm -f $@; exit 1)
+
+handler-udf_mod-fs_udf.lst: fs/udf.c $(fs/udf.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(udf_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh udf > $@ || (rm -f $@; exit 1)
+
+udf_mod_CFLAGS = $(COMMON_CFLAGS)
+udf_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For afs.mod.
+afs_mod_SOURCES = fs/afs.c
+
+clean-module-afs.mod.1:
+	rm -f afs.mod mod-afs.o mod-afs.c pre-afs.o afs_mod-fs_afs.o und-afs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-afs.mod.1
+
+ifneq ($(afs_mod_EXPORTS),no)
+clean-module-afs.mod-symbol.1:
+	rm -f def-afs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-afs.mod-symbol.1
+DEFSYMFILES += def-afs.lst
+endif
+mostlyclean-module-afs.mod.1:
+	rm -f afs_mod-fs_afs.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-afs.mod.1
+UNDSYMFILES += und-afs.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+afs.mod: pre-afs.o mod-afs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(afs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-afs.o mod-afs.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+afs.mod: pre-afs.o mod-afs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(afs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-afs.o mod-afs.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-afs.o: $(afs_mod_DEPENDENCIES) afs_mod-fs_afs.o
+	-rm -f $@
+	$(TARGET_CC) $(afs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ afs_mod-fs_afs.o
+
+mod-afs.o: mod-afs.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(afs_mod_CFLAGS) -c -o $@ $<
+
+mod-afs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'afs' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(afs_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-afs.lst: pre-afs.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 afs/' > $@
+else
+def-afs.lst: pre-afs.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 afs/' > $@
+endif
+endif
+
+und-afs.lst: pre-afs.o
+	echo 'afs' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+afs_mod-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(afs_mod_CFLAGS) -MD -c -o $@ $<
+-include afs_mod-fs_afs.d
+
+clean-module-afs_mod-fs_afs-extra.1:
+	rm -f cmd-afs_mod-fs_afs.lst fs-afs_mod-fs_afs.lst partmap-afs_mod-fs_afs.lst handler-afs_mod-fs_afs.lst parttool-afs_mod-fs_afs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-afs_mod-fs_afs-extra.1
+
+COMMANDFILES += cmd-afs_mod-fs_afs.lst
+FSFILES += fs-afs_mod-fs_afs.lst
+PARTTOOLFILES += parttool-afs_mod-fs_afs.lst
+PARTMAPFILES += partmap-afs_mod-fs_afs.lst
+HANDLERFILES += handler-afs_mod-fs_afs.lst
+
+cmd-afs_mod-fs_afs.lst: fs/afs.c $(fs/afs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(afs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh afs > $@ || (rm -f $@; exit 1)
+
+fs-afs_mod-fs_afs.lst: fs/afs.c $(fs/afs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(afs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh afs > $@ || (rm -f $@; exit 1)
+
+parttool-afs_mod-fs_afs.lst: fs/afs.c $(fs/afs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(afs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh afs > $@ || (rm -f $@; exit 1)
+
+partmap-afs_mod-fs_afs.lst: fs/afs.c $(fs/afs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(afs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh afs > $@ || (rm -f $@; exit 1)
+
+handler-afs_mod-fs_afs.lst: fs/afs.c $(fs/afs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(afs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh afs > $@ || (rm -f $@; exit 1)
+
+afs_mod_CFLAGS = $(COMMON_CFLAGS)
+afs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For afs_be.mod.
+afs_be_mod_SOURCES = fs/afs_be.c
+
+clean-module-afs_be.mod.1:
+	rm -f afs_be.mod mod-afs_be.o mod-afs_be.c pre-afs_be.o afs_be_mod-fs_afs_be.o und-afs_be.lst
+
+CLEAN_MODULE_TARGETS += clean-module-afs_be.mod.1
+
+ifneq ($(afs_be_mod_EXPORTS),no)
+clean-module-afs_be.mod-symbol.1:
+	rm -f def-afs_be.lst
+
+CLEAN_MODULE_TARGETS += clean-module-afs_be.mod-symbol.1
+DEFSYMFILES += def-afs_be.lst
+endif
+mostlyclean-module-afs_be.mod.1:
+	rm -f afs_be_mod-fs_afs_be.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-afs_be.mod.1
+UNDSYMFILES += und-afs_be.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+afs_be.mod: pre-afs_be.o mod-afs_be.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(afs_be_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-afs_be.o mod-afs_be.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+afs_be.mod: pre-afs_be.o mod-afs_be.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(afs_be_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-afs_be.o mod-afs_be.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-afs_be.o: $(afs_be_mod_DEPENDENCIES) afs_be_mod-fs_afs_be.o
+	-rm -f $@
+	$(TARGET_CC) $(afs_be_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ afs_be_mod-fs_afs_be.o
+
+mod-afs_be.o: mod-afs_be.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(afs_be_mod_CFLAGS) -c -o $@ $<
+
+mod-afs_be.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'afs_be' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(afs_be_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-afs_be.lst: pre-afs_be.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 afs_be/' > $@
+else
+def-afs_be.lst: pre-afs_be.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 afs_be/' > $@
+endif
+endif
+
+und-afs_be.lst: pre-afs_be.o
+	echo 'afs_be' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+afs_be_mod-fs_afs_be.o: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(afs_be_mod_CFLAGS) -MD -c -o $@ $<
+-include afs_be_mod-fs_afs_be.d
+
+clean-module-afs_be_mod-fs_afs_be-extra.1:
+	rm -f cmd-afs_be_mod-fs_afs_be.lst fs-afs_be_mod-fs_afs_be.lst partmap-afs_be_mod-fs_afs_be.lst handler-afs_be_mod-fs_afs_be.lst parttool-afs_be_mod-fs_afs_be.lst
+
+CLEAN_MODULE_TARGETS += clean-module-afs_be_mod-fs_afs_be-extra.1
+
+COMMANDFILES += cmd-afs_be_mod-fs_afs_be.lst
+FSFILES += fs-afs_be_mod-fs_afs_be.lst
+PARTTOOLFILES += parttool-afs_be_mod-fs_afs_be.lst
+PARTMAPFILES += partmap-afs_be_mod-fs_afs_be.lst
+HANDLERFILES += handler-afs_be_mod-fs_afs_be.lst
+
+cmd-afs_be_mod-fs_afs_be.lst: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(afs_be_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh afs_be > $@ || (rm -f $@; exit 1)
+
+fs-afs_be_mod-fs_afs_be.lst: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(afs_be_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh afs_be > $@ || (rm -f $@; exit 1)
+
+parttool-afs_be_mod-fs_afs_be.lst: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(afs_be_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh afs_be > $@ || (rm -f $@; exit 1)
+
+partmap-afs_be_mod-fs_afs_be.lst: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(afs_be_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh afs_be > $@ || (rm -f $@; exit 1)
+
+handler-afs_be_mod-fs_afs_be.lst: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(afs_be_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh afs_be > $@ || (rm -f $@; exit 1)
+
+afs_be_mod_CFLAGS = $(COMMON_CFLAGS)
+afs_be_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For befs.mod.
+befs_mod_SOURCES = fs/befs.c
+
+clean-module-befs.mod.1:
+	rm -f befs.mod mod-befs.o mod-befs.c pre-befs.o befs_mod-fs_befs.o und-befs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-befs.mod.1
+
+ifneq ($(befs_mod_EXPORTS),no)
+clean-module-befs.mod-symbol.1:
+	rm -f def-befs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-befs.mod-symbol.1
+DEFSYMFILES += def-befs.lst
+endif
+mostlyclean-module-befs.mod.1:
+	rm -f befs_mod-fs_befs.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-befs.mod.1
+UNDSYMFILES += und-befs.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+befs.mod: pre-befs.o mod-befs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(befs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-befs.o mod-befs.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+befs.mod: pre-befs.o mod-befs.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(befs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-befs.o mod-befs.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-befs.o: $(befs_mod_DEPENDENCIES) befs_mod-fs_befs.o
+	-rm -f $@
+	$(TARGET_CC) $(befs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ befs_mod-fs_befs.o
+
+mod-befs.o: mod-befs.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(befs_mod_CFLAGS) -c -o $@ $<
+
+mod-befs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'befs' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(befs_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-befs.lst: pre-befs.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 befs/' > $@
+else
+def-befs.lst: pre-befs.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 befs/' > $@
+endif
+endif
+
+und-befs.lst: pre-befs.o
+	echo 'befs' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+befs_mod-fs_befs.o: fs/befs.c $(fs/befs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(befs_mod_CFLAGS) -MD -c -o $@ $<
+-include befs_mod-fs_befs.d
+
+clean-module-befs_mod-fs_befs-extra.1:
+	rm -f cmd-befs_mod-fs_befs.lst fs-befs_mod-fs_befs.lst partmap-befs_mod-fs_befs.lst handler-befs_mod-fs_befs.lst parttool-befs_mod-fs_befs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-befs_mod-fs_befs-extra.1
+
+COMMANDFILES += cmd-befs_mod-fs_befs.lst
+FSFILES += fs-befs_mod-fs_befs.lst
+PARTTOOLFILES += parttool-befs_mod-fs_befs.lst
+PARTMAPFILES += partmap-befs_mod-fs_befs.lst
+HANDLERFILES += handler-befs_mod-fs_befs.lst
+
+cmd-befs_mod-fs_befs.lst: fs/befs.c $(fs/befs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(befs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh befs > $@ || (rm -f $@; exit 1)
+
+fs-befs_mod-fs_befs.lst: fs/befs.c $(fs/befs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(befs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh befs > $@ || (rm -f $@; exit 1)
+
+parttool-befs_mod-fs_befs.lst: fs/befs.c $(fs/befs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(befs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh befs > $@ || (rm -f $@; exit 1)
+
+partmap-befs_mod-fs_befs.lst: fs/befs.c $(fs/befs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(befs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh befs > $@ || (rm -f $@; exit 1)
+
+handler-befs_mod-fs_befs.lst: fs/befs.c $(fs/befs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(befs_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh befs > $@ || (rm -f $@; exit 1)
+
+befs_mod_CFLAGS = $(COMMON_CFLAGS)
+befs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For befs_be.mod.
+befs_be_mod_SOURCES = fs/befs_be.c
+
+clean-module-befs_be.mod.1:
+	rm -f befs_be.mod mod-befs_be.o mod-befs_be.c pre-befs_be.o befs_be_mod-fs_befs_be.o und-befs_be.lst
+
+CLEAN_MODULE_TARGETS += clean-module-befs_be.mod.1
+
+ifneq ($(befs_be_mod_EXPORTS),no)
+clean-module-befs_be.mod-symbol.1:
+	rm -f def-befs_be.lst
+
+CLEAN_MODULE_TARGETS += clean-module-befs_be.mod-symbol.1
+DEFSYMFILES += def-befs_be.lst
+endif
+mostlyclean-module-befs_be.mod.1:
+	rm -f befs_be_mod-fs_befs_be.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-befs_be.mod.1
+UNDSYMFILES += und-befs_be.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+befs_be.mod: pre-befs_be.o mod-befs_be.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(befs_be_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-befs_be.o mod-befs_be.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+befs_be.mod: pre-befs_be.o mod-befs_be.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(befs_be_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-befs_be.o mod-befs_be.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-befs_be.o: $(befs_be_mod_DEPENDENCIES) befs_be_mod-fs_befs_be.o
+	-rm -f $@
+	$(TARGET_CC) $(befs_be_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ befs_be_mod-fs_befs_be.o
+
+mod-befs_be.o: mod-befs_be.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(befs_be_mod_CFLAGS) -c -o $@ $<
+
+mod-befs_be.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'befs_be' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(befs_be_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-befs_be.lst: pre-befs_be.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 befs_be/' > $@
+else
+def-befs_be.lst: pre-befs_be.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 befs_be/' > $@
+endif
+endif
+
+und-befs_be.lst: pre-befs_be.o
+	echo 'befs_be' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+befs_be_mod-fs_befs_be.o: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(befs_be_mod_CFLAGS) -MD -c -o $@ $<
+-include befs_be_mod-fs_befs_be.d
+
+clean-module-befs_be_mod-fs_befs_be-extra.1:
+	rm -f cmd-befs_be_mod-fs_befs_be.lst fs-befs_be_mod-fs_befs_be.lst partmap-befs_be_mod-fs_befs_be.lst handler-befs_be_mod-fs_befs_be.lst parttool-befs_be_mod-fs_befs_be.lst
+
+CLEAN_MODULE_TARGETS += clean-module-befs_be_mod-fs_befs_be-extra.1
+
+COMMANDFILES += cmd-befs_be_mod-fs_befs_be.lst
+FSFILES += fs-befs_be_mod-fs_befs_be.lst
+PARTTOOLFILES += parttool-befs_be_mod-fs_befs_be.lst
+PARTMAPFILES += partmap-befs_be_mod-fs_befs_be.lst
+HANDLERFILES += handler-befs_be_mod-fs_befs_be.lst
+
+cmd-befs_be_mod-fs_befs_be.lst: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(befs_be_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh befs_be > $@ || (rm -f $@; exit 1)
+
+fs-befs_be_mod-fs_befs_be.lst: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(befs_be_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh befs_be > $@ || (rm -f $@; exit 1)
+
+parttool-befs_be_mod-fs_befs_be.lst: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(befs_be_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh befs_be > $@ || (rm -f $@; exit 1)
+
+partmap-befs_be_mod-fs_befs_be.lst: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(befs_be_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh befs_be > $@ || (rm -f $@; exit 1)
+
+handler-befs_be_mod-fs_befs_be.lst: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(befs_be_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh befs_be > $@ || (rm -f $@; exit 1)
+
+befs_be_mod_CFLAGS = $(COMMON_CFLAGS)
+befs_be_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Partition maps.
+
+pkglib_MODULES += part_amiga.mod
+part_amiga_mod_SOURCES = partmap/amiga.c
+
+clean-module-part_amiga.mod.1:
+	rm -f part_amiga.mod mod-part_amiga.o mod-part_amiga.c pre-part_amiga.o part_amiga_mod-partmap_amiga.o und-part_amiga.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_amiga.mod.1
+
+ifneq ($(part_amiga_mod_EXPORTS),no)
+clean-module-part_amiga.mod-symbol.1:
+	rm -f def-part_amiga.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_amiga.mod-symbol.1
+DEFSYMFILES += def-part_amiga.lst
+endif
+mostlyclean-module-part_amiga.mod.1:
+	rm -f part_amiga_mod-partmap_amiga.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-part_amiga.mod.1
+UNDSYMFILES += und-part_amiga.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+part_amiga.mod: pre-part_amiga.o mod-part_amiga.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(part_amiga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-part_amiga.o mod-part_amiga.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+part_amiga.mod: pre-part_amiga.o mod-part_amiga.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(part_amiga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-part_amiga.o mod-part_amiga.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-part_amiga.o: $(part_amiga_mod_DEPENDENCIES) part_amiga_mod-partmap_amiga.o
+	-rm -f $@
+	$(TARGET_CC) $(part_amiga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ part_amiga_mod-partmap_amiga.o
+
+mod-part_amiga.o: mod-part_amiga.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(part_amiga_mod_CFLAGS) -c -o $@ $<
+
+mod-part_amiga.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'part_amiga' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(part_amiga_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-part_amiga.lst: pre-part_amiga.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 part_amiga/' > $@
+else
+def-part_amiga.lst: pre-part_amiga.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 part_amiga/' > $@
+endif
+endif
+
+und-part_amiga.lst: pre-part_amiga.o
+	echo 'part_amiga' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+part_amiga_mod-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES)
+	$(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_amiga_mod_CFLAGS) -MD -c -o $@ $<
+-include part_amiga_mod-partmap_amiga.d
+
+clean-module-part_amiga_mod-partmap_amiga-extra.1:
+	rm -f cmd-part_amiga_mod-partmap_amiga.lst fs-part_amiga_mod-partmap_amiga.lst partmap-part_amiga_mod-partmap_amiga.lst handler-part_amiga_mod-partmap_amiga.lst parttool-part_amiga_mod-partmap_amiga.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_amiga_mod-partmap_amiga-extra.1
+
+COMMANDFILES += cmd-part_amiga_mod-partmap_amiga.lst
+FSFILES += fs-part_amiga_mod-partmap_amiga.lst
+PARTTOOLFILES += parttool-part_amiga_mod-partmap_amiga.lst
+PARTMAPFILES += partmap-part_amiga_mod-partmap_amiga.lst
+HANDLERFILES += handler-part_amiga_mod-partmap_amiga.lst
+
+cmd-part_amiga_mod-partmap_amiga.lst: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_amiga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh part_amiga > $@ || (rm -f $@; exit 1)
+
+fs-part_amiga_mod-partmap_amiga.lst: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_amiga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh part_amiga > $@ || (rm -f $@; exit 1)
+
+parttool-part_amiga_mod-partmap_amiga.lst: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_amiga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh part_amiga > $@ || (rm -f $@; exit 1)
+
+partmap-part_amiga_mod-partmap_amiga.lst: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_amiga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh part_amiga > $@ || (rm -f $@; exit 1)
+
+handler-part_amiga_mod-partmap_amiga.lst: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_amiga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh part_amiga > $@ || (rm -f $@; exit 1)
+
+part_amiga_mod_CFLAGS = $(COMMON_CFLAGS)
+part_amiga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_apple.mod
+part_apple_mod_SOURCES = partmap/apple.c
+
+clean-module-part_apple.mod.1:
+	rm -f part_apple.mod mod-part_apple.o mod-part_apple.c pre-part_apple.o part_apple_mod-partmap_apple.o und-part_apple.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_apple.mod.1
+
+ifneq ($(part_apple_mod_EXPORTS),no)
+clean-module-part_apple.mod-symbol.1:
+	rm -f def-part_apple.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_apple.mod-symbol.1
+DEFSYMFILES += def-part_apple.lst
+endif
+mostlyclean-module-part_apple.mod.1:
+	rm -f part_apple_mod-partmap_apple.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-part_apple.mod.1
+UNDSYMFILES += und-part_apple.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+part_apple.mod: pre-part_apple.o mod-part_apple.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(part_apple_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-part_apple.o mod-part_apple.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+part_apple.mod: pre-part_apple.o mod-part_apple.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(part_apple_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-part_apple.o mod-part_apple.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-part_apple.o: $(part_apple_mod_DEPENDENCIES) part_apple_mod-partmap_apple.o
+	-rm -f $@
+	$(TARGET_CC) $(part_apple_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ part_apple_mod-partmap_apple.o
+
+mod-part_apple.o: mod-part_apple.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(part_apple_mod_CFLAGS) -c -o $@ $<
+
+mod-part_apple.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'part_apple' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(part_apple_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-part_apple.lst: pre-part_apple.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 part_apple/' > $@
+else
+def-part_apple.lst: pre-part_apple.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 part_apple/' > $@
+endif
+endif
+
+und-part_apple.lst: pre-part_apple.o
+	echo 'part_apple' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+part_apple_mod-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES)
+	$(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_apple_mod_CFLAGS) -MD -c -o $@ $<
+-include part_apple_mod-partmap_apple.d
+
+clean-module-part_apple_mod-partmap_apple-extra.1:
+	rm -f cmd-part_apple_mod-partmap_apple.lst fs-part_apple_mod-partmap_apple.lst partmap-part_apple_mod-partmap_apple.lst handler-part_apple_mod-partmap_apple.lst parttool-part_apple_mod-partmap_apple.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_apple_mod-partmap_apple-extra.1
+
+COMMANDFILES += cmd-part_apple_mod-partmap_apple.lst
+FSFILES += fs-part_apple_mod-partmap_apple.lst
+PARTTOOLFILES += parttool-part_apple_mod-partmap_apple.lst
+PARTMAPFILES += partmap-part_apple_mod-partmap_apple.lst
+HANDLERFILES += handler-part_apple_mod-partmap_apple.lst
+
+cmd-part_apple_mod-partmap_apple.lst: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_apple_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh part_apple > $@ || (rm -f $@; exit 1)
+
+fs-part_apple_mod-partmap_apple.lst: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_apple_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh part_apple > $@ || (rm -f $@; exit 1)
+
+parttool-part_apple_mod-partmap_apple.lst: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_apple_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh part_apple > $@ || (rm -f $@; exit 1)
+
+partmap-part_apple_mod-partmap_apple.lst: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_apple_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh part_apple > $@ || (rm -f $@; exit 1)
+
+handler-part_apple_mod-partmap_apple.lst: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_apple_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh part_apple > $@ || (rm -f $@; exit 1)
+
+part_apple_mod_CFLAGS = $(COMMON_CFLAGS)
+part_apple_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_msdos.mod
+part_msdos_mod_SOURCES = partmap/msdos.c
+
+clean-module-part_msdos.mod.1:
+	rm -f part_msdos.mod mod-part_msdos.o mod-part_msdos.c pre-part_msdos.o part_msdos_mod-partmap_msdos.o und-part_msdos.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_msdos.mod.1
+
+ifneq ($(part_msdos_mod_EXPORTS),no)
+clean-module-part_msdos.mod-symbol.1:
+	rm -f def-part_msdos.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_msdos.mod-symbol.1
+DEFSYMFILES += def-part_msdos.lst
+endif
+mostlyclean-module-part_msdos.mod.1:
+	rm -f part_msdos_mod-partmap_msdos.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-part_msdos.mod.1
+UNDSYMFILES += und-part_msdos.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+part_msdos.mod: pre-part_msdos.o mod-part_msdos.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(part_msdos_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-part_msdos.o mod-part_msdos.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+part_msdos.mod: pre-part_msdos.o mod-part_msdos.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(part_msdos_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-part_msdos.o mod-part_msdos.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-part_msdos.o: $(part_msdos_mod_DEPENDENCIES) part_msdos_mod-partmap_msdos.o
+	-rm -f $@
+	$(TARGET_CC) $(part_msdos_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ part_msdos_mod-partmap_msdos.o
+
+mod-part_msdos.o: mod-part_msdos.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(part_msdos_mod_CFLAGS) -c -o $@ $<
+
+mod-part_msdos.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'part_msdos' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(part_msdos_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-part_msdos.lst: pre-part_msdos.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 part_msdos/' > $@
+else
+def-part_msdos.lst: pre-part_msdos.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 part_msdos/' > $@
+endif
+endif
+
+und-part_msdos.lst: pre-part_msdos.o
+	echo 'part_msdos' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+part_msdos_mod-partmap_msdos.o: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES)
+	$(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_msdos_mod_CFLAGS) -MD -c -o $@ $<
+-include part_msdos_mod-partmap_msdos.d
+
+clean-module-part_msdos_mod-partmap_msdos-extra.1:
+	rm -f cmd-part_msdos_mod-partmap_msdos.lst fs-part_msdos_mod-partmap_msdos.lst partmap-part_msdos_mod-partmap_msdos.lst handler-part_msdos_mod-partmap_msdos.lst parttool-part_msdos_mod-partmap_msdos.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_msdos_mod-partmap_msdos-extra.1
+
+COMMANDFILES += cmd-part_msdos_mod-partmap_msdos.lst
+FSFILES += fs-part_msdos_mod-partmap_msdos.lst
+PARTTOOLFILES += parttool-part_msdos_mod-partmap_msdos.lst
+PARTMAPFILES += partmap-part_msdos_mod-partmap_msdos.lst
+HANDLERFILES += handler-part_msdos_mod-partmap_msdos.lst
+
+cmd-part_msdos_mod-partmap_msdos.lst: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_msdos_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh part_msdos > $@ || (rm -f $@; exit 1)
+
+fs-part_msdos_mod-partmap_msdos.lst: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_msdos_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh part_msdos > $@ || (rm -f $@; exit 1)
+
+parttool-part_msdos_mod-partmap_msdos.lst: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_msdos_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh part_msdos > $@ || (rm -f $@; exit 1)
+
+partmap-part_msdos_mod-partmap_msdos.lst: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_msdos_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh part_msdos > $@ || (rm -f $@; exit 1)
+
+handler-part_msdos_mod-partmap_msdos.lst: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_msdos_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh part_msdos > $@ || (rm -f $@; exit 1)
+
+part_msdos_mod_CFLAGS = $(COMMON_CFLAGS)
+part_msdos_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_sun.mod
+part_sun_mod_SOURCES = partmap/sun.c
+
+clean-module-part_sun.mod.1:
+	rm -f part_sun.mod mod-part_sun.o mod-part_sun.c pre-part_sun.o part_sun_mod-partmap_sun.o und-part_sun.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_sun.mod.1
+
+ifneq ($(part_sun_mod_EXPORTS),no)
+clean-module-part_sun.mod-symbol.1:
+	rm -f def-part_sun.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_sun.mod-symbol.1
+DEFSYMFILES += def-part_sun.lst
+endif
+mostlyclean-module-part_sun.mod.1:
+	rm -f part_sun_mod-partmap_sun.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-part_sun.mod.1
+UNDSYMFILES += und-part_sun.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+part_sun.mod: pre-part_sun.o mod-part_sun.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(part_sun_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-part_sun.o mod-part_sun.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+part_sun.mod: pre-part_sun.o mod-part_sun.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(part_sun_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-part_sun.o mod-part_sun.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-part_sun.o: $(part_sun_mod_DEPENDENCIES) part_sun_mod-partmap_sun.o
+	-rm -f $@
+	$(TARGET_CC) $(part_sun_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ part_sun_mod-partmap_sun.o
+
+mod-part_sun.o: mod-part_sun.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(part_sun_mod_CFLAGS) -c -o $@ $<
+
+mod-part_sun.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'part_sun' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(part_sun_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-part_sun.lst: pre-part_sun.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 part_sun/' > $@
+else
+def-part_sun.lst: pre-part_sun.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 part_sun/' > $@
+endif
+endif
+
+und-part_sun.lst: pre-part_sun.o
+	echo 'part_sun' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+part_sun_mod-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES)
+	$(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_sun_mod_CFLAGS) -MD -c -o $@ $<
+-include part_sun_mod-partmap_sun.d
+
+clean-module-part_sun_mod-partmap_sun-extra.1:
+	rm -f cmd-part_sun_mod-partmap_sun.lst fs-part_sun_mod-partmap_sun.lst partmap-part_sun_mod-partmap_sun.lst handler-part_sun_mod-partmap_sun.lst parttool-part_sun_mod-partmap_sun.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_sun_mod-partmap_sun-extra.1
+
+COMMANDFILES += cmd-part_sun_mod-partmap_sun.lst
+FSFILES += fs-part_sun_mod-partmap_sun.lst
+PARTTOOLFILES += parttool-part_sun_mod-partmap_sun.lst
+PARTMAPFILES += partmap-part_sun_mod-partmap_sun.lst
+HANDLERFILES += handler-part_sun_mod-partmap_sun.lst
+
+cmd-part_sun_mod-partmap_sun.lst: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_sun_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh part_sun > $@ || (rm -f $@; exit 1)
+
+fs-part_sun_mod-partmap_sun.lst: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_sun_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh part_sun > $@ || (rm -f $@; exit 1)
+
+parttool-part_sun_mod-partmap_sun.lst: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_sun_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh part_sun > $@ || (rm -f $@; exit 1)
+
+partmap-part_sun_mod-partmap_sun.lst: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_sun_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh part_sun > $@ || (rm -f $@; exit 1)
+
+handler-part_sun_mod-partmap_sun.lst: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_sun_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh part_sun > $@ || (rm -f $@; exit 1)
+
+part_sun_mod_CFLAGS = $(COMMON_CFLAGS)
+part_sun_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_acorn.mod
+part_acorn_mod_SOURCES = partmap/acorn.c
+
+clean-module-part_acorn.mod.1:
+	rm -f part_acorn.mod mod-part_acorn.o mod-part_acorn.c pre-part_acorn.o part_acorn_mod-partmap_acorn.o und-part_acorn.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_acorn.mod.1
+
+ifneq ($(part_acorn_mod_EXPORTS),no)
+clean-module-part_acorn.mod-symbol.1:
+	rm -f def-part_acorn.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_acorn.mod-symbol.1
+DEFSYMFILES += def-part_acorn.lst
+endif
+mostlyclean-module-part_acorn.mod.1:
+	rm -f part_acorn_mod-partmap_acorn.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-part_acorn.mod.1
+UNDSYMFILES += und-part_acorn.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+part_acorn.mod: pre-part_acorn.o mod-part_acorn.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(part_acorn_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-part_acorn.o mod-part_acorn.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+part_acorn.mod: pre-part_acorn.o mod-part_acorn.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(part_acorn_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-part_acorn.o mod-part_acorn.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-part_acorn.o: $(part_acorn_mod_DEPENDENCIES) part_acorn_mod-partmap_acorn.o
+	-rm -f $@
+	$(TARGET_CC) $(part_acorn_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ part_acorn_mod-partmap_acorn.o
+
+mod-part_acorn.o: mod-part_acorn.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(part_acorn_mod_CFLAGS) -c -o $@ $<
+
+mod-part_acorn.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'part_acorn' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(part_acorn_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-part_acorn.lst: pre-part_acorn.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 part_acorn/' > $@
+else
+def-part_acorn.lst: pre-part_acorn.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 part_acorn/' > $@
+endif
+endif
+
+und-part_acorn.lst: pre-part_acorn.o
+	echo 'part_acorn' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+part_acorn_mod-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES)
+	$(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_acorn_mod_CFLAGS) -MD -c -o $@ $<
+-include part_acorn_mod-partmap_acorn.d
+
+clean-module-part_acorn_mod-partmap_acorn-extra.1:
+	rm -f cmd-part_acorn_mod-partmap_acorn.lst fs-part_acorn_mod-partmap_acorn.lst partmap-part_acorn_mod-partmap_acorn.lst handler-part_acorn_mod-partmap_acorn.lst parttool-part_acorn_mod-partmap_acorn.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_acorn_mod-partmap_acorn-extra.1
+
+COMMANDFILES += cmd-part_acorn_mod-partmap_acorn.lst
+FSFILES += fs-part_acorn_mod-partmap_acorn.lst
+PARTTOOLFILES += parttool-part_acorn_mod-partmap_acorn.lst
+PARTMAPFILES += partmap-part_acorn_mod-partmap_acorn.lst
+HANDLERFILES += handler-part_acorn_mod-partmap_acorn.lst
+
+cmd-part_acorn_mod-partmap_acorn.lst: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_acorn_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh part_acorn > $@ || (rm -f $@; exit 1)
+
+fs-part_acorn_mod-partmap_acorn.lst: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_acorn_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh part_acorn > $@ || (rm -f $@; exit 1)
+
+parttool-part_acorn_mod-partmap_acorn.lst: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_acorn_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh part_acorn > $@ || (rm -f $@; exit 1)
+
+partmap-part_acorn_mod-partmap_acorn.lst: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_acorn_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh part_acorn > $@ || (rm -f $@; exit 1)
+
+handler-part_acorn_mod-partmap_acorn.lst: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_acorn_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh part_acorn > $@ || (rm -f $@; exit 1)
+
+part_acorn_mod_CFLAGS = $(COMMON_CFLAGS)
+part_acorn_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_gpt.mod
+part_gpt_mod_SOURCES = partmap/gpt.c
+
+clean-module-part_gpt.mod.1:
+	rm -f part_gpt.mod mod-part_gpt.o mod-part_gpt.c pre-part_gpt.o part_gpt_mod-partmap_gpt.o und-part_gpt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_gpt.mod.1
+
+ifneq ($(part_gpt_mod_EXPORTS),no)
+clean-module-part_gpt.mod-symbol.1:
+	rm -f def-part_gpt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_gpt.mod-symbol.1
+DEFSYMFILES += def-part_gpt.lst
+endif
+mostlyclean-module-part_gpt.mod.1:
+	rm -f part_gpt_mod-partmap_gpt.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-part_gpt.mod.1
+UNDSYMFILES += und-part_gpt.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+part_gpt.mod: pre-part_gpt.o mod-part_gpt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(part_gpt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-part_gpt.o mod-part_gpt.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+part_gpt.mod: pre-part_gpt.o mod-part_gpt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(part_gpt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-part_gpt.o mod-part_gpt.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-part_gpt.o: $(part_gpt_mod_DEPENDENCIES) part_gpt_mod-partmap_gpt.o
+	-rm -f $@
+	$(TARGET_CC) $(part_gpt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ part_gpt_mod-partmap_gpt.o
+
+mod-part_gpt.o: mod-part_gpt.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(part_gpt_mod_CFLAGS) -c -o $@ $<
+
+mod-part_gpt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'part_gpt' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(part_gpt_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-part_gpt.lst: pre-part_gpt.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 part_gpt/' > $@
+else
+def-part_gpt.lst: pre-part_gpt.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 part_gpt/' > $@
+endif
+endif
+
+und-part_gpt.lst: pre-part_gpt.o
+	echo 'part_gpt' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+part_gpt_mod-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES)
+	$(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_gpt_mod_CFLAGS) -MD -c -o $@ $<
+-include part_gpt_mod-partmap_gpt.d
+
+clean-module-part_gpt_mod-partmap_gpt-extra.1:
+	rm -f cmd-part_gpt_mod-partmap_gpt.lst fs-part_gpt_mod-partmap_gpt.lst partmap-part_gpt_mod-partmap_gpt.lst handler-part_gpt_mod-partmap_gpt.lst parttool-part_gpt_mod-partmap_gpt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-part_gpt_mod-partmap_gpt-extra.1
+
+COMMANDFILES += cmd-part_gpt_mod-partmap_gpt.lst
+FSFILES += fs-part_gpt_mod-partmap_gpt.lst
+PARTTOOLFILES += parttool-part_gpt_mod-partmap_gpt.lst
+PARTMAPFILES += partmap-part_gpt_mod-partmap_gpt.lst
+HANDLERFILES += handler-part_gpt_mod-partmap_gpt.lst
+
+cmd-part_gpt_mod-partmap_gpt.lst: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_gpt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh part_gpt > $@ || (rm -f $@; exit 1)
+
+fs-part_gpt_mod-partmap_gpt.lst: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_gpt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh part_gpt > $@ || (rm -f $@; exit 1)
+
+parttool-part_gpt_mod-partmap_gpt.lst: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_gpt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh part_gpt > $@ || (rm -f $@; exit 1)
+
+partmap-part_gpt_mod-partmap_gpt.lst: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_gpt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh part_gpt > $@ || (rm -f $@; exit 1)
+
+handler-part_gpt_mod-partmap_gpt.lst: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(part_gpt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh part_gpt > $@ || (rm -f $@; exit 1)
+
+part_gpt_mod_CFLAGS = $(COMMON_CFLAGS)
+part_gpt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Special disk structures and generic drivers
+
+pkglib_MODULES += raid.mod raid5rec.mod raid6rec.mod mdraid.mod dm_nv.mod \
+	lvm.mod scsi.mod
+
+# For raid.mod
+raid_mod_SOURCES = disk/raid.c
+
+clean-module-raid.mod.1:
+	rm -f raid.mod mod-raid.o mod-raid.c pre-raid.o raid_mod-disk_raid.o und-raid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-raid.mod.1
+
+ifneq ($(raid_mod_EXPORTS),no)
+clean-module-raid.mod-symbol.1:
+	rm -f def-raid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-raid.mod-symbol.1
+DEFSYMFILES += def-raid.lst
+endif
+mostlyclean-module-raid.mod.1:
+	rm -f raid_mod-disk_raid.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-raid.mod.1
+UNDSYMFILES += und-raid.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+raid.mod: pre-raid.o mod-raid.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(raid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-raid.o mod-raid.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+raid.mod: pre-raid.o mod-raid.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(raid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-raid.o mod-raid.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-raid.o: $(raid_mod_DEPENDENCIES) raid_mod-disk_raid.o
+	-rm -f $@
+	$(TARGET_CC) $(raid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ raid_mod-disk_raid.o
+
+mod-raid.o: mod-raid.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -c -o $@ $<
+
+mod-raid.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'raid' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(raid_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-raid.lst: pre-raid.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 raid/' > $@
+else
+def-raid.lst: pre-raid.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 raid/' > $@
+endif
+endif
+
+und-raid.lst: pre-raid.o
+	echo 'raid' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+raid_mod-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -MD -c -o $@ $<
+-include raid_mod-disk_raid.d
+
+clean-module-raid_mod-disk_raid-extra.1:
+	rm -f cmd-raid_mod-disk_raid.lst fs-raid_mod-disk_raid.lst partmap-raid_mod-disk_raid.lst handler-raid_mod-disk_raid.lst parttool-raid_mod-disk_raid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-raid_mod-disk_raid-extra.1
+
+COMMANDFILES += cmd-raid_mod-disk_raid.lst
+FSFILES += fs-raid_mod-disk_raid.lst
+PARTTOOLFILES += parttool-raid_mod-disk_raid.lst
+PARTMAPFILES += partmap-raid_mod-disk_raid.lst
+HANDLERFILES += handler-raid_mod-disk_raid.lst
+
+cmd-raid_mod-disk_raid.lst: disk/raid.c $(disk/raid.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh raid > $@ || (rm -f $@; exit 1)
+
+fs-raid_mod-disk_raid.lst: disk/raid.c $(disk/raid.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh raid > $@ || (rm -f $@; exit 1)
+
+parttool-raid_mod-disk_raid.lst: disk/raid.c $(disk/raid.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh raid > $@ || (rm -f $@; exit 1)
+
+partmap-raid_mod-disk_raid.lst: disk/raid.c $(disk/raid.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh raid > $@ || (rm -f $@; exit 1)
+
+handler-raid_mod-disk_raid.lst: disk/raid.c $(disk/raid.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh raid > $@ || (rm -f $@; exit 1)
+
+raid_mod_CFLAGS = $(COMMON_CFLAGS)
+raid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For raid5rec.mod
+raid5rec_mod_SOURCES = disk/raid5_recover.c
+
+clean-module-raid5rec.mod.1:
+	rm -f raid5rec.mod mod-raid5rec.o mod-raid5rec.c pre-raid5rec.o raid5rec_mod-disk_raid5_recover.o und-raid5rec.lst
+
+CLEAN_MODULE_TARGETS += clean-module-raid5rec.mod.1
+
+ifneq ($(raid5rec_mod_EXPORTS),no)
+clean-module-raid5rec.mod-symbol.1:
+	rm -f def-raid5rec.lst
+
+CLEAN_MODULE_TARGETS += clean-module-raid5rec.mod-symbol.1
+DEFSYMFILES += def-raid5rec.lst
+endif
+mostlyclean-module-raid5rec.mod.1:
+	rm -f raid5rec_mod-disk_raid5_recover.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-raid5rec.mod.1
+UNDSYMFILES += und-raid5rec.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+raid5rec.mod: pre-raid5rec.o mod-raid5rec.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(raid5rec_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-raid5rec.o mod-raid5rec.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+raid5rec.mod: pre-raid5rec.o mod-raid5rec.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(raid5rec_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-raid5rec.o mod-raid5rec.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-raid5rec.o: $(raid5rec_mod_DEPENDENCIES) raid5rec_mod-disk_raid5_recover.o
+	-rm -f $@
+	$(TARGET_CC) $(raid5rec_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ raid5rec_mod-disk_raid5_recover.o
+
+mod-raid5rec.o: mod-raid5rec.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid5rec_mod_CFLAGS) -c -o $@ $<
+
+mod-raid5rec.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'raid5rec' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(raid5rec_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-raid5rec.lst: pre-raid5rec.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 raid5rec/' > $@
+else
+def-raid5rec.lst: pre-raid5rec.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 raid5rec/' > $@
+endif
+endif
+
+und-raid5rec.lst: pre-raid5rec.o
+	echo 'raid5rec' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+raid5rec_mod-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid5rec_mod_CFLAGS) -MD -c -o $@ $<
+-include raid5rec_mod-disk_raid5_recover.d
+
+clean-module-raid5rec_mod-disk_raid5_recover-extra.1:
+	rm -f cmd-raid5rec_mod-disk_raid5_recover.lst fs-raid5rec_mod-disk_raid5_recover.lst partmap-raid5rec_mod-disk_raid5_recover.lst handler-raid5rec_mod-disk_raid5_recover.lst parttool-raid5rec_mod-disk_raid5_recover.lst
+
+CLEAN_MODULE_TARGETS += clean-module-raid5rec_mod-disk_raid5_recover-extra.1
+
+COMMANDFILES += cmd-raid5rec_mod-disk_raid5_recover.lst
+FSFILES += fs-raid5rec_mod-disk_raid5_recover.lst
+PARTTOOLFILES += parttool-raid5rec_mod-disk_raid5_recover.lst
+PARTMAPFILES += partmap-raid5rec_mod-disk_raid5_recover.lst
+HANDLERFILES += handler-raid5rec_mod-disk_raid5_recover.lst
+
+cmd-raid5rec_mod-disk_raid5_recover.lst: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid5rec_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh raid5rec > $@ || (rm -f $@; exit 1)
+
+fs-raid5rec_mod-disk_raid5_recover.lst: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid5rec_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh raid5rec > $@ || (rm -f $@; exit 1)
+
+parttool-raid5rec_mod-disk_raid5_recover.lst: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid5rec_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh raid5rec > $@ || (rm -f $@; exit 1)
+
+partmap-raid5rec_mod-disk_raid5_recover.lst: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid5rec_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh raid5rec > $@ || (rm -f $@; exit 1)
+
+handler-raid5rec_mod-disk_raid5_recover.lst: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid5rec_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh raid5rec > $@ || (rm -f $@; exit 1)
+
+raid5rec_mod_CFLAGS = $(COMMON_CFLAGS)
+raid5rec_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For raid6rec.mod
+raid6rec_mod_SOURCES = disk/raid6_recover.c
+
+clean-module-raid6rec.mod.1:
+	rm -f raid6rec.mod mod-raid6rec.o mod-raid6rec.c pre-raid6rec.o raid6rec_mod-disk_raid6_recover.o und-raid6rec.lst
+
+CLEAN_MODULE_TARGETS += clean-module-raid6rec.mod.1
+
+ifneq ($(raid6rec_mod_EXPORTS),no)
+clean-module-raid6rec.mod-symbol.1:
+	rm -f def-raid6rec.lst
+
+CLEAN_MODULE_TARGETS += clean-module-raid6rec.mod-symbol.1
+DEFSYMFILES += def-raid6rec.lst
+endif
+mostlyclean-module-raid6rec.mod.1:
+	rm -f raid6rec_mod-disk_raid6_recover.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-raid6rec.mod.1
+UNDSYMFILES += und-raid6rec.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+raid6rec.mod: pre-raid6rec.o mod-raid6rec.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(raid6rec_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-raid6rec.o mod-raid6rec.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+raid6rec.mod: pre-raid6rec.o mod-raid6rec.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(raid6rec_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-raid6rec.o mod-raid6rec.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-raid6rec.o: $(raid6rec_mod_DEPENDENCIES) raid6rec_mod-disk_raid6_recover.o
+	-rm -f $@
+	$(TARGET_CC) $(raid6rec_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ raid6rec_mod-disk_raid6_recover.o
+
+mod-raid6rec.o: mod-raid6rec.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid6rec_mod_CFLAGS) -c -o $@ $<
+
+mod-raid6rec.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'raid6rec' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(raid6rec_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-raid6rec.lst: pre-raid6rec.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 raid6rec/' > $@
+else
+def-raid6rec.lst: pre-raid6rec.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 raid6rec/' > $@
+endif
+endif
+
+und-raid6rec.lst: pre-raid6rec.o
+	echo 'raid6rec' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+raid6rec_mod-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid6rec_mod_CFLAGS) -MD -c -o $@ $<
+-include raid6rec_mod-disk_raid6_recover.d
+
+clean-module-raid6rec_mod-disk_raid6_recover-extra.1:
+	rm -f cmd-raid6rec_mod-disk_raid6_recover.lst fs-raid6rec_mod-disk_raid6_recover.lst partmap-raid6rec_mod-disk_raid6_recover.lst handler-raid6rec_mod-disk_raid6_recover.lst parttool-raid6rec_mod-disk_raid6_recover.lst
+
+CLEAN_MODULE_TARGETS += clean-module-raid6rec_mod-disk_raid6_recover-extra.1
+
+COMMANDFILES += cmd-raid6rec_mod-disk_raid6_recover.lst
+FSFILES += fs-raid6rec_mod-disk_raid6_recover.lst
+PARTTOOLFILES += parttool-raid6rec_mod-disk_raid6_recover.lst
+PARTMAPFILES += partmap-raid6rec_mod-disk_raid6_recover.lst
+HANDLERFILES += handler-raid6rec_mod-disk_raid6_recover.lst
+
+cmd-raid6rec_mod-disk_raid6_recover.lst: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid6rec_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh raid6rec > $@ || (rm -f $@; exit 1)
+
+fs-raid6rec_mod-disk_raid6_recover.lst: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid6rec_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh raid6rec > $@ || (rm -f $@; exit 1)
+
+parttool-raid6rec_mod-disk_raid6_recover.lst: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid6rec_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh raid6rec > $@ || (rm -f $@; exit 1)
+
+partmap-raid6rec_mod-disk_raid6_recover.lst: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid6rec_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh raid6rec > $@ || (rm -f $@; exit 1)
+
+handler-raid6rec_mod-disk_raid6_recover.lst: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(raid6rec_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh raid6rec > $@ || (rm -f $@; exit 1)
+
+raid6rec_mod_CFLAGS = $(COMMON_CFLAGS)
+raid6rec_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mdraid.mod
+mdraid_mod_SOURCES = disk/mdraid_linux.c
+
+clean-module-mdraid.mod.1:
+	rm -f mdraid.mod mod-mdraid.o mod-mdraid.c pre-mdraid.o mdraid_mod-disk_mdraid_linux.o und-mdraid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mdraid.mod.1
+
+ifneq ($(mdraid_mod_EXPORTS),no)
+clean-module-mdraid.mod-symbol.1:
+	rm -f def-mdraid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mdraid.mod-symbol.1
+DEFSYMFILES += def-mdraid.lst
+endif
+mostlyclean-module-mdraid.mod.1:
+	rm -f mdraid_mod-disk_mdraid_linux.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-mdraid.mod.1
+UNDSYMFILES += und-mdraid.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+mdraid.mod: pre-mdraid.o mod-mdraid.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(mdraid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-mdraid.o mod-mdraid.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+mdraid.mod: pre-mdraid.o mod-mdraid.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(mdraid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-mdraid.o mod-mdraid.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-mdraid.o: $(mdraid_mod_DEPENDENCIES) mdraid_mod-disk_mdraid_linux.o
+	-rm -f $@
+	$(TARGET_CC) $(mdraid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ mdraid_mod-disk_mdraid_linux.o
+
+mod-mdraid.o: mod-mdraid.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(mdraid_mod_CFLAGS) -c -o $@ $<
+
+mod-mdraid.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'mdraid' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(mdraid_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-mdraid.lst: pre-mdraid.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 mdraid/' > $@
+else
+def-mdraid.lst: pre-mdraid.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 mdraid/' > $@
+endif
+endif
+
+und-mdraid.lst: pre-mdraid.o
+	echo 'mdraid' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+mdraid_mod-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mdraid_mod_CFLAGS) -MD -c -o $@ $<
+-include mdraid_mod-disk_mdraid_linux.d
+
+clean-module-mdraid_mod-disk_mdraid_linux-extra.1:
+	rm -f cmd-mdraid_mod-disk_mdraid_linux.lst fs-mdraid_mod-disk_mdraid_linux.lst partmap-mdraid_mod-disk_mdraid_linux.lst handler-mdraid_mod-disk_mdraid_linux.lst parttool-mdraid_mod-disk_mdraid_linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mdraid_mod-disk_mdraid_linux-extra.1
+
+COMMANDFILES += cmd-mdraid_mod-disk_mdraid_linux.lst
+FSFILES += fs-mdraid_mod-disk_mdraid_linux.lst
+PARTTOOLFILES += parttool-mdraid_mod-disk_mdraid_linux.lst
+PARTMAPFILES += partmap-mdraid_mod-disk_mdraid_linux.lst
+HANDLERFILES += handler-mdraid_mod-disk_mdraid_linux.lst
+
+cmd-mdraid_mod-disk_mdraid_linux.lst: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mdraid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mdraid > $@ || (rm -f $@; exit 1)
+
+fs-mdraid_mod-disk_mdraid_linux.lst: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mdraid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mdraid > $@ || (rm -f $@; exit 1)
+
+parttool-mdraid_mod-disk_mdraid_linux.lst: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mdraid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mdraid > $@ || (rm -f $@; exit 1)
+
+partmap-mdraid_mod-disk_mdraid_linux.lst: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mdraid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mdraid > $@ || (rm -f $@; exit 1)
+
+handler-mdraid_mod-disk_mdraid_linux.lst: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mdraid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mdraid > $@ || (rm -f $@; exit 1)
+
+mdraid_mod_CFLAGS = $(COMMON_CFLAGS)
+mdraid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For dm_nv.mod
+dm_nv_mod_SOURCES = disk/dmraid_nvidia.c
+
+clean-module-dm_nv.mod.1:
+	rm -f dm_nv.mod mod-dm_nv.o mod-dm_nv.c pre-dm_nv.o dm_nv_mod-disk_dmraid_nvidia.o und-dm_nv.lst
+
+CLEAN_MODULE_TARGETS += clean-module-dm_nv.mod.1
+
+ifneq ($(dm_nv_mod_EXPORTS),no)
+clean-module-dm_nv.mod-symbol.1:
+	rm -f def-dm_nv.lst
+
+CLEAN_MODULE_TARGETS += clean-module-dm_nv.mod-symbol.1
+DEFSYMFILES += def-dm_nv.lst
+endif
+mostlyclean-module-dm_nv.mod.1:
+	rm -f dm_nv_mod-disk_dmraid_nvidia.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-dm_nv.mod.1
+UNDSYMFILES += und-dm_nv.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+dm_nv.mod: pre-dm_nv.o mod-dm_nv.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(dm_nv_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-dm_nv.o mod-dm_nv.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+dm_nv.mod: pre-dm_nv.o mod-dm_nv.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(dm_nv_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-dm_nv.o mod-dm_nv.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-dm_nv.o: $(dm_nv_mod_DEPENDENCIES) dm_nv_mod-disk_dmraid_nvidia.o
+	-rm -f $@
+	$(TARGET_CC) $(dm_nv_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ dm_nv_mod-disk_dmraid_nvidia.o
+
+mod-dm_nv.o: mod-dm_nv.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(dm_nv_mod_CFLAGS) -c -o $@ $<
+
+mod-dm_nv.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'dm_nv' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(dm_nv_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-dm_nv.lst: pre-dm_nv.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 dm_nv/' > $@
+else
+def-dm_nv.lst: pre-dm_nv.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 dm_nv/' > $@
+endif
+endif
+
+und-dm_nv.lst: pre-dm_nv.o
+	echo 'dm_nv' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+dm_nv_mod-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(dm_nv_mod_CFLAGS) -MD -c -o $@ $<
+-include dm_nv_mod-disk_dmraid_nvidia.d
+
+clean-module-dm_nv_mod-disk_dmraid_nvidia-extra.1:
+	rm -f cmd-dm_nv_mod-disk_dmraid_nvidia.lst fs-dm_nv_mod-disk_dmraid_nvidia.lst partmap-dm_nv_mod-disk_dmraid_nvidia.lst handler-dm_nv_mod-disk_dmraid_nvidia.lst parttool-dm_nv_mod-disk_dmraid_nvidia.lst
+
+CLEAN_MODULE_TARGETS += clean-module-dm_nv_mod-disk_dmraid_nvidia-extra.1
+
+COMMANDFILES += cmd-dm_nv_mod-disk_dmraid_nvidia.lst
+FSFILES += fs-dm_nv_mod-disk_dmraid_nvidia.lst
+PARTTOOLFILES += parttool-dm_nv_mod-disk_dmraid_nvidia.lst
+PARTMAPFILES += partmap-dm_nv_mod-disk_dmraid_nvidia.lst
+HANDLERFILES += handler-dm_nv_mod-disk_dmraid_nvidia.lst
+
+cmd-dm_nv_mod-disk_dmraid_nvidia.lst: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(dm_nv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh dm_nv > $@ || (rm -f $@; exit 1)
+
+fs-dm_nv_mod-disk_dmraid_nvidia.lst: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(dm_nv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh dm_nv > $@ || (rm -f $@; exit 1)
+
+parttool-dm_nv_mod-disk_dmraid_nvidia.lst: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(dm_nv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh dm_nv > $@ || (rm -f $@; exit 1)
+
+partmap-dm_nv_mod-disk_dmraid_nvidia.lst: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(dm_nv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh dm_nv > $@ || (rm -f $@; exit 1)
+
+handler-dm_nv_mod-disk_dmraid_nvidia.lst: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(dm_nv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh dm_nv > $@ || (rm -f $@; exit 1)
+
+dm_nv_mod_CFLAGS = $(COMMON_CFLAGS)
+dm_nv_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lvm.mod
+lvm_mod_SOURCES = disk/lvm.c
+
+clean-module-lvm.mod.1:
+	rm -f lvm.mod mod-lvm.o mod-lvm.c pre-lvm.o lvm_mod-disk_lvm.o und-lvm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lvm.mod.1
+
+ifneq ($(lvm_mod_EXPORTS),no)
+clean-module-lvm.mod-symbol.1:
+	rm -f def-lvm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lvm.mod-symbol.1
+DEFSYMFILES += def-lvm.lst
+endif
+mostlyclean-module-lvm.mod.1:
+	rm -f lvm_mod-disk_lvm.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-lvm.mod.1
+UNDSYMFILES += und-lvm.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+lvm.mod: pre-lvm.o mod-lvm.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(lvm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-lvm.o mod-lvm.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+lvm.mod: pre-lvm.o mod-lvm.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(lvm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-lvm.o mod-lvm.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-lvm.o: $(lvm_mod_DEPENDENCIES) lvm_mod-disk_lvm.o
+	-rm -f $@
+	$(TARGET_CC) $(lvm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lvm_mod-disk_lvm.o
+
+mod-lvm.o: mod-lvm.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -c -o $@ $<
+
+mod-lvm.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'lvm' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(lvm_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-lvm.lst: pre-lvm.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lvm/' > $@
+else
+def-lvm.lst: pre-lvm.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 lvm/' > $@
+endif
+endif
+
+und-lvm.lst: pre-lvm.o
+	echo 'lvm' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+lvm_mod-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -MD -c -o $@ $<
+-include lvm_mod-disk_lvm.d
+
+clean-module-lvm_mod-disk_lvm-extra.1:
+	rm -f cmd-lvm_mod-disk_lvm.lst fs-lvm_mod-disk_lvm.lst partmap-lvm_mod-disk_lvm.lst handler-lvm_mod-disk_lvm.lst parttool-lvm_mod-disk_lvm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lvm_mod-disk_lvm-extra.1
+
+COMMANDFILES += cmd-lvm_mod-disk_lvm.lst
+FSFILES += fs-lvm_mod-disk_lvm.lst
+PARTTOOLFILES += parttool-lvm_mod-disk_lvm.lst
+PARTMAPFILES += partmap-lvm_mod-disk_lvm.lst
+HANDLERFILES += handler-lvm_mod-disk_lvm.lst
+
+cmd-lvm_mod-disk_lvm.lst: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh lvm > $@ || (rm -f $@; exit 1)
+
+fs-lvm_mod-disk_lvm.lst: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh lvm > $@ || (rm -f $@; exit 1)
+
+parttool-lvm_mod-disk_lvm.lst: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh lvm > $@ || (rm -f $@; exit 1)
+
+partmap-lvm_mod-disk_lvm.lst: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh lvm > $@ || (rm -f $@; exit 1)
+
+handler-lvm_mod-disk_lvm.lst: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh lvm > $@ || (rm -f $@; exit 1)
+
+lvm_mod_CFLAGS = $(COMMON_CFLAGS)
+lvm_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For scsi.mod
+scsi_mod_SOURCES = disk/scsi.c
+
+clean-module-scsi.mod.1:
+	rm -f scsi.mod mod-scsi.o mod-scsi.c pre-scsi.o scsi_mod-disk_scsi.o und-scsi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-scsi.mod.1
+
+ifneq ($(scsi_mod_EXPORTS),no)
+clean-module-scsi.mod-symbol.1:
+	rm -f def-scsi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-scsi.mod-symbol.1
+DEFSYMFILES += def-scsi.lst
+endif
+mostlyclean-module-scsi.mod.1:
+	rm -f scsi_mod-disk_scsi.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-scsi.mod.1
+UNDSYMFILES += und-scsi.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+scsi.mod: pre-scsi.o mod-scsi.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(scsi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-scsi.o mod-scsi.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+scsi.mod: pre-scsi.o mod-scsi.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(scsi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-scsi.o mod-scsi.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-scsi.o: $(scsi_mod_DEPENDENCIES) scsi_mod-disk_scsi.o
+	-rm -f $@
+	$(TARGET_CC) $(scsi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ scsi_mod-disk_scsi.o
+
+mod-scsi.o: mod-scsi.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(scsi_mod_CFLAGS) -c -o $@ $<
+
+mod-scsi.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'scsi' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(scsi_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-scsi.lst: pre-scsi.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 scsi/' > $@
+else
+def-scsi.lst: pre-scsi.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 scsi/' > $@
+endif
+endif
+
+und-scsi.lst: pre-scsi.o
+	echo 'scsi' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+scsi_mod-disk_scsi.o: disk/scsi.c $(disk/scsi.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(scsi_mod_CFLAGS) -MD -c -o $@ $<
+-include scsi_mod-disk_scsi.d
+
+clean-module-scsi_mod-disk_scsi-extra.1:
+	rm -f cmd-scsi_mod-disk_scsi.lst fs-scsi_mod-disk_scsi.lst partmap-scsi_mod-disk_scsi.lst handler-scsi_mod-disk_scsi.lst parttool-scsi_mod-disk_scsi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-scsi_mod-disk_scsi-extra.1
+
+COMMANDFILES += cmd-scsi_mod-disk_scsi.lst
+FSFILES += fs-scsi_mod-disk_scsi.lst
+PARTTOOLFILES += parttool-scsi_mod-disk_scsi.lst
+PARTMAPFILES += partmap-scsi_mod-disk_scsi.lst
+HANDLERFILES += handler-scsi_mod-disk_scsi.lst
+
+cmd-scsi_mod-disk_scsi.lst: disk/scsi.c $(disk/scsi.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(scsi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh scsi > $@ || (rm -f $@; exit 1)
+
+fs-scsi_mod-disk_scsi.lst: disk/scsi.c $(disk/scsi.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(scsi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh scsi > $@ || (rm -f $@; exit 1)
+
+parttool-scsi_mod-disk_scsi.lst: disk/scsi.c $(disk/scsi.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(scsi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh scsi > $@ || (rm -f $@; exit 1)
+
+partmap-scsi_mod-disk_scsi.lst: disk/scsi.c $(disk/scsi.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(scsi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh scsi > $@ || (rm -f $@; exit 1)
+
+handler-scsi_mod-disk_scsi.lst: disk/scsi.c $(disk/scsi.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(scsi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh scsi > $@ || (rm -f $@; exit 1)
+
+scsi_mod_CFLAGS = $(COMMON_CFLAGS)
+scsi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Commands.
+pkglib_MODULES += minicmd.mod extcmd.mod hello.mod handler.mod	\
+	ls.mod cmp.mod cat.mod help.mod search.mod loopback.mod	\
+	fs_file.mod fs_uuid.mod configfile.mod echo.mod		\
+	terminfo.mod test.mod blocklist.mod hexdump.mod		\
+	read.mod sleep.mod loadenv.mod crc.mod parttool.mod	\
+	msdospart.mod memrw.mod normal.mod sh.mod 		\
+	gptsync.mod true.mod probe.mod password.mod		\
+	keystatus.mod
+
+# For password.mod.
+password_mod_SOURCES = commands/password.c
+
+clean-module-password.mod.1:
+	rm -f password.mod mod-password.o mod-password.c pre-password.o password_mod-commands_password.o und-password.lst
+
+CLEAN_MODULE_TARGETS += clean-module-password.mod.1
+
+ifneq ($(password_mod_EXPORTS),no)
+clean-module-password.mod-symbol.1:
+	rm -f def-password.lst
+
+CLEAN_MODULE_TARGETS += clean-module-password.mod-symbol.1
+DEFSYMFILES += def-password.lst
+endif
+mostlyclean-module-password.mod.1:
+	rm -f password_mod-commands_password.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-password.mod.1
+UNDSYMFILES += und-password.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+password.mod: pre-password.o mod-password.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(password_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-password.o mod-password.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+password.mod: pre-password.o mod-password.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(password_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-password.o mod-password.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-password.o: $(password_mod_DEPENDENCIES) password_mod-commands_password.o
+	-rm -f $@
+	$(TARGET_CC) $(password_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ password_mod-commands_password.o
+
+mod-password.o: mod-password.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(password_mod_CFLAGS) -c -o $@ $<
+
+mod-password.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'password' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(password_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-password.lst: pre-password.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 password/' > $@
+else
+def-password.lst: pre-password.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 password/' > $@
+endif
+endif
+
+und-password.lst: pre-password.o
+	echo 'password' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+password_mod-commands_password.o: commands/password.c $(commands/password.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(password_mod_CFLAGS) -MD -c -o $@ $<
+-include password_mod-commands_password.d
+
+clean-module-password_mod-commands_password-extra.1:
+	rm -f cmd-password_mod-commands_password.lst fs-password_mod-commands_password.lst partmap-password_mod-commands_password.lst handler-password_mod-commands_password.lst parttool-password_mod-commands_password.lst
+
+CLEAN_MODULE_TARGETS += clean-module-password_mod-commands_password-extra.1
+
+COMMANDFILES += cmd-password_mod-commands_password.lst
+FSFILES += fs-password_mod-commands_password.lst
+PARTTOOLFILES += parttool-password_mod-commands_password.lst
+PARTMAPFILES += partmap-password_mod-commands_password.lst
+HANDLERFILES += handler-password_mod-commands_password.lst
+
+cmd-password_mod-commands_password.lst: commands/password.c $(commands/password.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(password_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh password > $@ || (rm -f $@; exit 1)
+
+fs-password_mod-commands_password.lst: commands/password.c $(commands/password.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(password_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh password > $@ || (rm -f $@; exit 1)
+
+parttool-password_mod-commands_password.lst: commands/password.c $(commands/password.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(password_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh password > $@ || (rm -f $@; exit 1)
+
+partmap-password_mod-commands_password.lst: commands/password.c $(commands/password.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(password_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh password > $@ || (rm -f $@; exit 1)
+
+handler-password_mod-commands_password.lst: commands/password.c $(commands/password.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(password_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh password > $@ || (rm -f $@; exit 1)
+
+password_mod_CFLAGS = $(COMMON_CFLAGS)
+password_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For gptsync.mod.
+gptsync_mod_SOURCES = commands/gptsync.c
+
+clean-module-gptsync.mod.1:
+	rm -f gptsync.mod mod-gptsync.o mod-gptsync.c pre-gptsync.o gptsync_mod-commands_gptsync.o und-gptsync.lst
+
+CLEAN_MODULE_TARGETS += clean-module-gptsync.mod.1
+
+ifneq ($(gptsync_mod_EXPORTS),no)
+clean-module-gptsync.mod-symbol.1:
+	rm -f def-gptsync.lst
+
+CLEAN_MODULE_TARGETS += clean-module-gptsync.mod-symbol.1
+DEFSYMFILES += def-gptsync.lst
+endif
+mostlyclean-module-gptsync.mod.1:
+	rm -f gptsync_mod-commands_gptsync.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-gptsync.mod.1
+UNDSYMFILES += und-gptsync.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+gptsync.mod: pre-gptsync.o mod-gptsync.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(gptsync_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-gptsync.o mod-gptsync.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+gptsync.mod: pre-gptsync.o mod-gptsync.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(gptsync_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-gptsync.o mod-gptsync.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-gptsync.o: $(gptsync_mod_DEPENDENCIES) gptsync_mod-commands_gptsync.o
+	-rm -f $@
+	$(TARGET_CC) $(gptsync_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ gptsync_mod-commands_gptsync.o
+
+mod-gptsync.o: mod-gptsync.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gptsync_mod_CFLAGS) -c -o $@ $<
+
+mod-gptsync.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'gptsync' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(gptsync_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-gptsync.lst: pre-gptsync.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 gptsync/' > $@
+else
+def-gptsync.lst: pre-gptsync.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 gptsync/' > $@
+endif
+endif
+
+und-gptsync.lst: pre-gptsync.o
+	echo 'gptsync' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+gptsync_mod-commands_gptsync.o: commands/gptsync.c $(commands/gptsync.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gptsync_mod_CFLAGS) -MD -c -o $@ $<
+-include gptsync_mod-commands_gptsync.d
+
+clean-module-gptsync_mod-commands_gptsync-extra.1:
+	rm -f cmd-gptsync_mod-commands_gptsync.lst fs-gptsync_mod-commands_gptsync.lst partmap-gptsync_mod-commands_gptsync.lst handler-gptsync_mod-commands_gptsync.lst parttool-gptsync_mod-commands_gptsync.lst
+
+CLEAN_MODULE_TARGETS += clean-module-gptsync_mod-commands_gptsync-extra.1
+
+COMMANDFILES += cmd-gptsync_mod-commands_gptsync.lst
+FSFILES += fs-gptsync_mod-commands_gptsync.lst
+PARTTOOLFILES += parttool-gptsync_mod-commands_gptsync.lst
+PARTMAPFILES += partmap-gptsync_mod-commands_gptsync.lst
+HANDLERFILES += handler-gptsync_mod-commands_gptsync.lst
+
+cmd-gptsync_mod-commands_gptsync.lst: commands/gptsync.c $(commands/gptsync.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gptsync_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh gptsync > $@ || (rm -f $@; exit 1)
+
+fs-gptsync_mod-commands_gptsync.lst: commands/gptsync.c $(commands/gptsync.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gptsync_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh gptsync > $@ || (rm -f $@; exit 1)
+
+parttool-gptsync_mod-commands_gptsync.lst: commands/gptsync.c $(commands/gptsync.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gptsync_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh gptsync > $@ || (rm -f $@; exit 1)
+
+partmap-gptsync_mod-commands_gptsync.lst: commands/gptsync.c $(commands/gptsync.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gptsync_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh gptsync > $@ || (rm -f $@; exit 1)
+
+handler-gptsync_mod-commands_gptsync.lst: commands/gptsync.c $(commands/gptsync.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gptsync_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh gptsync > $@ || (rm -f $@; exit 1)
+
+gptsync_mod_CFLAGS = $(COMMON_CFLAGS)
+gptsync_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For minicmd.mod.
+minicmd_mod_SOURCES = commands/minicmd.c
+
+clean-module-minicmd.mod.1:
+	rm -f minicmd.mod mod-minicmd.o mod-minicmd.c pre-minicmd.o minicmd_mod-commands_minicmd.o und-minicmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-minicmd.mod.1
+
+ifneq ($(minicmd_mod_EXPORTS),no)
+clean-module-minicmd.mod-symbol.1:
+	rm -f def-minicmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-minicmd.mod-symbol.1
+DEFSYMFILES += def-minicmd.lst
+endif
+mostlyclean-module-minicmd.mod.1:
+	rm -f minicmd_mod-commands_minicmd.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-minicmd.mod.1
+UNDSYMFILES += und-minicmd.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+minicmd.mod: pre-minicmd.o mod-minicmd.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(minicmd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-minicmd.o mod-minicmd.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+minicmd.mod: pre-minicmd.o mod-minicmd.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(minicmd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-minicmd.o mod-minicmd.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-minicmd.o: $(minicmd_mod_DEPENDENCIES) minicmd_mod-commands_minicmd.o
+	-rm -f $@
+	$(TARGET_CC) $(minicmd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ minicmd_mod-commands_minicmd.o
+
+mod-minicmd.o: mod-minicmd.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(minicmd_mod_CFLAGS) -c -o $@ $<
+
+mod-minicmd.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'minicmd' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(minicmd_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-minicmd.lst: pre-minicmd.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 minicmd/' > $@
+else
+def-minicmd.lst: pre-minicmd.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 minicmd/' > $@
+endif
+endif
+
+und-minicmd.lst: pre-minicmd.o
+	echo 'minicmd' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+minicmd_mod-commands_minicmd.o: commands/minicmd.c $(commands/minicmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(minicmd_mod_CFLAGS) -MD -c -o $@ $<
+-include minicmd_mod-commands_minicmd.d
+
+clean-module-minicmd_mod-commands_minicmd-extra.1:
+	rm -f cmd-minicmd_mod-commands_minicmd.lst fs-minicmd_mod-commands_minicmd.lst partmap-minicmd_mod-commands_minicmd.lst handler-minicmd_mod-commands_minicmd.lst parttool-minicmd_mod-commands_minicmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-minicmd_mod-commands_minicmd-extra.1
+
+COMMANDFILES += cmd-minicmd_mod-commands_minicmd.lst
+FSFILES += fs-minicmd_mod-commands_minicmd.lst
+PARTTOOLFILES += parttool-minicmd_mod-commands_minicmd.lst
+PARTMAPFILES += partmap-minicmd_mod-commands_minicmd.lst
+HANDLERFILES += handler-minicmd_mod-commands_minicmd.lst
+
+cmd-minicmd_mod-commands_minicmd.lst: commands/minicmd.c $(commands/minicmd.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(minicmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh minicmd > $@ || (rm -f $@; exit 1)
+
+fs-minicmd_mod-commands_minicmd.lst: commands/minicmd.c $(commands/minicmd.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(minicmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh minicmd > $@ || (rm -f $@; exit 1)
+
+parttool-minicmd_mod-commands_minicmd.lst: commands/minicmd.c $(commands/minicmd.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(minicmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh minicmd > $@ || (rm -f $@; exit 1)
+
+partmap-minicmd_mod-commands_minicmd.lst: commands/minicmd.c $(commands/minicmd.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(minicmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh minicmd > $@ || (rm -f $@; exit 1)
+
+handler-minicmd_mod-commands_minicmd.lst: commands/minicmd.c $(commands/minicmd.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(minicmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh minicmd > $@ || (rm -f $@; exit 1)
+
+minicmd_mod_CFLAGS = $(COMMON_CFLAGS)
+minicmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For extcmd.mod.
+extcmd_mod_SOURCES = commands/extcmd.c lib/arg.c
+
+clean-module-extcmd.mod.1:
+	rm -f extcmd.mod mod-extcmd.o mod-extcmd.c pre-extcmd.o extcmd_mod-commands_extcmd.o extcmd_mod-lib_arg.o und-extcmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-extcmd.mod.1
+
+ifneq ($(extcmd_mod_EXPORTS),no)
+clean-module-extcmd.mod-symbol.1:
+	rm -f def-extcmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-extcmd.mod-symbol.1
+DEFSYMFILES += def-extcmd.lst
+endif
+mostlyclean-module-extcmd.mod.1:
+	rm -f extcmd_mod-commands_extcmd.d extcmd_mod-lib_arg.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-extcmd.mod.1
+UNDSYMFILES += und-extcmd.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+extcmd.mod: pre-extcmd.o mod-extcmd.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(extcmd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-extcmd.o mod-extcmd.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+extcmd.mod: pre-extcmd.o mod-extcmd.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(extcmd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-extcmd.o mod-extcmd.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-extcmd.o: $(extcmd_mod_DEPENDENCIES) extcmd_mod-commands_extcmd.o extcmd_mod-lib_arg.o
+	-rm -f $@
+	$(TARGET_CC) $(extcmd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ extcmd_mod-commands_extcmd.o extcmd_mod-lib_arg.o
+
+mod-extcmd.o: mod-extcmd.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -c -o $@ $<
+
+mod-extcmd.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'extcmd' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(extcmd_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-extcmd.lst: pre-extcmd.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 extcmd/' > $@
+else
+def-extcmd.lst: pre-extcmd.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 extcmd/' > $@
+endif
+endif
+
+und-extcmd.lst: pre-extcmd.o
+	echo 'extcmd' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+extcmd_mod-commands_extcmd.o: commands/extcmd.c $(commands/extcmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -MD -c -o $@ $<
+-include extcmd_mod-commands_extcmd.d
+
+clean-module-extcmd_mod-commands_extcmd-extra.1:
+	rm -f cmd-extcmd_mod-commands_extcmd.lst fs-extcmd_mod-commands_extcmd.lst partmap-extcmd_mod-commands_extcmd.lst handler-extcmd_mod-commands_extcmd.lst parttool-extcmd_mod-commands_extcmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-extcmd_mod-commands_extcmd-extra.1
+
+COMMANDFILES += cmd-extcmd_mod-commands_extcmd.lst
+FSFILES += fs-extcmd_mod-commands_extcmd.lst
+PARTTOOLFILES += parttool-extcmd_mod-commands_extcmd.lst
+PARTMAPFILES += partmap-extcmd_mod-commands_extcmd.lst
+HANDLERFILES += handler-extcmd_mod-commands_extcmd.lst
+
+cmd-extcmd_mod-commands_extcmd.lst: commands/extcmd.c $(commands/extcmd.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh extcmd > $@ || (rm -f $@; exit 1)
+
+fs-extcmd_mod-commands_extcmd.lst: commands/extcmd.c $(commands/extcmd.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh extcmd > $@ || (rm -f $@; exit 1)
+
+parttool-extcmd_mod-commands_extcmd.lst: commands/extcmd.c $(commands/extcmd.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh extcmd > $@ || (rm -f $@; exit 1)
+
+partmap-extcmd_mod-commands_extcmd.lst: commands/extcmd.c $(commands/extcmd.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh extcmd > $@ || (rm -f $@; exit 1)
+
+handler-extcmd_mod-commands_extcmd.lst: commands/extcmd.c $(commands/extcmd.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh extcmd > $@ || (rm -f $@; exit 1)
+
+extcmd_mod-lib_arg.o: lib/arg.c $(lib/arg.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -MD -c -o $@ $<
+-include extcmd_mod-lib_arg.d
+
+clean-module-extcmd_mod-lib_arg-extra.1:
+	rm -f cmd-extcmd_mod-lib_arg.lst fs-extcmd_mod-lib_arg.lst partmap-extcmd_mod-lib_arg.lst handler-extcmd_mod-lib_arg.lst parttool-extcmd_mod-lib_arg.lst
+
+CLEAN_MODULE_TARGETS += clean-module-extcmd_mod-lib_arg-extra.1
+
+COMMANDFILES += cmd-extcmd_mod-lib_arg.lst
+FSFILES += fs-extcmd_mod-lib_arg.lst
+PARTTOOLFILES += parttool-extcmd_mod-lib_arg.lst
+PARTMAPFILES += partmap-extcmd_mod-lib_arg.lst
+HANDLERFILES += handler-extcmd_mod-lib_arg.lst
+
+cmd-extcmd_mod-lib_arg.lst: lib/arg.c $(lib/arg.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh extcmd > $@ || (rm -f $@; exit 1)
+
+fs-extcmd_mod-lib_arg.lst: lib/arg.c $(lib/arg.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh extcmd > $@ || (rm -f $@; exit 1)
+
+parttool-extcmd_mod-lib_arg.lst: lib/arg.c $(lib/arg.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh extcmd > $@ || (rm -f $@; exit 1)
+
+partmap-extcmd_mod-lib_arg.lst: lib/arg.c $(lib/arg.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh extcmd > $@ || (rm -f $@; exit 1)
+
+handler-extcmd_mod-lib_arg.lst: lib/arg.c $(lib/arg.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(extcmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh extcmd > $@ || (rm -f $@; exit 1)
+
+extcmd_mod_CFLAGS = $(COMMON_CFLAGS)
+extcmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hello.mod.
+hello_mod_SOURCES = hello/hello.c
+
+clean-module-hello.mod.1:
+	rm -f hello.mod mod-hello.o mod-hello.c pre-hello.o hello_mod-hello_hello.o und-hello.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hello.mod.1
+
+ifneq ($(hello_mod_EXPORTS),no)
+clean-module-hello.mod-symbol.1:
+	rm -f def-hello.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hello.mod-symbol.1
+DEFSYMFILES += def-hello.lst
+endif
+mostlyclean-module-hello.mod.1:
+	rm -f hello_mod-hello_hello.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-hello.mod.1
+UNDSYMFILES += und-hello.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+hello.mod: pre-hello.o mod-hello.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(hello_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-hello.o mod-hello.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+hello.mod: pre-hello.o mod-hello.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(hello_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-hello.o mod-hello.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-hello.o: $(hello_mod_DEPENDENCIES) hello_mod-hello_hello.o
+	-rm -f $@
+	$(TARGET_CC) $(hello_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ hello_mod-hello_hello.o
+
+mod-hello.o: mod-hello.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -c -o $@ $<
+
+mod-hello.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'hello' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(hello_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-hello.lst: pre-hello.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 hello/' > $@
+else
+def-hello.lst: pre-hello.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 hello/' > $@
+endif
+endif
+
+und-hello.lst: pre-hello.o
+	echo 'hello' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+hello_mod-hello_hello.o: hello/hello.c $(hello/hello.c_DEPENDENCIES)
+	$(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -MD -c -o $@ $<
+-include hello_mod-hello_hello.d
+
+clean-module-hello_mod-hello_hello-extra.1:
+	rm -f cmd-hello_mod-hello_hello.lst fs-hello_mod-hello_hello.lst partmap-hello_mod-hello_hello.lst handler-hello_mod-hello_hello.lst parttool-hello_mod-hello_hello.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hello_mod-hello_hello-extra.1
+
+COMMANDFILES += cmd-hello_mod-hello_hello.lst
+FSFILES += fs-hello_mod-hello_hello.lst
+PARTTOOLFILES += parttool-hello_mod-hello_hello.lst
+PARTMAPFILES += partmap-hello_mod-hello_hello.lst
+HANDLERFILES += handler-hello_mod-hello_hello.lst
+
+cmd-hello_mod-hello_hello.lst: hello/hello.c $(hello/hello.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh hello > $@ || (rm -f $@; exit 1)
+
+fs-hello_mod-hello_hello.lst: hello/hello.c $(hello/hello.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh hello > $@ || (rm -f $@; exit 1)
+
+parttool-hello_mod-hello_hello.lst: hello/hello.c $(hello/hello.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh hello > $@ || (rm -f $@; exit 1)
+
+partmap-hello_mod-hello_hello.lst: hello/hello.c $(hello/hello.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh hello > $@ || (rm -f $@; exit 1)
+
+handler-hello_mod-hello_hello.lst: hello/hello.c $(hello/hello.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh hello > $@ || (rm -f $@; exit 1)
+
+hello_mod_CFLAGS = $(COMMON_CFLAGS)
+hello_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For parttool.mod.
+parttool_mod_SOURCES = commands/parttool.c
+
+clean-module-parttool.mod.1:
+	rm -f parttool.mod mod-parttool.o mod-parttool.c pre-parttool.o parttool_mod-commands_parttool.o und-parttool.lst
+
+CLEAN_MODULE_TARGETS += clean-module-parttool.mod.1
+
+ifneq ($(parttool_mod_EXPORTS),no)
+clean-module-parttool.mod-symbol.1:
+	rm -f def-parttool.lst
+
+CLEAN_MODULE_TARGETS += clean-module-parttool.mod-symbol.1
+DEFSYMFILES += def-parttool.lst
+endif
+mostlyclean-module-parttool.mod.1:
+	rm -f parttool_mod-commands_parttool.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-parttool.mod.1
+UNDSYMFILES += und-parttool.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+parttool.mod: pre-parttool.o mod-parttool.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(parttool_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-parttool.o mod-parttool.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+parttool.mod: pre-parttool.o mod-parttool.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(parttool_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-parttool.o mod-parttool.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-parttool.o: $(parttool_mod_DEPENDENCIES) parttool_mod-commands_parttool.o
+	-rm -f $@
+	$(TARGET_CC) $(parttool_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ parttool_mod-commands_parttool.o
+
+mod-parttool.o: mod-parttool.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(parttool_mod_CFLAGS) -c -o $@ $<
+
+mod-parttool.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'parttool' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(parttool_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-parttool.lst: pre-parttool.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 parttool/' > $@
+else
+def-parttool.lst: pre-parttool.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 parttool/' > $@
+endif
+endif
+
+und-parttool.lst: pre-parttool.o
+	echo 'parttool' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+parttool_mod-commands_parttool.o: commands/parttool.c $(commands/parttool.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(parttool_mod_CFLAGS) -MD -c -o $@ $<
+-include parttool_mod-commands_parttool.d
+
+clean-module-parttool_mod-commands_parttool-extra.1:
+	rm -f cmd-parttool_mod-commands_parttool.lst fs-parttool_mod-commands_parttool.lst partmap-parttool_mod-commands_parttool.lst handler-parttool_mod-commands_parttool.lst parttool-parttool_mod-commands_parttool.lst
+
+CLEAN_MODULE_TARGETS += clean-module-parttool_mod-commands_parttool-extra.1
+
+COMMANDFILES += cmd-parttool_mod-commands_parttool.lst
+FSFILES += fs-parttool_mod-commands_parttool.lst
+PARTTOOLFILES += parttool-parttool_mod-commands_parttool.lst
+PARTMAPFILES += partmap-parttool_mod-commands_parttool.lst
+HANDLERFILES += handler-parttool_mod-commands_parttool.lst
+
+cmd-parttool_mod-commands_parttool.lst: commands/parttool.c $(commands/parttool.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(parttool_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh parttool > $@ || (rm -f $@; exit 1)
+
+fs-parttool_mod-commands_parttool.lst: commands/parttool.c $(commands/parttool.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(parttool_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh parttool > $@ || (rm -f $@; exit 1)
+
+parttool-parttool_mod-commands_parttool.lst: commands/parttool.c $(commands/parttool.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(parttool_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh parttool > $@ || (rm -f $@; exit 1)
+
+partmap-parttool_mod-commands_parttool.lst: commands/parttool.c $(commands/parttool.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(parttool_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh parttool > $@ || (rm -f $@; exit 1)
+
+handler-parttool_mod-commands_parttool.lst: commands/parttool.c $(commands/parttool.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(parttool_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh parttool > $@ || (rm -f $@; exit 1)
+
+parttool_mod_CFLAGS = $(COMMON_CFLAGS)
+parttool_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For msdospart.mod.
+msdospart_mod_SOURCES = parttool/msdospart.c
+
+clean-module-msdospart.mod.1:
+	rm -f msdospart.mod mod-msdospart.o mod-msdospart.c pre-msdospart.o msdospart_mod-parttool_msdospart.o und-msdospart.lst
+
+CLEAN_MODULE_TARGETS += clean-module-msdospart.mod.1
+
+ifneq ($(msdospart_mod_EXPORTS),no)
+clean-module-msdospart.mod-symbol.1:
+	rm -f def-msdospart.lst
+
+CLEAN_MODULE_TARGETS += clean-module-msdospart.mod-symbol.1
+DEFSYMFILES += def-msdospart.lst
+endif
+mostlyclean-module-msdospart.mod.1:
+	rm -f msdospart_mod-parttool_msdospart.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-msdospart.mod.1
+UNDSYMFILES += und-msdospart.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+msdospart.mod: pre-msdospart.o mod-msdospart.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(msdospart_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-msdospart.o mod-msdospart.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+msdospart.mod: pre-msdospart.o mod-msdospart.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(msdospart_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-msdospart.o mod-msdospart.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-msdospart.o: $(msdospart_mod_DEPENDENCIES) msdospart_mod-parttool_msdospart.o
+	-rm -f $@
+	$(TARGET_CC) $(msdospart_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ msdospart_mod-parttool_msdospart.o
+
+mod-msdospart.o: mod-msdospart.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(msdospart_mod_CFLAGS) -c -o $@ $<
+
+mod-msdospart.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'msdospart' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(msdospart_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-msdospart.lst: pre-msdospart.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 msdospart/' > $@
+else
+def-msdospart.lst: pre-msdospart.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 msdospart/' > $@
+endif
+endif
+
+und-msdospart.lst: pre-msdospart.o
+	echo 'msdospart' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+msdospart_mod-parttool_msdospart.o: parttool/msdospart.c $(parttool/msdospart.c_DEPENDENCIES)
+	$(TARGET_CC) -Iparttool -I$(srcdir)/parttool $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(msdospart_mod_CFLAGS) -MD -c -o $@ $<
+-include msdospart_mod-parttool_msdospart.d
+
+clean-module-msdospart_mod-parttool_msdospart-extra.1:
+	rm -f cmd-msdospart_mod-parttool_msdospart.lst fs-msdospart_mod-parttool_msdospart.lst partmap-msdospart_mod-parttool_msdospart.lst handler-msdospart_mod-parttool_msdospart.lst parttool-msdospart_mod-parttool_msdospart.lst
+
+CLEAN_MODULE_TARGETS += clean-module-msdospart_mod-parttool_msdospart-extra.1
+
+COMMANDFILES += cmd-msdospart_mod-parttool_msdospart.lst
+FSFILES += fs-msdospart_mod-parttool_msdospart.lst
+PARTTOOLFILES += parttool-msdospart_mod-parttool_msdospart.lst
+PARTMAPFILES += partmap-msdospart_mod-parttool_msdospart.lst
+HANDLERFILES += handler-msdospart_mod-parttool_msdospart.lst
+
+cmd-msdospart_mod-parttool_msdospart.lst: parttool/msdospart.c $(parttool/msdospart.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iparttool -I$(srcdir)/parttool $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(msdospart_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh msdospart > $@ || (rm -f $@; exit 1)
+
+fs-msdospart_mod-parttool_msdospart.lst: parttool/msdospart.c $(parttool/msdospart.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iparttool -I$(srcdir)/parttool $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(msdospart_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh msdospart > $@ || (rm -f $@; exit 1)
+
+parttool-msdospart_mod-parttool_msdospart.lst: parttool/msdospart.c $(parttool/msdospart.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iparttool -I$(srcdir)/parttool $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(msdospart_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh msdospart > $@ || (rm -f $@; exit 1)
+
+partmap-msdospart_mod-parttool_msdospart.lst: parttool/msdospart.c $(parttool/msdospart.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iparttool -I$(srcdir)/parttool $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(msdospart_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh msdospart > $@ || (rm -f $@; exit 1)
+
+handler-msdospart_mod-parttool_msdospart.lst: parttool/msdospart.c $(parttool/msdospart.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iparttool -I$(srcdir)/parttool $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(msdospart_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh msdospart > $@ || (rm -f $@; exit 1)
+
+msdospart_mod_CFLAGS = $(COMMON_CFLAGS)
+msdospart_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For handler.mod.
+handler_mod_SOURCES = commands/handler.c
+
+clean-module-handler.mod.1:
+	rm -f handler.mod mod-handler.o mod-handler.c pre-handler.o handler_mod-commands_handler.o und-handler.lst
+
+CLEAN_MODULE_TARGETS += clean-module-handler.mod.1
+
+ifneq ($(handler_mod_EXPORTS),no)
+clean-module-handler.mod-symbol.1:
+	rm -f def-handler.lst
+
+CLEAN_MODULE_TARGETS += clean-module-handler.mod-symbol.1
+DEFSYMFILES += def-handler.lst
+endif
+mostlyclean-module-handler.mod.1:
+	rm -f handler_mod-commands_handler.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-handler.mod.1
+UNDSYMFILES += und-handler.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+handler.mod: pre-handler.o mod-handler.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(handler_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-handler.o mod-handler.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+handler.mod: pre-handler.o mod-handler.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(handler_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-handler.o mod-handler.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-handler.o: $(handler_mod_DEPENDENCIES) handler_mod-commands_handler.o
+	-rm -f $@
+	$(TARGET_CC) $(handler_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ handler_mod-commands_handler.o
+
+mod-handler.o: mod-handler.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(handler_mod_CFLAGS) -c -o $@ $<
+
+mod-handler.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'handler' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(handler_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-handler.lst: pre-handler.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 handler/' > $@
+else
+def-handler.lst: pre-handler.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 handler/' > $@
+endif
+endif
+
+und-handler.lst: pre-handler.o
+	echo 'handler' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+handler_mod-commands_handler.o: commands/handler.c $(commands/handler.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(handler_mod_CFLAGS) -MD -c -o $@ $<
+-include handler_mod-commands_handler.d
+
+clean-module-handler_mod-commands_handler-extra.1:
+	rm -f cmd-handler_mod-commands_handler.lst fs-handler_mod-commands_handler.lst partmap-handler_mod-commands_handler.lst handler-handler_mod-commands_handler.lst parttool-handler_mod-commands_handler.lst
+
+CLEAN_MODULE_TARGETS += clean-module-handler_mod-commands_handler-extra.1
+
+COMMANDFILES += cmd-handler_mod-commands_handler.lst
+FSFILES += fs-handler_mod-commands_handler.lst
+PARTTOOLFILES += parttool-handler_mod-commands_handler.lst
+PARTMAPFILES += partmap-handler_mod-commands_handler.lst
+HANDLERFILES += handler-handler_mod-commands_handler.lst
+
+cmd-handler_mod-commands_handler.lst: commands/handler.c $(commands/handler.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(handler_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh handler > $@ || (rm -f $@; exit 1)
+
+fs-handler_mod-commands_handler.lst: commands/handler.c $(commands/handler.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(handler_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh handler > $@ || (rm -f $@; exit 1)
+
+parttool-handler_mod-commands_handler.lst: commands/handler.c $(commands/handler.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(handler_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh handler > $@ || (rm -f $@; exit 1)
+
+partmap-handler_mod-commands_handler.lst: commands/handler.c $(commands/handler.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(handler_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh handler > $@ || (rm -f $@; exit 1)
+
+handler-handler_mod-commands_handler.lst: commands/handler.c $(commands/handler.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(handler_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh handler > $@ || (rm -f $@; exit 1)
+
+handler_mod_CFLAGS = $(COMMON_CFLAGS)
+handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ls.mod.
+ls_mod_SOURCES = commands/ls.c
+
+clean-module-ls.mod.1:
+	rm -f ls.mod mod-ls.o mod-ls.c pre-ls.o ls_mod-commands_ls.o und-ls.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ls.mod.1
+
+ifneq ($(ls_mod_EXPORTS),no)
+clean-module-ls.mod-symbol.1:
+	rm -f def-ls.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ls.mod-symbol.1
+DEFSYMFILES += def-ls.lst
+endif
+mostlyclean-module-ls.mod.1:
+	rm -f ls_mod-commands_ls.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-ls.mod.1
+UNDSYMFILES += und-ls.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+ls.mod: pre-ls.o mod-ls.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(ls_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-ls.o mod-ls.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+ls.mod: pre-ls.o mod-ls.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(ls_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-ls.o mod-ls.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-ls.o: $(ls_mod_DEPENDENCIES) ls_mod-commands_ls.o
+	-rm -f $@
+	$(TARGET_CC) $(ls_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ls_mod-commands_ls.o
+
+mod-ls.o: mod-ls.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -c -o $@ $<
+
+mod-ls.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'ls' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(ls_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-ls.lst: pre-ls.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ls/' > $@
+else
+def-ls.lst: pre-ls.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 ls/' > $@
+endif
+endif
+
+und-ls.lst: pre-ls.o
+	echo 'ls' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+ls_mod-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -MD -c -o $@ $<
+-include ls_mod-commands_ls.d
+
+clean-module-ls_mod-commands_ls-extra.1:
+	rm -f cmd-ls_mod-commands_ls.lst fs-ls_mod-commands_ls.lst partmap-ls_mod-commands_ls.lst handler-ls_mod-commands_ls.lst parttool-ls_mod-commands_ls.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ls_mod-commands_ls-extra.1
+
+COMMANDFILES += cmd-ls_mod-commands_ls.lst
+FSFILES += fs-ls_mod-commands_ls.lst
+PARTTOOLFILES += parttool-ls_mod-commands_ls.lst
+PARTMAPFILES += partmap-ls_mod-commands_ls.lst
+HANDLERFILES += handler-ls_mod-commands_ls.lst
+
+cmd-ls_mod-commands_ls.lst: commands/ls.c $(commands/ls.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh ls > $@ || (rm -f $@; exit 1)
+
+fs-ls_mod-commands_ls.lst: commands/ls.c $(commands/ls.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh ls > $@ || (rm -f $@; exit 1)
+
+parttool-ls_mod-commands_ls.lst: commands/ls.c $(commands/ls.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh ls > $@ || (rm -f $@; exit 1)
+
+partmap-ls_mod-commands_ls.lst: commands/ls.c $(commands/ls.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh ls > $@ || (rm -f $@; exit 1)
+
+handler-ls_mod-commands_ls.lst: commands/ls.c $(commands/ls.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh ls > $@ || (rm -f $@; exit 1)
+
+ls_mod_CFLAGS = $(COMMON_CFLAGS)
+ls_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For cmp.mod.
+cmp_mod_SOURCES = commands/cmp.c
+
+clean-module-cmp.mod.1:
+	rm -f cmp.mod mod-cmp.o mod-cmp.c pre-cmp.o cmp_mod-commands_cmp.o und-cmp.lst
+
+CLEAN_MODULE_TARGETS += clean-module-cmp.mod.1
+
+ifneq ($(cmp_mod_EXPORTS),no)
+clean-module-cmp.mod-symbol.1:
+	rm -f def-cmp.lst
+
+CLEAN_MODULE_TARGETS += clean-module-cmp.mod-symbol.1
+DEFSYMFILES += def-cmp.lst
+endif
+mostlyclean-module-cmp.mod.1:
+	rm -f cmp_mod-commands_cmp.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-cmp.mod.1
+UNDSYMFILES += und-cmp.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+cmp.mod: pre-cmp.o mod-cmp.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(cmp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-cmp.o mod-cmp.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+cmp.mod: pre-cmp.o mod-cmp.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(cmp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-cmp.o mod-cmp.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-cmp.o: $(cmp_mod_DEPENDENCIES) cmp_mod-commands_cmp.o
+	-rm -f $@
+	$(TARGET_CC) $(cmp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ cmp_mod-commands_cmp.o
+
+mod-cmp.o: mod-cmp.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -c -o $@ $<
+
+mod-cmp.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'cmp' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(cmp_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-cmp.lst: pre-cmp.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 cmp/' > $@
+else
+def-cmp.lst: pre-cmp.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 cmp/' > $@
+endif
+endif
+
+und-cmp.lst: pre-cmp.o
+	echo 'cmp' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+cmp_mod-commands_cmp.o: commands/cmp.c $(commands/cmp.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -MD -c -o $@ $<
+-include cmp_mod-commands_cmp.d
+
+clean-module-cmp_mod-commands_cmp-extra.1:
+	rm -f cmd-cmp_mod-commands_cmp.lst fs-cmp_mod-commands_cmp.lst partmap-cmp_mod-commands_cmp.lst handler-cmp_mod-commands_cmp.lst parttool-cmp_mod-commands_cmp.lst
+
+CLEAN_MODULE_TARGETS += clean-module-cmp_mod-commands_cmp-extra.1
+
+COMMANDFILES += cmd-cmp_mod-commands_cmp.lst
+FSFILES += fs-cmp_mod-commands_cmp.lst
+PARTTOOLFILES += parttool-cmp_mod-commands_cmp.lst
+PARTMAPFILES += partmap-cmp_mod-commands_cmp.lst
+HANDLERFILES += handler-cmp_mod-commands_cmp.lst
+
+cmd-cmp_mod-commands_cmp.lst: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh cmp > $@ || (rm -f $@; exit 1)
+
+fs-cmp_mod-commands_cmp.lst: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh cmp > $@ || (rm -f $@; exit 1)
+
+parttool-cmp_mod-commands_cmp.lst: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh cmp > $@ || (rm -f $@; exit 1)
+
+partmap-cmp_mod-commands_cmp.lst: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh cmp > $@ || (rm -f $@; exit 1)
+
+handler-cmp_mod-commands_cmp.lst: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh cmp > $@ || (rm -f $@; exit 1)
+
+cmp_mod_CFLAGS = $(COMMON_CFLAGS)
+cmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For cat.mod.
+cat_mod_SOURCES = commands/cat.c
+
+clean-module-cat.mod.1:
+	rm -f cat.mod mod-cat.o mod-cat.c pre-cat.o cat_mod-commands_cat.o und-cat.lst
+
+CLEAN_MODULE_TARGETS += clean-module-cat.mod.1
+
+ifneq ($(cat_mod_EXPORTS),no)
+clean-module-cat.mod-symbol.1:
+	rm -f def-cat.lst
+
+CLEAN_MODULE_TARGETS += clean-module-cat.mod-symbol.1
+DEFSYMFILES += def-cat.lst
+endif
+mostlyclean-module-cat.mod.1:
+	rm -f cat_mod-commands_cat.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-cat.mod.1
+UNDSYMFILES += und-cat.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+cat.mod: pre-cat.o mod-cat.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(cat_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-cat.o mod-cat.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+cat.mod: pre-cat.o mod-cat.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(cat_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-cat.o mod-cat.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-cat.o: $(cat_mod_DEPENDENCIES) cat_mod-commands_cat.o
+	-rm -f $@
+	$(TARGET_CC) $(cat_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ cat_mod-commands_cat.o
+
+mod-cat.o: mod-cat.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -c -o $@ $<
+
+mod-cat.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'cat' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(cat_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-cat.lst: pre-cat.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 cat/' > $@
+else
+def-cat.lst: pre-cat.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 cat/' > $@
+endif
+endif
+
+und-cat.lst: pre-cat.o
+	echo 'cat' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+cat_mod-commands_cat.o: commands/cat.c $(commands/cat.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -MD -c -o $@ $<
+-include cat_mod-commands_cat.d
+
+clean-module-cat_mod-commands_cat-extra.1:
+	rm -f cmd-cat_mod-commands_cat.lst fs-cat_mod-commands_cat.lst partmap-cat_mod-commands_cat.lst handler-cat_mod-commands_cat.lst parttool-cat_mod-commands_cat.lst
+
+CLEAN_MODULE_TARGETS += clean-module-cat_mod-commands_cat-extra.1
+
+COMMANDFILES += cmd-cat_mod-commands_cat.lst
+FSFILES += fs-cat_mod-commands_cat.lst
+PARTTOOLFILES += parttool-cat_mod-commands_cat.lst
+PARTMAPFILES += partmap-cat_mod-commands_cat.lst
+HANDLERFILES += handler-cat_mod-commands_cat.lst
+
+cmd-cat_mod-commands_cat.lst: commands/cat.c $(commands/cat.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh cat > $@ || (rm -f $@; exit 1)
+
+fs-cat_mod-commands_cat.lst: commands/cat.c $(commands/cat.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh cat > $@ || (rm -f $@; exit 1)
+
+parttool-cat_mod-commands_cat.lst: commands/cat.c $(commands/cat.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh cat > $@ || (rm -f $@; exit 1)
+
+partmap-cat_mod-commands_cat.lst: commands/cat.c $(commands/cat.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh cat > $@ || (rm -f $@; exit 1)
+
+handler-cat_mod-commands_cat.lst: commands/cat.c $(commands/cat.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh cat > $@ || (rm -f $@; exit 1)
+
+cat_mod_CFLAGS = $(COMMON_CFLAGS)
+cat_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For echo.mod
+echo_mod_SOURCES = commands/echo.c
+
+clean-module-echo.mod.1:
+	rm -f echo.mod mod-echo.o mod-echo.c pre-echo.o echo_mod-commands_echo.o und-echo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-echo.mod.1
+
+ifneq ($(echo_mod_EXPORTS),no)
+clean-module-echo.mod-symbol.1:
+	rm -f def-echo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-echo.mod-symbol.1
+DEFSYMFILES += def-echo.lst
+endif
+mostlyclean-module-echo.mod.1:
+	rm -f echo_mod-commands_echo.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-echo.mod.1
+UNDSYMFILES += und-echo.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+echo.mod: pre-echo.o mod-echo.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(echo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-echo.o mod-echo.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+echo.mod: pre-echo.o mod-echo.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(echo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-echo.o mod-echo.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-echo.o: $(echo_mod_DEPENDENCIES) echo_mod-commands_echo.o
+	-rm -f $@
+	$(TARGET_CC) $(echo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ echo_mod-commands_echo.o
+
+mod-echo.o: mod-echo.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -c -o $@ $<
+
+mod-echo.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'echo' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(echo_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-echo.lst: pre-echo.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 echo/' > $@
+else
+def-echo.lst: pre-echo.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 echo/' > $@
+endif
+endif
+
+und-echo.lst: pre-echo.o
+	echo 'echo' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+echo_mod-commands_echo.o: commands/echo.c $(commands/echo.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -MD -c -o $@ $<
+-include echo_mod-commands_echo.d
+
+clean-module-echo_mod-commands_echo-extra.1:
+	rm -f cmd-echo_mod-commands_echo.lst fs-echo_mod-commands_echo.lst partmap-echo_mod-commands_echo.lst handler-echo_mod-commands_echo.lst parttool-echo_mod-commands_echo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-echo_mod-commands_echo-extra.1
+
+COMMANDFILES += cmd-echo_mod-commands_echo.lst
+FSFILES += fs-echo_mod-commands_echo.lst
+PARTTOOLFILES += parttool-echo_mod-commands_echo.lst
+PARTMAPFILES += partmap-echo_mod-commands_echo.lst
+HANDLERFILES += handler-echo_mod-commands_echo.lst
+
+cmd-echo_mod-commands_echo.lst: commands/echo.c $(commands/echo.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh echo > $@ || (rm -f $@; exit 1)
+
+fs-echo_mod-commands_echo.lst: commands/echo.c $(commands/echo.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh echo > $@ || (rm -f $@; exit 1)
+
+parttool-echo_mod-commands_echo.lst: commands/echo.c $(commands/echo.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh echo > $@ || (rm -f $@; exit 1)
+
+partmap-echo_mod-commands_echo.lst: commands/echo.c $(commands/echo.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh echo > $@ || (rm -f $@; exit 1)
+
+handler-echo_mod-commands_echo.lst: commands/echo.c $(commands/echo.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh echo > $@ || (rm -f $@; exit 1)
+
+echo_mod_CFLAGS = $(COMMON_CFLAGS)
+echo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For help.mod.
+help_mod_SOURCES = commands/help.c
+
+clean-module-help.mod.1:
+	rm -f help.mod mod-help.o mod-help.c pre-help.o help_mod-commands_help.o und-help.lst
+
+CLEAN_MODULE_TARGETS += clean-module-help.mod.1
+
+ifneq ($(help_mod_EXPORTS),no)
+clean-module-help.mod-symbol.1:
+	rm -f def-help.lst
+
+CLEAN_MODULE_TARGETS += clean-module-help.mod-symbol.1
+DEFSYMFILES += def-help.lst
+endif
+mostlyclean-module-help.mod.1:
+	rm -f help_mod-commands_help.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-help.mod.1
+UNDSYMFILES += und-help.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+help.mod: pre-help.o mod-help.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(help_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-help.o mod-help.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+help.mod: pre-help.o mod-help.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(help_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-help.o mod-help.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-help.o: $(help_mod_DEPENDENCIES) help_mod-commands_help.o
+	-rm -f $@
+	$(TARGET_CC) $(help_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ help_mod-commands_help.o
+
+mod-help.o: mod-help.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(help_mod_CFLAGS) -c -o $@ $<
+
+mod-help.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'help' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(help_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-help.lst: pre-help.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 help/' > $@
+else
+def-help.lst: pre-help.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 help/' > $@
+endif
+endif
+
+und-help.lst: pre-help.o
+	echo 'help' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+help_mod-commands_help.o: commands/help.c $(commands/help.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(help_mod_CFLAGS) -MD -c -o $@ $<
+-include help_mod-commands_help.d
+
+clean-module-help_mod-commands_help-extra.1:
+	rm -f cmd-help_mod-commands_help.lst fs-help_mod-commands_help.lst partmap-help_mod-commands_help.lst handler-help_mod-commands_help.lst parttool-help_mod-commands_help.lst
+
+CLEAN_MODULE_TARGETS += clean-module-help_mod-commands_help-extra.1
+
+COMMANDFILES += cmd-help_mod-commands_help.lst
+FSFILES += fs-help_mod-commands_help.lst
+PARTTOOLFILES += parttool-help_mod-commands_help.lst
+PARTMAPFILES += partmap-help_mod-commands_help.lst
+HANDLERFILES += handler-help_mod-commands_help.lst
+
+cmd-help_mod-commands_help.lst: commands/help.c $(commands/help.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(help_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh help > $@ || (rm -f $@; exit 1)
+
+fs-help_mod-commands_help.lst: commands/help.c $(commands/help.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(help_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh help > $@ || (rm -f $@; exit 1)
+
+parttool-help_mod-commands_help.lst: commands/help.c $(commands/help.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(help_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh help > $@ || (rm -f $@; exit 1)
+
+partmap-help_mod-commands_help.lst: commands/help.c $(commands/help.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(help_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh help > $@ || (rm -f $@; exit 1)
+
+handler-help_mod-commands_help.lst: commands/help.c $(commands/help.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(help_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh help > $@ || (rm -f $@; exit 1)
+
+help_mod_CFLAGS = $(COMMON_CFLAGS)
+help_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For search.mod.
+search_mod_SOURCES = commands/search.c
+
+clean-module-search.mod.1:
+	rm -f search.mod mod-search.o mod-search.c pre-search.o search_mod-commands_search.o und-search.lst
+
+CLEAN_MODULE_TARGETS += clean-module-search.mod.1
+
+ifneq ($(search_mod_EXPORTS),no)
+clean-module-search.mod-symbol.1:
+	rm -f def-search.lst
+
+CLEAN_MODULE_TARGETS += clean-module-search.mod-symbol.1
+DEFSYMFILES += def-search.lst
+endif
+mostlyclean-module-search.mod.1:
+	rm -f search_mod-commands_search.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-search.mod.1
+UNDSYMFILES += und-search.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+search.mod: pre-search.o mod-search.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(search_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-search.o mod-search.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+search.mod: pre-search.o mod-search.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(search_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-search.o mod-search.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-search.o: $(search_mod_DEPENDENCIES) search_mod-commands_search.o
+	-rm -f $@
+	$(TARGET_CC) $(search_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ search_mod-commands_search.o
+
+mod-search.o: mod-search.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(search_mod_CFLAGS) -c -o $@ $<
+
+mod-search.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'search' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(search_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-search.lst: pre-search.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 search/' > $@
+else
+def-search.lst: pre-search.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 search/' > $@
+endif
+endif
+
+und-search.lst: pre-search.o
+	echo 'search' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+search_mod-commands_search.o: commands/search.c $(commands/search.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(search_mod_CFLAGS) -MD -c -o $@ $<
+-include search_mod-commands_search.d
+
+clean-module-search_mod-commands_search-extra.1:
+	rm -f cmd-search_mod-commands_search.lst fs-search_mod-commands_search.lst partmap-search_mod-commands_search.lst handler-search_mod-commands_search.lst parttool-search_mod-commands_search.lst
+
+CLEAN_MODULE_TARGETS += clean-module-search_mod-commands_search-extra.1
+
+COMMANDFILES += cmd-search_mod-commands_search.lst
+FSFILES += fs-search_mod-commands_search.lst
+PARTTOOLFILES += parttool-search_mod-commands_search.lst
+PARTMAPFILES += partmap-search_mod-commands_search.lst
+HANDLERFILES += handler-search_mod-commands_search.lst
+
+cmd-search_mod-commands_search.lst: commands/search.c $(commands/search.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(search_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh search > $@ || (rm -f $@; exit 1)
+
+fs-search_mod-commands_search.lst: commands/search.c $(commands/search.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(search_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh search > $@ || (rm -f $@; exit 1)
+
+parttool-search_mod-commands_search.lst: commands/search.c $(commands/search.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(search_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh search > $@ || (rm -f $@; exit 1)
+
+partmap-search_mod-commands_search.lst: commands/search.c $(commands/search.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(search_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh search > $@ || (rm -f $@; exit 1)
+
+handler-search_mod-commands_search.lst: commands/search.c $(commands/search.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(search_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh search > $@ || (rm -f $@; exit 1)
+
+search_mod_CFLAGS = $(COMMON_CFLAGS)
+search_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For test.mod.
+test_mod_SOURCES = commands/test.c
+
+clean-module-test.mod.1:
+	rm -f test.mod mod-test.o mod-test.c pre-test.o test_mod-commands_test.o und-test.lst
+
+CLEAN_MODULE_TARGETS += clean-module-test.mod.1
+
+ifneq ($(test_mod_EXPORTS),no)
+clean-module-test.mod-symbol.1:
+	rm -f def-test.lst
+
+CLEAN_MODULE_TARGETS += clean-module-test.mod-symbol.1
+DEFSYMFILES += def-test.lst
+endif
+mostlyclean-module-test.mod.1:
+	rm -f test_mod-commands_test.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-test.mod.1
+UNDSYMFILES += und-test.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+test.mod: pre-test.o mod-test.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(test_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-test.o mod-test.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+test.mod: pre-test.o mod-test.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(test_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-test.o mod-test.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-test.o: $(test_mod_DEPENDENCIES) test_mod-commands_test.o
+	-rm -f $@
+	$(TARGET_CC) $(test_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ test_mod-commands_test.o
+
+mod-test.o: mod-test.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(test_mod_CFLAGS) -c -o $@ $<
+
+mod-test.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'test' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(test_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-test.lst: pre-test.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 test/' > $@
+else
+def-test.lst: pre-test.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 test/' > $@
+endif
+endif
+
+und-test.lst: pre-test.o
+	echo 'test' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+test_mod-commands_test.o: commands/test.c $(commands/test.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(test_mod_CFLAGS) -MD -c -o $@ $<
+-include test_mod-commands_test.d
+
+clean-module-test_mod-commands_test-extra.1:
+	rm -f cmd-test_mod-commands_test.lst fs-test_mod-commands_test.lst partmap-test_mod-commands_test.lst handler-test_mod-commands_test.lst parttool-test_mod-commands_test.lst
+
+CLEAN_MODULE_TARGETS += clean-module-test_mod-commands_test-extra.1
+
+COMMANDFILES += cmd-test_mod-commands_test.lst
+FSFILES += fs-test_mod-commands_test.lst
+PARTTOOLFILES += parttool-test_mod-commands_test.lst
+PARTMAPFILES += partmap-test_mod-commands_test.lst
+HANDLERFILES += handler-test_mod-commands_test.lst
+
+cmd-test_mod-commands_test.lst: commands/test.c $(commands/test.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(test_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh test > $@ || (rm -f $@; exit 1)
+
+fs-test_mod-commands_test.lst: commands/test.c $(commands/test.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(test_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh test > $@ || (rm -f $@; exit 1)
+
+parttool-test_mod-commands_test.lst: commands/test.c $(commands/test.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(test_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh test > $@ || (rm -f $@; exit 1)
+
+partmap-test_mod-commands_test.lst: commands/test.c $(commands/test.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(test_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh test > $@ || (rm -f $@; exit 1)
+
+handler-test_mod-commands_test.lst: commands/test.c $(commands/test.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(test_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh test > $@ || (rm -f $@; exit 1)
+
+test_mod_CFLAGS = $(COMMON_CFLAGS)
+test_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For loopback.mod
+loopback_mod_SOURCES = disk/loopback.c
+
+clean-module-loopback.mod.1:
+	rm -f loopback.mod mod-loopback.o mod-loopback.c pre-loopback.o loopback_mod-disk_loopback.o und-loopback.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loopback.mod.1
+
+ifneq ($(loopback_mod_EXPORTS),no)
+clean-module-loopback.mod-symbol.1:
+	rm -f def-loopback.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loopback.mod-symbol.1
+DEFSYMFILES += def-loopback.lst
+endif
+mostlyclean-module-loopback.mod.1:
+	rm -f loopback_mod-disk_loopback.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-loopback.mod.1
+UNDSYMFILES += und-loopback.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+loopback.mod: pre-loopback.o mod-loopback.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(loopback_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-loopback.o mod-loopback.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+loopback.mod: pre-loopback.o mod-loopback.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(loopback_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-loopback.o mod-loopback.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-loopback.o: $(loopback_mod_DEPENDENCIES) loopback_mod-disk_loopback.o
+	-rm -f $@
+	$(TARGET_CC) $(loopback_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ loopback_mod-disk_loopback.o
+
+mod-loopback.o: mod-loopback.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -c -o $@ $<
+
+mod-loopback.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'loopback' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(loopback_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-loopback.lst: pre-loopback.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 loopback/' > $@
+else
+def-loopback.lst: pre-loopback.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 loopback/' > $@
+endif
+endif
+
+und-loopback.lst: pre-loopback.o
+	echo 'loopback' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+loopback_mod-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -MD -c -o $@ $<
+-include loopback_mod-disk_loopback.d
+
+clean-module-loopback_mod-disk_loopback-extra.1:
+	rm -f cmd-loopback_mod-disk_loopback.lst fs-loopback_mod-disk_loopback.lst partmap-loopback_mod-disk_loopback.lst handler-loopback_mod-disk_loopback.lst parttool-loopback_mod-disk_loopback.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loopback_mod-disk_loopback-extra.1
+
+COMMANDFILES += cmd-loopback_mod-disk_loopback.lst
+FSFILES += fs-loopback_mod-disk_loopback.lst
+PARTTOOLFILES += parttool-loopback_mod-disk_loopback.lst
+PARTMAPFILES += partmap-loopback_mod-disk_loopback.lst
+HANDLERFILES += handler-loopback_mod-disk_loopback.lst
+
+cmd-loopback_mod-disk_loopback.lst: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh loopback > $@ || (rm -f $@; exit 1)
+
+fs-loopback_mod-disk_loopback.lst: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh loopback > $@ || (rm -f $@; exit 1)
+
+parttool-loopback_mod-disk_loopback.lst: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh loopback > $@ || (rm -f $@; exit 1)
+
+partmap-loopback_mod-disk_loopback.lst: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh loopback > $@ || (rm -f $@; exit 1)
+
+handler-loopback_mod-disk_loopback.lst: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh loopback > $@ || (rm -f $@; exit 1)
+
+loopback_mod_CFLAGS = $(COMMON_CFLAGS)
+loopback_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For fs_file.mod
+fs_file_mod_SOURCES = disk/fs_file.c
+
+clean-module-fs_file.mod.1:
+	rm -f fs_file.mod mod-fs_file.o mod-fs_file.c pre-fs_file.o fs_file_mod-disk_fs_file.o und-fs_file.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fs_file.mod.1
+
+ifneq ($(fs_file_mod_EXPORTS),no)
+clean-module-fs_file.mod-symbol.1:
+	rm -f def-fs_file.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fs_file.mod-symbol.1
+DEFSYMFILES += def-fs_file.lst
+endif
+mostlyclean-module-fs_file.mod.1:
+	rm -f fs_file_mod-disk_fs_file.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-fs_file.mod.1
+UNDSYMFILES += und-fs_file.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+fs_file.mod: pre-fs_file.o mod-fs_file.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(fs_file_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-fs_file.o mod-fs_file.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+fs_file.mod: pre-fs_file.o mod-fs_file.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(fs_file_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-fs_file.o mod-fs_file.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-fs_file.o: $(fs_file_mod_DEPENDENCIES) fs_file_mod-disk_fs_file.o
+	-rm -f $@
+	$(TARGET_CC) $(fs_file_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ fs_file_mod-disk_fs_file.o
+
+mod-fs_file.o: mod-fs_file.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fs_file_mod_CFLAGS) -c -o $@ $<
+
+mod-fs_file.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'fs_file' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(fs_file_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-fs_file.lst: pre-fs_file.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fs_file/' > $@
+else
+def-fs_file.lst: pre-fs_file.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 fs_file/' > $@
+endif
+endif
+
+und-fs_file.lst: pre-fs_file.o
+	echo 'fs_file' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+fs_file_mod-disk_fs_file.o: disk/fs_file.c $(disk/fs_file.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_file_mod_CFLAGS) -MD -c -o $@ $<
+-include fs_file_mod-disk_fs_file.d
+
+clean-module-fs_file_mod-disk_fs_file-extra.1:
+	rm -f cmd-fs_file_mod-disk_fs_file.lst fs-fs_file_mod-disk_fs_file.lst partmap-fs_file_mod-disk_fs_file.lst handler-fs_file_mod-disk_fs_file.lst parttool-fs_file_mod-disk_fs_file.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fs_file_mod-disk_fs_file-extra.1
+
+COMMANDFILES += cmd-fs_file_mod-disk_fs_file.lst
+FSFILES += fs-fs_file_mod-disk_fs_file.lst
+PARTTOOLFILES += parttool-fs_file_mod-disk_fs_file.lst
+PARTMAPFILES += partmap-fs_file_mod-disk_fs_file.lst
+HANDLERFILES += handler-fs_file_mod-disk_fs_file.lst
+
+cmd-fs_file_mod-disk_fs_file.lst: disk/fs_file.c $(disk/fs_file.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_file_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh fs_file > $@ || (rm -f $@; exit 1)
+
+fs-fs_file_mod-disk_fs_file.lst: disk/fs_file.c $(disk/fs_file.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_file_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh fs_file > $@ || (rm -f $@; exit 1)
+
+parttool-fs_file_mod-disk_fs_file.lst: disk/fs_file.c $(disk/fs_file.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_file_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh fs_file > $@ || (rm -f $@; exit 1)
+
+partmap-fs_file_mod-disk_fs_file.lst: disk/fs_file.c $(disk/fs_file.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_file_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh fs_file > $@ || (rm -f $@; exit 1)
+
+handler-fs_file_mod-disk_fs_file.lst: disk/fs_file.c $(disk/fs_file.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_file_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh fs_file > $@ || (rm -f $@; exit 1)
+
+fs_file_mod_CFLAGS = $(COMMON_CFLAGS)
+fs_file_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For fs_uuid.mod
+fs_uuid_mod_SOURCES = disk/fs_uuid.c
+
+clean-module-fs_uuid.mod.1:
+	rm -f fs_uuid.mod mod-fs_uuid.o mod-fs_uuid.c pre-fs_uuid.o fs_uuid_mod-disk_fs_uuid.o und-fs_uuid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fs_uuid.mod.1
+
+ifneq ($(fs_uuid_mod_EXPORTS),no)
+clean-module-fs_uuid.mod-symbol.1:
+	rm -f def-fs_uuid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fs_uuid.mod-symbol.1
+DEFSYMFILES += def-fs_uuid.lst
+endif
+mostlyclean-module-fs_uuid.mod.1:
+	rm -f fs_uuid_mod-disk_fs_uuid.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-fs_uuid.mod.1
+UNDSYMFILES += und-fs_uuid.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+fs_uuid.mod: pre-fs_uuid.o mod-fs_uuid.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(fs_uuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-fs_uuid.o mod-fs_uuid.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+fs_uuid.mod: pre-fs_uuid.o mod-fs_uuid.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(fs_uuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-fs_uuid.o mod-fs_uuid.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-fs_uuid.o: $(fs_uuid_mod_DEPENDENCIES) fs_uuid_mod-disk_fs_uuid.o
+	-rm -f $@
+	$(TARGET_CC) $(fs_uuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ fs_uuid_mod-disk_fs_uuid.o
+
+mod-fs_uuid.o: mod-fs_uuid.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -c -o $@ $<
+
+mod-fs_uuid.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'fs_uuid' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(fs_uuid_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-fs_uuid.lst: pre-fs_uuid.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fs_uuid/' > $@
+else
+def-fs_uuid.lst: pre-fs_uuid.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 fs_uuid/' > $@
+endif
+endif
+
+und-fs_uuid.lst: pre-fs_uuid.o
+	echo 'fs_uuid' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+fs_uuid_mod-disk_fs_uuid.o: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -MD -c -o $@ $<
+-include fs_uuid_mod-disk_fs_uuid.d
+
+clean-module-fs_uuid_mod-disk_fs_uuid-extra.1:
+	rm -f cmd-fs_uuid_mod-disk_fs_uuid.lst fs-fs_uuid_mod-disk_fs_uuid.lst partmap-fs_uuid_mod-disk_fs_uuid.lst handler-fs_uuid_mod-disk_fs_uuid.lst parttool-fs_uuid_mod-disk_fs_uuid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fs_uuid_mod-disk_fs_uuid-extra.1
+
+COMMANDFILES += cmd-fs_uuid_mod-disk_fs_uuid.lst
+FSFILES += fs-fs_uuid_mod-disk_fs_uuid.lst
+PARTTOOLFILES += parttool-fs_uuid_mod-disk_fs_uuid.lst
+PARTMAPFILES += partmap-fs_uuid_mod-disk_fs_uuid.lst
+HANDLERFILES += handler-fs_uuid_mod-disk_fs_uuid.lst
+
+cmd-fs_uuid_mod-disk_fs_uuid.lst: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh fs_uuid > $@ || (rm -f $@; exit 1)
+
+fs-fs_uuid_mod-disk_fs_uuid.lst: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh fs_uuid > $@ || (rm -f $@; exit 1)
+
+parttool-fs_uuid_mod-disk_fs_uuid.lst: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh fs_uuid > $@ || (rm -f $@; exit 1)
+
+partmap-fs_uuid_mod-disk_fs_uuid.lst: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh fs_uuid > $@ || (rm -f $@; exit 1)
+
+handler-fs_uuid_mod-disk_fs_uuid.lst: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh fs_uuid > $@ || (rm -f $@; exit 1)
+
+fs_uuid_mod_CFLAGS = $(COMMON_CFLAGS)
+fs_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For configfile.mod
+configfile_mod_SOURCES = commands/configfile.c
+
+clean-module-configfile.mod.1:
+	rm -f configfile.mod mod-configfile.o mod-configfile.c pre-configfile.o configfile_mod-commands_configfile.o und-configfile.lst
+
+CLEAN_MODULE_TARGETS += clean-module-configfile.mod.1
+
+ifneq ($(configfile_mod_EXPORTS),no)
+clean-module-configfile.mod-symbol.1:
+	rm -f def-configfile.lst
+
+CLEAN_MODULE_TARGETS += clean-module-configfile.mod-symbol.1
+DEFSYMFILES += def-configfile.lst
+endif
+mostlyclean-module-configfile.mod.1:
+	rm -f configfile_mod-commands_configfile.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-configfile.mod.1
+UNDSYMFILES += und-configfile.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+configfile.mod: pre-configfile.o mod-configfile.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(configfile_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-configfile.o mod-configfile.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+configfile.mod: pre-configfile.o mod-configfile.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(configfile_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-configfile.o mod-configfile.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-configfile.o: $(configfile_mod_DEPENDENCIES) configfile_mod-commands_configfile.o
+	-rm -f $@
+	$(TARGET_CC) $(configfile_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ configfile_mod-commands_configfile.o
+
+mod-configfile.o: mod-configfile.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -c -o $@ $<
+
+mod-configfile.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'configfile' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(configfile_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-configfile.lst: pre-configfile.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 configfile/' > $@
+else
+def-configfile.lst: pre-configfile.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 configfile/' > $@
+endif
+endif
+
+und-configfile.lst: pre-configfile.o
+	echo 'configfile' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+configfile_mod-commands_configfile.o: commands/configfile.c $(commands/configfile.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -MD -c -o $@ $<
+-include configfile_mod-commands_configfile.d
+
+clean-module-configfile_mod-commands_configfile-extra.1:
+	rm -f cmd-configfile_mod-commands_configfile.lst fs-configfile_mod-commands_configfile.lst partmap-configfile_mod-commands_configfile.lst handler-configfile_mod-commands_configfile.lst parttool-configfile_mod-commands_configfile.lst
+
+CLEAN_MODULE_TARGETS += clean-module-configfile_mod-commands_configfile-extra.1
+
+COMMANDFILES += cmd-configfile_mod-commands_configfile.lst
+FSFILES += fs-configfile_mod-commands_configfile.lst
+PARTTOOLFILES += parttool-configfile_mod-commands_configfile.lst
+PARTMAPFILES += partmap-configfile_mod-commands_configfile.lst
+HANDLERFILES += handler-configfile_mod-commands_configfile.lst
+
+cmd-configfile_mod-commands_configfile.lst: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh configfile > $@ || (rm -f $@; exit 1)
+
+fs-configfile_mod-commands_configfile.lst: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh configfile > $@ || (rm -f $@; exit 1)
+
+parttool-configfile_mod-commands_configfile.lst: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh configfile > $@ || (rm -f $@; exit 1)
+
+partmap-configfile_mod-commands_configfile.lst: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh configfile > $@ || (rm -f $@; exit 1)
+
+handler-configfile_mod-commands_configfile.lst: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh configfile > $@ || (rm -f $@; exit 1)
+
+configfile_mod_CFLAGS = $(COMMON_CFLAGS)
+configfile_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For terminfo.mod.
+terminfo_mod_SOURCES = term/terminfo.c term/tparm.c
+
+clean-module-terminfo.mod.1:
+	rm -f terminfo.mod mod-terminfo.o mod-terminfo.c pre-terminfo.o terminfo_mod-term_terminfo.o terminfo_mod-term_tparm.o und-terminfo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-terminfo.mod.1
+
+ifneq ($(terminfo_mod_EXPORTS),no)
+clean-module-terminfo.mod-symbol.1:
+	rm -f def-terminfo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-terminfo.mod-symbol.1
+DEFSYMFILES += def-terminfo.lst
+endif
+mostlyclean-module-terminfo.mod.1:
+	rm -f terminfo_mod-term_terminfo.d terminfo_mod-term_tparm.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-terminfo.mod.1
+UNDSYMFILES += und-terminfo.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+terminfo.mod: pre-terminfo.o mod-terminfo.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(terminfo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-terminfo.o mod-terminfo.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+terminfo.mod: pre-terminfo.o mod-terminfo.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(terminfo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-terminfo.o mod-terminfo.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-terminfo.o: $(terminfo_mod_DEPENDENCIES) terminfo_mod-term_terminfo.o terminfo_mod-term_tparm.o
+	-rm -f $@
+	$(TARGET_CC) $(terminfo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ terminfo_mod-term_terminfo.o terminfo_mod-term_tparm.o
+
+mod-terminfo.o: mod-terminfo.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -c -o $@ $<
+
+mod-terminfo.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'terminfo' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(terminfo_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-terminfo.lst: pre-terminfo.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 terminfo/' > $@
+else
+def-terminfo.lst: pre-terminfo.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 terminfo/' > $@
+endif
+endif
+
+und-terminfo.lst: pre-terminfo.o
+	echo 'terminfo' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+terminfo_mod-term_terminfo.o: term/terminfo.c $(term/terminfo.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -MD -c -o $@ $<
+-include terminfo_mod-term_terminfo.d
+
+clean-module-terminfo_mod-term_terminfo-extra.1:
+	rm -f cmd-terminfo_mod-term_terminfo.lst fs-terminfo_mod-term_terminfo.lst partmap-terminfo_mod-term_terminfo.lst handler-terminfo_mod-term_terminfo.lst parttool-terminfo_mod-term_terminfo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-terminfo_mod-term_terminfo-extra.1
+
+COMMANDFILES += cmd-terminfo_mod-term_terminfo.lst
+FSFILES += fs-terminfo_mod-term_terminfo.lst
+PARTTOOLFILES += parttool-terminfo_mod-term_terminfo.lst
+PARTMAPFILES += partmap-terminfo_mod-term_terminfo.lst
+HANDLERFILES += handler-terminfo_mod-term_terminfo.lst
+
+cmd-terminfo_mod-term_terminfo.lst: term/terminfo.c $(term/terminfo.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh terminfo > $@ || (rm -f $@; exit 1)
+
+fs-terminfo_mod-term_terminfo.lst: term/terminfo.c $(term/terminfo.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh terminfo > $@ || (rm -f $@; exit 1)
+
+parttool-terminfo_mod-term_terminfo.lst: term/terminfo.c $(term/terminfo.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh terminfo > $@ || (rm -f $@; exit 1)
+
+partmap-terminfo_mod-term_terminfo.lst: term/terminfo.c $(term/terminfo.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh terminfo > $@ || (rm -f $@; exit 1)
+
+handler-terminfo_mod-term_terminfo.lst: term/terminfo.c $(term/terminfo.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh terminfo > $@ || (rm -f $@; exit 1)
+
+terminfo_mod-term_tparm.o: term/tparm.c $(term/tparm.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -MD -c -o $@ $<
+-include terminfo_mod-term_tparm.d
+
+clean-module-terminfo_mod-term_tparm-extra.1:
+	rm -f cmd-terminfo_mod-term_tparm.lst fs-terminfo_mod-term_tparm.lst partmap-terminfo_mod-term_tparm.lst handler-terminfo_mod-term_tparm.lst parttool-terminfo_mod-term_tparm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-terminfo_mod-term_tparm-extra.1
+
+COMMANDFILES += cmd-terminfo_mod-term_tparm.lst
+FSFILES += fs-terminfo_mod-term_tparm.lst
+PARTTOOLFILES += parttool-terminfo_mod-term_tparm.lst
+PARTMAPFILES += partmap-terminfo_mod-term_tparm.lst
+HANDLERFILES += handler-terminfo_mod-term_tparm.lst
+
+cmd-terminfo_mod-term_tparm.lst: term/tparm.c $(term/tparm.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh terminfo > $@ || (rm -f $@; exit 1)
+
+fs-terminfo_mod-term_tparm.lst: term/tparm.c $(term/tparm.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh terminfo > $@ || (rm -f $@; exit 1)
+
+parttool-terminfo_mod-term_tparm.lst: term/tparm.c $(term/tparm.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh terminfo > $@ || (rm -f $@; exit 1)
+
+partmap-terminfo_mod-term_tparm.lst: term/tparm.c $(term/tparm.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh terminfo > $@ || (rm -f $@; exit 1)
+
+handler-terminfo_mod-term_tparm.lst: term/tparm.c $(term/tparm.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh terminfo > $@ || (rm -f $@; exit 1)
+
+terminfo_mod_CFLAGS = $(COMMON_CFLAGS)
+terminfo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For blocklist.mod.
+blocklist_mod_SOURCES = commands/blocklist.c
+
+clean-module-blocklist.mod.1:
+	rm -f blocklist.mod mod-blocklist.o mod-blocklist.c pre-blocklist.o blocklist_mod-commands_blocklist.o und-blocklist.lst
+
+CLEAN_MODULE_TARGETS += clean-module-blocklist.mod.1
+
+ifneq ($(blocklist_mod_EXPORTS),no)
+clean-module-blocklist.mod-symbol.1:
+	rm -f def-blocklist.lst
+
+CLEAN_MODULE_TARGETS += clean-module-blocklist.mod-symbol.1
+DEFSYMFILES += def-blocklist.lst
+endif
+mostlyclean-module-blocklist.mod.1:
+	rm -f blocklist_mod-commands_blocklist.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-blocklist.mod.1
+UNDSYMFILES += und-blocklist.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+blocklist.mod: pre-blocklist.o mod-blocklist.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(blocklist_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-blocklist.o mod-blocklist.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+blocklist.mod: pre-blocklist.o mod-blocklist.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(blocklist_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-blocklist.o mod-blocklist.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-blocklist.o: $(blocklist_mod_DEPENDENCIES) blocklist_mod-commands_blocklist.o
+	-rm -f $@
+	$(TARGET_CC) $(blocklist_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ blocklist_mod-commands_blocklist.o
+
+mod-blocklist.o: mod-blocklist.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(blocklist_mod_CFLAGS) -c -o $@ $<
+
+mod-blocklist.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'blocklist' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(blocklist_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-blocklist.lst: pre-blocklist.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 blocklist/' > $@
+else
+def-blocklist.lst: pre-blocklist.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 blocklist/' > $@
+endif
+endif
+
+und-blocklist.lst: pre-blocklist.o
+	echo 'blocklist' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+blocklist_mod-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(blocklist_mod_CFLAGS) -MD -c -o $@ $<
+-include blocklist_mod-commands_blocklist.d
+
+clean-module-blocklist_mod-commands_blocklist-extra.1:
+	rm -f cmd-blocklist_mod-commands_blocklist.lst fs-blocklist_mod-commands_blocklist.lst partmap-blocklist_mod-commands_blocklist.lst handler-blocklist_mod-commands_blocklist.lst parttool-blocklist_mod-commands_blocklist.lst
+
+CLEAN_MODULE_TARGETS += clean-module-blocklist_mod-commands_blocklist-extra.1
+
+COMMANDFILES += cmd-blocklist_mod-commands_blocklist.lst
+FSFILES += fs-blocklist_mod-commands_blocklist.lst
+PARTTOOLFILES += parttool-blocklist_mod-commands_blocklist.lst
+PARTMAPFILES += partmap-blocklist_mod-commands_blocklist.lst
+HANDLERFILES += handler-blocklist_mod-commands_blocklist.lst
+
+cmd-blocklist_mod-commands_blocklist.lst: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(blocklist_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh blocklist > $@ || (rm -f $@; exit 1)
+
+fs-blocklist_mod-commands_blocklist.lst: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(blocklist_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh blocklist > $@ || (rm -f $@; exit 1)
+
+parttool-blocklist_mod-commands_blocklist.lst: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(blocklist_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh blocklist > $@ || (rm -f $@; exit 1)
+
+partmap-blocklist_mod-commands_blocklist.lst: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(blocklist_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh blocklist > $@ || (rm -f $@; exit 1)
+
+handler-blocklist_mod-commands_blocklist.lst: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(blocklist_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh blocklist > $@ || (rm -f $@; exit 1)
+
+blocklist_mod_CFLAGS = $(COMMON_CFLAGS)
+blocklist_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hexdump.mod.
+hexdump_mod_SOURCES = commands/hexdump.c lib/hexdump.c
+
+clean-module-hexdump.mod.1:
+	rm -f hexdump.mod mod-hexdump.o mod-hexdump.c pre-hexdump.o hexdump_mod-commands_hexdump.o hexdump_mod-lib_hexdump.o und-hexdump.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hexdump.mod.1
+
+ifneq ($(hexdump_mod_EXPORTS),no)
+clean-module-hexdump.mod-symbol.1:
+	rm -f def-hexdump.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hexdump.mod-symbol.1
+DEFSYMFILES += def-hexdump.lst
+endif
+mostlyclean-module-hexdump.mod.1:
+	rm -f hexdump_mod-commands_hexdump.d hexdump_mod-lib_hexdump.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-hexdump.mod.1
+UNDSYMFILES += und-hexdump.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+hexdump.mod: pre-hexdump.o mod-hexdump.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(hexdump_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-hexdump.o mod-hexdump.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+hexdump.mod: pre-hexdump.o mod-hexdump.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(hexdump_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-hexdump.o mod-hexdump.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-hexdump.o: $(hexdump_mod_DEPENDENCIES) hexdump_mod-commands_hexdump.o hexdump_mod-lib_hexdump.o
+	-rm -f $@
+	$(TARGET_CC) $(hexdump_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ hexdump_mod-commands_hexdump.o hexdump_mod-lib_hexdump.o
+
+mod-hexdump.o: mod-hexdump.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -c -o $@ $<
+
+mod-hexdump.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'hexdump' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(hexdump_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-hexdump.lst: pre-hexdump.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 hexdump/' > $@
+else
+def-hexdump.lst: pre-hexdump.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 hexdump/' > $@
+endif
+endif
+
+und-hexdump.lst: pre-hexdump.o
+	echo 'hexdump' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+hexdump_mod-commands_hexdump.o: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -MD -c -o $@ $<
+-include hexdump_mod-commands_hexdump.d
+
+clean-module-hexdump_mod-commands_hexdump-extra.1:
+	rm -f cmd-hexdump_mod-commands_hexdump.lst fs-hexdump_mod-commands_hexdump.lst partmap-hexdump_mod-commands_hexdump.lst handler-hexdump_mod-commands_hexdump.lst parttool-hexdump_mod-commands_hexdump.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hexdump_mod-commands_hexdump-extra.1
+
+COMMANDFILES += cmd-hexdump_mod-commands_hexdump.lst
+FSFILES += fs-hexdump_mod-commands_hexdump.lst
+PARTTOOLFILES += parttool-hexdump_mod-commands_hexdump.lst
+PARTMAPFILES += partmap-hexdump_mod-commands_hexdump.lst
+HANDLERFILES += handler-hexdump_mod-commands_hexdump.lst
+
+cmd-hexdump_mod-commands_hexdump.lst: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh hexdump > $@ || (rm -f $@; exit 1)
+
+fs-hexdump_mod-commands_hexdump.lst: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh hexdump > $@ || (rm -f $@; exit 1)
+
+parttool-hexdump_mod-commands_hexdump.lst: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh hexdump > $@ || (rm -f $@; exit 1)
+
+partmap-hexdump_mod-commands_hexdump.lst: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh hexdump > $@ || (rm -f $@; exit 1)
+
+handler-hexdump_mod-commands_hexdump.lst: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh hexdump > $@ || (rm -f $@; exit 1)
+
+hexdump_mod-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -MD -c -o $@ $<
+-include hexdump_mod-lib_hexdump.d
+
+clean-module-hexdump_mod-lib_hexdump-extra.1:
+	rm -f cmd-hexdump_mod-lib_hexdump.lst fs-hexdump_mod-lib_hexdump.lst partmap-hexdump_mod-lib_hexdump.lst handler-hexdump_mod-lib_hexdump.lst parttool-hexdump_mod-lib_hexdump.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hexdump_mod-lib_hexdump-extra.1
+
+COMMANDFILES += cmd-hexdump_mod-lib_hexdump.lst
+FSFILES += fs-hexdump_mod-lib_hexdump.lst
+PARTTOOLFILES += parttool-hexdump_mod-lib_hexdump.lst
+PARTMAPFILES += partmap-hexdump_mod-lib_hexdump.lst
+HANDLERFILES += handler-hexdump_mod-lib_hexdump.lst
+
+cmd-hexdump_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh hexdump > $@ || (rm -f $@; exit 1)
+
+fs-hexdump_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh hexdump > $@ || (rm -f $@; exit 1)
+
+parttool-hexdump_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh hexdump > $@ || (rm -f $@; exit 1)
+
+partmap-hexdump_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh hexdump > $@ || (rm -f $@; exit 1)
+
+handler-hexdump_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh hexdump > $@ || (rm -f $@; exit 1)
+
+hexdump_mod_CFLAGS = $(COMMON_CFLAGS)
+hexdump_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For read.mod.
+read_mod_SOURCES = commands/read.c
+
+clean-module-read.mod.1:
+	rm -f read.mod mod-read.o mod-read.c pre-read.o read_mod-commands_read.o und-read.lst
+
+CLEAN_MODULE_TARGETS += clean-module-read.mod.1
+
+ifneq ($(read_mod_EXPORTS),no)
+clean-module-read.mod-symbol.1:
+	rm -f def-read.lst
+
+CLEAN_MODULE_TARGETS += clean-module-read.mod-symbol.1
+DEFSYMFILES += def-read.lst
+endif
+mostlyclean-module-read.mod.1:
+	rm -f read_mod-commands_read.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-read.mod.1
+UNDSYMFILES += und-read.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+read.mod: pre-read.o mod-read.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(read_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-read.o mod-read.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+read.mod: pre-read.o mod-read.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(read_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-read.o mod-read.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-read.o: $(read_mod_DEPENDENCIES) read_mod-commands_read.o
+	-rm -f $@
+	$(TARGET_CC) $(read_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ read_mod-commands_read.o
+
+mod-read.o: mod-read.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(read_mod_CFLAGS) -c -o $@ $<
+
+mod-read.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'read' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(read_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-read.lst: pre-read.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 read/' > $@
+else
+def-read.lst: pre-read.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 read/' > $@
+endif
+endif
+
+und-read.lst: pre-read.o
+	echo 'read' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+read_mod-commands_read.o: commands/read.c $(commands/read.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(read_mod_CFLAGS) -MD -c -o $@ $<
+-include read_mod-commands_read.d
+
+clean-module-read_mod-commands_read-extra.1:
+	rm -f cmd-read_mod-commands_read.lst fs-read_mod-commands_read.lst partmap-read_mod-commands_read.lst handler-read_mod-commands_read.lst parttool-read_mod-commands_read.lst
+
+CLEAN_MODULE_TARGETS += clean-module-read_mod-commands_read-extra.1
+
+COMMANDFILES += cmd-read_mod-commands_read.lst
+FSFILES += fs-read_mod-commands_read.lst
+PARTTOOLFILES += parttool-read_mod-commands_read.lst
+PARTMAPFILES += partmap-read_mod-commands_read.lst
+HANDLERFILES += handler-read_mod-commands_read.lst
+
+cmd-read_mod-commands_read.lst: commands/read.c $(commands/read.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(read_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh read > $@ || (rm -f $@; exit 1)
+
+fs-read_mod-commands_read.lst: commands/read.c $(commands/read.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(read_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh read > $@ || (rm -f $@; exit 1)
+
+parttool-read_mod-commands_read.lst: commands/read.c $(commands/read.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(read_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh read > $@ || (rm -f $@; exit 1)
+
+partmap-read_mod-commands_read.lst: commands/read.c $(commands/read.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(read_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh read > $@ || (rm -f $@; exit 1)
+
+handler-read_mod-commands_read.lst: commands/read.c $(commands/read.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(read_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh read > $@ || (rm -f $@; exit 1)
+
+read_mod_CFLAGS = $(COMMON_CFLAGS)
+read_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For sleep.mod.
+sleep_mod_SOURCES = commands/sleep.c
+
+clean-module-sleep.mod.1:
+	rm -f sleep.mod mod-sleep.o mod-sleep.c pre-sleep.o sleep_mod-commands_sleep.o und-sleep.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sleep.mod.1
+
+ifneq ($(sleep_mod_EXPORTS),no)
+clean-module-sleep.mod-symbol.1:
+	rm -f def-sleep.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sleep.mod-symbol.1
+DEFSYMFILES += def-sleep.lst
+endif
+mostlyclean-module-sleep.mod.1:
+	rm -f sleep_mod-commands_sleep.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-sleep.mod.1
+UNDSYMFILES += und-sleep.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+sleep.mod: pre-sleep.o mod-sleep.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(sleep_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-sleep.o mod-sleep.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+sleep.mod: pre-sleep.o mod-sleep.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(sleep_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-sleep.o mod-sleep.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-sleep.o: $(sleep_mod_DEPENDENCIES) sleep_mod-commands_sleep.o
+	-rm -f $@
+	$(TARGET_CC) $(sleep_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ sleep_mod-commands_sleep.o
+
+mod-sleep.o: mod-sleep.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sleep_mod_CFLAGS) -c -o $@ $<
+
+mod-sleep.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'sleep' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(sleep_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-sleep.lst: pre-sleep.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 sleep/' > $@
+else
+def-sleep.lst: pre-sleep.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 sleep/' > $@
+endif
+endif
+
+und-sleep.lst: pre-sleep.o
+	echo 'sleep' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+sleep_mod-commands_sleep.o: commands/sleep.c $(commands/sleep.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sleep_mod_CFLAGS) -MD -c -o $@ $<
+-include sleep_mod-commands_sleep.d
+
+clean-module-sleep_mod-commands_sleep-extra.1:
+	rm -f cmd-sleep_mod-commands_sleep.lst fs-sleep_mod-commands_sleep.lst partmap-sleep_mod-commands_sleep.lst handler-sleep_mod-commands_sleep.lst parttool-sleep_mod-commands_sleep.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sleep_mod-commands_sleep-extra.1
+
+COMMANDFILES += cmd-sleep_mod-commands_sleep.lst
+FSFILES += fs-sleep_mod-commands_sleep.lst
+PARTTOOLFILES += parttool-sleep_mod-commands_sleep.lst
+PARTMAPFILES += partmap-sleep_mod-commands_sleep.lst
+HANDLERFILES += handler-sleep_mod-commands_sleep.lst
+
+cmd-sleep_mod-commands_sleep.lst: commands/sleep.c $(commands/sleep.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sleep_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh sleep > $@ || (rm -f $@; exit 1)
+
+fs-sleep_mod-commands_sleep.lst: commands/sleep.c $(commands/sleep.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sleep_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh sleep > $@ || (rm -f $@; exit 1)
+
+parttool-sleep_mod-commands_sleep.lst: commands/sleep.c $(commands/sleep.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sleep_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh sleep > $@ || (rm -f $@; exit 1)
+
+partmap-sleep_mod-commands_sleep.lst: commands/sleep.c $(commands/sleep.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sleep_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh sleep > $@ || (rm -f $@; exit 1)
+
+handler-sleep_mod-commands_sleep.lst: commands/sleep.c $(commands/sleep.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sleep_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh sleep > $@ || (rm -f $@; exit 1)
+
+sleep_mod_CFLAGS = $(COMMON_CFLAGS)
+sleep_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For loadenv.mod.
+loadenv_mod_SOURCES = commands/loadenv.c lib/envblk.c
+
+clean-module-loadenv.mod.1:
+	rm -f loadenv.mod mod-loadenv.o mod-loadenv.c pre-loadenv.o loadenv_mod-commands_loadenv.o loadenv_mod-lib_envblk.o und-loadenv.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loadenv.mod.1
+
+ifneq ($(loadenv_mod_EXPORTS),no)
+clean-module-loadenv.mod-symbol.1:
+	rm -f def-loadenv.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loadenv.mod-symbol.1
+DEFSYMFILES += def-loadenv.lst
+endif
+mostlyclean-module-loadenv.mod.1:
+	rm -f loadenv_mod-commands_loadenv.d loadenv_mod-lib_envblk.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-loadenv.mod.1
+UNDSYMFILES += und-loadenv.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+loadenv.mod: pre-loadenv.o mod-loadenv.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(loadenv_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-loadenv.o mod-loadenv.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+loadenv.mod: pre-loadenv.o mod-loadenv.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(loadenv_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-loadenv.o mod-loadenv.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-loadenv.o: $(loadenv_mod_DEPENDENCIES) loadenv_mod-commands_loadenv.o loadenv_mod-lib_envblk.o
+	-rm -f $@
+	$(TARGET_CC) $(loadenv_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ loadenv_mod-commands_loadenv.o loadenv_mod-lib_envblk.o
+
+mod-loadenv.o: mod-loadenv.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -c -o $@ $<
+
+mod-loadenv.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'loadenv' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(loadenv_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-loadenv.lst: pre-loadenv.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 loadenv/' > $@
+else
+def-loadenv.lst: pre-loadenv.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 loadenv/' > $@
+endif
+endif
+
+und-loadenv.lst: pre-loadenv.o
+	echo 'loadenv' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+loadenv_mod-commands_loadenv.o: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -MD -c -o $@ $<
+-include loadenv_mod-commands_loadenv.d
+
+clean-module-loadenv_mod-commands_loadenv-extra.1:
+	rm -f cmd-loadenv_mod-commands_loadenv.lst fs-loadenv_mod-commands_loadenv.lst partmap-loadenv_mod-commands_loadenv.lst handler-loadenv_mod-commands_loadenv.lst parttool-loadenv_mod-commands_loadenv.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loadenv_mod-commands_loadenv-extra.1
+
+COMMANDFILES += cmd-loadenv_mod-commands_loadenv.lst
+FSFILES += fs-loadenv_mod-commands_loadenv.lst
+PARTTOOLFILES += parttool-loadenv_mod-commands_loadenv.lst
+PARTMAPFILES += partmap-loadenv_mod-commands_loadenv.lst
+HANDLERFILES += handler-loadenv_mod-commands_loadenv.lst
+
+cmd-loadenv_mod-commands_loadenv.lst: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh loadenv > $@ || (rm -f $@; exit 1)
+
+fs-loadenv_mod-commands_loadenv.lst: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh loadenv > $@ || (rm -f $@; exit 1)
+
+parttool-loadenv_mod-commands_loadenv.lst: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh loadenv > $@ || (rm -f $@; exit 1)
+
+partmap-loadenv_mod-commands_loadenv.lst: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh loadenv > $@ || (rm -f $@; exit 1)
+
+handler-loadenv_mod-commands_loadenv.lst: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh loadenv > $@ || (rm -f $@; exit 1)
+
+loadenv_mod-lib_envblk.o: lib/envblk.c $(lib/envblk.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -MD -c -o $@ $<
+-include loadenv_mod-lib_envblk.d
+
+clean-module-loadenv_mod-lib_envblk-extra.1:
+	rm -f cmd-loadenv_mod-lib_envblk.lst fs-loadenv_mod-lib_envblk.lst partmap-loadenv_mod-lib_envblk.lst handler-loadenv_mod-lib_envblk.lst parttool-loadenv_mod-lib_envblk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loadenv_mod-lib_envblk-extra.1
+
+COMMANDFILES += cmd-loadenv_mod-lib_envblk.lst
+FSFILES += fs-loadenv_mod-lib_envblk.lst
+PARTTOOLFILES += parttool-loadenv_mod-lib_envblk.lst
+PARTMAPFILES += partmap-loadenv_mod-lib_envblk.lst
+HANDLERFILES += handler-loadenv_mod-lib_envblk.lst
+
+cmd-loadenv_mod-lib_envblk.lst: lib/envblk.c $(lib/envblk.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh loadenv > $@ || (rm -f $@; exit 1)
+
+fs-loadenv_mod-lib_envblk.lst: lib/envblk.c $(lib/envblk.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh loadenv > $@ || (rm -f $@; exit 1)
+
+parttool-loadenv_mod-lib_envblk.lst: lib/envblk.c $(lib/envblk.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh loadenv > $@ || (rm -f $@; exit 1)
+
+partmap-loadenv_mod-lib_envblk.lst: lib/envblk.c $(lib/envblk.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh loadenv > $@ || (rm -f $@; exit 1)
+
+handler-loadenv_mod-lib_envblk.lst: lib/envblk.c $(lib/envblk.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh loadenv > $@ || (rm -f $@; exit 1)
+
+loadenv_mod_CFLAGS = $(COMMON_CFLAGS)
+loadenv_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For crc.mod.
+crc_mod_SOURCES = commands/crc.c lib/crc.c
+
+clean-module-crc.mod.1:
+	rm -f crc.mod mod-crc.o mod-crc.c pre-crc.o crc_mod-commands_crc.o crc_mod-lib_crc.o und-crc.lst
+
+CLEAN_MODULE_TARGETS += clean-module-crc.mod.1
+
+ifneq ($(crc_mod_EXPORTS),no)
+clean-module-crc.mod-symbol.1:
+	rm -f def-crc.lst
+
+CLEAN_MODULE_TARGETS += clean-module-crc.mod-symbol.1
+DEFSYMFILES += def-crc.lst
+endif
+mostlyclean-module-crc.mod.1:
+	rm -f crc_mod-commands_crc.d crc_mod-lib_crc.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-crc.mod.1
+UNDSYMFILES += und-crc.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+crc.mod: pre-crc.o mod-crc.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(crc_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-crc.o mod-crc.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+crc.mod: pre-crc.o mod-crc.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(crc_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-crc.o mod-crc.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-crc.o: $(crc_mod_DEPENDENCIES) crc_mod-commands_crc.o crc_mod-lib_crc.o
+	-rm -f $@
+	$(TARGET_CC) $(crc_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ crc_mod-commands_crc.o crc_mod-lib_crc.o
+
+mod-crc.o: mod-crc.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -c -o $@ $<
+
+mod-crc.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'crc' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(crc_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-crc.lst: pre-crc.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 crc/' > $@
+else
+def-crc.lst: pre-crc.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 crc/' > $@
+endif
+endif
+
+und-crc.lst: pre-crc.o
+	echo 'crc' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+crc_mod-commands_crc.o: commands/crc.c $(commands/crc.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -MD -c -o $@ $<
+-include crc_mod-commands_crc.d
+
+clean-module-crc_mod-commands_crc-extra.1:
+	rm -f cmd-crc_mod-commands_crc.lst fs-crc_mod-commands_crc.lst partmap-crc_mod-commands_crc.lst handler-crc_mod-commands_crc.lst parttool-crc_mod-commands_crc.lst
+
+CLEAN_MODULE_TARGETS += clean-module-crc_mod-commands_crc-extra.1
+
+COMMANDFILES += cmd-crc_mod-commands_crc.lst
+FSFILES += fs-crc_mod-commands_crc.lst
+PARTTOOLFILES += parttool-crc_mod-commands_crc.lst
+PARTMAPFILES += partmap-crc_mod-commands_crc.lst
+HANDLERFILES += handler-crc_mod-commands_crc.lst
+
+cmd-crc_mod-commands_crc.lst: commands/crc.c $(commands/crc.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh crc > $@ || (rm -f $@; exit 1)
+
+fs-crc_mod-commands_crc.lst: commands/crc.c $(commands/crc.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh crc > $@ || (rm -f $@; exit 1)
+
+parttool-crc_mod-commands_crc.lst: commands/crc.c $(commands/crc.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh crc > $@ || (rm -f $@; exit 1)
+
+partmap-crc_mod-commands_crc.lst: commands/crc.c $(commands/crc.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh crc > $@ || (rm -f $@; exit 1)
+
+handler-crc_mod-commands_crc.lst: commands/crc.c $(commands/crc.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh crc > $@ || (rm -f $@; exit 1)
+
+crc_mod-lib_crc.o: lib/crc.c $(lib/crc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -MD -c -o $@ $<
+-include crc_mod-lib_crc.d
+
+clean-module-crc_mod-lib_crc-extra.1:
+	rm -f cmd-crc_mod-lib_crc.lst fs-crc_mod-lib_crc.lst partmap-crc_mod-lib_crc.lst handler-crc_mod-lib_crc.lst parttool-crc_mod-lib_crc.lst
+
+CLEAN_MODULE_TARGETS += clean-module-crc_mod-lib_crc-extra.1
+
+COMMANDFILES += cmd-crc_mod-lib_crc.lst
+FSFILES += fs-crc_mod-lib_crc.lst
+PARTTOOLFILES += parttool-crc_mod-lib_crc.lst
+PARTMAPFILES += partmap-crc_mod-lib_crc.lst
+HANDLERFILES += handler-crc_mod-lib_crc.lst
+
+cmd-crc_mod-lib_crc.lst: lib/crc.c $(lib/crc.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh crc > $@ || (rm -f $@; exit 1)
+
+fs-crc_mod-lib_crc.lst: lib/crc.c $(lib/crc.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh crc > $@ || (rm -f $@; exit 1)
+
+parttool-crc_mod-lib_crc.lst: lib/crc.c $(lib/crc.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh crc > $@ || (rm -f $@; exit 1)
+
+partmap-crc_mod-lib_crc.lst: lib/crc.c $(lib/crc.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh crc > $@ || (rm -f $@; exit 1)
+
+handler-crc_mod-lib_crc.lst: lib/crc.c $(lib/crc.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh crc > $@ || (rm -f $@; exit 1)
+
+crc_mod_CFLAGS = $(COMMON_CFLAGS)
+crc_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memrw.mod.
+memrw_mod_SOURCES = commands/memrw.c
+
+clean-module-memrw.mod.1:
+	rm -f memrw.mod mod-memrw.o mod-memrw.c pre-memrw.o memrw_mod-commands_memrw.o und-memrw.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memrw.mod.1
+
+ifneq ($(memrw_mod_EXPORTS),no)
+clean-module-memrw.mod-symbol.1:
+	rm -f def-memrw.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memrw.mod-symbol.1
+DEFSYMFILES += def-memrw.lst
+endif
+mostlyclean-module-memrw.mod.1:
+	rm -f memrw_mod-commands_memrw.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-memrw.mod.1
+UNDSYMFILES += und-memrw.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+memrw.mod: pre-memrw.o mod-memrw.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(memrw_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-memrw.o mod-memrw.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+memrw.mod: pre-memrw.o mod-memrw.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(memrw_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-memrw.o mod-memrw.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-memrw.o: $(memrw_mod_DEPENDENCIES) memrw_mod-commands_memrw.o
+	-rm -f $@
+	$(TARGET_CC) $(memrw_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memrw_mod-commands_memrw.o
+
+mod-memrw.o: mod-memrw.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memrw_mod_CFLAGS) -c -o $@ $<
+
+mod-memrw.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'memrw' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(memrw_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-memrw.lst: pre-memrw.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memrw/' > $@
+else
+def-memrw.lst: pre-memrw.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 memrw/' > $@
+endif
+endif
+
+und-memrw.lst: pre-memrw.o
+	echo 'memrw' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+memrw_mod-commands_memrw.o: commands/memrw.c $(commands/memrw.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memrw_mod_CFLAGS) -MD -c -o $@ $<
+-include memrw_mod-commands_memrw.d
+
+clean-module-memrw_mod-commands_memrw-extra.1:
+	rm -f cmd-memrw_mod-commands_memrw.lst fs-memrw_mod-commands_memrw.lst partmap-memrw_mod-commands_memrw.lst handler-memrw_mod-commands_memrw.lst parttool-memrw_mod-commands_memrw.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memrw_mod-commands_memrw-extra.1
+
+COMMANDFILES += cmd-memrw_mod-commands_memrw.lst
+FSFILES += fs-memrw_mod-commands_memrw.lst
+PARTTOOLFILES += parttool-memrw_mod-commands_memrw.lst
+PARTMAPFILES += partmap-memrw_mod-commands_memrw.lst
+HANDLERFILES += handler-memrw_mod-commands_memrw.lst
+
+cmd-memrw_mod-commands_memrw.lst: commands/memrw.c $(commands/memrw.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memrw_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh memrw > $@ || (rm -f $@; exit 1)
+
+fs-memrw_mod-commands_memrw.lst: commands/memrw.c $(commands/memrw.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memrw_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh memrw > $@ || (rm -f $@; exit 1)
+
+parttool-memrw_mod-commands_memrw.lst: commands/memrw.c $(commands/memrw.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memrw_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh memrw > $@ || (rm -f $@; exit 1)
+
+partmap-memrw_mod-commands_memrw.lst: commands/memrw.c $(commands/memrw.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memrw_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh memrw > $@ || (rm -f $@; exit 1)
+
+handler-memrw_mod-commands_memrw.lst: commands/memrw.c $(commands/memrw.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memrw_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh memrw > $@ || (rm -f $@; exit 1)
+
+memrw_mod_CFLAGS = $(COMMON_CFLAGS)
+memrw_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For true.mod
+true_mod_SOURCES = commands/true.c
+
+clean-module-true.mod.1:
+	rm -f true.mod mod-true.o mod-true.c pre-true.o true_mod-commands_true.o und-true.lst
+
+CLEAN_MODULE_TARGETS += clean-module-true.mod.1
+
+ifneq ($(true_mod_EXPORTS),no)
+clean-module-true.mod-symbol.1:
+	rm -f def-true.lst
+
+CLEAN_MODULE_TARGETS += clean-module-true.mod-symbol.1
+DEFSYMFILES += def-true.lst
+endif
+mostlyclean-module-true.mod.1:
+	rm -f true_mod-commands_true.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-true.mod.1
+UNDSYMFILES += und-true.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+true.mod: pre-true.o mod-true.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(true_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-true.o mod-true.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+true.mod: pre-true.o mod-true.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(true_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-true.o mod-true.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-true.o: $(true_mod_DEPENDENCIES) true_mod-commands_true.o
+	-rm -f $@
+	$(TARGET_CC) $(true_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ true_mod-commands_true.o
+
+mod-true.o: mod-true.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(true_mod_CFLAGS) -c -o $@ $<
+
+mod-true.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'true' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(true_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-true.lst: pre-true.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 true/' > $@
+else
+def-true.lst: pre-true.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 true/' > $@
+endif
+endif
+
+und-true.lst: pre-true.o
+	echo 'true' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+true_mod-commands_true.o: commands/true.c $(commands/true.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(true_mod_CFLAGS) -MD -c -o $@ $<
+-include true_mod-commands_true.d
+
+clean-module-true_mod-commands_true-extra.1:
+	rm -f cmd-true_mod-commands_true.lst fs-true_mod-commands_true.lst partmap-true_mod-commands_true.lst handler-true_mod-commands_true.lst parttool-true_mod-commands_true.lst
+
+CLEAN_MODULE_TARGETS += clean-module-true_mod-commands_true-extra.1
+
+COMMANDFILES += cmd-true_mod-commands_true.lst
+FSFILES += fs-true_mod-commands_true.lst
+PARTTOOLFILES += parttool-true_mod-commands_true.lst
+PARTMAPFILES += partmap-true_mod-commands_true.lst
+HANDLERFILES += handler-true_mod-commands_true.lst
+
+cmd-true_mod-commands_true.lst: commands/true.c $(commands/true.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(true_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh true > $@ || (rm -f $@; exit 1)
+
+fs-true_mod-commands_true.lst: commands/true.c $(commands/true.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(true_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh true > $@ || (rm -f $@; exit 1)
+
+parttool-true_mod-commands_true.lst: commands/true.c $(commands/true.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(true_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh true > $@ || (rm -f $@; exit 1)
+
+partmap-true_mod-commands_true.lst: commands/true.c $(commands/true.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(true_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh true > $@ || (rm -f $@; exit 1)
+
+handler-true_mod-commands_true.lst: commands/true.c $(commands/true.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(true_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh true > $@ || (rm -f $@; exit 1)
+
+true_mod_CFLAGS = $(COMMON_CFLAGS)
+true_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For probe.mod.
+probe_mod_SOURCES = commands/probe.c
+
+clean-module-probe.mod.1:
+	rm -f probe.mod mod-probe.o mod-probe.c pre-probe.o probe_mod-commands_probe.o und-probe.lst
+
+CLEAN_MODULE_TARGETS += clean-module-probe.mod.1
+
+ifneq ($(probe_mod_EXPORTS),no)
+clean-module-probe.mod-symbol.1:
+	rm -f def-probe.lst
+
+CLEAN_MODULE_TARGETS += clean-module-probe.mod-symbol.1
+DEFSYMFILES += def-probe.lst
+endif
+mostlyclean-module-probe.mod.1:
+	rm -f probe_mod-commands_probe.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-probe.mod.1
+UNDSYMFILES += und-probe.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+probe.mod: pre-probe.o mod-probe.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(probe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-probe.o mod-probe.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+probe.mod: pre-probe.o mod-probe.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(probe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-probe.o mod-probe.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-probe.o: $(probe_mod_DEPENDENCIES) probe_mod-commands_probe.o
+	-rm -f $@
+	$(TARGET_CC) $(probe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ probe_mod-commands_probe.o
+
+mod-probe.o: mod-probe.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(probe_mod_CFLAGS) -c -o $@ $<
+
+mod-probe.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'probe' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(probe_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-probe.lst: pre-probe.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 probe/' > $@
+else
+def-probe.lst: pre-probe.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 probe/' > $@
+endif
+endif
+
+und-probe.lst: pre-probe.o
+	echo 'probe' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+probe_mod-commands_probe.o: commands/probe.c $(commands/probe.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(probe_mod_CFLAGS) -MD -c -o $@ $<
+-include probe_mod-commands_probe.d
+
+clean-module-probe_mod-commands_probe-extra.1:
+	rm -f cmd-probe_mod-commands_probe.lst fs-probe_mod-commands_probe.lst partmap-probe_mod-commands_probe.lst handler-probe_mod-commands_probe.lst parttool-probe_mod-commands_probe.lst
+
+CLEAN_MODULE_TARGETS += clean-module-probe_mod-commands_probe-extra.1
+
+COMMANDFILES += cmd-probe_mod-commands_probe.lst
+FSFILES += fs-probe_mod-commands_probe.lst
+PARTTOOLFILES += parttool-probe_mod-commands_probe.lst
+PARTMAPFILES += partmap-probe_mod-commands_probe.lst
+HANDLERFILES += handler-probe_mod-commands_probe.lst
+
+cmd-probe_mod-commands_probe.lst: commands/probe.c $(commands/probe.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(probe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh probe > $@ || (rm -f $@; exit 1)
+
+fs-probe_mod-commands_probe.lst: commands/probe.c $(commands/probe.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(probe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh probe > $@ || (rm -f $@; exit 1)
+
+parttool-probe_mod-commands_probe.lst: commands/probe.c $(commands/probe.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(probe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh probe > $@ || (rm -f $@; exit 1)
+
+partmap-probe_mod-commands_probe.lst: commands/probe.c $(commands/probe.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(probe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh probe > $@ || (rm -f $@; exit 1)
+
+handler-probe_mod-commands_probe.lst: commands/probe.c $(commands/probe.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(probe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh probe > $@ || (rm -f $@; exit 1)
+
+probe_mod_CFLAGS = $(COMMON_CFLAGS)
+probe_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For keystatus.mod.
+keystatus_mod_SOURCES = commands/keystatus.c
+
+clean-module-keystatus.mod.1:
+	rm -f keystatus.mod mod-keystatus.o mod-keystatus.c pre-keystatus.o keystatus_mod-commands_keystatus.o und-keystatus.lst
+
+CLEAN_MODULE_TARGETS += clean-module-keystatus.mod.1
+
+ifneq ($(keystatus_mod_EXPORTS),no)
+clean-module-keystatus.mod-symbol.1:
+	rm -f def-keystatus.lst
+
+CLEAN_MODULE_TARGETS += clean-module-keystatus.mod-symbol.1
+DEFSYMFILES += def-keystatus.lst
+endif
+mostlyclean-module-keystatus.mod.1:
+	rm -f keystatus_mod-commands_keystatus.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-keystatus.mod.1
+UNDSYMFILES += und-keystatus.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+keystatus.mod: pre-keystatus.o mod-keystatus.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(keystatus_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-keystatus.o mod-keystatus.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+keystatus.mod: pre-keystatus.o mod-keystatus.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(keystatus_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-keystatus.o mod-keystatus.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-keystatus.o: $(keystatus_mod_DEPENDENCIES) keystatus_mod-commands_keystatus.o
+	-rm -f $@
+	$(TARGET_CC) $(keystatus_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ keystatus_mod-commands_keystatus.o
+
+mod-keystatus.o: mod-keystatus.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(keystatus_mod_CFLAGS) -c -o $@ $<
+
+mod-keystatus.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'keystatus' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(keystatus_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-keystatus.lst: pre-keystatus.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 keystatus/' > $@
+else
+def-keystatus.lst: pre-keystatus.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 keystatus/' > $@
+endif
+endif
+
+und-keystatus.lst: pre-keystatus.o
+	echo 'keystatus' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+keystatus_mod-commands_keystatus.o: commands/keystatus.c $(commands/keystatus.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(keystatus_mod_CFLAGS) -MD -c -o $@ $<
+-include keystatus_mod-commands_keystatus.d
+
+clean-module-keystatus_mod-commands_keystatus-extra.1:
+	rm -f cmd-keystatus_mod-commands_keystatus.lst fs-keystatus_mod-commands_keystatus.lst partmap-keystatus_mod-commands_keystatus.lst handler-keystatus_mod-commands_keystatus.lst parttool-keystatus_mod-commands_keystatus.lst
+
+CLEAN_MODULE_TARGETS += clean-module-keystatus_mod-commands_keystatus-extra.1
+
+COMMANDFILES += cmd-keystatus_mod-commands_keystatus.lst
+FSFILES += fs-keystatus_mod-commands_keystatus.lst
+PARTTOOLFILES += parttool-keystatus_mod-commands_keystatus.lst
+PARTMAPFILES += partmap-keystatus_mod-commands_keystatus.lst
+HANDLERFILES += handler-keystatus_mod-commands_keystatus.lst
+
+cmd-keystatus_mod-commands_keystatus.lst: commands/keystatus.c $(commands/keystatus.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(keystatus_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh keystatus > $@ || (rm -f $@; exit 1)
+
+fs-keystatus_mod-commands_keystatus.lst: commands/keystatus.c $(commands/keystatus.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(keystatus_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh keystatus > $@ || (rm -f $@; exit 1)
+
+parttool-keystatus_mod-commands_keystatus.lst: commands/keystatus.c $(commands/keystatus.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(keystatus_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh keystatus > $@ || (rm -f $@; exit 1)
+
+partmap-keystatus_mod-commands_keystatus.lst: commands/keystatus.c $(commands/keystatus.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(keystatus_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh keystatus > $@ || (rm -f $@; exit 1)
+
+handler-keystatus_mod-commands_keystatus.lst: commands/keystatus.c $(commands/keystatus.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(keystatus_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh keystatus > $@ || (rm -f $@; exit 1)
+
+keystatus_mod_CFLAGS = $(COMMON_CFLAGS)
+keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For normal.mod.
+normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
+	normal/auth.c normal/autofs.c normal/handler.c \
+	normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
+	normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \
+	normal/misc.c
+
+clean-module-normal.mod.1:
+	rm -f normal.mod mod-normal.o mod-normal.c pre-normal.o normal_mod-normal_main.o normal_mod-normal_cmdline.o normal_mod-normal_dyncmd.o normal_mod-normal_auth.o normal_mod-normal_autofs.o normal_mod-normal_handler.o normal_mod-normal_color.o normal_mod-normal_completion.o normal_mod-normal_datetime.o normal_mod-normal_menu.o normal_mod-normal_menu_entry.o normal_mod-normal_menu_text.o normal_mod-normal_menu_viewer.o normal_mod-normal_misc.o und-normal.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal.mod.1
+
+ifneq ($(normal_mod_EXPORTS),no)
+clean-module-normal.mod-symbol.1:
+	rm -f def-normal.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal.mod-symbol.1
+DEFSYMFILES += def-normal.lst
+endif
+mostlyclean-module-normal.mod.1:
+	rm -f normal_mod-normal_main.d normal_mod-normal_cmdline.d normal_mod-normal_dyncmd.d normal_mod-normal_auth.d normal_mod-normal_autofs.d normal_mod-normal_handler.d normal_mod-normal_color.d normal_mod-normal_completion.d normal_mod-normal_datetime.d normal_mod-normal_menu.d normal_mod-normal_menu_entry.d normal_mod-normal_menu_text.d normal_mod-normal_menu_viewer.d normal_mod-normal_misc.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-normal.mod.1
+UNDSYMFILES += und-normal.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+normal.mod: pre-normal.o mod-normal.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-normal.o mod-normal.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+normal.mod: pre-normal.o mod-normal.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-normal.o mod-normal.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-normal.o: $(normal_mod_DEPENDENCIES) normal_mod-normal_main.o normal_mod-normal_cmdline.o normal_mod-normal_dyncmd.o normal_mod-normal_auth.o normal_mod-normal_autofs.o normal_mod-normal_handler.o normal_mod-normal_color.o normal_mod-normal_completion.o normal_mod-normal_datetime.o normal_mod-normal_menu.o normal_mod-normal_menu_entry.o normal_mod-normal_menu_text.o normal_mod-normal_menu_viewer.o normal_mod-normal_misc.o
+	-rm -f $@
+	$(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ normal_mod-normal_main.o normal_mod-normal_cmdline.o normal_mod-normal_dyncmd.o normal_mod-normal_auth.o normal_mod-normal_autofs.o normal_mod-normal_handler.o normal_mod-normal_color.o normal_mod-normal_completion.o normal_mod-normal_datetime.o normal_mod-normal_menu.o normal_mod-normal_menu_entry.o normal_mod-normal_menu_text.o normal_mod-normal_menu_viewer.o normal_mod-normal_misc.o
+
+mod-normal.o: mod-normal.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -c -o $@ $<
+
+mod-normal.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'normal' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(normal_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-normal.lst: pre-normal.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 normal/' > $@
+else
+def-normal.lst: pre-normal.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 normal/' > $@
+endif
+endif
+
+und-normal.lst: pre-normal.o
+	echo 'normal' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+normal_mod-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_main.d
+
+clean-module-normal_mod-normal_main-extra.1:
+	rm -f cmd-normal_mod-normal_main.lst fs-normal_mod-normal_main.lst partmap-normal_mod-normal_main.lst handler-normal_mod-normal_main.lst parttool-normal_mod-normal_main.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_main-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_main.lst
+FSFILES += fs-normal_mod-normal_main.lst
+PARTTOOLFILES += parttool-normal_mod-normal_main.lst
+PARTMAPFILES += partmap-normal_mod-normal_main.lst
+HANDLERFILES += handler-normal_mod-normal_main.lst
+
+cmd-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_cmdline.d
+
+clean-module-normal_mod-normal_cmdline-extra.1:
+	rm -f cmd-normal_mod-normal_cmdline.lst fs-normal_mod-normal_cmdline.lst partmap-normal_mod-normal_cmdline.lst handler-normal_mod-normal_cmdline.lst parttool-normal_mod-normal_cmdline.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_cmdline-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_cmdline.lst
+FSFILES += fs-normal_mod-normal_cmdline.lst
+PARTTOOLFILES += parttool-normal_mod-normal_cmdline.lst
+PARTMAPFILES += partmap-normal_mod-normal_cmdline.lst
+HANDLERFILES += handler-normal_mod-normal_cmdline.lst
+
+cmd-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_dyncmd.o: normal/dyncmd.c $(normal/dyncmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_dyncmd.d
+
+clean-module-normal_mod-normal_dyncmd-extra.1:
+	rm -f cmd-normal_mod-normal_dyncmd.lst fs-normal_mod-normal_dyncmd.lst partmap-normal_mod-normal_dyncmd.lst handler-normal_mod-normal_dyncmd.lst parttool-normal_mod-normal_dyncmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_dyncmd-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_dyncmd.lst
+FSFILES += fs-normal_mod-normal_dyncmd.lst
+PARTTOOLFILES += parttool-normal_mod-normal_dyncmd.lst
+PARTMAPFILES += partmap-normal_mod-normal_dyncmd.lst
+HANDLERFILES += handler-normal_mod-normal_dyncmd.lst
+
+cmd-normal_mod-normal_dyncmd.lst: normal/dyncmd.c $(normal/dyncmd.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_dyncmd.lst: normal/dyncmd.c $(normal/dyncmd.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_dyncmd.lst: normal/dyncmd.c $(normal/dyncmd.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_dyncmd.lst: normal/dyncmd.c $(normal/dyncmd.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_dyncmd.lst: normal/dyncmd.c $(normal/dyncmd.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_auth.o: normal/auth.c $(normal/auth.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_auth.d
+
+clean-module-normal_mod-normal_auth-extra.1:
+	rm -f cmd-normal_mod-normal_auth.lst fs-normal_mod-normal_auth.lst partmap-normal_mod-normal_auth.lst handler-normal_mod-normal_auth.lst parttool-normal_mod-normal_auth.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_auth-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_auth.lst
+FSFILES += fs-normal_mod-normal_auth.lst
+PARTTOOLFILES += parttool-normal_mod-normal_auth.lst
+PARTMAPFILES += partmap-normal_mod-normal_auth.lst
+HANDLERFILES += handler-normal_mod-normal_auth.lst
+
+cmd-normal_mod-normal_auth.lst: normal/auth.c $(normal/auth.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_auth.lst: normal/auth.c $(normal/auth.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_auth.lst: normal/auth.c $(normal/auth.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_auth.lst: normal/auth.c $(normal/auth.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_auth.lst: normal/auth.c $(normal/auth.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_autofs.o: normal/autofs.c $(normal/autofs.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_autofs.d
+
+clean-module-normal_mod-normal_autofs-extra.1:
+	rm -f cmd-normal_mod-normal_autofs.lst fs-normal_mod-normal_autofs.lst partmap-normal_mod-normal_autofs.lst handler-normal_mod-normal_autofs.lst parttool-normal_mod-normal_autofs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_autofs-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_autofs.lst
+FSFILES += fs-normal_mod-normal_autofs.lst
+PARTTOOLFILES += parttool-normal_mod-normal_autofs.lst
+PARTMAPFILES += partmap-normal_mod-normal_autofs.lst
+HANDLERFILES += handler-normal_mod-normal_autofs.lst
+
+cmd-normal_mod-normal_autofs.lst: normal/autofs.c $(normal/autofs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_autofs.lst: normal/autofs.c $(normal/autofs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_autofs.lst: normal/autofs.c $(normal/autofs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_autofs.lst: normal/autofs.c $(normal/autofs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_autofs.lst: normal/autofs.c $(normal/autofs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_handler.o: normal/handler.c $(normal/handler.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_handler.d
+
+clean-module-normal_mod-normal_handler-extra.1:
+	rm -f cmd-normal_mod-normal_handler.lst fs-normal_mod-normal_handler.lst partmap-normal_mod-normal_handler.lst handler-normal_mod-normal_handler.lst parttool-normal_mod-normal_handler.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_handler-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_handler.lst
+FSFILES += fs-normal_mod-normal_handler.lst
+PARTTOOLFILES += parttool-normal_mod-normal_handler.lst
+PARTMAPFILES += partmap-normal_mod-normal_handler.lst
+HANDLERFILES += handler-normal_mod-normal_handler.lst
+
+cmd-normal_mod-normal_handler.lst: normal/handler.c $(normal/handler.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_handler.lst: normal/handler.c $(normal/handler.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_handler.lst: normal/handler.c $(normal/handler.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_handler.lst: normal/handler.c $(normal/handler.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_handler.lst: normal/handler.c $(normal/handler.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_color.d
+
+clean-module-normal_mod-normal_color-extra.1:
+	rm -f cmd-normal_mod-normal_color.lst fs-normal_mod-normal_color.lst partmap-normal_mod-normal_color.lst handler-normal_mod-normal_color.lst parttool-normal_mod-normal_color.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_color-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_color.lst
+FSFILES += fs-normal_mod-normal_color.lst
+PARTTOOLFILES += parttool-normal_mod-normal_color.lst
+PARTMAPFILES += partmap-normal_mod-normal_color.lst
+HANDLERFILES += handler-normal_mod-normal_color.lst
+
+cmd-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_completion.d
+
+clean-module-normal_mod-normal_completion-extra.1:
+	rm -f cmd-normal_mod-normal_completion.lst fs-normal_mod-normal_completion.lst partmap-normal_mod-normal_completion.lst handler-normal_mod-normal_completion.lst parttool-normal_mod-normal_completion.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_completion-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_completion.lst
+FSFILES += fs-normal_mod-normal_completion.lst
+PARTTOOLFILES += parttool-normal_mod-normal_completion.lst
+PARTMAPFILES += partmap-normal_mod-normal_completion.lst
+HANDLERFILES += handler-normal_mod-normal_completion.lst
+
+cmd-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_datetime.o: normal/datetime.c $(normal/datetime.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_datetime.d
+
+clean-module-normal_mod-normal_datetime-extra.1:
+	rm -f cmd-normal_mod-normal_datetime.lst fs-normal_mod-normal_datetime.lst partmap-normal_mod-normal_datetime.lst handler-normal_mod-normal_datetime.lst parttool-normal_mod-normal_datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_datetime-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_datetime.lst
+FSFILES += fs-normal_mod-normal_datetime.lst
+PARTTOOLFILES += parttool-normal_mod-normal_datetime.lst
+PARTMAPFILES += partmap-normal_mod-normal_datetime.lst
+HANDLERFILES += handler-normal_mod-normal_datetime.lst
+
+cmd-normal_mod-normal_datetime.lst: normal/datetime.c $(normal/datetime.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_datetime.lst: normal/datetime.c $(normal/datetime.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_datetime.lst: normal/datetime.c $(normal/datetime.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_datetime.lst: normal/datetime.c $(normal/datetime.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_datetime.lst: normal/datetime.c $(normal/datetime.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_menu.d
+
+clean-module-normal_mod-normal_menu-extra.1:
+	rm -f cmd-normal_mod-normal_menu.lst fs-normal_mod-normal_menu.lst partmap-normal_mod-normal_menu.lst handler-normal_mod-normal_menu.lst parttool-normal_mod-normal_menu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_menu-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_menu.lst
+FSFILES += fs-normal_mod-normal_menu.lst
+PARTTOOLFILES += parttool-normal_mod-normal_menu.lst
+PARTMAPFILES += partmap-normal_mod-normal_menu.lst
+HANDLERFILES += handler-normal_mod-normal_menu.lst
+
+cmd-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_menu_entry.d
+
+clean-module-normal_mod-normal_menu_entry-extra.1:
+	rm -f cmd-normal_mod-normal_menu_entry.lst fs-normal_mod-normal_menu_entry.lst partmap-normal_mod-normal_menu_entry.lst handler-normal_mod-normal_menu_entry.lst parttool-normal_mod-normal_menu_entry.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_menu_entry-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_menu_entry.lst
+FSFILES += fs-normal_mod-normal_menu_entry.lst
+PARTTOOLFILES += parttool-normal_mod-normal_menu_entry.lst
+PARTMAPFILES += partmap-normal_mod-normal_menu_entry.lst
+HANDLERFILES += handler-normal_mod-normal_menu_entry.lst
+
+cmd-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_menu_text.d
+
+clean-module-normal_mod-normal_menu_text-extra.1:
+	rm -f cmd-normal_mod-normal_menu_text.lst fs-normal_mod-normal_menu_text.lst partmap-normal_mod-normal_menu_text.lst handler-normal_mod-normal_menu_text.lst parttool-normal_mod-normal_menu_text.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_menu_text-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_menu_text.lst
+FSFILES += fs-normal_mod-normal_menu_text.lst
+PARTTOOLFILES += parttool-normal_mod-normal_menu_text.lst
+PARTMAPFILES += partmap-normal_mod-normal_menu_text.lst
+HANDLERFILES += handler-normal_mod-normal_menu_text.lst
+
+cmd-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_menu_viewer.d
+
+clean-module-normal_mod-normal_menu_viewer-extra.1:
+	rm -f cmd-normal_mod-normal_menu_viewer.lst fs-normal_mod-normal_menu_viewer.lst partmap-normal_mod-normal_menu_viewer.lst handler-normal_mod-normal_menu_viewer.lst parttool-normal_mod-normal_menu_viewer.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_menu_viewer-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_menu_viewer.lst
+FSFILES += fs-normal_mod-normal_menu_viewer.lst
+PARTTOOLFILES += parttool-normal_mod-normal_menu_viewer.lst
+PARTMAPFILES += partmap-normal_mod-normal_menu_viewer.lst
+HANDLERFILES += handler-normal_mod-normal_menu_viewer.lst
+
+cmd-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES)
+	$(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $<
+-include normal_mod-normal_misc.d
+
+clean-module-normal_mod-normal_misc-extra.1:
+	rm -f cmd-normal_mod-normal_misc.lst fs-normal_mod-normal_misc.lst partmap-normal_mod-normal_misc.lst handler-normal_mod-normal_misc.lst parttool-normal_mod-normal_misc.lst
+
+CLEAN_MODULE_TARGETS += clean-module-normal_mod-normal_misc-extra.1
+
+COMMANDFILES += cmd-normal_mod-normal_misc.lst
+FSFILES += fs-normal_mod-normal_misc.lst
+PARTTOOLFILES += parttool-normal_mod-normal_misc.lst
+PARTMAPFILES += partmap-normal_mod-normal_misc.lst
+HANDLERFILES += handler-normal_mod-normal_misc.lst
+
+cmd-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1)
+
+fs-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
+
+parttool-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh normal > $@ || (rm -f $@; exit 1)
+
+partmap-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1)
+
+handler-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh normal > $@ || (rm -f $@; exit 1)
+
+normal_mod_CFLAGS = $(COMMON_CFLAGS)
+normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For sh.mod.
+sh_mod_SOURCES = script/sh/main.c script/sh/script.c script/sh/execute.c \
+	script/sh/function.c script/sh/lexer.c grub_script.tab.c
+
+clean-module-sh.mod.1:
+	rm -f sh.mod mod-sh.o mod-sh.c pre-sh.o sh_mod-script_sh_main.o sh_mod-script_sh_script.o sh_mod-script_sh_execute.o sh_mod-script_sh_function.o sh_mod-script_sh_lexer.o sh_mod-grub_script_tab.o und-sh.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sh.mod.1
+
+ifneq ($(sh_mod_EXPORTS),no)
+clean-module-sh.mod-symbol.1:
+	rm -f def-sh.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sh.mod-symbol.1
+DEFSYMFILES += def-sh.lst
+endif
+mostlyclean-module-sh.mod.1:
+	rm -f sh_mod-script_sh_main.d sh_mod-script_sh_script.d sh_mod-script_sh_execute.d sh_mod-script_sh_function.d sh_mod-script_sh_lexer.d sh_mod-grub_script_tab.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-sh.mod.1
+UNDSYMFILES += und-sh.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+sh.mod: pre-sh.o mod-sh.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(sh_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-sh.o mod-sh.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+sh.mod: pre-sh.o mod-sh.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(sh_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-sh.o mod-sh.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-sh.o: $(sh_mod_DEPENDENCIES) sh_mod-script_sh_main.o sh_mod-script_sh_script.o sh_mod-script_sh_execute.o sh_mod-script_sh_function.o sh_mod-script_sh_lexer.o sh_mod-grub_script_tab.o
+	-rm -f $@
+	$(TARGET_CC) $(sh_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ sh_mod-script_sh_main.o sh_mod-script_sh_script.o sh_mod-script_sh_execute.o sh_mod-script_sh_function.o sh_mod-script_sh_lexer.o sh_mod-grub_script_tab.o
+
+mod-sh.o: mod-sh.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -c -o $@ $<
+
+mod-sh.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'sh' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(sh_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-sh.lst: pre-sh.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 sh/' > $@
+else
+def-sh.lst: pre-sh.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 sh/' > $@
+endif
+endif
+
+und-sh.lst: pre-sh.o
+	echo 'sh' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+sh_mod-script_sh_main.o: script/sh/main.c $(script/sh/main.c_DEPENDENCIES)
+	$(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -MD -c -o $@ $<
+-include sh_mod-script_sh_main.d
+
+clean-module-sh_mod-script_sh_main-extra.1:
+	rm -f cmd-sh_mod-script_sh_main.lst fs-sh_mod-script_sh_main.lst partmap-sh_mod-script_sh_main.lst handler-sh_mod-script_sh_main.lst parttool-sh_mod-script_sh_main.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sh_mod-script_sh_main-extra.1
+
+COMMANDFILES += cmd-sh_mod-script_sh_main.lst
+FSFILES += fs-sh_mod-script_sh_main.lst
+PARTTOOLFILES += parttool-sh_mod-script_sh_main.lst
+PARTMAPFILES += partmap-sh_mod-script_sh_main.lst
+HANDLERFILES += handler-sh_mod-script_sh_main.lst
+
+cmd-sh_mod-script_sh_main.lst: script/sh/main.c $(script/sh/main.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh sh > $@ || (rm -f $@; exit 1)
+
+fs-sh_mod-script_sh_main.lst: script/sh/main.c $(script/sh/main.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh sh > $@ || (rm -f $@; exit 1)
+
+parttool-sh_mod-script_sh_main.lst: script/sh/main.c $(script/sh/main.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh sh > $@ || (rm -f $@; exit 1)
+
+partmap-sh_mod-script_sh_main.lst: script/sh/main.c $(script/sh/main.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh sh > $@ || (rm -f $@; exit 1)
+
+handler-sh_mod-script_sh_main.lst: script/sh/main.c $(script/sh/main.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh sh > $@ || (rm -f $@; exit 1)
+
+sh_mod-script_sh_script.o: script/sh/script.c $(script/sh/script.c_DEPENDENCIES)
+	$(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -MD -c -o $@ $<
+-include sh_mod-script_sh_script.d
+
+clean-module-sh_mod-script_sh_script-extra.1:
+	rm -f cmd-sh_mod-script_sh_script.lst fs-sh_mod-script_sh_script.lst partmap-sh_mod-script_sh_script.lst handler-sh_mod-script_sh_script.lst parttool-sh_mod-script_sh_script.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sh_mod-script_sh_script-extra.1
+
+COMMANDFILES += cmd-sh_mod-script_sh_script.lst
+FSFILES += fs-sh_mod-script_sh_script.lst
+PARTTOOLFILES += parttool-sh_mod-script_sh_script.lst
+PARTMAPFILES += partmap-sh_mod-script_sh_script.lst
+HANDLERFILES += handler-sh_mod-script_sh_script.lst
+
+cmd-sh_mod-script_sh_script.lst: script/sh/script.c $(script/sh/script.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh sh > $@ || (rm -f $@; exit 1)
+
+fs-sh_mod-script_sh_script.lst: script/sh/script.c $(script/sh/script.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh sh > $@ || (rm -f $@; exit 1)
+
+parttool-sh_mod-script_sh_script.lst: script/sh/script.c $(script/sh/script.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh sh > $@ || (rm -f $@; exit 1)
+
+partmap-sh_mod-script_sh_script.lst: script/sh/script.c $(script/sh/script.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh sh > $@ || (rm -f $@; exit 1)
+
+handler-sh_mod-script_sh_script.lst: script/sh/script.c $(script/sh/script.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh sh > $@ || (rm -f $@; exit 1)
+
+sh_mod-script_sh_execute.o: script/sh/execute.c $(script/sh/execute.c_DEPENDENCIES)
+	$(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -MD -c -o $@ $<
+-include sh_mod-script_sh_execute.d
+
+clean-module-sh_mod-script_sh_execute-extra.1:
+	rm -f cmd-sh_mod-script_sh_execute.lst fs-sh_mod-script_sh_execute.lst partmap-sh_mod-script_sh_execute.lst handler-sh_mod-script_sh_execute.lst parttool-sh_mod-script_sh_execute.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sh_mod-script_sh_execute-extra.1
+
+COMMANDFILES += cmd-sh_mod-script_sh_execute.lst
+FSFILES += fs-sh_mod-script_sh_execute.lst
+PARTTOOLFILES += parttool-sh_mod-script_sh_execute.lst
+PARTMAPFILES += partmap-sh_mod-script_sh_execute.lst
+HANDLERFILES += handler-sh_mod-script_sh_execute.lst
+
+cmd-sh_mod-script_sh_execute.lst: script/sh/execute.c $(script/sh/execute.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh sh > $@ || (rm -f $@; exit 1)
+
+fs-sh_mod-script_sh_execute.lst: script/sh/execute.c $(script/sh/execute.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh sh > $@ || (rm -f $@; exit 1)
+
+parttool-sh_mod-script_sh_execute.lst: script/sh/execute.c $(script/sh/execute.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh sh > $@ || (rm -f $@; exit 1)
+
+partmap-sh_mod-script_sh_execute.lst: script/sh/execute.c $(script/sh/execute.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh sh > $@ || (rm -f $@; exit 1)
+
+handler-sh_mod-script_sh_execute.lst: script/sh/execute.c $(script/sh/execute.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh sh > $@ || (rm -f $@; exit 1)
+
+sh_mod-script_sh_function.o: script/sh/function.c $(script/sh/function.c_DEPENDENCIES)
+	$(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -MD -c -o $@ $<
+-include sh_mod-script_sh_function.d
+
+clean-module-sh_mod-script_sh_function-extra.1:
+	rm -f cmd-sh_mod-script_sh_function.lst fs-sh_mod-script_sh_function.lst partmap-sh_mod-script_sh_function.lst handler-sh_mod-script_sh_function.lst parttool-sh_mod-script_sh_function.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sh_mod-script_sh_function-extra.1
+
+COMMANDFILES += cmd-sh_mod-script_sh_function.lst
+FSFILES += fs-sh_mod-script_sh_function.lst
+PARTTOOLFILES += parttool-sh_mod-script_sh_function.lst
+PARTMAPFILES += partmap-sh_mod-script_sh_function.lst
+HANDLERFILES += handler-sh_mod-script_sh_function.lst
+
+cmd-sh_mod-script_sh_function.lst: script/sh/function.c $(script/sh/function.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh sh > $@ || (rm -f $@; exit 1)
+
+fs-sh_mod-script_sh_function.lst: script/sh/function.c $(script/sh/function.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh sh > $@ || (rm -f $@; exit 1)
+
+parttool-sh_mod-script_sh_function.lst: script/sh/function.c $(script/sh/function.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh sh > $@ || (rm -f $@; exit 1)
+
+partmap-sh_mod-script_sh_function.lst: script/sh/function.c $(script/sh/function.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh sh > $@ || (rm -f $@; exit 1)
+
+handler-sh_mod-script_sh_function.lst: script/sh/function.c $(script/sh/function.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh sh > $@ || (rm -f $@; exit 1)
+
+sh_mod-script_sh_lexer.o: script/sh/lexer.c $(script/sh/lexer.c_DEPENDENCIES)
+	$(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -MD -c -o $@ $<
+-include sh_mod-script_sh_lexer.d
+
+clean-module-sh_mod-script_sh_lexer-extra.1:
+	rm -f cmd-sh_mod-script_sh_lexer.lst fs-sh_mod-script_sh_lexer.lst partmap-sh_mod-script_sh_lexer.lst handler-sh_mod-script_sh_lexer.lst parttool-sh_mod-script_sh_lexer.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sh_mod-script_sh_lexer-extra.1
+
+COMMANDFILES += cmd-sh_mod-script_sh_lexer.lst
+FSFILES += fs-sh_mod-script_sh_lexer.lst
+PARTTOOLFILES += parttool-sh_mod-script_sh_lexer.lst
+PARTMAPFILES += partmap-sh_mod-script_sh_lexer.lst
+HANDLERFILES += handler-sh_mod-script_sh_lexer.lst
+
+cmd-sh_mod-script_sh_lexer.lst: script/sh/lexer.c $(script/sh/lexer.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh sh > $@ || (rm -f $@; exit 1)
+
+fs-sh_mod-script_sh_lexer.lst: script/sh/lexer.c $(script/sh/lexer.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh sh > $@ || (rm -f $@; exit 1)
+
+parttool-sh_mod-script_sh_lexer.lst: script/sh/lexer.c $(script/sh/lexer.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh sh > $@ || (rm -f $@; exit 1)
+
+partmap-sh_mod-script_sh_lexer.lst: script/sh/lexer.c $(script/sh/lexer.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh sh > $@ || (rm -f $@; exit 1)
+
+handler-sh_mod-script_sh_lexer.lst: script/sh/lexer.c $(script/sh/lexer.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iscript/sh -I$(srcdir)/script/sh $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh sh > $@ || (rm -f $@; exit 1)
+
+sh_mod-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES)
+	$(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -MD -c -o $@ $<
+-include sh_mod-grub_script_tab.d
+
+clean-module-sh_mod-grub_script_tab-extra.1:
+	rm -f cmd-sh_mod-grub_script_tab.lst fs-sh_mod-grub_script_tab.lst partmap-sh_mod-grub_script_tab.lst handler-sh_mod-grub_script_tab.lst parttool-sh_mod-grub_script_tab.lst
+
+CLEAN_MODULE_TARGETS += clean-module-sh_mod-grub_script_tab-extra.1
+
+COMMANDFILES += cmd-sh_mod-grub_script_tab.lst
+FSFILES += fs-sh_mod-grub_script_tab.lst
+PARTTOOLFILES += parttool-sh_mod-grub_script_tab.lst
+PARTMAPFILES += partmap-sh_mod-grub_script_tab.lst
+HANDLERFILES += handler-sh_mod-grub_script_tab.lst
+
+cmd-sh_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh sh > $@ || (rm -f $@; exit 1)
+
+fs-sh_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh sh > $@ || (rm -f $@; exit 1)
+
+parttool-sh_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh sh > $@ || (rm -f $@; exit 1)
+
+partmap-sh_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh sh > $@ || (rm -f $@; exit 1)
+
+handler-sh_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(sh_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh sh > $@ || (rm -f $@; exit 1)
+
+sh_mod_CFLAGS = $(COMMON_CFLAGS)
+sh_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Common Video Subsystem specific modules.
+pkglib_MODULES += video.mod videotest.mod bitmap.mod tga.mod jpeg.mod	\
+	png.mod	font.mod gfxterm.mod video_fb.mod
+
+# For video.mod.
+video_mod_SOURCES = video/video.c
+
+clean-module-video.mod.1:
+	rm -f video.mod mod-video.o mod-video.c pre-video.o video_mod-video_video.o und-video.lst
+
+CLEAN_MODULE_TARGETS += clean-module-video.mod.1
+
+ifneq ($(video_mod_EXPORTS),no)
+clean-module-video.mod-symbol.1:
+	rm -f def-video.lst
+
+CLEAN_MODULE_TARGETS += clean-module-video.mod-symbol.1
+DEFSYMFILES += def-video.lst
+endif
+mostlyclean-module-video.mod.1:
+	rm -f video_mod-video_video.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-video.mod.1
+UNDSYMFILES += und-video.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+video.mod: pre-video.o mod-video.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(video_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-video.o mod-video.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+video.mod: pre-video.o mod-video.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(video_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-video.o mod-video.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-video.o: $(video_mod_DEPENDENCIES) video_mod-video_video.o
+	-rm -f $@
+	$(TARGET_CC) $(video_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ video_mod-video_video.o
+
+mod-video.o: mod-video.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(video_mod_CFLAGS) -c -o $@ $<
+
+mod-video.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'video' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(video_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-video.lst: pre-video.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 video/' > $@
+else
+def-video.lst: pre-video.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 video/' > $@
+endif
+endif
+
+und-video.lst: pre-video.o
+	echo 'video' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+video_mod-video_video.o: video/video.c $(video/video.c_DEPENDENCIES)
+	$(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_mod_CFLAGS) -MD -c -o $@ $<
+-include video_mod-video_video.d
+
+clean-module-video_mod-video_video-extra.1:
+	rm -f cmd-video_mod-video_video.lst fs-video_mod-video_video.lst partmap-video_mod-video_video.lst handler-video_mod-video_video.lst parttool-video_mod-video_video.lst
+
+CLEAN_MODULE_TARGETS += clean-module-video_mod-video_video-extra.1
+
+COMMANDFILES += cmd-video_mod-video_video.lst
+FSFILES += fs-video_mod-video_video.lst
+PARTTOOLFILES += parttool-video_mod-video_video.lst
+PARTMAPFILES += partmap-video_mod-video_video.lst
+HANDLERFILES += handler-video_mod-video_video.lst
+
+cmd-video_mod-video_video.lst: video/video.c $(video/video.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh video > $@ || (rm -f $@; exit 1)
+
+fs-video_mod-video_video.lst: video/video.c $(video/video.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh video > $@ || (rm -f $@; exit 1)
+
+parttool-video_mod-video_video.lst: video/video.c $(video/video.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh video > $@ || (rm -f $@; exit 1)
+
+partmap-video_mod-video_video.lst: video/video.c $(video/video.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh video > $@ || (rm -f $@; exit 1)
+
+handler-video_mod-video_video.lst: video/video.c $(video/video.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh video > $@ || (rm -f $@; exit 1)
+
+video_mod_CFLAGS = $(COMMON_CFLAGS)
+video_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+video_fb_mod_SOURCES = video/fb/video_fb.c video/fb/fbblit.c \
+		  video/fb/fbfill.c video/fb/fbutil.c
+
+clean-module-video_fb.mod.1:
+	rm -f video_fb.mod mod-video_fb.o mod-video_fb.c pre-video_fb.o video_fb_mod-video_fb_video_fb.o video_fb_mod-video_fb_fbblit.o video_fb_mod-video_fb_fbfill.o video_fb_mod-video_fb_fbutil.o und-video_fb.lst
+
+CLEAN_MODULE_TARGETS += clean-module-video_fb.mod.1
+
+ifneq ($(video_fb_mod_EXPORTS),no)
+clean-module-video_fb.mod-symbol.1:
+	rm -f def-video_fb.lst
+
+CLEAN_MODULE_TARGETS += clean-module-video_fb.mod-symbol.1
+DEFSYMFILES += def-video_fb.lst
+endif
+mostlyclean-module-video_fb.mod.1:
+	rm -f video_fb_mod-video_fb_video_fb.d video_fb_mod-video_fb_fbblit.d video_fb_mod-video_fb_fbfill.d video_fb_mod-video_fb_fbutil.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-video_fb.mod.1
+UNDSYMFILES += und-video_fb.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+video_fb.mod: pre-video_fb.o mod-video_fb.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(video_fb_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-video_fb.o mod-video_fb.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+video_fb.mod: pre-video_fb.o mod-video_fb.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(video_fb_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-video_fb.o mod-video_fb.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-video_fb.o: $(video_fb_mod_DEPENDENCIES) video_fb_mod-video_fb_video_fb.o video_fb_mod-video_fb_fbblit.o video_fb_mod-video_fb_fbfill.o video_fb_mod-video_fb_fbutil.o
+	-rm -f $@
+	$(TARGET_CC) $(video_fb_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ video_fb_mod-video_fb_video_fb.o video_fb_mod-video_fb_fbblit.o video_fb_mod-video_fb_fbfill.o video_fb_mod-video_fb_fbutil.o
+
+mod-video_fb.o: mod-video_fb.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -c -o $@ $<
+
+mod-video_fb.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'video_fb' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(video_fb_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-video_fb.lst: pre-video_fb.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 video_fb/' > $@
+else
+def-video_fb.lst: pre-video_fb.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 video_fb/' > $@
+endif
+endif
+
+und-video_fb.lst: pre-video_fb.o
+	echo 'video_fb' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+video_fb_mod-video_fb_video_fb.o: video/fb/video_fb.c $(video/fb/video_fb.c_DEPENDENCIES)
+	$(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -MD -c -o $@ $<
+-include video_fb_mod-video_fb_video_fb.d
+
+clean-module-video_fb_mod-video_fb_video_fb-extra.1:
+	rm -f cmd-video_fb_mod-video_fb_video_fb.lst fs-video_fb_mod-video_fb_video_fb.lst partmap-video_fb_mod-video_fb_video_fb.lst handler-video_fb_mod-video_fb_video_fb.lst parttool-video_fb_mod-video_fb_video_fb.lst
+
+CLEAN_MODULE_TARGETS += clean-module-video_fb_mod-video_fb_video_fb-extra.1
+
+COMMANDFILES += cmd-video_fb_mod-video_fb_video_fb.lst
+FSFILES += fs-video_fb_mod-video_fb_video_fb.lst
+PARTTOOLFILES += parttool-video_fb_mod-video_fb_video_fb.lst
+PARTMAPFILES += partmap-video_fb_mod-video_fb_video_fb.lst
+HANDLERFILES += handler-video_fb_mod-video_fb_video_fb.lst
+
+cmd-video_fb_mod-video_fb_video_fb.lst: video/fb/video_fb.c $(video/fb/video_fb.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+fs-video_fb_mod-video_fb_video_fb.lst: video/fb/video_fb.c $(video/fb/video_fb.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+parttool-video_fb_mod-video_fb_video_fb.lst: video/fb/video_fb.c $(video/fb/video_fb.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+partmap-video_fb_mod-video_fb_video_fb.lst: video/fb/video_fb.c $(video/fb/video_fb.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+handler-video_fb_mod-video_fb_video_fb.lst: video/fb/video_fb.c $(video/fb/video_fb.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+video_fb_mod-video_fb_fbblit.o: video/fb/fbblit.c $(video/fb/fbblit.c_DEPENDENCIES)
+	$(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -MD -c -o $@ $<
+-include video_fb_mod-video_fb_fbblit.d
+
+clean-module-video_fb_mod-video_fb_fbblit-extra.1:
+	rm -f cmd-video_fb_mod-video_fb_fbblit.lst fs-video_fb_mod-video_fb_fbblit.lst partmap-video_fb_mod-video_fb_fbblit.lst handler-video_fb_mod-video_fb_fbblit.lst parttool-video_fb_mod-video_fb_fbblit.lst
+
+CLEAN_MODULE_TARGETS += clean-module-video_fb_mod-video_fb_fbblit-extra.1
+
+COMMANDFILES += cmd-video_fb_mod-video_fb_fbblit.lst
+FSFILES += fs-video_fb_mod-video_fb_fbblit.lst
+PARTTOOLFILES += parttool-video_fb_mod-video_fb_fbblit.lst
+PARTMAPFILES += partmap-video_fb_mod-video_fb_fbblit.lst
+HANDLERFILES += handler-video_fb_mod-video_fb_fbblit.lst
+
+cmd-video_fb_mod-video_fb_fbblit.lst: video/fb/fbblit.c $(video/fb/fbblit.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+fs-video_fb_mod-video_fb_fbblit.lst: video/fb/fbblit.c $(video/fb/fbblit.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+parttool-video_fb_mod-video_fb_fbblit.lst: video/fb/fbblit.c $(video/fb/fbblit.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+partmap-video_fb_mod-video_fb_fbblit.lst: video/fb/fbblit.c $(video/fb/fbblit.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+handler-video_fb_mod-video_fb_fbblit.lst: video/fb/fbblit.c $(video/fb/fbblit.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+video_fb_mod-video_fb_fbfill.o: video/fb/fbfill.c $(video/fb/fbfill.c_DEPENDENCIES)
+	$(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -MD -c -o $@ $<
+-include video_fb_mod-video_fb_fbfill.d
+
+clean-module-video_fb_mod-video_fb_fbfill-extra.1:
+	rm -f cmd-video_fb_mod-video_fb_fbfill.lst fs-video_fb_mod-video_fb_fbfill.lst partmap-video_fb_mod-video_fb_fbfill.lst handler-video_fb_mod-video_fb_fbfill.lst parttool-video_fb_mod-video_fb_fbfill.lst
+
+CLEAN_MODULE_TARGETS += clean-module-video_fb_mod-video_fb_fbfill-extra.1
+
+COMMANDFILES += cmd-video_fb_mod-video_fb_fbfill.lst
+FSFILES += fs-video_fb_mod-video_fb_fbfill.lst
+PARTTOOLFILES += parttool-video_fb_mod-video_fb_fbfill.lst
+PARTMAPFILES += partmap-video_fb_mod-video_fb_fbfill.lst
+HANDLERFILES += handler-video_fb_mod-video_fb_fbfill.lst
+
+cmd-video_fb_mod-video_fb_fbfill.lst: video/fb/fbfill.c $(video/fb/fbfill.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+fs-video_fb_mod-video_fb_fbfill.lst: video/fb/fbfill.c $(video/fb/fbfill.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+parttool-video_fb_mod-video_fb_fbfill.lst: video/fb/fbfill.c $(video/fb/fbfill.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+partmap-video_fb_mod-video_fb_fbfill.lst: video/fb/fbfill.c $(video/fb/fbfill.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+handler-video_fb_mod-video_fb_fbfill.lst: video/fb/fbfill.c $(video/fb/fbfill.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+video_fb_mod-video_fb_fbutil.o: video/fb/fbutil.c $(video/fb/fbutil.c_DEPENDENCIES)
+	$(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -MD -c -o $@ $<
+-include video_fb_mod-video_fb_fbutil.d
+
+clean-module-video_fb_mod-video_fb_fbutil-extra.1:
+	rm -f cmd-video_fb_mod-video_fb_fbutil.lst fs-video_fb_mod-video_fb_fbutil.lst partmap-video_fb_mod-video_fb_fbutil.lst handler-video_fb_mod-video_fb_fbutil.lst parttool-video_fb_mod-video_fb_fbutil.lst
+
+CLEAN_MODULE_TARGETS += clean-module-video_fb_mod-video_fb_fbutil-extra.1
+
+COMMANDFILES += cmd-video_fb_mod-video_fb_fbutil.lst
+FSFILES += fs-video_fb_mod-video_fb_fbutil.lst
+PARTTOOLFILES += parttool-video_fb_mod-video_fb_fbutil.lst
+PARTMAPFILES += partmap-video_fb_mod-video_fb_fbutil.lst
+HANDLERFILES += handler-video_fb_mod-video_fb_fbutil.lst
+
+cmd-video_fb_mod-video_fb_fbutil.lst: video/fb/fbutil.c $(video/fb/fbutil.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+fs-video_fb_mod-video_fb_fbutil.lst: video/fb/fbutil.c $(video/fb/fbutil.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+parttool-video_fb_mod-video_fb_fbutil.lst: video/fb/fbutil.c $(video/fb/fbutil.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+partmap-video_fb_mod-video_fb_fbutil.lst: video/fb/fbutil.c $(video/fb/fbutil.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+handler-video_fb_mod-video_fb_fbutil.lst: video/fb/fbutil.c $(video/fb/fbutil.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/fb -I$(srcdir)/video/fb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(video_fb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh video_fb > $@ || (rm -f $@; exit 1)
+
+video_fb_mod_CFLAGS = $(COMMON_CFLAGS)
+video_fb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For videotest.mod.
+videotest_mod_SOURCES = commands/videotest.c
+
+clean-module-videotest.mod.1:
+	rm -f videotest.mod mod-videotest.o mod-videotest.c pre-videotest.o videotest_mod-commands_videotest.o und-videotest.lst
+
+CLEAN_MODULE_TARGETS += clean-module-videotest.mod.1
+
+ifneq ($(videotest_mod_EXPORTS),no)
+clean-module-videotest.mod-symbol.1:
+	rm -f def-videotest.lst
+
+CLEAN_MODULE_TARGETS += clean-module-videotest.mod-symbol.1
+DEFSYMFILES += def-videotest.lst
+endif
+mostlyclean-module-videotest.mod.1:
+	rm -f videotest_mod-commands_videotest.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-videotest.mod.1
+UNDSYMFILES += und-videotest.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+videotest.mod: pre-videotest.o mod-videotest.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(videotest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-videotest.o mod-videotest.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+videotest.mod: pre-videotest.o mod-videotest.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(videotest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-videotest.o mod-videotest.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-videotest.o: $(videotest_mod_DEPENDENCIES) videotest_mod-commands_videotest.o
+	-rm -f $@
+	$(TARGET_CC) $(videotest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ videotest_mod-commands_videotest.o
+
+mod-videotest.o: mod-videotest.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(videotest_mod_CFLAGS) -c -o $@ $<
+
+mod-videotest.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'videotest' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(videotest_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-videotest.lst: pre-videotest.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 videotest/' > $@
+else
+def-videotest.lst: pre-videotest.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 videotest/' > $@
+endif
+endif
+
+und-videotest.lst: pre-videotest.o
+	echo 'videotest' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+videotest_mod-commands_videotest.o: commands/videotest.c $(commands/videotest.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(videotest_mod_CFLAGS) -MD -c -o $@ $<
+-include videotest_mod-commands_videotest.d
+
+clean-module-videotest_mod-commands_videotest-extra.1:
+	rm -f cmd-videotest_mod-commands_videotest.lst fs-videotest_mod-commands_videotest.lst partmap-videotest_mod-commands_videotest.lst handler-videotest_mod-commands_videotest.lst parttool-videotest_mod-commands_videotest.lst
+
+CLEAN_MODULE_TARGETS += clean-module-videotest_mod-commands_videotest-extra.1
+
+COMMANDFILES += cmd-videotest_mod-commands_videotest.lst
+FSFILES += fs-videotest_mod-commands_videotest.lst
+PARTTOOLFILES += parttool-videotest_mod-commands_videotest.lst
+PARTMAPFILES += partmap-videotest_mod-commands_videotest.lst
+HANDLERFILES += handler-videotest_mod-commands_videotest.lst
+
+cmd-videotest_mod-commands_videotest.lst: commands/videotest.c $(commands/videotest.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(videotest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh videotest > $@ || (rm -f $@; exit 1)
+
+fs-videotest_mod-commands_videotest.lst: commands/videotest.c $(commands/videotest.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(videotest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh videotest > $@ || (rm -f $@; exit 1)
+
+parttool-videotest_mod-commands_videotest.lst: commands/videotest.c $(commands/videotest.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(videotest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh videotest > $@ || (rm -f $@; exit 1)
+
+partmap-videotest_mod-commands_videotest.lst: commands/videotest.c $(commands/videotest.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(videotest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh videotest > $@ || (rm -f $@; exit 1)
+
+handler-videotest_mod-commands_videotest.lst: commands/videotest.c $(commands/videotest.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(videotest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh videotest > $@ || (rm -f $@; exit 1)
+
+videotest_mod_CFLAGS = $(COMMON_CFLAGS)
+videotest_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bitmap.mod
+bitmap_mod_SOURCES = video/bitmap.c
+
+clean-module-bitmap.mod.1:
+	rm -f bitmap.mod mod-bitmap.o mod-bitmap.c pre-bitmap.o bitmap_mod-video_bitmap.o und-bitmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bitmap.mod.1
+
+ifneq ($(bitmap_mod_EXPORTS),no)
+clean-module-bitmap.mod-symbol.1:
+	rm -f def-bitmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bitmap.mod-symbol.1
+DEFSYMFILES += def-bitmap.lst
+endif
+mostlyclean-module-bitmap.mod.1:
+	rm -f bitmap_mod-video_bitmap.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-bitmap.mod.1
+UNDSYMFILES += und-bitmap.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+bitmap.mod: pre-bitmap.o mod-bitmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(bitmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-bitmap.o mod-bitmap.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+bitmap.mod: pre-bitmap.o mod-bitmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(bitmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-bitmap.o mod-bitmap.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-bitmap.o: $(bitmap_mod_DEPENDENCIES) bitmap_mod-video_bitmap.o
+	-rm -f $@
+	$(TARGET_CC) $(bitmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ bitmap_mod-video_bitmap.o
+
+mod-bitmap.o: mod-bitmap.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -c -o $@ $<
+
+mod-bitmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'bitmap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(bitmap_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-bitmap.lst: pre-bitmap.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 bitmap/' > $@
+else
+def-bitmap.lst: pre-bitmap.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 bitmap/' > $@
+endif
+endif
+
+und-bitmap.lst: pre-bitmap.o
+	echo 'bitmap' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+bitmap_mod-video_bitmap.o: video/bitmap.c $(video/bitmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -MD -c -o $@ $<
+-include bitmap_mod-video_bitmap.d
+
+clean-module-bitmap_mod-video_bitmap-extra.1:
+	rm -f cmd-bitmap_mod-video_bitmap.lst fs-bitmap_mod-video_bitmap.lst partmap-bitmap_mod-video_bitmap.lst handler-bitmap_mod-video_bitmap.lst parttool-bitmap_mod-video_bitmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bitmap_mod-video_bitmap-extra.1
+
+COMMANDFILES += cmd-bitmap_mod-video_bitmap.lst
+FSFILES += fs-bitmap_mod-video_bitmap.lst
+PARTTOOLFILES += parttool-bitmap_mod-video_bitmap.lst
+PARTMAPFILES += partmap-bitmap_mod-video_bitmap.lst
+HANDLERFILES += handler-bitmap_mod-video_bitmap.lst
+
+cmd-bitmap_mod-video_bitmap.lst: video/bitmap.c $(video/bitmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh bitmap > $@ || (rm -f $@; exit 1)
+
+fs-bitmap_mod-video_bitmap.lst: video/bitmap.c $(video/bitmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh bitmap > $@ || (rm -f $@; exit 1)
+
+parttool-bitmap_mod-video_bitmap.lst: video/bitmap.c $(video/bitmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh bitmap > $@ || (rm -f $@; exit 1)
+
+partmap-bitmap_mod-video_bitmap.lst: video/bitmap.c $(video/bitmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh bitmap > $@ || (rm -f $@; exit 1)
+
+handler-bitmap_mod-video_bitmap.lst: video/bitmap.c $(video/bitmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh bitmap > $@ || (rm -f $@; exit 1)
+
+bitmap_mod_CFLAGS = $(COMMON_CFLAGS)
+bitmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For tga.mod
+tga_mod_SOURCES = video/readers/tga.c
+
+clean-module-tga.mod.1:
+	rm -f tga.mod mod-tga.o mod-tga.c pre-tga.o tga_mod-video_readers_tga.o und-tga.lst
+
+CLEAN_MODULE_TARGETS += clean-module-tga.mod.1
+
+ifneq ($(tga_mod_EXPORTS),no)
+clean-module-tga.mod-symbol.1:
+	rm -f def-tga.lst
+
+CLEAN_MODULE_TARGETS += clean-module-tga.mod-symbol.1
+DEFSYMFILES += def-tga.lst
+endif
+mostlyclean-module-tga.mod.1:
+	rm -f tga_mod-video_readers_tga.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-tga.mod.1
+UNDSYMFILES += und-tga.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+tga.mod: pre-tga.o mod-tga.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(tga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-tga.o mod-tga.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+tga.mod: pre-tga.o mod-tga.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(tga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-tga.o mod-tga.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-tga.o: $(tga_mod_DEPENDENCIES) tga_mod-video_readers_tga.o
+	-rm -f $@
+	$(TARGET_CC) $(tga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ tga_mod-video_readers_tga.o
+
+mod-tga.o: mod-tga.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -c -o $@ $<
+
+mod-tga.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'tga' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(tga_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-tga.lst: pre-tga.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 tga/' > $@
+else
+def-tga.lst: pre-tga.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 tga/' > $@
+endif
+endif
+
+und-tga.lst: pre-tga.o
+	echo 'tga' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+tga_mod-video_readers_tga.o: video/readers/tga.c $(video/readers/tga.c_DEPENDENCIES)
+	$(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -MD -c -o $@ $<
+-include tga_mod-video_readers_tga.d
+
+clean-module-tga_mod-video_readers_tga-extra.1:
+	rm -f cmd-tga_mod-video_readers_tga.lst fs-tga_mod-video_readers_tga.lst partmap-tga_mod-video_readers_tga.lst handler-tga_mod-video_readers_tga.lst parttool-tga_mod-video_readers_tga.lst
+
+CLEAN_MODULE_TARGETS += clean-module-tga_mod-video_readers_tga-extra.1
+
+COMMANDFILES += cmd-tga_mod-video_readers_tga.lst
+FSFILES += fs-tga_mod-video_readers_tga.lst
+PARTTOOLFILES += parttool-tga_mod-video_readers_tga.lst
+PARTMAPFILES += partmap-tga_mod-video_readers_tga.lst
+HANDLERFILES += handler-tga_mod-video_readers_tga.lst
+
+cmd-tga_mod-video_readers_tga.lst: video/readers/tga.c $(video/readers/tga.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh tga > $@ || (rm -f $@; exit 1)
+
+fs-tga_mod-video_readers_tga.lst: video/readers/tga.c $(video/readers/tga.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh tga > $@ || (rm -f $@; exit 1)
+
+parttool-tga_mod-video_readers_tga.lst: video/readers/tga.c $(video/readers/tga.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh tga > $@ || (rm -f $@; exit 1)
+
+partmap-tga_mod-video_readers_tga.lst: video/readers/tga.c $(video/readers/tga.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh tga > $@ || (rm -f $@; exit 1)
+
+handler-tga_mod-video_readers_tga.lst: video/readers/tga.c $(video/readers/tga.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh tga > $@ || (rm -f $@; exit 1)
+
+tga_mod_CFLAGS = $(COMMON_CFLAGS)
+tga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For jpeg.mod.
+jpeg_mod_SOURCES = video/readers/jpeg.c
+
+clean-module-jpeg.mod.1:
+	rm -f jpeg.mod mod-jpeg.o mod-jpeg.c pre-jpeg.o jpeg_mod-video_readers_jpeg.o und-jpeg.lst
+
+CLEAN_MODULE_TARGETS += clean-module-jpeg.mod.1
+
+ifneq ($(jpeg_mod_EXPORTS),no)
+clean-module-jpeg.mod-symbol.1:
+	rm -f def-jpeg.lst
+
+CLEAN_MODULE_TARGETS += clean-module-jpeg.mod-symbol.1
+DEFSYMFILES += def-jpeg.lst
+endif
+mostlyclean-module-jpeg.mod.1:
+	rm -f jpeg_mod-video_readers_jpeg.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-jpeg.mod.1
+UNDSYMFILES += und-jpeg.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+jpeg.mod: pre-jpeg.o mod-jpeg.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(jpeg_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-jpeg.o mod-jpeg.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+jpeg.mod: pre-jpeg.o mod-jpeg.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(jpeg_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-jpeg.o mod-jpeg.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-jpeg.o: $(jpeg_mod_DEPENDENCIES) jpeg_mod-video_readers_jpeg.o
+	-rm -f $@
+	$(TARGET_CC) $(jpeg_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ jpeg_mod-video_readers_jpeg.o
+
+mod-jpeg.o: mod-jpeg.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jpeg_mod_CFLAGS) -c -o $@ $<
+
+mod-jpeg.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'jpeg' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(jpeg_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-jpeg.lst: pre-jpeg.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 jpeg/' > $@
+else
+def-jpeg.lst: pre-jpeg.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 jpeg/' > $@
+endif
+endif
+
+und-jpeg.lst: pre-jpeg.o
+	echo 'jpeg' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+jpeg_mod-video_readers_jpeg.o: video/readers/jpeg.c $(video/readers/jpeg.c_DEPENDENCIES)
+	$(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(jpeg_mod_CFLAGS) -MD -c -o $@ $<
+-include jpeg_mod-video_readers_jpeg.d
+
+clean-module-jpeg_mod-video_readers_jpeg-extra.1:
+	rm -f cmd-jpeg_mod-video_readers_jpeg.lst fs-jpeg_mod-video_readers_jpeg.lst partmap-jpeg_mod-video_readers_jpeg.lst handler-jpeg_mod-video_readers_jpeg.lst parttool-jpeg_mod-video_readers_jpeg.lst
+
+CLEAN_MODULE_TARGETS += clean-module-jpeg_mod-video_readers_jpeg-extra.1
+
+COMMANDFILES += cmd-jpeg_mod-video_readers_jpeg.lst
+FSFILES += fs-jpeg_mod-video_readers_jpeg.lst
+PARTTOOLFILES += parttool-jpeg_mod-video_readers_jpeg.lst
+PARTMAPFILES += partmap-jpeg_mod-video_readers_jpeg.lst
+HANDLERFILES += handler-jpeg_mod-video_readers_jpeg.lst
+
+cmd-jpeg_mod-video_readers_jpeg.lst: video/readers/jpeg.c $(video/readers/jpeg.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(jpeg_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh jpeg > $@ || (rm -f $@; exit 1)
+
+fs-jpeg_mod-video_readers_jpeg.lst: video/readers/jpeg.c $(video/readers/jpeg.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(jpeg_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh jpeg > $@ || (rm -f $@; exit 1)
+
+parttool-jpeg_mod-video_readers_jpeg.lst: video/readers/jpeg.c $(video/readers/jpeg.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(jpeg_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh jpeg > $@ || (rm -f $@; exit 1)
+
+partmap-jpeg_mod-video_readers_jpeg.lst: video/readers/jpeg.c $(video/readers/jpeg.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(jpeg_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh jpeg > $@ || (rm -f $@; exit 1)
+
+handler-jpeg_mod-video_readers_jpeg.lst: video/readers/jpeg.c $(video/readers/jpeg.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(jpeg_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh jpeg > $@ || (rm -f $@; exit 1)
+
+jpeg_mod_CFLAGS = $(COMMON_CFLAGS)
+jpeg_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For png.mod.
+png_mod_SOURCES = video/readers/png.c
+
+clean-module-png.mod.1:
+	rm -f png.mod mod-png.o mod-png.c pre-png.o png_mod-video_readers_png.o und-png.lst
+
+CLEAN_MODULE_TARGETS += clean-module-png.mod.1
+
+ifneq ($(png_mod_EXPORTS),no)
+clean-module-png.mod-symbol.1:
+	rm -f def-png.lst
+
+CLEAN_MODULE_TARGETS += clean-module-png.mod-symbol.1
+DEFSYMFILES += def-png.lst
+endif
+mostlyclean-module-png.mod.1:
+	rm -f png_mod-video_readers_png.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-png.mod.1
+UNDSYMFILES += und-png.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+png.mod: pre-png.o mod-png.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(png_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-png.o mod-png.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+png.mod: pre-png.o mod-png.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(png_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-png.o mod-png.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-png.o: $(png_mod_DEPENDENCIES) png_mod-video_readers_png.o
+	-rm -f $@
+	$(TARGET_CC) $(png_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ png_mod-video_readers_png.o
+
+mod-png.o: mod-png.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(png_mod_CFLAGS) -c -o $@ $<
+
+mod-png.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'png' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(png_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-png.lst: pre-png.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 png/' > $@
+else
+def-png.lst: pre-png.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 png/' > $@
+endif
+endif
+
+und-png.lst: pre-png.o
+	echo 'png' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+png_mod-video_readers_png.o: video/readers/png.c $(video/readers/png.c_DEPENDENCIES)
+	$(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(png_mod_CFLAGS) -MD -c -o $@ $<
+-include png_mod-video_readers_png.d
+
+clean-module-png_mod-video_readers_png-extra.1:
+	rm -f cmd-png_mod-video_readers_png.lst fs-png_mod-video_readers_png.lst partmap-png_mod-video_readers_png.lst handler-png_mod-video_readers_png.lst parttool-png_mod-video_readers_png.lst
+
+CLEAN_MODULE_TARGETS += clean-module-png_mod-video_readers_png-extra.1
+
+COMMANDFILES += cmd-png_mod-video_readers_png.lst
+FSFILES += fs-png_mod-video_readers_png.lst
+PARTTOOLFILES += parttool-png_mod-video_readers_png.lst
+PARTMAPFILES += partmap-png_mod-video_readers_png.lst
+HANDLERFILES += handler-png_mod-video_readers_png.lst
+
+cmd-png_mod-video_readers_png.lst: video/readers/png.c $(video/readers/png.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(png_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh png > $@ || (rm -f $@; exit 1)
+
+fs-png_mod-video_readers_png.lst: video/readers/png.c $(video/readers/png.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(png_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh png > $@ || (rm -f $@; exit 1)
+
+parttool-png_mod-video_readers_png.lst: video/readers/png.c $(video/readers/png.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(png_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh png > $@ || (rm -f $@; exit 1)
+
+partmap-png_mod-video_readers_png.lst: video/readers/png.c $(video/readers/png.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(png_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh png > $@ || (rm -f $@; exit 1)
+
+handler-png_mod-video_readers_png.lst: video/readers/png.c $(video/readers/png.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(png_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh png > $@ || (rm -f $@; exit 1)
+
+png_mod_CFLAGS = $(COMMON_CFLAGS)
+png_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For font.mod.
+font_mod_SOURCES = font/font_cmd.c font/font.c
+
+clean-module-font.mod.1:
+	rm -f font.mod mod-font.o mod-font.c pre-font.o font_mod-font_font_cmd.o font_mod-font_font.o und-font.lst
+
+CLEAN_MODULE_TARGETS += clean-module-font.mod.1
+
+ifneq ($(font_mod_EXPORTS),no)
+clean-module-font.mod-symbol.1:
+	rm -f def-font.lst
+
+CLEAN_MODULE_TARGETS += clean-module-font.mod-symbol.1
+DEFSYMFILES += def-font.lst
+endif
+mostlyclean-module-font.mod.1:
+	rm -f font_mod-font_font_cmd.d font_mod-font_font.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-font.mod.1
+UNDSYMFILES += und-font.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+font.mod: pre-font.o mod-font.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(font_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-font.o mod-font.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+font.mod: pre-font.o mod-font.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(font_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-font.o mod-font.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-font.o: $(font_mod_DEPENDENCIES) font_mod-font_font_cmd.o font_mod-font_font.o
+	-rm -f $@
+	$(TARGET_CC) $(font_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ font_mod-font_font_cmd.o font_mod-font_font.o
+
+mod-font.o: mod-font.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -c -o $@ $<
+
+mod-font.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'font' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(font_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-font.lst: pre-font.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 font/' > $@
+else
+def-font.lst: pre-font.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 font/' > $@
+endif
+endif
+
+und-font.lst: pre-font.o
+	echo 'font' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+font_mod-font_font_cmd.o: font/font_cmd.c $(font/font_cmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(font_mod_CFLAGS) -MD -c -o $@ $<
+-include font_mod-font_font_cmd.d
+
+clean-module-font_mod-font_font_cmd-extra.1:
+	rm -f cmd-font_mod-font_font_cmd.lst fs-font_mod-font_font_cmd.lst partmap-font_mod-font_font_cmd.lst handler-font_mod-font_font_cmd.lst parttool-font_mod-font_font_cmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-font_mod-font_font_cmd-extra.1
+
+COMMANDFILES += cmd-font_mod-font_font_cmd.lst
+FSFILES += fs-font_mod-font_font_cmd.lst
+PARTTOOLFILES += parttool-font_mod-font_font_cmd.lst
+PARTMAPFILES += partmap-font_mod-font_font_cmd.lst
+HANDLERFILES += handler-font_mod-font_font_cmd.lst
+
+cmd-font_mod-font_font_cmd.lst: font/font_cmd.c $(font/font_cmd.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh font > $@ || (rm -f $@; exit 1)
+
+fs-font_mod-font_font_cmd.lst: font/font_cmd.c $(font/font_cmd.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh font > $@ || (rm -f $@; exit 1)
+
+parttool-font_mod-font_font_cmd.lst: font/font_cmd.c $(font/font_cmd.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh font > $@ || (rm -f $@; exit 1)
+
+partmap-font_mod-font_font_cmd.lst: font/font_cmd.c $(font/font_cmd.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh font > $@ || (rm -f $@; exit 1)
+
+handler-font_mod-font_font_cmd.lst: font/font_cmd.c $(font/font_cmd.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh font > $@ || (rm -f $@; exit 1)
+
+font_mod-font_font.o: font/font.c $(font/font.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(font_mod_CFLAGS) -MD -c -o $@ $<
+-include font_mod-font_font.d
+
+clean-module-font_mod-font_font-extra.1:
+	rm -f cmd-font_mod-font_font.lst fs-font_mod-font_font.lst partmap-font_mod-font_font.lst handler-font_mod-font_font.lst parttool-font_mod-font_font.lst
+
+CLEAN_MODULE_TARGETS += clean-module-font_mod-font_font-extra.1
+
+COMMANDFILES += cmd-font_mod-font_font.lst
+FSFILES += fs-font_mod-font_font.lst
+PARTTOOLFILES += parttool-font_mod-font_font.lst
+PARTMAPFILES += partmap-font_mod-font_font.lst
+HANDLERFILES += handler-font_mod-font_font.lst
+
+cmd-font_mod-font_font.lst: font/font.c $(font/font.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh font > $@ || (rm -f $@; exit 1)
+
+fs-font_mod-font_font.lst: font/font.c $(font/font.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh font > $@ || (rm -f $@; exit 1)
+
+parttool-font_mod-font_font.lst: font/font.c $(font/font.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh font > $@ || (rm -f $@; exit 1)
+
+partmap-font_mod-font_font.lst: font/font.c $(font/font.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh font > $@ || (rm -f $@; exit 1)
+
+handler-font_mod-font_font.lst: font/font.c $(font/font.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh font > $@ || (rm -f $@; exit 1)
+
+font_mod_CFLAGS = $(COMMON_CFLAGS)
+font_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For gfxterm.mod.
+gfxterm_mod_SOURCES = term/gfxterm.c
+
+clean-module-gfxterm.mod.1:
+	rm -f gfxterm.mod mod-gfxterm.o mod-gfxterm.c pre-gfxterm.o gfxterm_mod-term_gfxterm.o und-gfxterm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-gfxterm.mod.1
+
+ifneq ($(gfxterm_mod_EXPORTS),no)
+clean-module-gfxterm.mod-symbol.1:
+	rm -f def-gfxterm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-gfxterm.mod-symbol.1
+DEFSYMFILES += def-gfxterm.lst
+endif
+mostlyclean-module-gfxterm.mod.1:
+	rm -f gfxterm_mod-term_gfxterm.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-gfxterm.mod.1
+UNDSYMFILES += und-gfxterm.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+gfxterm.mod: pre-gfxterm.o mod-gfxterm.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(gfxterm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-gfxterm.o mod-gfxterm.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+gfxterm.mod: pre-gfxterm.o mod-gfxterm.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(gfxterm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-gfxterm.o mod-gfxterm.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-gfxterm.o: $(gfxterm_mod_DEPENDENCIES) gfxterm_mod-term_gfxterm.o
+	-rm -f $@
+	$(TARGET_CC) $(gfxterm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ gfxterm_mod-term_gfxterm.o
+
+mod-gfxterm.o: mod-gfxterm.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gfxterm_mod_CFLAGS) -c -o $@ $<
+
+mod-gfxterm.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'gfxterm' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(gfxterm_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-gfxterm.lst: pre-gfxterm.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 gfxterm/' > $@
+else
+def-gfxterm.lst: pre-gfxterm.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 gfxterm/' > $@
+endif
+endif
+
+und-gfxterm.lst: pre-gfxterm.o
+	echo 'gfxterm' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+gfxterm_mod-term_gfxterm.o: term/gfxterm.c $(term/gfxterm.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gfxterm_mod_CFLAGS) -MD -c -o $@ $<
+-include gfxterm_mod-term_gfxterm.d
+
+clean-module-gfxterm_mod-term_gfxterm-extra.1:
+	rm -f cmd-gfxterm_mod-term_gfxterm.lst fs-gfxterm_mod-term_gfxterm.lst partmap-gfxterm_mod-term_gfxterm.lst handler-gfxterm_mod-term_gfxterm.lst parttool-gfxterm_mod-term_gfxterm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-gfxterm_mod-term_gfxterm-extra.1
+
+COMMANDFILES += cmd-gfxterm_mod-term_gfxterm.lst
+FSFILES += fs-gfxterm_mod-term_gfxterm.lst
+PARTTOOLFILES += parttool-gfxterm_mod-term_gfxterm.lst
+PARTMAPFILES += partmap-gfxterm_mod-term_gfxterm.lst
+HANDLERFILES += handler-gfxterm_mod-term_gfxterm.lst
+
+cmd-gfxterm_mod-term_gfxterm.lst: term/gfxterm.c $(term/gfxterm.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gfxterm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh gfxterm > $@ || (rm -f $@; exit 1)
+
+fs-gfxterm_mod-term_gfxterm.lst: term/gfxterm.c $(term/gfxterm.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gfxterm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh gfxterm > $@ || (rm -f $@; exit 1)
+
+parttool-gfxterm_mod-term_gfxterm.lst: term/gfxterm.c $(term/gfxterm.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gfxterm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh gfxterm > $@ || (rm -f $@; exit 1)
+
+partmap-gfxterm_mod-term_gfxterm.lst: term/gfxterm.c $(term/gfxterm.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gfxterm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh gfxterm > $@ || (rm -f $@; exit 1)
+
+handler-gfxterm_mod-term_gfxterm.lst: term/gfxterm.c $(term/gfxterm.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gfxterm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh gfxterm > $@ || (rm -f $@; exit 1)
+
+gfxterm_mod_CFLAGS = $(COMMON_CFLAGS)
+gfxterm_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Misc.
+pkglib_MODULES += gzio.mod bufio.mod elf.mod
+
+# For elf.mod.
+elf_mod_SOURCES = kern/elf.c
+
+clean-module-elf.mod.1:
+	rm -f elf.mod mod-elf.o mod-elf.c pre-elf.o elf_mod-kern_elf.o und-elf.lst
+
+CLEAN_MODULE_TARGETS += clean-module-elf.mod.1
+
+ifneq ($(elf_mod_EXPORTS),no)
+clean-module-elf.mod-symbol.1:
+	rm -f def-elf.lst
+
+CLEAN_MODULE_TARGETS += clean-module-elf.mod-symbol.1
+DEFSYMFILES += def-elf.lst
+endif
+mostlyclean-module-elf.mod.1:
+	rm -f elf_mod-kern_elf.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-elf.mod.1
+UNDSYMFILES += und-elf.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+elf.mod: pre-elf.o mod-elf.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(elf_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-elf.o mod-elf.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+elf.mod: pre-elf.o mod-elf.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(elf_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-elf.o mod-elf.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-elf.o: $(elf_mod_DEPENDENCIES) elf_mod-kern_elf.o
+	-rm -f $@
+	$(TARGET_CC) $(elf_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ elf_mod-kern_elf.o
+
+mod-elf.o: mod-elf.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(elf_mod_CFLAGS) -c -o $@ $<
+
+mod-elf.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'elf' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(elf_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-elf.lst: pre-elf.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 elf/' > $@
+else
+def-elf.lst: pre-elf.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 elf/' > $@
+endif
+endif
+
+und-elf.lst: pre-elf.o
+	echo 'elf' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+elf_mod-kern_elf.o: kern/elf.c $(kern/elf.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(elf_mod_CFLAGS) -MD -c -o $@ $<
+-include elf_mod-kern_elf.d
+
+clean-module-elf_mod-kern_elf-extra.1:
+	rm -f cmd-elf_mod-kern_elf.lst fs-elf_mod-kern_elf.lst partmap-elf_mod-kern_elf.lst handler-elf_mod-kern_elf.lst parttool-elf_mod-kern_elf.lst
+
+CLEAN_MODULE_TARGETS += clean-module-elf_mod-kern_elf-extra.1
+
+COMMANDFILES += cmd-elf_mod-kern_elf.lst
+FSFILES += fs-elf_mod-kern_elf.lst
+PARTTOOLFILES += parttool-elf_mod-kern_elf.lst
+PARTMAPFILES += partmap-elf_mod-kern_elf.lst
+HANDLERFILES += handler-elf_mod-kern_elf.lst
+
+cmd-elf_mod-kern_elf.lst: kern/elf.c $(kern/elf.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(elf_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh elf > $@ || (rm -f $@; exit 1)
+
+fs-elf_mod-kern_elf.lst: kern/elf.c $(kern/elf.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(elf_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh elf > $@ || (rm -f $@; exit 1)
+
+parttool-elf_mod-kern_elf.lst: kern/elf.c $(kern/elf.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(elf_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh elf > $@ || (rm -f $@; exit 1)
+
+partmap-elf_mod-kern_elf.lst: kern/elf.c $(kern/elf.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(elf_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh elf > $@ || (rm -f $@; exit 1)
+
+handler-elf_mod-kern_elf.lst: kern/elf.c $(kern/elf.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(elf_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh elf > $@ || (rm -f $@; exit 1)
+
+elf_mod_CFLAGS = $(COMMON_CFLAGS)
+elf_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For gzio.mod.
+gzio_mod_SOURCES = io/gzio.c
+
+clean-module-gzio.mod.1:
+	rm -f gzio.mod mod-gzio.o mod-gzio.c pre-gzio.o gzio_mod-io_gzio.o und-gzio.lst
+
+CLEAN_MODULE_TARGETS += clean-module-gzio.mod.1
+
+ifneq ($(gzio_mod_EXPORTS),no)
+clean-module-gzio.mod-symbol.1:
+	rm -f def-gzio.lst
+
+CLEAN_MODULE_TARGETS += clean-module-gzio.mod-symbol.1
+DEFSYMFILES += def-gzio.lst
+endif
+mostlyclean-module-gzio.mod.1:
+	rm -f gzio_mod-io_gzio.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-gzio.mod.1
+UNDSYMFILES += und-gzio.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+gzio.mod: pre-gzio.o mod-gzio.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(gzio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-gzio.o mod-gzio.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+gzio.mod: pre-gzio.o mod-gzio.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(gzio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-gzio.o mod-gzio.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-gzio.o: $(gzio_mod_DEPENDENCIES) gzio_mod-io_gzio.o
+	-rm -f $@
+	$(TARGET_CC) $(gzio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ gzio_mod-io_gzio.o
+
+mod-gzio.o: mod-gzio.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -c -o $@ $<
+
+mod-gzio.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'gzio' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(gzio_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-gzio.lst: pre-gzio.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 gzio/' > $@
+else
+def-gzio.lst: pre-gzio.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 gzio/' > $@
+endif
+endif
+
+und-gzio.lst: pre-gzio.o
+	echo 'gzio' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+gzio_mod-io_gzio.o: io/gzio.c $(io/gzio.c_DEPENDENCIES)
+	$(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -MD -c -o $@ $<
+-include gzio_mod-io_gzio.d
+
+clean-module-gzio_mod-io_gzio-extra.1:
+	rm -f cmd-gzio_mod-io_gzio.lst fs-gzio_mod-io_gzio.lst partmap-gzio_mod-io_gzio.lst handler-gzio_mod-io_gzio.lst parttool-gzio_mod-io_gzio.lst
+
+CLEAN_MODULE_TARGETS += clean-module-gzio_mod-io_gzio-extra.1
+
+COMMANDFILES += cmd-gzio_mod-io_gzio.lst
+FSFILES += fs-gzio_mod-io_gzio.lst
+PARTTOOLFILES += parttool-gzio_mod-io_gzio.lst
+PARTMAPFILES += partmap-gzio_mod-io_gzio.lst
+HANDLERFILES += handler-gzio_mod-io_gzio.lst
+
+cmd-gzio_mod-io_gzio.lst: io/gzio.c $(io/gzio.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh gzio > $@ || (rm -f $@; exit 1)
+
+fs-gzio_mod-io_gzio.lst: io/gzio.c $(io/gzio.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh gzio > $@ || (rm -f $@; exit 1)
+
+parttool-gzio_mod-io_gzio.lst: io/gzio.c $(io/gzio.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh gzio > $@ || (rm -f $@; exit 1)
+
+partmap-gzio_mod-io_gzio.lst: io/gzio.c $(io/gzio.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh gzio > $@ || (rm -f $@; exit 1)
+
+handler-gzio_mod-io_gzio.lst: io/gzio.c $(io/gzio.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh gzio > $@ || (rm -f $@; exit 1)
+
+gzio_mod_CFLAGS = $(COMMON_CFLAGS)
+gzio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bufio.mod.
+bufio_mod_SOURCES = io/bufio.c
+
+clean-module-bufio.mod.1:
+	rm -f bufio.mod mod-bufio.o mod-bufio.c pre-bufio.o bufio_mod-io_bufio.o und-bufio.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bufio.mod.1
+
+ifneq ($(bufio_mod_EXPORTS),no)
+clean-module-bufio.mod-symbol.1:
+	rm -f def-bufio.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bufio.mod-symbol.1
+DEFSYMFILES += def-bufio.lst
+endif
+mostlyclean-module-bufio.mod.1:
+	rm -f bufio_mod-io_bufio.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-bufio.mod.1
+UNDSYMFILES += und-bufio.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+bufio.mod: pre-bufio.o mod-bufio.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(bufio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-bufio.o mod-bufio.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+bufio.mod: pre-bufio.o mod-bufio.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(bufio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-bufio.o mod-bufio.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-bufio.o: $(bufio_mod_DEPENDENCIES) bufio_mod-io_bufio.o
+	-rm -f $@
+	$(TARGET_CC) $(bufio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ bufio_mod-io_bufio.o
+
+mod-bufio.o: mod-bufio.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bufio_mod_CFLAGS) -c -o $@ $<
+
+mod-bufio.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'bufio' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(bufio_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-bufio.lst: pre-bufio.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 bufio/' > $@
+else
+def-bufio.lst: pre-bufio.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 bufio/' > $@
+endif
+endif
+
+und-bufio.lst: pre-bufio.o
+	echo 'bufio' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+bufio_mod-io_bufio.o: io/bufio.c $(io/bufio.c_DEPENDENCIES)
+	$(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bufio_mod_CFLAGS) -MD -c -o $@ $<
+-include bufio_mod-io_bufio.d
+
+clean-module-bufio_mod-io_bufio-extra.1:
+	rm -f cmd-bufio_mod-io_bufio.lst fs-bufio_mod-io_bufio.lst partmap-bufio_mod-io_bufio.lst handler-bufio_mod-io_bufio.lst parttool-bufio_mod-io_bufio.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bufio_mod-io_bufio-extra.1
+
+COMMANDFILES += cmd-bufio_mod-io_bufio.lst
+FSFILES += fs-bufio_mod-io_bufio.lst
+PARTTOOLFILES += parttool-bufio_mod-io_bufio.lst
+PARTMAPFILES += partmap-bufio_mod-io_bufio.lst
+HANDLERFILES += handler-bufio_mod-io_bufio.lst
+
+cmd-bufio_mod-io_bufio.lst: io/bufio.c $(io/bufio.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bufio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh bufio > $@ || (rm -f $@; exit 1)
+
+fs-bufio_mod-io_bufio.lst: io/bufio.c $(io/bufio.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bufio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh bufio > $@ || (rm -f $@; exit 1)
+
+parttool-bufio_mod-io_bufio.lst: io/bufio.c $(io/bufio.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bufio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh bufio > $@ || (rm -f $@; exit 1)
+
+partmap-bufio_mod-io_bufio.lst: io/bufio.c $(io/bufio.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bufio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh bufio > $@ || (rm -f $@; exit 1)
+
+handler-bufio_mod-io_bufio.lst: io/bufio.c $(io/bufio.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bufio_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh bufio > $@ || (rm -f $@; exit 1)
+
+bufio_mod_CFLAGS = $(COMMON_CFLAGS)
+bufio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Misc.
+pkglib_MODULES += xnu_uuid.mod
+
+# For elf.mod.
+xnu_uuid_mod_SOURCES = commands/xnu_uuid.c
+
+clean-module-xnu_uuid.mod.1:
+	rm -f xnu_uuid.mod mod-xnu_uuid.o mod-xnu_uuid.c pre-xnu_uuid.o xnu_uuid_mod-commands_xnu_uuid.o und-xnu_uuid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_uuid.mod.1
+
+ifneq ($(xnu_uuid_mod_EXPORTS),no)
+clean-module-xnu_uuid.mod-symbol.1:
+	rm -f def-xnu_uuid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_uuid.mod-symbol.1
+DEFSYMFILES += def-xnu_uuid.lst
+endif
+mostlyclean-module-xnu_uuid.mod.1:
+	rm -f xnu_uuid_mod-commands_xnu_uuid.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-xnu_uuid.mod.1
+UNDSYMFILES += und-xnu_uuid.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+xnu_uuid.mod: pre-xnu_uuid.o mod-xnu_uuid.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(xnu_uuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-xnu_uuid.o mod-xnu_uuid.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+xnu_uuid.mod: pre-xnu_uuid.o mod-xnu_uuid.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(xnu_uuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-xnu_uuid.o mod-xnu_uuid.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-xnu_uuid.o: $(xnu_uuid_mod_DEPENDENCIES) xnu_uuid_mod-commands_xnu_uuid.o
+	-rm -f $@
+	$(TARGET_CC) $(xnu_uuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ xnu_uuid_mod-commands_xnu_uuid.o
+
+mod-xnu_uuid.o: mod-xnu_uuid.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xnu_uuid_mod_CFLAGS) -c -o $@ $<
+
+mod-xnu_uuid.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'xnu_uuid' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(xnu_uuid_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-xnu_uuid.lst: pre-xnu_uuid.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 xnu_uuid/' > $@
+else
+def-xnu_uuid.lst: pre-xnu_uuid.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 xnu_uuid/' > $@
+endif
+endif
+
+und-xnu_uuid.lst: pre-xnu_uuid.o
+	echo 'xnu_uuid' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+xnu_uuid_mod-commands_xnu_uuid.o: commands/xnu_uuid.c $(commands/xnu_uuid.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_uuid_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_uuid_mod-commands_xnu_uuid.d
+
+clean-module-xnu_uuid_mod-commands_xnu_uuid-extra.1:
+	rm -f cmd-xnu_uuid_mod-commands_xnu_uuid.lst fs-xnu_uuid_mod-commands_xnu_uuid.lst partmap-xnu_uuid_mod-commands_xnu_uuid.lst handler-xnu_uuid_mod-commands_xnu_uuid.lst parttool-xnu_uuid_mod-commands_xnu_uuid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_uuid_mod-commands_xnu_uuid-extra.1
+
+COMMANDFILES += cmd-xnu_uuid_mod-commands_xnu_uuid.lst
+FSFILES += fs-xnu_uuid_mod-commands_xnu_uuid.lst
+PARTTOOLFILES += parttool-xnu_uuid_mod-commands_xnu_uuid.lst
+PARTMAPFILES += partmap-xnu_uuid_mod-commands_xnu_uuid.lst
+HANDLERFILES += handler-xnu_uuid_mod-commands_xnu_uuid.lst
+
+cmd-xnu_uuid_mod-commands_xnu_uuid.lst: commands/xnu_uuid.c $(commands/xnu_uuid.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_uuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu_uuid > $@ || (rm -f $@; exit 1)
+
+fs-xnu_uuid_mod-commands_xnu_uuid.lst: commands/xnu_uuid.c $(commands/xnu_uuid.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_uuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu_uuid > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_uuid_mod-commands_xnu_uuid.lst: commands/xnu_uuid.c $(commands/xnu_uuid.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_uuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu_uuid > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_uuid_mod-commands_xnu_uuid.lst: commands/xnu_uuid.c $(commands/xnu_uuid.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_uuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu_uuid > $@ || (rm -f $@; exit 1)
+
+handler-xnu_uuid_mod-commands_xnu_uuid.lst: commands/xnu_uuid.c $(commands/xnu_uuid.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_uuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu_uuid > $@ || (rm -f $@; exit 1)
+
+xnu_uuid_mod_CFLAGS = $(COMMON_CFLAGS)
+xnu_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += setjmp.mod
+setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S
+
+clean-module-setjmp.mod.1:
+	rm -f setjmp.mod mod-setjmp.o mod-setjmp.c pre-setjmp.o setjmp_mod-lib___target_cpu__setjmp.o und-setjmp.lst
+
+CLEAN_MODULE_TARGETS += clean-module-setjmp.mod.1
+
+ifneq ($(setjmp_mod_EXPORTS),no)
+clean-module-setjmp.mod-symbol.1:
+	rm -f def-setjmp.lst
+
+CLEAN_MODULE_TARGETS += clean-module-setjmp.mod-symbol.1
+DEFSYMFILES += def-setjmp.lst
+endif
+mostlyclean-module-setjmp.mod.1:
+	rm -f setjmp_mod-lib___target_cpu__setjmp.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-setjmp.mod.1
+UNDSYMFILES += und-setjmp.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+setjmp.mod: pre-setjmp.o mod-setjmp.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(setjmp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-setjmp.o mod-setjmp.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+setjmp.mod: pre-setjmp.o mod-setjmp.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(setjmp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-setjmp.o mod-setjmp.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-setjmp.o: $(setjmp_mod_DEPENDENCIES) setjmp_mod-lib___target_cpu__setjmp.o
+	-rm -f $@
+	$(TARGET_CC) $(setjmp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ setjmp_mod-lib___target_cpu__setjmp.o
+
+mod-setjmp.o: mod-setjmp.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(setjmp_mod_CFLAGS) -c -o $@ $<
+
+mod-setjmp.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'setjmp' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(setjmp_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-setjmp.lst: pre-setjmp.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 setjmp/' > $@
+else
+def-setjmp.lst: pre-setjmp.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 setjmp/' > $@
+endif
+endif
+
+und-setjmp.lst: pre-setjmp.o
+	echo 'setjmp' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+setjmp_mod-lib___target_cpu__setjmp.o: lib/$(target_cpu)/setjmp.S $(lib/$(target_cpu)/setjmp.S_DEPENDENCIES)
+	$(TARGET_CC) -Ilib/$(target_cpu) -I$(srcdir)/lib/$(target_cpu) $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(setjmp_mod_ASFLAGS) -MD -c -o $@ $<
+-include setjmp_mod-lib___target_cpu__setjmp.d
+
+clean-module-setjmp_mod-lib___target_cpu__setjmp-extra.1:
+	rm -f cmd-setjmp_mod-lib___target_cpu__setjmp.lst fs-setjmp_mod-lib___target_cpu__setjmp.lst partmap-setjmp_mod-lib___target_cpu__setjmp.lst handler-setjmp_mod-lib___target_cpu__setjmp.lst parttool-setjmp_mod-lib___target_cpu__setjmp.lst
+
+CLEAN_MODULE_TARGETS += clean-module-setjmp_mod-lib___target_cpu__setjmp-extra.1
+
+COMMANDFILES += cmd-setjmp_mod-lib___target_cpu__setjmp.lst
+FSFILES += fs-setjmp_mod-lib___target_cpu__setjmp.lst
+PARTTOOLFILES += parttool-setjmp_mod-lib___target_cpu__setjmp.lst
+PARTMAPFILES += partmap-setjmp_mod-lib___target_cpu__setjmp.lst
+HANDLERFILES += handler-setjmp_mod-lib___target_cpu__setjmp.lst
+
+cmd-setjmp_mod-lib___target_cpu__setjmp.lst: lib/$(target_cpu)/setjmp.S $(lib/$(target_cpu)/setjmp.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/$(target_cpu) -I$(srcdir)/lib/$(target_cpu) $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(setjmp_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh setjmp > $@ || (rm -f $@; exit 1)
+
+fs-setjmp_mod-lib___target_cpu__setjmp.lst: lib/$(target_cpu)/setjmp.S $(lib/$(target_cpu)/setjmp.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/$(target_cpu) -I$(srcdir)/lib/$(target_cpu) $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(setjmp_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh setjmp > $@ || (rm -f $@; exit 1)
+
+parttool-setjmp_mod-lib___target_cpu__setjmp.lst: lib/$(target_cpu)/setjmp.S $(lib/$(target_cpu)/setjmp.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/$(target_cpu) -I$(srcdir)/lib/$(target_cpu) $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(setjmp_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh setjmp > $@ || (rm -f $@; exit 1)
+
+partmap-setjmp_mod-lib___target_cpu__setjmp.lst: lib/$(target_cpu)/setjmp.S $(lib/$(target_cpu)/setjmp.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/$(target_cpu) -I$(srcdir)/lib/$(target_cpu) $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(setjmp_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh setjmp > $@ || (rm -f $@; exit 1)
+
+handler-setjmp_mod-lib___target_cpu__setjmp.lst: lib/$(target_cpu)/setjmp.S $(lib/$(target_cpu)/setjmp.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/$(target_cpu) -I$(srcdir)/lib/$(target_cpu) $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(setjmp_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh setjmp > $@ || (rm -f $@; exit 1)
+
+setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS)
+setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
+grub-mkelfimage: $(grub_mkelfimage_DEPENDENCIES) $(grub_mkelfimage_OBJECTS)
+	$(CC) -o $@ $(grub_mkelfimage_OBJECTS) $(LDFLAGS) $(grub_mkelfimage_LDFLAGS)
+
+grub-probe: $(grub_probe_DEPENDENCIES) $(grub_probe_OBJECTS)
+	$(CC) -o $@ $(grub_probe_OBJECTS) $(LDFLAGS) $(grub_probe_LDFLAGS)
+
+grub-fstest: $(grub_fstest_DEPENDENCIES) $(grub_fstest_OBJECTS)
+	$(CC) -o $@ $(grub_fstest_OBJECTS) $(LDFLAGS) $(grub_fstest_LDFLAGS)
+
+grub-mkfont: $(grub_mkfont_DEPENDENCIES) $(grub_mkfont_OBJECTS)
+	$(CC) -o $@ $(grub_mkfont_OBJECTS) $(LDFLAGS) $(grub_mkfont_LDFLAGS)
+
+grub-editenv: $(grub_editenv_DEPENDENCIES) $(grub_editenv_OBJECTS)
+	$(CC) -o $@ $(grub_editenv_OBJECTS) $(LDFLAGS) $(grub_editenv_LDFLAGS)
+
+grub-macho2img: $(grub_macho2img_DEPENDENCIES) $(grub_macho2img_OBJECTS)
+	$(CC) -o $@ $(grub_macho2img_OBJECTS) $(LDFLAGS) $(grub_macho2img_LDFLAGS)
+
+grub-pe2elf: $(grub_pe2elf_DEPENDENCIES) $(grub_pe2elf_OBJECTS)
+	$(CC) -o $@ $(grub_pe2elf_OBJECTS) $(LDFLAGS) $(grub_pe2elf_LDFLAGS)
+
diff --git a/conf/common.rmk b/conf/common.rmk
new file mode 100644
index 0000000..c1f0bbd
--- /dev/null
+++ b/conf/common.rmk
@@ -0,0 +1,610 @@
+# -*- makefile -*-
+
+# For grub-mkelfimage.
+bin_UTILITIES += grub-mkelfimage
+grub_mkelfimage_SOURCES = util/elf/grub-mkimage.c util/misc.c \
+	util/resolve.c
+util/elf/grub-mkimage.c_DEPENDENCIES = Makefile
+
+# For grub-probe.
+sbin_UTILITIES += grub-probe
+util/grub-probe.c_DEPENDENCIES = grub_probe_init.h
+grub_probe_SOURCES = util/grub-probe.c	\
+	util/hostdisk.c	util/misc.c util/getroot.c		\
+	kern/device.c kern/disk.c kern/err.c kern/misc.c	\
+	kern/parser.c kern/partition.c kern/file.c		\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c	\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c		\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c	\
+	fs/befs.c fs/befs_be.c fs/tar.c		\
+	\
+	partmap/msdos.c partmap/apple.c partmap/sun.c partmap/gpt.c\
+	kern/fs.c kern/env.c fs/fshelp.c			\
+	disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c
+
+ifeq ($(enable_grub_fstest), yes)
+bin_UTILITIES += grub-fstest
+endif
+
+# For grub-fstest.
+util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h
+grub_fstest_SOURCES = util/grub-fstest.c util/hostfs.c util/misc.c 	\
+	kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c	\
+	disk/host.c disk/loopback.c kern/list.c kern/command.c		\
+	lib/arg.c commands/extcmd.c normal/datetime.c normal/misc.c	\
+	lib/hexdump.c lib/crc.c commands/blocklist.c commands/ls.c 	\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c 	\
+	fs/befs_be.c fs/tar.c			\
+	\
+	kern/partition.c partmap/msdos.c partmap/apple.c partmap/sun.c	\
+	partmap/gpt.c							\
+	kern/fs.c kern/env.c fs/fshelp.c disk/raid.c			\
+	disk/raid5_recover.c disk/raid6_recover.c 			\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c 		\
+	grub_fstest_init.c
+
+# For grub-mkfont.
+ifeq ($(enable_grub_mkfont), yes)
+bin_UTILITIES += grub-mkfont
+grub_mkfont_SOURCES = util/grub-mkfont.c util/misc.c
+grub_mkfont_CFLAGS = $(freetype_cflags)
+grub_mkfont_LDFLAGS = $(freetype_libs)
+endif
+
+# For the parser.
+grub_script.tab.c grub_script.tab.h: script/sh/parser.y
+	$(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/sh/parser.y
+DISTCLEANFILES += grub_script.tab.c grub_script.tab.h
+
+# For grub-emu.
+grub_emu_init.lst: geninit.sh $(filter-out grub_emu_init.c,$(grub_emu_SOURCES))
+	rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
+DISTCLEANFILES += grub_emu_init.lst
+
+grub_emu_init.h: grub_emu_init.lst $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) geninitheader.sh
+	rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
+DISTCLEANFILES += grub_emu_init.h
+
+grub_emu_init.c: grub_emu_init.lst $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) geninit.sh grub_emu_init.h
+	rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
+DISTCLEANFILES += grub_emu_init.c
+
+# For grub-probe.
+grub_probe_init.lst: geninit.sh $(filter-out grub_probe_init.c,$(grub_probe_SOURCES))
+	rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
+DISTCLEANFILES += grub_probe_init.lst
+
+grub_probe_init.h: grub_probe_init.lst $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) geninitheader.sh
+	rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
+DISTCLEANFILES += grub_probe_init.h
+
+grub_probe_init.c: grub_probe_init.lst $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) geninit.sh grub_probe_init.h
+	rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
+DISTCLEANFILES += grub_probe_init.c
+
+# For grub-setup.
+grub_setup_init.lst: geninit.sh $(filter-out grub_setup_init.c,$(grub_setup_SOURCES))
+	rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
+DISTCLEANFILES += grub_setup_init.lst
+
+grub_setup_init.h: grub_setup_init.lst $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) geninitheader.sh
+	rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
+DISTCLEANFILES += grub_setup_init.h
+
+grub_setup_init.c: grub_setup_init.lst $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) geninit.sh grub_setup_init.h
+	rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
+DISTCLEANFILES += grub_setup_init.c
+
+# For grub-fstest.
+grub_fstest_init.lst: geninit.sh $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES))
+	rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
+DISTCLEANFILES += grub_fstest_init.lst
+
+grub_fstest_init.h: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) geninitheader.sh
+	rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
+DISTCLEANFILES += grub_fstest_init.h
+
+grub_fstest_init.c: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) geninit.sh grub_fstest_init.h
+	rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
+DISTCLEANFILES += grub_fstest_init.c
+
+# for grub-editenv
+bin_UTILITIES += grub-editenv
+grub_editenv_SOURCES = util/grub-editenv.c lib/envblk.c util/misc.c kern/misc.c kern/err.c
+CLEANFILES += grub-editenv
+
+# Needed for genmk.rb to work
+ifeq (0,1)
+bin_UTILITIES += grub-macho2img grub-pe2elf
+endif
+
+grub_pe2elf_SOURCES = util/grub-pe2elf.c util/misc.c
+CLEANFILES += grub-pe2elf
+
+grub_macho2img_SOURCES = util/grub-macho2img.c
+CLEANFILES += grub-macho2img
+
+# For grub-mkconfig
+grub-mkconfig: util/grub-mkconfig.in config.status
+	./config.status --file=$@:$<
+	chmod +x $@
+sbin_SCRIPTS += grub-mkconfig
+CLEANFILES += grub-mkconfig
+
+grub-mkconfig_lib: util/grub-mkconfig_lib.in config.status
+	./config.status --file=$@:$<
+	chmod +x $@
+lib_SCRIPTS += grub-mkconfig_lib
+CLEANFILES += grub-mkconfig_lib
+
+update-grub_lib: util/update-grub_lib.in config.status
+	./config.status --file=$@:$<
+	chmod +x $@
+lib_SCRIPTS += update-grub_lib
+CLEANFILES += update-grub_lib
+
+%: util/grub.d/%.in config.status
+	./config.status --file=$@:$<
+	chmod +x $@
+grub-mkconfig_SCRIPTS = 00_header 30_os-prober 40_custom
+ifneq (, $(host_kernel))
+grub-mkconfig_SCRIPTS += 10_$(host_kernel)
+endif
+
+CLEANFILES += $(grub-mkconfig_SCRIPTS)
+
+grub-mkconfig_DATA += util/grub.d/README
+
+# Filing systems.
+pkglib_MODULES += fshelp.mod fat.mod ufs1.mod ufs2.mod ext2.mod ntfs.mod \
+	ntfscomp.mod minix.mod hfs.mod jfs.mod iso9660.mod xfs.mod	\
+	affs.mod sfs.mod hfsplus.mod reiserfs.mod cpio.mod tar.mod	\
+	udf.mod	afs.mod afs_be.mod befs.mod befs_be.mod
+
+# For fshelp.mod.
+fshelp_mod_SOURCES = fs/fshelp.c
+fshelp_mod_CFLAGS = $(COMMON_CFLAGS)
+fshelp_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For fat.mod.
+fat_mod_SOURCES = fs/fat.c
+fat_mod_CFLAGS = $(COMMON_CFLAGS)
+fat_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ufs1.mod.
+ufs1_mod_SOURCES = fs/ufs.c
+ufs1_mod_CFLAGS = $(COMMON_CFLAGS)
+ufs1_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ufs2.mod.
+ufs2_mod_SOURCES = fs/ufs2.c
+ufs2_mod_CFLAGS = $(COMMON_CFLAGS)
+ufs2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ext2.mod.
+ext2_mod_SOURCES = fs/ext2.c
+ext2_mod_CFLAGS = $(COMMON_CFLAGS)
+ext2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ntfs.mod.
+ntfs_mod_SOURCES = fs/ntfs.c
+ntfs_mod_CFLAGS = $(COMMON_CFLAGS)
+ntfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ntfscomp.mod.
+ntfscomp_mod_SOURCES = fs/ntfscomp.c
+ntfscomp_mod_CFLAGS = $(COMMON_CFLAGS)
+ntfscomp_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For minix.mod.
+minix_mod_SOURCES = fs/minix.c
+minix_mod_CFLAGS = $(COMMON_CFLAGS)
+minix_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hfs.mod.
+hfs_mod_SOURCES = fs/hfs.c
+hfs_mod_CFLAGS = $(COMMON_CFLAGS)
+hfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For jfs.mod.
+jfs_mod_SOURCES = fs/jfs.c
+jfs_mod_CFLAGS = $(COMMON_CFLAGS)
+jfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For iso9660.mod.
+iso9660_mod_SOURCES = fs/iso9660.c
+iso9660_mod_CFLAGS = $(COMMON_CFLAGS)
+iso9660_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For xfs.mod.
+xfs_mod_SOURCES = fs/xfs.c
+xfs_mod_CFLAGS = $(COMMON_CFLAGS)
+xfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For affs.mod.
+affs_mod_SOURCES = fs/affs.c
+affs_mod_CFLAGS = $(COMMON_CFLAGS)
+affs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For sfs.mod.
+sfs_mod_SOURCES = fs/sfs.c
+sfs_mod_CFLAGS = $(COMMON_CFLAGS)
+sfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hfsplus.mod.
+hfsplus_mod_SOURCES = fs/hfsplus.c
+hfsplus_mod_CFLAGS = $(COMMON_CFLAGS)
+hfsplus_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reiserfs.mod.
+reiserfs_mod_SOURCES = fs/reiserfs.c
+reiserfs_mod_CFLAGS = $(COMMON_CFLAGS)
+reiserfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For cpio.mod.
+cpio_mod_SOURCES = fs/cpio.c
+cpio_mod_CFLAGS = $(COMMON_CFLAGS)
+cpio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For tar.mod.
+tar_mod_SOURCES = fs/tar.c
+tar_mod_CFLAGS = $(COMMON_CFLAGS)
+tar_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For udf.mod.
+udf_mod_SOURCES = fs/udf.c
+udf_mod_CFLAGS = $(COMMON_CFLAGS)
+udf_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For afs.mod.
+afs_mod_SOURCES = fs/afs.c
+afs_mod_CFLAGS = $(COMMON_CFLAGS)
+afs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For afs_be.mod.
+afs_be_mod_SOURCES = fs/afs_be.c
+afs_be_mod_CFLAGS = $(COMMON_CFLAGS)
+afs_be_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For befs.mod.
+befs_mod_SOURCES = fs/befs.c
+befs_mod_CFLAGS = $(COMMON_CFLAGS)
+befs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For befs_be.mod.
+befs_be_mod_SOURCES = fs/befs_be.c
+befs_be_mod_CFLAGS = $(COMMON_CFLAGS)
+befs_be_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Partition maps.
+
+pkglib_MODULES += part_amiga.mod
+part_amiga_mod_SOURCES = partmap/amiga.c
+part_amiga_mod_CFLAGS = $(COMMON_CFLAGS)
+part_amiga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_apple.mod
+part_apple_mod_SOURCES = partmap/apple.c
+part_apple_mod_CFLAGS = $(COMMON_CFLAGS)
+part_apple_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_msdos.mod
+part_msdos_mod_SOURCES = partmap/msdos.c
+part_msdos_mod_CFLAGS = $(COMMON_CFLAGS)
+part_msdos_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_sun.mod
+part_sun_mod_SOURCES = partmap/sun.c
+part_sun_mod_CFLAGS = $(COMMON_CFLAGS)
+part_sun_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_acorn.mod
+part_acorn_mod_SOURCES = partmap/acorn.c
+part_acorn_mod_CFLAGS = $(COMMON_CFLAGS)
+part_acorn_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_gpt.mod
+part_gpt_mod_SOURCES = partmap/gpt.c
+part_gpt_mod_CFLAGS = $(COMMON_CFLAGS)
+part_gpt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Special disk structures and generic drivers
+
+pkglib_MODULES += raid.mod raid5rec.mod raid6rec.mod mdraid.mod dm_nv.mod \
+	lvm.mod scsi.mod
+
+# For raid.mod
+raid_mod_SOURCES = disk/raid.c
+raid_mod_CFLAGS = $(COMMON_CFLAGS)
+raid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For raid5rec.mod
+raid5rec_mod_SOURCES = disk/raid5_recover.c
+raid5rec_mod_CFLAGS = $(COMMON_CFLAGS)
+raid5rec_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For raid6rec.mod
+raid6rec_mod_SOURCES = disk/raid6_recover.c
+raid6rec_mod_CFLAGS = $(COMMON_CFLAGS)
+raid6rec_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mdraid.mod
+mdraid_mod_SOURCES = disk/mdraid_linux.c
+mdraid_mod_CFLAGS = $(COMMON_CFLAGS)
+mdraid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For dm_nv.mod
+dm_nv_mod_SOURCES = disk/dmraid_nvidia.c
+dm_nv_mod_CFLAGS = $(COMMON_CFLAGS)
+dm_nv_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lvm.mod
+lvm_mod_SOURCES = disk/lvm.c
+lvm_mod_CFLAGS = $(COMMON_CFLAGS)
+lvm_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For scsi.mod
+scsi_mod_SOURCES = disk/scsi.c
+scsi_mod_CFLAGS = $(COMMON_CFLAGS)
+scsi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Commands.
+pkglib_MODULES += minicmd.mod extcmd.mod hello.mod handler.mod	\
+	ls.mod cmp.mod cat.mod help.mod search.mod loopback.mod	\
+	fs_file.mod fs_uuid.mod configfile.mod echo.mod		\
+	terminfo.mod test.mod blocklist.mod hexdump.mod		\
+	read.mod sleep.mod loadenv.mod crc.mod parttool.mod	\
+	msdospart.mod memrw.mod normal.mod sh.mod 		\
+	gptsync.mod true.mod probe.mod password.mod		\
+	keystatus.mod
+
+# For password.mod.
+password_mod_SOURCES = commands/password.c
+password_mod_CFLAGS = $(COMMON_CFLAGS)
+password_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For gptsync.mod.
+gptsync_mod_SOURCES = commands/gptsync.c
+gptsync_mod_CFLAGS = $(COMMON_CFLAGS)
+gptsync_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For minicmd.mod.
+minicmd_mod_SOURCES = commands/minicmd.c
+minicmd_mod_CFLAGS = $(COMMON_CFLAGS)
+minicmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For extcmd.mod.
+extcmd_mod_SOURCES = commands/extcmd.c lib/arg.c
+extcmd_mod_CFLAGS = $(COMMON_CFLAGS)
+extcmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hello.mod.
+hello_mod_SOURCES = hello/hello.c
+hello_mod_CFLAGS = $(COMMON_CFLAGS)
+hello_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For parttool.mod.
+parttool_mod_SOURCES = commands/parttool.c
+parttool_mod_CFLAGS = $(COMMON_CFLAGS)
+parttool_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For msdospart.mod.
+msdospart_mod_SOURCES = parttool/msdospart.c
+msdospart_mod_CFLAGS = $(COMMON_CFLAGS)
+msdospart_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For handler.mod.
+handler_mod_SOURCES = commands/handler.c
+handler_mod_CFLAGS = $(COMMON_CFLAGS)
+handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ls.mod.
+ls_mod_SOURCES = commands/ls.c
+ls_mod_CFLAGS = $(COMMON_CFLAGS)
+ls_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For cmp.mod.
+cmp_mod_SOURCES = commands/cmp.c
+cmp_mod_CFLAGS = $(COMMON_CFLAGS)
+cmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For cat.mod.
+cat_mod_SOURCES = commands/cat.c
+cat_mod_CFLAGS = $(COMMON_CFLAGS)
+cat_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For echo.mod
+echo_mod_SOURCES = commands/echo.c
+echo_mod_CFLAGS = $(COMMON_CFLAGS)
+echo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For help.mod.
+help_mod_SOURCES = commands/help.c
+help_mod_CFLAGS = $(COMMON_CFLAGS)
+help_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For search.mod.
+search_mod_SOURCES = commands/search.c
+search_mod_CFLAGS = $(COMMON_CFLAGS)
+search_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For test.mod.
+test_mod_SOURCES = commands/test.c
+test_mod_CFLAGS = $(COMMON_CFLAGS)
+test_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For loopback.mod
+loopback_mod_SOURCES = disk/loopback.c
+loopback_mod_CFLAGS = $(COMMON_CFLAGS)
+loopback_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For fs_file.mod
+fs_file_mod_SOURCES = disk/fs_file.c
+fs_file_mod_CFLAGS = $(COMMON_CFLAGS)
+fs_file_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For fs_uuid.mod
+fs_uuid_mod_SOURCES = disk/fs_uuid.c
+fs_uuid_mod_CFLAGS = $(COMMON_CFLAGS)
+fs_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For configfile.mod
+configfile_mod_SOURCES = commands/configfile.c
+configfile_mod_CFLAGS = $(COMMON_CFLAGS)
+configfile_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For terminfo.mod.
+terminfo_mod_SOURCES = term/terminfo.c term/tparm.c
+terminfo_mod_CFLAGS = $(COMMON_CFLAGS)
+terminfo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For blocklist.mod.
+blocklist_mod_SOURCES = commands/blocklist.c
+blocklist_mod_CFLAGS = $(COMMON_CFLAGS)
+blocklist_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hexdump.mod.
+hexdump_mod_SOURCES = commands/hexdump.c lib/hexdump.c
+hexdump_mod_CFLAGS = $(COMMON_CFLAGS)
+hexdump_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For read.mod.
+read_mod_SOURCES = commands/read.c
+read_mod_CFLAGS = $(COMMON_CFLAGS)
+read_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For sleep.mod.
+sleep_mod_SOURCES = commands/sleep.c
+sleep_mod_CFLAGS = $(COMMON_CFLAGS)
+sleep_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For loadenv.mod.
+loadenv_mod_SOURCES = commands/loadenv.c lib/envblk.c
+loadenv_mod_CFLAGS = $(COMMON_CFLAGS)
+loadenv_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For crc.mod.
+crc_mod_SOURCES = commands/crc.c lib/crc.c
+crc_mod_CFLAGS = $(COMMON_CFLAGS)
+crc_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memrw.mod.
+memrw_mod_SOURCES = commands/memrw.c
+memrw_mod_CFLAGS = $(COMMON_CFLAGS)
+memrw_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For true.mod
+true_mod_SOURCES = commands/true.c
+true_mod_CFLAGS = $(COMMON_CFLAGS)
+true_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For probe.mod.
+probe_mod_SOURCES = commands/probe.c
+probe_mod_CFLAGS = $(COMMON_CFLAGS)
+probe_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For keystatus.mod.
+keystatus_mod_SOURCES = commands/keystatus.c
+keystatus_mod_CFLAGS = $(COMMON_CFLAGS)
+keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For normal.mod.
+normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
+	normal/auth.c normal/autofs.c normal/handler.c \
+	normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
+	normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \
+	normal/misc.c
+normal_mod_CFLAGS = $(COMMON_CFLAGS)
+normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For sh.mod.
+sh_mod_SOURCES = script/sh/main.c script/sh/script.c script/sh/execute.c \
+	script/sh/function.c script/sh/lexer.c grub_script.tab.c
+sh_mod_CFLAGS = $(COMMON_CFLAGS)
+sh_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Common Video Subsystem specific modules.
+pkglib_MODULES += video.mod videotest.mod bitmap.mod tga.mod jpeg.mod	\
+	png.mod	font.mod gfxterm.mod video_fb.mod
+
+# For video.mod.
+video_mod_SOURCES = video/video.c
+video_mod_CFLAGS = $(COMMON_CFLAGS)
+video_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+video_fb_mod_SOURCES = video/fb/video_fb.c video/fb/fbblit.c \
+		  video/fb/fbfill.c video/fb/fbutil.c
+video_fb_mod_CFLAGS = $(COMMON_CFLAGS)
+video_fb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For videotest.mod.
+videotest_mod_SOURCES = commands/videotest.c
+videotest_mod_CFLAGS = $(COMMON_CFLAGS)
+videotest_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bitmap.mod
+bitmap_mod_SOURCES = video/bitmap.c
+bitmap_mod_CFLAGS = $(COMMON_CFLAGS)
+bitmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For tga.mod
+tga_mod_SOURCES = video/readers/tga.c
+tga_mod_CFLAGS = $(COMMON_CFLAGS)
+tga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For jpeg.mod.
+jpeg_mod_SOURCES = video/readers/jpeg.c
+jpeg_mod_CFLAGS = $(COMMON_CFLAGS)
+jpeg_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For png.mod.
+png_mod_SOURCES = video/readers/png.c
+png_mod_CFLAGS = $(COMMON_CFLAGS)
+png_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For font.mod.
+font_mod_SOURCES = font/font_cmd.c font/font.c
+font_mod_CFLAGS = $(COMMON_CFLAGS)
+font_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For gfxterm.mod.
+gfxterm_mod_SOURCES = term/gfxterm.c
+gfxterm_mod_CFLAGS = $(COMMON_CFLAGS)
+gfxterm_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Misc.
+pkglib_MODULES += gzio.mod bufio.mod elf.mod
+
+# For elf.mod.
+elf_mod_SOURCES = kern/elf.c
+elf_mod_CFLAGS = $(COMMON_CFLAGS)
+elf_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For gzio.mod.
+gzio_mod_SOURCES = io/gzio.c
+gzio_mod_CFLAGS = $(COMMON_CFLAGS)
+gzio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bufio.mod.
+bufio_mod_SOURCES = io/bufio.c
+bufio_mod_CFLAGS = $(COMMON_CFLAGS)
+bufio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Misc.
+pkglib_MODULES += xnu_uuid.mod
+
+# For elf.mod.
+xnu_uuid_mod_SOURCES = commands/xnu_uuid.c
+xnu_uuid_mod_CFLAGS = $(COMMON_CFLAGS)
+xnu_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += setjmp.mod
+setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S
+setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS)
+setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/i386-coreboot.mk b/conf/i386-coreboot.mk
new file mode 100644
index 0000000..c7fa56d
--- /dev/null
+++ b/conf/i386-coreboot.mk
@@ -0,0 +1,3057 @@
+# -*- makefile -*-
+# Generated by genmk.rb, please don't edit!
+
+COMMON_ASFLAGS	= -nostdinc -fno-builtin -m32
+COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32
+COMMON_LDFLAGS	= -m32 -nostdlib
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Images.
+
+GRUB_KERNEL_MACHINE_LINK_ADDR	= 0x8200
+
+ifeq ($(platform), coreboot)
+
+pkglib_PROGRAMS += kernel.img
+kernel_img_SOURCES = kern/i386/coreboot/startup.S \
+	kern/i386/misc.S \
+	kern/i386/coreboot/init.c \
+	kern/i386/multiboot_mmap.c \
+	kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+	kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
+	kern/i386/tsc.c kern/i386/pit.c \
+	kern/generic/rtc_get_time_ms.c \
+	kern/generic/millisleep.c \
+	kern/env.c \
+	term/i386/pc/vga_text.c term/i386/vga_common.c \
+	symlist.c
+CLEANFILES += kernel.img kernel_img-kern_i386_coreboot_startup.o kernel_img-kern_i386_misc.o kernel_img-kern_i386_coreboot_init.o kernel_img-kern_i386_multiboot_mmap.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern_time.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_i386_tsc.o kernel_img-kern_i386_pit.o kernel_img-kern_generic_rtc_get_time_ms.o kernel_img-kern_generic_millisleep.o kernel_img-kern_env.o kernel_img-term_i386_pc_vga_text.o kernel_img-term_i386_vga_common.o kernel_img-symlist.o
+MOSTLYCLEANFILES += kernel_img-kern_i386_coreboot_startup.d kernel_img-kern_i386_misc.d kernel_img-kern_i386_coreboot_init.d kernel_img-kern_i386_multiboot_mmap.d kernel_img-kern_main.d kernel_img-kern_device.d kernel_img-kern_disk.d kernel_img-kern_dl.d kernel_img-kern_file.d kernel_img-kern_fs.d kernel_img-kern_err.d kernel_img-kern_misc.d kernel_img-kern_mm.d kernel_img-kern_reader.d kernel_img-kern_term.d kernel_img-kern_rescue_parser.d kernel_img-kern_rescue_reader.d kernel_img-kern_time.d kernel_img-kern_list.d kernel_img-kern_handler.d kernel_img-kern_command.d kernel_img-kern_corecmd.d kernel_img-kern___target_cpu__dl.d kernel_img-kern_parser.d kernel_img-kern_partition.d kernel_img-kern_i386_tsc.d kernel_img-kern_i386_pit.d kernel_img-kern_generic_rtc_get_time_ms.d kernel_img-kern_generic_millisleep.d kernel_img-kern_env.d kernel_img-term_i386_pc_vga_text.d kernel_img-term_i386_vga_common.d kernel_img-symlist.d
+
+kernel.img: $(kernel_img_DEPENDENCIES) kernel_img-kern_i386_coreboot_startup.o kernel_img-kern_i386_misc.o kernel_img-kern_i386_coreboot_init.o kernel_img-kern_i386_multiboot_mmap.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern_time.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_i386_tsc.o kernel_img-kern_i386_pit.o kernel_img-kern_generic_rtc_get_time_ms.o kernel_img-kern_generic_millisleep.o kernel_img-kern_env.o kernel_img-term_i386_pc_vga_text.o kernel_img-term_i386_vga_common.o kernel_img-symlist.o
+	$(TARGET_CC) -o $@ kernel_img-kern_i386_coreboot_startup.o kernel_img-kern_i386_misc.o kernel_img-kern_i386_coreboot_init.o kernel_img-kern_i386_multiboot_mmap.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern_time.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_i386_tsc.o kernel_img-kern_i386_pit.o kernel_img-kern_generic_rtc_get_time_ms.o kernel_img-kern_generic_millisleep.o kernel_img-kern_env.o kernel_img-term_i386_pc_vga_text.o kernel_img-term_i386_vga_common.o kernel_img-symlist.o $(TARGET_LDFLAGS) $(kernel_img_LDFLAGS)
+
+kernel_img-kern_i386_coreboot_startup.o: kern/i386/coreboot/startup.S $(kern/i386/coreboot/startup.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/coreboot -I$(srcdir)/kern/i386/coreboot $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_coreboot_startup.d
+
+kernel_img-kern_i386_misc.o: kern/i386/misc.S $(kern/i386/misc.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_misc.d
+
+kernel_img-kern_i386_coreboot_init.o: kern/i386/coreboot/init.c $(kern/i386/coreboot/init.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/coreboot -I$(srcdir)/kern/i386/coreboot $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_coreboot_init.d
+
+kernel_img-kern_i386_multiboot_mmap.o: kern/i386/multiboot_mmap.c $(kern/i386/multiboot_mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_multiboot_mmap.d
+
+kernel_img-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_main.d
+
+kernel_img-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_device.d
+
+kernel_img-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_disk.d
+
+kernel_img-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_dl.d
+
+kernel_img-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_file.d
+
+kernel_img-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_fs.d
+
+kernel_img-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_err.d
+
+kernel_img-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_misc.d
+
+kernel_img-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_mm.d
+
+kernel_img-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_reader.d
+
+kernel_img-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_term.d
+
+kernel_img-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_rescue_parser.d
+
+kernel_img-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_rescue_reader.d
+
+kernel_img-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_time.d
+
+kernel_img-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_list.d
+
+kernel_img-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_handler.d
+
+kernel_img-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_command.d
+
+kernel_img-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_corecmd.d
+
+kernel_img-kern___target_cpu__dl.o: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern___target_cpu__dl.d
+
+kernel_img-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_parser.d
+
+kernel_img-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_partition.d
+
+kernel_img-kern_i386_tsc.o: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_tsc.d
+
+kernel_img-kern_i386_pit.o: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_pit.d
+
+kernel_img-kern_generic_rtc_get_time_ms.o: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_generic_rtc_get_time_ms.d
+
+kernel_img-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_generic_millisleep.d
+
+kernel_img-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_env.d
+
+kernel_img-term_i386_pc_vga_text.o: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-term_i386_pc_vga_text.d
+
+kernel_img-term_i386_vga_common.o: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-term_i386_vga_common.d
+
+kernel_img-symlist.o: symlist.c $(symlist.c_DEPENDENCIES)
+	$(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-symlist.d
+
+kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	machine/boot.h machine/console.h machine/init.h \
+	machine/memory.h machine/loader.h list.h handler.h command.h
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic
+
+endif
+
+ifeq ($(platform), qemu)
+
+GRUB_BOOT_MACHINE_LINK_ADDR	= 0xffe00
+
+pkglib_IMAGES += boot.img
+boot_img_SOURCES = boot/i386/qemu/boot.S
+
+clean-image-boot.img.1:
+	rm -f boot.img boot.exec boot_img-boot_i386_qemu_boot.o
+
+CLEAN_IMAGE_TARGETS += clean-image-boot.img.1
+
+mostlyclean-image-boot.img.1:
+	rm -f boot_img-boot_i386_qemu_boot.d
+
+MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-boot.img.1
+
+ifneq ($(TARGET_APPLE_CC),1)
+boot.img: boot.exec
+	$(OBJCOPY) -O $(boot_img_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
+else
+ifneq (boot.exec,kernel.exec)
+boot.img: boot.exec ./grub-macho2img
+	./grub-macho2img $< $@
+else
+boot.img: boot.exec ./grub-macho2img
+	./grub-macho2img --bss $< $@
+endif
+endif
+
+boot.exec: boot_img-boot_i386_qemu_boot.o
+	$(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(boot_img_LDFLAGS)
+
+boot_img-boot_i386_qemu_boot.o: boot/i386/qemu/boot.S $(boot/i386/qemu/boot.S_DEPENDENCIES)
+	$(TARGET_CC) -Iboot/i386/qemu -I$(srcdir)/boot/i386/qemu $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(boot_img_ASFLAGS) -MD -c -o $@ $<
+-include boot_img-boot_i386_qemu_boot.d
+
+boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)
+boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR)
+boot_img_FORMAT = binary
+
+bin_UTILITIES += grub-mkimage
+grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \
+	util/resolve.c
+
+clean-utility-grub-mkimage.1:
+	rm -f grub-mkimage$(EXEEXT) grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkimage.1
+
+mostlyclean-utility-grub-mkimage.1:
+	rm -f grub_mkimage-util_i386_pc_grub_mkimage.d grub_mkimage-util_misc.d grub_mkimage-util_resolve.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkimage.1
+
+grub_mkimage_OBJECTS += grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o
+
+grub_mkimage-util_i386_pc_grub_mkimage.o: util/i386/pc/grub-mkimage.c $(util/i386/pc/grub-mkimage.c_DEPENDENCIES)
+	$(CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_i386_pc_grub_mkimage.d
+
+grub_mkimage-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_misc.d
+
+grub_mkimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_resolve.d
+
+grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
+
+pkglib_IMAGES += kernel.img
+kernel_img_SOURCES = kern/i386/qemu/startup.S \
+	kern/i386/misc.S \
+	kern/i386/coreboot/init.c \
+	kern/i386/qemu/mmap.c \
+	kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+	kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
+	kern/i386/tsc.c kern/i386/pit.c \
+	kern/generic/rtc_get_time_ms.c \
+	kern/generic/millisleep.c \
+	kern/env.c \
+	term/i386/pc/vga_text.c term/i386/vga_common.c \
+	symlist.c
+
+clean-image-kernel.img.1:
+	rm -f kernel.img kernel.exec kernel_img-kern_i386_qemu_startup.o kernel_img-kern_i386_misc.o kernel_img-kern_i386_coreboot_init.o kernel_img-kern_i386_qemu_mmap.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern_time.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_i386_tsc.o kernel_img-kern_i386_pit.o kernel_img-kern_generic_rtc_get_time_ms.o kernel_img-kern_generic_millisleep.o kernel_img-kern_env.o kernel_img-term_i386_pc_vga_text.o kernel_img-term_i386_vga_common.o kernel_img-symlist.o
+
+CLEAN_IMAGE_TARGETS += clean-image-kernel.img.1
+
+mostlyclean-image-kernel.img.1:
+	rm -f kernel_img-kern_i386_qemu_startup.d kernel_img-kern_i386_misc.d kernel_img-kern_i386_coreboot_init.d kernel_img-kern_i386_qemu_mmap.d kernel_img-kern_main.d kernel_img-kern_device.d kernel_img-kern_disk.d kernel_img-kern_dl.d kernel_img-kern_file.d kernel_img-kern_fs.d kernel_img-kern_err.d kernel_img-kern_misc.d kernel_img-kern_mm.d kernel_img-kern_reader.d kernel_img-kern_term.d kernel_img-kern_rescue_parser.d kernel_img-kern_rescue_reader.d kernel_img-kern_time.d kernel_img-kern_list.d kernel_img-kern_handler.d kernel_img-kern_command.d kernel_img-kern_corecmd.d kernel_img-kern___target_cpu__dl.d kernel_img-kern_parser.d kernel_img-kern_partition.d kernel_img-kern_i386_tsc.d kernel_img-kern_i386_pit.d kernel_img-kern_generic_rtc_get_time_ms.d kernel_img-kern_generic_millisleep.d kernel_img-kern_env.d kernel_img-term_i386_pc_vga_text.d kernel_img-term_i386_vga_common.d kernel_img-symlist.d
+
+MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-kernel.img.1
+
+ifneq ($(TARGET_APPLE_CC),1)
+kernel.img: kernel.exec
+	$(OBJCOPY) -O $(kernel_img_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
+else
+ifneq (kernel.exec,kernel.exec)
+kernel.img: kernel.exec ./grub-macho2img
+	./grub-macho2img $< $@
+else
+kernel.img: kernel.exec ./grub-macho2img
+	./grub-macho2img --bss $< $@
+endif
+endif
+
+kernel.exec: kernel_img-kern_i386_qemu_startup.o kernel_img-kern_i386_misc.o kernel_img-kern_i386_coreboot_init.o kernel_img-kern_i386_qemu_mmap.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern_time.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_i386_tsc.o kernel_img-kern_i386_pit.o kernel_img-kern_generic_rtc_get_time_ms.o kernel_img-kern_generic_millisleep.o kernel_img-kern_env.o kernel_img-term_i386_pc_vga_text.o kernel_img-term_i386_vga_common.o kernel_img-symlist.o
+	$(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(kernel_img_LDFLAGS)
+
+kernel_img-kern_i386_qemu_startup.o: kern/i386/qemu/startup.S $(kern/i386/qemu/startup.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/qemu -I$(srcdir)/kern/i386/qemu $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_qemu_startup.d
+
+kernel_img-kern_i386_misc.o: kern/i386/misc.S $(kern/i386/misc.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_misc.d
+
+kernel_img-kern_i386_coreboot_init.o: kern/i386/coreboot/init.c $(kern/i386/coreboot/init.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/coreboot -I$(srcdir)/kern/i386/coreboot $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_coreboot_init.d
+
+kernel_img-kern_i386_qemu_mmap.o: kern/i386/qemu/mmap.c $(kern/i386/qemu/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/qemu -I$(srcdir)/kern/i386/qemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_qemu_mmap.d
+
+kernel_img-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_main.d
+
+kernel_img-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_device.d
+
+kernel_img-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_disk.d
+
+kernel_img-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_dl.d
+
+kernel_img-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_file.d
+
+kernel_img-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_fs.d
+
+kernel_img-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_err.d
+
+kernel_img-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_misc.d
+
+kernel_img-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_mm.d
+
+kernel_img-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_reader.d
+
+kernel_img-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_term.d
+
+kernel_img-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_rescue_parser.d
+
+kernel_img-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_rescue_reader.d
+
+kernel_img-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_time.d
+
+kernel_img-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_list.d
+
+kernel_img-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_handler.d
+
+kernel_img-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_command.d
+
+kernel_img-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_corecmd.d
+
+kernel_img-kern___target_cpu__dl.o: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern___target_cpu__dl.d
+
+kernel_img-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_parser.d
+
+kernel_img-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_partition.d
+
+kernel_img-kern_i386_tsc.o: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_tsc.d
+
+kernel_img-kern_i386_pit.o: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_pit.d
+
+kernel_img-kern_generic_rtc_get_time_ms.o: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_generic_rtc_get_time_ms.d
+
+kernel_img-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_generic_millisleep.d
+
+kernel_img-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_env.d
+
+kernel_img-term_i386_pc_vga_text.o: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-term_i386_pc_vga_text.d
+
+kernel_img-term_i386_vga_common.o: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-term_i386_vga_common.d
+
+kernel_img-symlist.o: symlist.c $(symlist.c_DEPENDENCIES)
+	$(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-symlist.d
+
+kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	machine/boot.h machine/console.h machine/init.h \
+	machine/memory.h machine/loader.h list.h handler.h command.h
+kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR)
+kernel_img_FORMAT = binary
+endif
+
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# Utilities.
+sbin_UTILITIES = grub-mkdevicemap
+ifeq ($(enable_grub_emu), yes)
+sbin_UTILITIES += grub-emu
+endif
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/devicemap.c util/misc.c
+
+clean-utility-grub-mkdevicemap.1:
+	rm -f grub-mkdevicemap$(EXEEXT) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_devicemap.o grub_mkdevicemap-util_misc.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkdevicemap.1
+
+mostlyclean-utility-grub-mkdevicemap.1:
+	rm -f grub_mkdevicemap-util_grub_mkdevicemap.d grub_mkdevicemap-util_deviceiter.d grub_mkdevicemap-util_devicemap.d grub_mkdevicemap-util_misc.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkdevicemap.1
+
+grub_mkdevicemap_OBJECTS += grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_devicemap.o grub_mkdevicemap-util_misc.o
+
+grub_mkdevicemap-util_grub_mkdevicemap.o: util/grub-mkdevicemap.c $(util/grub-mkdevicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_grub_mkdevicemap.d
+
+grub_mkdevicemap-util_deviceiter.o: util/deviceiter.c $(util/deviceiter.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_deviceiter.d
+
+grub_mkdevicemap-util_devicemap.o: util/devicemap.c $(util/devicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_devicemap.d
+
+grub_mkdevicemap-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_misc.d
+
+
+# For grub-emu.
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c	\
+	commands/configfile.c commands/echo.c commands/help.c		\
+	commands/handler.c commands/ls.c commands/test.c 		\
+	commands/search.c commands/blocklist.c commands/hexdump.c	\
+	commands/gptsync.c commands/probe.c commands/xnu_uuid.c		\
+	commands/password.c commands/keystatus.c			\
+	lib/hexdump.c commands/i386/cpuid.c				\
+	lib/envblk.c commands/loadenv.c					\
+	disk/host.c disk/loopback.c					\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c  fs/hfs.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c		\
+	fs/befs.c fs/befs_be.c fs/tar.c				\
+	\
+	fs/fshelp.c							\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/list.c kern/handler.c				\
+	kern/command.c kern/corecmd.c commands/extcmd.c kern/file.c	\
+	kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c	\
+	kern/partition.c kern/reader.c kern/term.c			\
+	kern/rescue_reader.c kern/rescue_parser.c                       \
+	lib/arg.c normal/cmdline.c normal/misc.c			\
+	normal/handler.c normal/auth.c normal/autofs.c			\
+	normal/completion.c normal/datetime.c normal/main.c 		\
+	normal/menu_text.c						\
+	normal/menu.c normal/menu_entry.c normal/menu_viewer.c		\
+	normal/color.c							\
+	script/sh/main.c script/sh/execute.c script/sh/function.c       \
+	script/sh/lexer.c script/sh/script.c grub_script.tab.c          \
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c partmap/gpt.c					\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	commands/parttool.c parttool/msdospart.c				\
+	grub_emu_init.c
+
+clean-utility-grub-emu.1:
+	rm -f grub-emu$(EXEEXT) grub_emu-commands_minicmd.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_handler.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-commands_gptsync.o grub_emu-commands_probe.o grub_emu-commands_xnu_uuid.o grub_emu-commands_password.o grub_emu-commands_keystatus.o grub_emu-lib_hexdump.o grub_emu-commands_i386_cpuid.o grub_emu-lib_envblk.o grub_emu-commands_loadenv.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_ufs2.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_afs_be.o grub_emu-fs_befs.o grub_emu-fs_befs_be.o grub_emu-fs_tar.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_list.o grub_emu-kern_handler.o grub_emu-kern_command.o grub_emu-kern_corecmd.o grub_emu-commands_extcmd.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-commands_boot.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_reader.o grub_emu-kern_term.o grub_emu-kern_rescue_reader.o grub_emu-kern_rescue_parser.o grub_emu-lib_arg.o grub_emu-normal_cmdline.o grub_emu-normal_misc.o grub_emu-normal_handler.o grub_emu-normal_auth.o grub_emu-normal_autofs.o grub_emu-normal_completion.o grub_emu-normal_datetime.o grub_emu-normal_main.o grub_emu-normal_menu_text.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_color.o grub_emu-script_sh_main.o grub_emu-script_sh_execute.o grub_emu-script_sh_function.o grub_emu-script_sh_lexer.o grub_emu-script_sh_script.o grub_emu-grub_script_tab.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_msdos.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-commands_parttool.o grub_emu-parttool_msdospart.o grub_emu-grub_emu_init.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-emu.1
+
+mostlyclean-utility-grub-emu.1:
+	rm -f grub_emu-commands_minicmd.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_echo.d grub_emu-commands_help.d grub_emu-commands_handler.d grub_emu-commands_ls.d grub_emu-commands_test.d grub_emu-commands_search.d grub_emu-commands_blocklist.d grub_emu-commands_hexdump.d grub_emu-commands_gptsync.d grub_emu-commands_probe.d grub_emu-commands_xnu_uuid.d grub_emu-commands_password.d grub_emu-commands_keystatus.d grub_emu-lib_hexdump.d grub_emu-commands_i386_cpuid.d grub_emu-lib_envblk.d grub_emu-commands_loadenv.d grub_emu-disk_host.d grub_emu-disk_loopback.d grub_emu-fs_affs.d grub_emu-fs_cpio.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_hfs.d grub_emu-fs_hfsplus.d grub_emu-fs_iso9660.d grub_emu-fs_udf.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ntfs.d grub_emu-fs_ntfscomp.d grub_emu-fs_reiserfs.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_ufs2.d grub_emu-fs_xfs.d grub_emu-fs_afs.d grub_emu-fs_afs_be.d grub_emu-fs_befs.d grub_emu-fs_befs_be.d grub_emu-fs_tar.d grub_emu-fs_fshelp.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_elf.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-kern_list.d grub_emu-kern_handler.d grub_emu-kern_command.d grub_emu-kern_corecmd.d grub_emu-commands_extcmd.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-commands_boot.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-kern_partition.d grub_emu-kern_reader.d grub_emu-kern_term.d grub_emu-kern_rescue_reader.d grub_emu-kern_rescue_parser.d grub_emu-lib_arg.d grub_emu-normal_cmdline.d grub_emu-normal_misc.d grub_emu-normal_handler.d grub_emu-normal_auth.d grub_emu-normal_autofs.d grub_emu-normal_completion.d grub_emu-normal_datetime.d grub_emu-normal_main.d grub_emu-normal_menu_text.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d grub_emu-normal_menu_viewer.d grub_emu-normal_color.d grub_emu-script_sh_main.d grub_emu-script_sh_execute.d grub_emu-script_sh_function.d grub_emu-script_sh_lexer.d grub_emu-script_sh_script.d grub_emu-grub_script_tab.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_msdos.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-partmap_gpt.d grub_emu-util_console.d grub_emu-util_hostfs.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_hostdisk.d grub_emu-util_getroot.d grub_emu-disk_raid.d grub_emu-disk_raid5_recover.d grub_emu-disk_raid6_recover.d grub_emu-disk_mdraid_linux.d grub_emu-disk_dmraid_nvidia.d grub_emu-disk_lvm.d grub_emu-commands_parttool.d grub_emu-parttool_msdospart.d grub_emu-grub_emu_init.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-emu.1
+
+grub_emu_OBJECTS += grub_emu-commands_minicmd.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_handler.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-commands_gptsync.o grub_emu-commands_probe.o grub_emu-commands_xnu_uuid.o grub_emu-commands_password.o grub_emu-commands_keystatus.o grub_emu-lib_hexdump.o grub_emu-commands_i386_cpuid.o grub_emu-lib_envblk.o grub_emu-commands_loadenv.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_ufs2.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_afs_be.o grub_emu-fs_befs.o grub_emu-fs_befs_be.o grub_emu-fs_tar.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_list.o grub_emu-kern_handler.o grub_emu-kern_command.o grub_emu-kern_corecmd.o grub_emu-commands_extcmd.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-commands_boot.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_reader.o grub_emu-kern_term.o grub_emu-kern_rescue_reader.o grub_emu-kern_rescue_parser.o grub_emu-lib_arg.o grub_emu-normal_cmdline.o grub_emu-normal_misc.o grub_emu-normal_handler.o grub_emu-normal_auth.o grub_emu-normal_autofs.o grub_emu-normal_completion.o grub_emu-normal_datetime.o grub_emu-normal_main.o grub_emu-normal_menu_text.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_color.o grub_emu-script_sh_main.o grub_emu-script_sh_execute.o grub_emu-script_sh_function.o grub_emu-script_sh_lexer.o grub_emu-script_sh_script.o grub_emu-grub_script_tab.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_msdos.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-commands_parttool.o grub_emu-parttool_msdospart.o grub_emu-grub_emu_init.o
+
+grub_emu-commands_minicmd.o: commands/minicmd.c $(commands/minicmd.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_minicmd.d
+
+grub_emu-commands_cat.o: commands/cat.c $(commands/cat.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_cat.d
+
+grub_emu-commands_cmp.o: commands/cmp.c $(commands/cmp.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_cmp.d
+
+grub_emu-commands_configfile.o: commands/configfile.c $(commands/configfile.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_configfile.d
+
+grub_emu-commands_echo.o: commands/echo.c $(commands/echo.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_echo.d
+
+grub_emu-commands_help.o: commands/help.c $(commands/help.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_help.d
+
+grub_emu-commands_handler.o: commands/handler.c $(commands/handler.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_handler.d
+
+grub_emu-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_ls.d
+
+grub_emu-commands_test.o: commands/test.c $(commands/test.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_test.d
+
+grub_emu-commands_search.o: commands/search.c $(commands/search.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_search.d
+
+grub_emu-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_blocklist.d
+
+grub_emu-commands_hexdump.o: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_hexdump.d
+
+grub_emu-commands_gptsync.o: commands/gptsync.c $(commands/gptsync.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_gptsync.d
+
+grub_emu-commands_probe.o: commands/probe.c $(commands/probe.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_probe.d
+
+grub_emu-commands_xnu_uuid.o: commands/xnu_uuid.c $(commands/xnu_uuid.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_xnu_uuid.d
+
+grub_emu-commands_password.o: commands/password.c $(commands/password.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_password.d
+
+grub_emu-commands_keystatus.o: commands/keystatus.c $(commands/keystatus.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_keystatus.d
+
+grub_emu-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_hexdump.d
+
+grub_emu-commands_i386_cpuid.o: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES)
+	$(CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_i386_cpuid.d
+
+grub_emu-lib_envblk.o: lib/envblk.c $(lib/envblk.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_envblk.d
+
+grub_emu-commands_loadenv.o: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_loadenv.d
+
+grub_emu-disk_host.o: disk/host.c $(disk/host.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_host.d
+
+grub_emu-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_loopback.d
+
+grub_emu-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_affs.d
+
+grub_emu-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_cpio.d
+
+grub_emu-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_fat.d
+
+grub_emu-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ext2.d
+
+grub_emu-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_hfs.d
+
+grub_emu-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_hfsplus.d
+
+grub_emu-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_iso9660.d
+
+grub_emu-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_udf.d
+
+grub_emu-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_jfs.d
+
+grub_emu-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_minix.d
+
+grub_emu-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ntfs.d
+
+grub_emu-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ntfscomp.d
+
+grub_emu-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_reiserfs.d
+
+grub_emu-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_sfs.d
+
+grub_emu-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ufs.d
+
+grub_emu-fs_ufs2.o: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ufs2.d
+
+grub_emu-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_xfs.d
+
+grub_emu-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_afs.d
+
+grub_emu-fs_afs_be.o: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_afs_be.d
+
+grub_emu-fs_befs.o: fs/befs.c $(fs/befs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_befs.d
+
+grub_emu-fs_befs_be.o: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_befs_be.d
+
+grub_emu-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_tar.d
+
+grub_emu-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_fshelp.d
+
+grub_emu-io_gzio.o: io/gzio.c $(io/gzio.c_DEPENDENCIES)
+	$(CC) -Iio -I$(srcdir)/io $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-io_gzio.d
+
+grub_emu-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_device.d
+
+grub_emu-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_disk.d
+
+grub_emu-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_dl.d
+
+grub_emu-kern_elf.o: kern/elf.c $(kern/elf.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_elf.d
+
+grub_emu-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_env.d
+
+grub_emu-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_err.d
+
+grub_emu-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_list.d
+
+grub_emu-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_handler.d
+
+grub_emu-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_command.d
+
+grub_emu-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_corecmd.d
+
+grub_emu-commands_extcmd.o: commands/extcmd.c $(commands/extcmd.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_extcmd.d
+
+grub_emu-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_file.d
+
+grub_emu-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_fs.d
+
+grub_emu-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_boot.d
+
+grub_emu-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_main.d
+
+grub_emu-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_misc.d
+
+grub_emu-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_parser.d
+
+grub_emu-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_partition.d
+
+grub_emu-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_reader.d
+
+grub_emu-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_term.d
+
+grub_emu-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_rescue_reader.d
+
+grub_emu-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_rescue_parser.d
+
+grub_emu-lib_arg.o: lib/arg.c $(lib/arg.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_arg.d
+
+grub_emu-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_cmdline.d
+
+grub_emu-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_misc.d
+
+grub_emu-normal_handler.o: normal/handler.c $(normal/handler.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_handler.d
+
+grub_emu-normal_auth.o: normal/auth.c $(normal/auth.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_auth.d
+
+grub_emu-normal_autofs.o: normal/autofs.c $(normal/autofs.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_autofs.d
+
+grub_emu-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_completion.d
+
+grub_emu-normal_datetime.o: normal/datetime.c $(normal/datetime.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_datetime.d
+
+grub_emu-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_main.d
+
+grub_emu-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_text.d
+
+grub_emu-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu.d
+
+grub_emu-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_entry.d
+
+grub_emu-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_viewer.d
+
+grub_emu-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_color.d
+
+grub_emu-script_sh_main.o: script/sh/main.c $(script/sh/main.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_main.d
+
+grub_emu-script_sh_execute.o: script/sh/execute.c $(script/sh/execute.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_execute.d
+
+grub_emu-script_sh_function.o: script/sh/function.c $(script/sh/function.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_function.d
+
+grub_emu-script_sh_lexer.o: script/sh/lexer.c $(script/sh/lexer.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_lexer.d
+
+grub_emu-script_sh_script.o: script/sh/script.c $(script/sh/script.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_script.d
+
+grub_emu-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-grub_script_tab.d
+
+grub_emu-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_amiga.d
+
+grub_emu-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_apple.d
+
+grub_emu-partmap_msdos.o: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_msdos.d
+
+grub_emu-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_sun.d
+
+grub_emu-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_acorn.d
+
+grub_emu-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_gpt.d
+
+grub_emu-util_console.o: util/console.c $(util/console.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_console.d
+
+grub_emu-util_hostfs.o: util/hostfs.c $(util/hostfs.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_hostfs.d
+
+grub_emu-util_grub_emu.o: util/grub-emu.c $(util/grub-emu.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_grub_emu.d
+
+grub_emu-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_misc.d
+
+grub_emu-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_hostdisk.d
+
+grub_emu-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_getroot.d
+
+grub_emu-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid.d
+
+grub_emu-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid5_recover.d
+
+grub_emu-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid6_recover.d
+
+grub_emu-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_mdraid_linux.d
+
+grub_emu-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_dmraid_nvidia.d
+
+grub_emu-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_lvm.d
+
+grub_emu-commands_parttool.o: commands/parttool.c $(commands/parttool.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_parttool.d
+
+grub_emu-parttool_msdospart.o: parttool/msdospart.c $(parttool/msdospart.c_DEPENDENCIES)
+	$(CC) -Iparttool -I$(srcdir)/parttool $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-parttool_msdospart.d
+
+grub_emu-grub_emu_init.o: grub_emu_init.c $(grub_emu_init.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-grub_emu_init.d
+
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+sbin_SCRIPTS += grub-install
+grub_install_SOURCES = util/i386/pc/grub-install.in
+CLEANFILES += grub-install
+
+grub-install: util/i386/pc/grub-install.in $(util/i386/pc/grub-install.in_DEPENDENCIES) config.status
+	./config.status --file=grub-install:util/i386/pc/grub-install.in
+	chmod +x $@
+
+
+# Modules.
+pkglib_MODULES = linux.mod multiboot.mod 		\
+	aout.mod play.mod serial.mod ata.mod		\
+	memdisk.mod pci.mod lspci.mod reboot.mod	\
+	halt.mod datetime.mod date.mod datehook.mod	\
+	lsmmap.mod mmap.mod
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c
+
+clean-module-boot.mod.1:
+	rm -f boot.mod mod-boot.o mod-boot.c pre-boot.o boot_mod-commands_boot.o und-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod.1
+
+ifneq ($(boot_mod_EXPORTS),no)
+clean-module-boot.mod-symbol.1:
+	rm -f def-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod-symbol.1
+DEFSYMFILES += def-boot.lst
+endif
+mostlyclean-module-boot.mod.1:
+	rm -f boot_mod-commands_boot.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-boot.mod.1
+UNDSYMFILES += und-boot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-boot.o mod-boot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-boot.o mod-boot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-boot.o: $(boot_mod_DEPENDENCIES) boot_mod-commands_boot.o
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ boot_mod-commands_boot.o
+
+mod-boot.o: mod-boot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -c -o $@ $<
+
+mod-boot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'boot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(boot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-boot.lst: pre-boot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+else
+def-boot.lst: pre-boot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+endif
+endif
+
+und-boot.lst: pre-boot.o
+	echo 'boot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+boot_mod-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $<
+-include boot_mod-commands_boot.d
+
+clean-module-boot_mod-commands_boot-extra.1:
+	rm -f cmd-boot_mod-commands_boot.lst fs-boot_mod-commands_boot.lst partmap-boot_mod-commands_boot.lst handler-boot_mod-commands_boot.lst parttool-boot_mod-commands_boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot_mod-commands_boot-extra.1
+
+COMMANDFILES += cmd-boot_mod-commands_boot.lst
+FSFILES += fs-boot_mod-commands_boot.lst
+PARTTOOLFILES += parttool-boot_mod-commands_boot.lst
+PARTMAPFILES += partmap-boot_mod-commands_boot.lst
+HANDLERFILES += handler-boot_mod-commands_boot.lst
+
+cmd-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1)
+
+fs-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1)
+
+parttool-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh boot > $@ || (rm -f $@; exit 1)
+
+partmap-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1)
+
+handler-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh boot > $@ || (rm -f $@; exit 1)
+
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
+
+clean-module-mmap.mod.1:
+	rm -f mmap.mod mod-mmap.o mod-mmap.c pre-mmap.o mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o und-mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap.mod.1
+
+ifneq ($(mmap_mod_EXPORTS),no)
+clean-module-mmap.mod-symbol.1:
+	rm -f def-mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap.mod-symbol.1
+DEFSYMFILES += def-mmap.lst
+endif
+mostlyclean-module-mmap.mod.1:
+	rm -f mmap_mod-mmap_mmap.d mmap_mod-mmap_i386_uppermem.d mmap_mod-mmap_i386_mmap.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-mmap.mod.1
+UNDSYMFILES += und-mmap.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+mmap.mod: pre-mmap.o mod-mmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-mmap.o mod-mmap.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+mmap.mod: pre-mmap.o mod-mmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-mmap.o mod-mmap.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-mmap.o: $(mmap_mod_DEPENDENCIES) mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o
+	-rm -f $@
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o
+
+mod-mmap.o: mod-mmap.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -c -o $@ $<
+
+mod-mmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'mmap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(mmap_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-mmap.lst: pre-mmap.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 mmap/' > $@
+else
+def-mmap.lst: pre-mmap.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 mmap/' > $@
+endif
+endif
+
+und-mmap.lst: pre-mmap.o
+	echo 'mmap' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+mmap_mod-mmap_mmap.o: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_mmap.d
+
+clean-module-mmap_mod-mmap_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_mmap.lst fs-mmap_mod-mmap_mmap.lst partmap-mmap_mod-mmap_mmap.lst handler-mmap_mod-mmap_mmap.lst parttool-mmap_mod-mmap_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_mmap.lst
+FSFILES += fs-mmap_mod-mmap_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_mmap.lst
+
+cmd-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_i386_uppermem.o: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_i386_uppermem.d
+
+clean-module-mmap_mod-mmap_i386_uppermem-extra.1:
+	rm -f cmd-mmap_mod-mmap_i386_uppermem.lst fs-mmap_mod-mmap_i386_uppermem.lst partmap-mmap_mod-mmap_i386_uppermem.lst handler-mmap_mod-mmap_i386_uppermem.lst parttool-mmap_mod-mmap_i386_uppermem.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_i386_uppermem-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_i386_uppermem.lst
+FSFILES += fs-mmap_mod-mmap_i386_uppermem.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_i386_uppermem.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_i386_uppermem.lst
+HANDLERFILES += handler-mmap_mod-mmap_i386_uppermem.lst
+
+cmd-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_i386_mmap.o: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_i386_mmap.d
+
+clean-module-mmap_mod-mmap_i386_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_i386_mmap.lst fs-mmap_mod-mmap_i386_mmap.lst partmap-mmap_mod-mmap_i386_mmap.lst handler-mmap_mod-mmap_i386_mmap.lst parttool-mmap_mod-mmap_i386_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_i386_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_i386_mmap.lst
+FSFILES += fs-mmap_mod-mmap_i386_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_i386_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_i386_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_i386_mmap.lst
+
+cmd-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/i386/linux.c
+
+clean-module-linux.mod.1:
+	rm -f linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_i386_linux.o und-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod.1
+
+ifneq ($(linux_mod_EXPORTS),no)
+clean-module-linux.mod-symbol.1:
+	rm -f def-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod-symbol.1
+DEFSYMFILES += def-linux.lst
+endif
+mostlyclean-module-linux.mod.1:
+	rm -f linux_mod-loader_i386_linux.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-linux.mod.1
+UNDSYMFILES += und-linux.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-linux.o mod-linux.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_i386_linux.o
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_i386_linux.o
+
+mod-linux.o: mod-linux.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $<
+
+mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(linux_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-linux.lst: pre-linux.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+else
+def-linux.lst: pre-linux.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+endif
+endif
+
+und-linux.lst: pre-linux.o
+	echo 'linux' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+linux_mod-loader_i386_linux.o: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $<
+-include linux_mod-loader_i386_linux.d
+
+clean-module-linux_mod-loader_i386_linux-extra.1:
+	rm -f cmd-linux_mod-loader_i386_linux.lst fs-linux_mod-loader_i386_linux.lst partmap-linux_mod-loader_i386_linux.lst handler-linux_mod-loader_i386_linux.lst parttool-linux_mod-loader_i386_linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux_mod-loader_i386_linux-extra.1
+
+COMMANDFILES += cmd-linux_mod-loader_i386_linux.lst
+FSFILES += fs-linux_mod-loader_i386_linux.lst
+PARTTOOLFILES += parttool-linux_mod-loader_i386_linux.lst
+PARTMAPFILES += partmap-linux_mod-loader_i386_linux.lst
+HANDLERFILES += handler-linux_mod-loader_i386_linux.lst
+
+cmd-linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1)
+
+fs-linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1)
+
+parttool-linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh linux > $@ || (rm -f $@; exit 1)
+
+partmap-linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1)
+
+handler-linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh linux > $@ || (rm -f $@; exit 1)
+
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod.
+reboot_mod_SOURCES = commands/reboot.c kern/i386/reboot.c
+
+clean-module-reboot.mod.1:
+	rm -f reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o reboot_mod-kern_i386_reboot.o und-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod.1
+
+ifneq ($(reboot_mod_EXPORTS),no)
+clean-module-reboot.mod-symbol.1:
+	rm -f def-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod-symbol.1
+DEFSYMFILES += def-reboot.lst
+endif
+mostlyclean-module-reboot.mod.1:
+	rm -f reboot_mod-commands_reboot.d reboot_mod-kern_i386_reboot.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-reboot.mod.1
+UNDSYMFILES += und-reboot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-reboot.o mod-reboot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o reboot_mod-kern_i386_reboot.o
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o reboot_mod-kern_i386_reboot.o
+
+mod-reboot.o: mod-reboot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $<
+
+mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(reboot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-reboot.lst: pre-reboot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+else
+def-reboot.lst: pre-reboot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+endif
+endif
+
+und-reboot.lst: pre-reboot.o
+	echo 'reboot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $<
+-include reboot_mod-commands_reboot.d
+
+clean-module-reboot_mod-commands_reboot-extra.1:
+	rm -f cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst handler-reboot_mod-commands_reboot.lst parttool-reboot_mod-commands_reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot_mod-commands_reboot-extra.1
+
+COMMANDFILES += cmd-reboot_mod-commands_reboot.lst
+FSFILES += fs-reboot_mod-commands_reboot.lst
+PARTTOOLFILES += parttool-reboot_mod-commands_reboot.lst
+PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst
+HANDLERFILES += handler-reboot_mod-commands_reboot.lst
+
+cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1)
+
+parttool-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh reboot > $@ || (rm -f $@; exit 1)
+
+partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1)
+
+handler-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+reboot_mod-kern_i386_reboot.o: kern/i386/reboot.c $(kern/i386/reboot.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $<
+-include reboot_mod-kern_i386_reboot.d
+
+clean-module-reboot_mod-kern_i386_reboot-extra.1:
+	rm -f cmd-reboot_mod-kern_i386_reboot.lst fs-reboot_mod-kern_i386_reboot.lst partmap-reboot_mod-kern_i386_reboot.lst handler-reboot_mod-kern_i386_reboot.lst parttool-reboot_mod-kern_i386_reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot_mod-kern_i386_reboot-extra.1
+
+COMMANDFILES += cmd-reboot_mod-kern_i386_reboot.lst
+FSFILES += fs-reboot_mod-kern_i386_reboot.lst
+PARTTOOLFILES += parttool-reboot_mod-kern_i386_reboot.lst
+PARTMAPFILES += partmap-reboot_mod-kern_i386_reboot.lst
+HANDLERFILES += handler-reboot_mod-kern_i386_reboot.lst
+
+cmd-reboot_mod-kern_i386_reboot.lst: kern/i386/reboot.c $(kern/i386/reboot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+fs-reboot_mod-kern_i386_reboot.lst: kern/i386/reboot.c $(kern/i386/reboot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1)
+
+parttool-reboot_mod-kern_i386_reboot.lst: kern/i386/reboot.c $(kern/i386/reboot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh reboot > $@ || (rm -f $@; exit 1)
+
+partmap-reboot_mod-kern_i386_reboot.lst: kern/i386/reboot.c $(kern/i386/reboot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1)
+
+handler-reboot_mod-kern_i386_reboot.lst: kern/i386/reboot.c $(kern/i386/reboot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/halt.c kern/i386/halt.c
+
+clean-module-halt.mod.1:
+	rm -f halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_halt.o halt_mod-kern_i386_halt.o und-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod.1
+
+ifneq ($(halt_mod_EXPORTS),no)
+clean-module-halt.mod-symbol.1:
+	rm -f def-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod-symbol.1
+DEFSYMFILES += def-halt.lst
+endif
+mostlyclean-module-halt.mod.1:
+	rm -f halt_mod-commands_halt.d halt_mod-kern_i386_halt.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-halt.mod.1
+UNDSYMFILES += und-halt.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-halt.o mod-halt.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_halt.o halt_mod-kern_i386_halt.o
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_halt.o halt_mod-kern_i386_halt.o
+
+mod-halt.o: mod-halt.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $<
+
+mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(halt_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-halt.lst: pre-halt.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+else
+def-halt.lst: pre-halt.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+endif
+endif
+
+und-halt.lst: pre-halt.o
+	echo 'halt' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+halt_mod-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $<
+-include halt_mod-commands_halt.d
+
+clean-module-halt_mod-commands_halt-extra.1:
+	rm -f cmd-halt_mod-commands_halt.lst fs-halt_mod-commands_halt.lst partmap-halt_mod-commands_halt.lst handler-halt_mod-commands_halt.lst parttool-halt_mod-commands_halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt_mod-commands_halt-extra.1
+
+COMMANDFILES += cmd-halt_mod-commands_halt.lst
+FSFILES += fs-halt_mod-commands_halt.lst
+PARTTOOLFILES += parttool-halt_mod-commands_halt.lst
+PARTMAPFILES += partmap-halt_mod-commands_halt.lst
+HANDLERFILES += handler-halt_mod-commands_halt.lst
+
+cmd-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1)
+
+fs-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1)
+
+parttool-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh halt > $@ || (rm -f $@; exit 1)
+
+partmap-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1)
+
+handler-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh halt > $@ || (rm -f $@; exit 1)
+
+halt_mod-kern_i386_halt.o: kern/i386/halt.c $(kern/i386/halt.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $<
+-include halt_mod-kern_i386_halt.d
+
+clean-module-halt_mod-kern_i386_halt-extra.1:
+	rm -f cmd-halt_mod-kern_i386_halt.lst fs-halt_mod-kern_i386_halt.lst partmap-halt_mod-kern_i386_halt.lst handler-halt_mod-kern_i386_halt.lst parttool-halt_mod-kern_i386_halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt_mod-kern_i386_halt-extra.1
+
+COMMANDFILES += cmd-halt_mod-kern_i386_halt.lst
+FSFILES += fs-halt_mod-kern_i386_halt.lst
+PARTTOOLFILES += parttool-halt_mod-kern_i386_halt.lst
+PARTMAPFILES += partmap-halt_mod-kern_i386_halt.lst
+HANDLERFILES += handler-halt_mod-kern_i386_halt.lst
+
+cmd-halt_mod-kern_i386_halt.lst: kern/i386/halt.c $(kern/i386/halt.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1)
+
+fs-halt_mod-kern_i386_halt.lst: kern/i386/halt.c $(kern/i386/halt.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1)
+
+parttool-halt_mod-kern_i386_halt.lst: kern/i386/halt.c $(kern/i386/halt.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh halt > $@ || (rm -f $@; exit 1)
+
+partmap-halt_mod-kern_i386_halt.lst: kern/i386/halt.c $(kern/i386/halt.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1)
+
+handler-halt_mod-kern_i386_halt.lst: kern/i386/halt.c $(kern/i386/halt.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh halt > $@ || (rm -f $@; exit 1)
+
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For serial.mod.
+serial_mod_SOURCES = term/i386/pc/serial.c
+
+clean-module-serial.mod.1:
+	rm -f serial.mod mod-serial.o mod-serial.c pre-serial.o serial_mod-term_i386_pc_serial.o und-serial.lst
+
+CLEAN_MODULE_TARGETS += clean-module-serial.mod.1
+
+ifneq ($(serial_mod_EXPORTS),no)
+clean-module-serial.mod-symbol.1:
+	rm -f def-serial.lst
+
+CLEAN_MODULE_TARGETS += clean-module-serial.mod-symbol.1
+DEFSYMFILES += def-serial.lst
+endif
+mostlyclean-module-serial.mod.1:
+	rm -f serial_mod-term_i386_pc_serial.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-serial.mod.1
+UNDSYMFILES += und-serial.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+serial.mod: pre-serial.o mod-serial.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-serial.o mod-serial.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+serial.mod: pre-serial.o mod-serial.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-serial.o mod-serial.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-serial.o: $(serial_mod_DEPENDENCIES) serial_mod-term_i386_pc_serial.o
+	-rm -f $@
+	$(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ serial_mod-term_i386_pc_serial.o
+
+mod-serial.o: mod-serial.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -c -o $@ $<
+
+mod-serial.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'serial' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(serial_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-serial.lst: pre-serial.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 serial/' > $@
+else
+def-serial.lst: pre-serial.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 serial/' > $@
+endif
+endif
+
+und-serial.lst: pre-serial.o
+	echo 'serial' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+serial_mod-term_i386_pc_serial.o: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -MD -c -o $@ $<
+-include serial_mod-term_i386_pc_serial.d
+
+clean-module-serial_mod-term_i386_pc_serial-extra.1:
+	rm -f cmd-serial_mod-term_i386_pc_serial.lst fs-serial_mod-term_i386_pc_serial.lst partmap-serial_mod-term_i386_pc_serial.lst handler-serial_mod-term_i386_pc_serial.lst parttool-serial_mod-term_i386_pc_serial.lst
+
+CLEAN_MODULE_TARGETS += clean-module-serial_mod-term_i386_pc_serial-extra.1
+
+COMMANDFILES += cmd-serial_mod-term_i386_pc_serial.lst
+FSFILES += fs-serial_mod-term_i386_pc_serial.lst
+PARTTOOLFILES += parttool-serial_mod-term_i386_pc_serial.lst
+PARTMAPFILES += partmap-serial_mod-term_i386_pc_serial.lst
+HANDLERFILES += handler-serial_mod-term_i386_pc_serial.lst
+
+cmd-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh serial > $@ || (rm -f $@; exit 1)
+
+fs-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh serial > $@ || (rm -f $@; exit 1)
+
+parttool-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh serial > $@ || (rm -f $@; exit 1)
+
+partmap-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh serial > $@ || (rm -f $@; exit 1)
+
+handler-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh serial > $@ || (rm -f $@; exit 1)
+
+serial_mod_CFLAGS = $(COMMON_CFLAGS)
+serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For multiboot.mod.
+multiboot_mod_SOURCES = loader/i386/multiboot.c \
+			loader/i386/multiboot_helper.S \
+                         loader/i386/pc/multiboot2.c \
+                         loader/multiboot2.c \
+                         loader/multiboot_loader.c
+
+clean-module-multiboot.mod.1:
+	rm -f multiboot.mod mod-multiboot.o mod-multiboot.c pre-multiboot.o multiboot_mod-loader_i386_multiboot.o multiboot_mod-loader_i386_multiboot_helper.o multiboot_mod-loader_i386_pc_multiboot2.o multiboot_mod-loader_multiboot2.o multiboot_mod-loader_multiboot_loader.o und-multiboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot.mod.1
+
+ifneq ($(multiboot_mod_EXPORTS),no)
+clean-module-multiboot.mod-symbol.1:
+	rm -f def-multiboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot.mod-symbol.1
+DEFSYMFILES += def-multiboot.lst
+endif
+mostlyclean-module-multiboot.mod.1:
+	rm -f multiboot_mod-loader_i386_multiboot.d multiboot_mod-loader_i386_multiboot_helper.d multiboot_mod-loader_i386_pc_multiboot2.d multiboot_mod-loader_multiboot2.d multiboot_mod-loader_multiboot_loader.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-multiboot.mod.1
+UNDSYMFILES += und-multiboot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+multiboot.mod: pre-multiboot.o mod-multiboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-multiboot.o mod-multiboot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+multiboot.mod: pre-multiboot.o mod-multiboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-multiboot.o mod-multiboot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-multiboot.o: $(multiboot_mod_DEPENDENCIES) multiboot_mod-loader_i386_multiboot.o multiboot_mod-loader_i386_multiboot_helper.o multiboot_mod-loader_i386_pc_multiboot2.o multiboot_mod-loader_multiboot2.o multiboot_mod-loader_multiboot_loader.o
+	-rm -f $@
+	$(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ multiboot_mod-loader_i386_multiboot.o multiboot_mod-loader_i386_multiboot_helper.o multiboot_mod-loader_i386_pc_multiboot2.o multiboot_mod-loader_multiboot2.o multiboot_mod-loader_multiboot_loader.o
+
+mod-multiboot.o: mod-multiboot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -c -o $@ $<
+
+mod-multiboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'multiboot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(multiboot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-multiboot.lst: pre-multiboot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@
+else
+def-multiboot.lst: pre-multiboot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@
+endif
+endif
+
+und-multiboot.lst: pre-multiboot.o
+	echo 'multiboot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+multiboot_mod-loader_i386_multiboot.o: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_i386_multiboot.d
+
+clean-module-multiboot_mod-loader_i386_multiboot-extra.1:
+	rm -f cmd-multiboot_mod-loader_i386_multiboot.lst fs-multiboot_mod-loader_i386_multiboot.lst partmap-multiboot_mod-loader_i386_multiboot.lst handler-multiboot_mod-loader_i386_multiboot.lst parttool-multiboot_mod-loader_i386_multiboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_i386_multiboot-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_i386_multiboot.lst
+FSFILES += fs-multiboot_mod-loader_i386_multiboot.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_i386_multiboot.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_i386_multiboot.lst
+HANDLERFILES += handler-multiboot_mod-loader_i386_multiboot.lst
+
+cmd-multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_i386_multiboot_helper.o: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_i386_multiboot_helper.d
+
+clean-module-multiboot_mod-loader_i386_multiboot_helper-extra.1:
+	rm -f cmd-multiboot_mod-loader_i386_multiboot_helper.lst fs-multiboot_mod-loader_i386_multiboot_helper.lst partmap-multiboot_mod-loader_i386_multiboot_helper.lst handler-multiboot_mod-loader_i386_multiboot_helper.lst parttool-multiboot_mod-loader_i386_multiboot_helper.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_i386_multiboot_helper-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_i386_multiboot_helper.lst
+FSFILES += fs-multiboot_mod-loader_i386_multiboot_helper.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_i386_multiboot_helper.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_i386_multiboot_helper.lst
+HANDLERFILES += handler-multiboot_mod-loader_i386_multiboot_helper.lst
+
+cmd-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_i386_pc_multiboot2.o: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_i386_pc_multiboot2.d
+
+clean-module-multiboot_mod-loader_i386_pc_multiboot2-extra.1:
+	rm -f cmd-multiboot_mod-loader_i386_pc_multiboot2.lst fs-multiboot_mod-loader_i386_pc_multiboot2.lst partmap-multiboot_mod-loader_i386_pc_multiboot2.lst handler-multiboot_mod-loader_i386_pc_multiboot2.lst parttool-multiboot_mod-loader_i386_pc_multiboot2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_i386_pc_multiboot2-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_i386_pc_multiboot2.lst
+FSFILES += fs-multiboot_mod-loader_i386_pc_multiboot2.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_i386_pc_multiboot2.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_i386_pc_multiboot2.lst
+HANDLERFILES += handler-multiboot_mod-loader_i386_pc_multiboot2.lst
+
+cmd-multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_multiboot2.o: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_multiboot2.d
+
+clean-module-multiboot_mod-loader_multiboot2-extra.1:
+	rm -f cmd-multiboot_mod-loader_multiboot2.lst fs-multiboot_mod-loader_multiboot2.lst partmap-multiboot_mod-loader_multiboot2.lst handler-multiboot_mod-loader_multiboot2.lst parttool-multiboot_mod-loader_multiboot2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_multiboot2-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_multiboot2.lst
+FSFILES += fs-multiboot_mod-loader_multiboot2.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_multiboot2.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_multiboot2.lst
+HANDLERFILES += handler-multiboot_mod-loader_multiboot2.lst
+
+cmd-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_multiboot_loader.o: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_multiboot_loader.d
+
+clean-module-multiboot_mod-loader_multiboot_loader-extra.1:
+	rm -f cmd-multiboot_mod-loader_multiboot_loader.lst fs-multiboot_mod-loader_multiboot_loader.lst partmap-multiboot_mod-loader_multiboot_loader.lst handler-multiboot_mod-loader_multiboot_loader.lst parttool-multiboot_mod-loader_multiboot_loader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_multiboot_loader-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_multiboot_loader.lst
+FSFILES += fs-multiboot_mod-loader_multiboot_loader.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_multiboot_loader.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_multiboot_loader.lst
+HANDLERFILES += handler-multiboot_mod-loader_multiboot_loader.lst
+
+cmd-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For aout.mod.
+aout_mod_SOURCES = loader/aout.c
+
+clean-module-aout.mod.1:
+	rm -f aout.mod mod-aout.o mod-aout.c pre-aout.o aout_mod-loader_aout.o und-aout.lst
+
+CLEAN_MODULE_TARGETS += clean-module-aout.mod.1
+
+ifneq ($(aout_mod_EXPORTS),no)
+clean-module-aout.mod-symbol.1:
+	rm -f def-aout.lst
+
+CLEAN_MODULE_TARGETS += clean-module-aout.mod-symbol.1
+DEFSYMFILES += def-aout.lst
+endif
+mostlyclean-module-aout.mod.1:
+	rm -f aout_mod-loader_aout.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-aout.mod.1
+UNDSYMFILES += und-aout.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+aout.mod: pre-aout.o mod-aout.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-aout.o mod-aout.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+aout.mod: pre-aout.o mod-aout.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-aout.o mod-aout.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-aout.o: $(aout_mod_DEPENDENCIES) aout_mod-loader_aout.o
+	-rm -f $@
+	$(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ aout_mod-loader_aout.o
+
+mod-aout.o: mod-aout.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -c -o $@ $<
+
+mod-aout.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'aout' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(aout_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-aout.lst: pre-aout.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 aout/' > $@
+else
+def-aout.lst: pre-aout.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 aout/' > $@
+endif
+endif
+
+und-aout.lst: pre-aout.o
+	echo 'aout' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+aout_mod-loader_aout.o: loader/aout.c $(loader/aout.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -MD -c -o $@ $<
+-include aout_mod-loader_aout.d
+
+clean-module-aout_mod-loader_aout-extra.1:
+	rm -f cmd-aout_mod-loader_aout.lst fs-aout_mod-loader_aout.lst partmap-aout_mod-loader_aout.lst handler-aout_mod-loader_aout.lst parttool-aout_mod-loader_aout.lst
+
+CLEAN_MODULE_TARGETS += clean-module-aout_mod-loader_aout-extra.1
+
+COMMANDFILES += cmd-aout_mod-loader_aout.lst
+FSFILES += fs-aout_mod-loader_aout.lst
+PARTTOOLFILES += parttool-aout_mod-loader_aout.lst
+PARTMAPFILES += partmap-aout_mod-loader_aout.lst
+HANDLERFILES += handler-aout_mod-loader_aout.lst
+
+cmd-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh aout > $@ || (rm -f $@; exit 1)
+
+fs-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh aout > $@ || (rm -f $@; exit 1)
+
+parttool-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh aout > $@ || (rm -f $@; exit 1)
+
+partmap-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh aout > $@ || (rm -f $@; exit 1)
+
+handler-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh aout > $@ || (rm -f $@; exit 1)
+
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bsd.mod
+pkglib_MODULES += bsd.mod
+bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
+
+clean-module-bsd.mod.1:
+	rm -f bsd.mod mod-bsd.o mod-bsd.c pre-bsd.o bsd_mod-loader_i386_bsd.o bsd_mod-loader_i386_bsd32.o bsd_mod-loader_i386_bsd64.o bsd_mod-loader_i386_bsd_helper.o bsd_mod-loader_i386_bsd_trampoline.o und-bsd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd.mod.1
+
+ifneq ($(bsd_mod_EXPORTS),no)
+clean-module-bsd.mod-symbol.1:
+	rm -f def-bsd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd.mod-symbol.1
+DEFSYMFILES += def-bsd.lst
+endif
+mostlyclean-module-bsd.mod.1:
+	rm -f bsd_mod-loader_i386_bsd.d bsd_mod-loader_i386_bsd32.d bsd_mod-loader_i386_bsd64.d bsd_mod-loader_i386_bsd_helper.d bsd_mod-loader_i386_bsd_trampoline.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-bsd.mod.1
+UNDSYMFILES += und-bsd.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+bsd.mod: pre-bsd.o mod-bsd.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(bsd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-bsd.o mod-bsd.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+bsd.mod: pre-bsd.o mod-bsd.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(bsd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-bsd.o mod-bsd.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-bsd.o: $(bsd_mod_DEPENDENCIES) bsd_mod-loader_i386_bsd.o bsd_mod-loader_i386_bsd32.o bsd_mod-loader_i386_bsd64.o bsd_mod-loader_i386_bsd_helper.o bsd_mod-loader_i386_bsd_trampoline.o
+	-rm -f $@
+	$(TARGET_CC) $(bsd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ bsd_mod-loader_i386_bsd.o bsd_mod-loader_i386_bsd32.o bsd_mod-loader_i386_bsd64.o bsd_mod-loader_i386_bsd_helper.o bsd_mod-loader_i386_bsd_trampoline.o
+
+mod-bsd.o: mod-bsd.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -c -o $@ $<
+
+mod-bsd.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'bsd' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(bsd_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-bsd.lst: pre-bsd.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 bsd/' > $@
+else
+def-bsd.lst: pre-bsd.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 bsd/' > $@
+endif
+endif
+
+und-bsd.lst: pre-bsd.o
+	echo 'bsd' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+bsd_mod-loader_i386_bsd.o: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -MD -c -o $@ $<
+-include bsd_mod-loader_i386_bsd.d
+
+clean-module-bsd_mod-loader_i386_bsd-extra.1:
+	rm -f cmd-bsd_mod-loader_i386_bsd.lst fs-bsd_mod-loader_i386_bsd.lst partmap-bsd_mod-loader_i386_bsd.lst handler-bsd_mod-loader_i386_bsd.lst parttool-bsd_mod-loader_i386_bsd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd_mod-loader_i386_bsd-extra.1
+
+COMMANDFILES += cmd-bsd_mod-loader_i386_bsd.lst
+FSFILES += fs-bsd_mod-loader_i386_bsd.lst
+PARTTOOLFILES += parttool-bsd_mod-loader_i386_bsd.lst
+PARTMAPFILES += partmap-bsd_mod-loader_i386_bsd.lst
+HANDLERFILES += handler-bsd_mod-loader_i386_bsd.lst
+
+cmd-bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+fs-bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh bsd > $@ || (rm -f $@; exit 1)
+
+parttool-bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh bsd > $@ || (rm -f $@; exit 1)
+
+partmap-bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh bsd > $@ || (rm -f $@; exit 1)
+
+handler-bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+bsd_mod-loader_i386_bsd32.o: loader/i386/bsd32.c $(loader/i386/bsd32.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -MD -c -o $@ $<
+-include bsd_mod-loader_i386_bsd32.d
+
+clean-module-bsd_mod-loader_i386_bsd32-extra.1:
+	rm -f cmd-bsd_mod-loader_i386_bsd32.lst fs-bsd_mod-loader_i386_bsd32.lst partmap-bsd_mod-loader_i386_bsd32.lst handler-bsd_mod-loader_i386_bsd32.lst parttool-bsd_mod-loader_i386_bsd32.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd_mod-loader_i386_bsd32-extra.1
+
+COMMANDFILES += cmd-bsd_mod-loader_i386_bsd32.lst
+FSFILES += fs-bsd_mod-loader_i386_bsd32.lst
+PARTTOOLFILES += parttool-bsd_mod-loader_i386_bsd32.lst
+PARTMAPFILES += partmap-bsd_mod-loader_i386_bsd32.lst
+HANDLERFILES += handler-bsd_mod-loader_i386_bsd32.lst
+
+cmd-bsd_mod-loader_i386_bsd32.lst: loader/i386/bsd32.c $(loader/i386/bsd32.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+fs-bsd_mod-loader_i386_bsd32.lst: loader/i386/bsd32.c $(loader/i386/bsd32.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh bsd > $@ || (rm -f $@; exit 1)
+
+parttool-bsd_mod-loader_i386_bsd32.lst: loader/i386/bsd32.c $(loader/i386/bsd32.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh bsd > $@ || (rm -f $@; exit 1)
+
+partmap-bsd_mod-loader_i386_bsd32.lst: loader/i386/bsd32.c $(loader/i386/bsd32.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh bsd > $@ || (rm -f $@; exit 1)
+
+handler-bsd_mod-loader_i386_bsd32.lst: loader/i386/bsd32.c $(loader/i386/bsd32.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+bsd_mod-loader_i386_bsd64.o: loader/i386/bsd64.c $(loader/i386/bsd64.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -MD -c -o $@ $<
+-include bsd_mod-loader_i386_bsd64.d
+
+clean-module-bsd_mod-loader_i386_bsd64-extra.1:
+	rm -f cmd-bsd_mod-loader_i386_bsd64.lst fs-bsd_mod-loader_i386_bsd64.lst partmap-bsd_mod-loader_i386_bsd64.lst handler-bsd_mod-loader_i386_bsd64.lst parttool-bsd_mod-loader_i386_bsd64.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd_mod-loader_i386_bsd64-extra.1
+
+COMMANDFILES += cmd-bsd_mod-loader_i386_bsd64.lst
+FSFILES += fs-bsd_mod-loader_i386_bsd64.lst
+PARTTOOLFILES += parttool-bsd_mod-loader_i386_bsd64.lst
+PARTMAPFILES += partmap-bsd_mod-loader_i386_bsd64.lst
+HANDLERFILES += handler-bsd_mod-loader_i386_bsd64.lst
+
+cmd-bsd_mod-loader_i386_bsd64.lst: loader/i386/bsd64.c $(loader/i386/bsd64.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+fs-bsd_mod-loader_i386_bsd64.lst: loader/i386/bsd64.c $(loader/i386/bsd64.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh bsd > $@ || (rm -f $@; exit 1)
+
+parttool-bsd_mod-loader_i386_bsd64.lst: loader/i386/bsd64.c $(loader/i386/bsd64.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh bsd > $@ || (rm -f $@; exit 1)
+
+partmap-bsd_mod-loader_i386_bsd64.lst: loader/i386/bsd64.c $(loader/i386/bsd64.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh bsd > $@ || (rm -f $@; exit 1)
+
+handler-bsd_mod-loader_i386_bsd64.lst: loader/i386/bsd64.c $(loader/i386/bsd64.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+bsd_mod-loader_i386_bsd_helper.o: loader/i386/bsd_helper.S $(loader/i386/bsd_helper.S_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -MD -c -o $@ $<
+-include bsd_mod-loader_i386_bsd_helper.d
+
+clean-module-bsd_mod-loader_i386_bsd_helper-extra.1:
+	rm -f cmd-bsd_mod-loader_i386_bsd_helper.lst fs-bsd_mod-loader_i386_bsd_helper.lst partmap-bsd_mod-loader_i386_bsd_helper.lst handler-bsd_mod-loader_i386_bsd_helper.lst parttool-bsd_mod-loader_i386_bsd_helper.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd_mod-loader_i386_bsd_helper-extra.1
+
+COMMANDFILES += cmd-bsd_mod-loader_i386_bsd_helper.lst
+FSFILES += fs-bsd_mod-loader_i386_bsd_helper.lst
+PARTTOOLFILES += parttool-bsd_mod-loader_i386_bsd_helper.lst
+PARTMAPFILES += partmap-bsd_mod-loader_i386_bsd_helper.lst
+HANDLERFILES += handler-bsd_mod-loader_i386_bsd_helper.lst
+
+cmd-bsd_mod-loader_i386_bsd_helper.lst: loader/i386/bsd_helper.S $(loader/i386/bsd_helper.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+fs-bsd_mod-loader_i386_bsd_helper.lst: loader/i386/bsd_helper.S $(loader/i386/bsd_helper.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh bsd > $@ || (rm -f $@; exit 1)
+
+parttool-bsd_mod-loader_i386_bsd_helper.lst: loader/i386/bsd_helper.S $(loader/i386/bsd_helper.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh bsd > $@ || (rm -f $@; exit 1)
+
+partmap-bsd_mod-loader_i386_bsd_helper.lst: loader/i386/bsd_helper.S $(loader/i386/bsd_helper.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh bsd > $@ || (rm -f $@; exit 1)
+
+handler-bsd_mod-loader_i386_bsd_helper.lst: loader/i386/bsd_helper.S $(loader/i386/bsd_helper.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+bsd_mod-loader_i386_bsd_trampoline.o: loader/i386/bsd_trampoline.S $(loader/i386/bsd_trampoline.S_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -MD -c -o $@ $<
+-include bsd_mod-loader_i386_bsd_trampoline.d
+
+clean-module-bsd_mod-loader_i386_bsd_trampoline-extra.1:
+	rm -f cmd-bsd_mod-loader_i386_bsd_trampoline.lst fs-bsd_mod-loader_i386_bsd_trampoline.lst partmap-bsd_mod-loader_i386_bsd_trampoline.lst handler-bsd_mod-loader_i386_bsd_trampoline.lst parttool-bsd_mod-loader_i386_bsd_trampoline.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd_mod-loader_i386_bsd_trampoline-extra.1
+
+COMMANDFILES += cmd-bsd_mod-loader_i386_bsd_trampoline.lst
+FSFILES += fs-bsd_mod-loader_i386_bsd_trampoline.lst
+PARTTOOLFILES += parttool-bsd_mod-loader_i386_bsd_trampoline.lst
+PARTMAPFILES += partmap-bsd_mod-loader_i386_bsd_trampoline.lst
+HANDLERFILES += handler-bsd_mod-loader_i386_bsd_trampoline.lst
+
+cmd-bsd_mod-loader_i386_bsd_trampoline.lst: loader/i386/bsd_trampoline.S $(loader/i386/bsd_trampoline.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+fs-bsd_mod-loader_i386_bsd_trampoline.lst: loader/i386/bsd_trampoline.S $(loader/i386/bsd_trampoline.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh bsd > $@ || (rm -f $@; exit 1)
+
+parttool-bsd_mod-loader_i386_bsd_trampoline.lst: loader/i386/bsd_trampoline.S $(loader/i386/bsd_trampoline.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh bsd > $@ || (rm -f $@; exit 1)
+
+partmap-bsd_mod-loader_i386_bsd_trampoline.lst: loader/i386/bsd_trampoline.S $(loader/i386/bsd_trampoline.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh bsd > $@ || (rm -f $@; exit 1)
+
+handler-bsd_mod-loader_i386_bsd_trampoline.lst: loader/i386/bsd_trampoline.S $(loader/i386/bsd_trampoline.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+bsd_mod_CFLAGS = $(COMMON_CFLAGS)
+bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For play.mod.
+play_mod_SOURCES = commands/i386/pc/play.c
+
+clean-module-play.mod.1:
+	rm -f play.mod mod-play.o mod-play.c pre-play.o play_mod-commands_i386_pc_play.o und-play.lst
+
+CLEAN_MODULE_TARGETS += clean-module-play.mod.1
+
+ifneq ($(play_mod_EXPORTS),no)
+clean-module-play.mod-symbol.1:
+	rm -f def-play.lst
+
+CLEAN_MODULE_TARGETS += clean-module-play.mod-symbol.1
+DEFSYMFILES += def-play.lst
+endif
+mostlyclean-module-play.mod.1:
+	rm -f play_mod-commands_i386_pc_play.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-play.mod.1
+UNDSYMFILES += und-play.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+play.mod: pre-play.o mod-play.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(play_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-play.o mod-play.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+play.mod: pre-play.o mod-play.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(play_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-play.o mod-play.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-play.o: $(play_mod_DEPENDENCIES) play_mod-commands_i386_pc_play.o
+	-rm -f $@
+	$(TARGET_CC) $(play_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ play_mod-commands_i386_pc_play.o
+
+mod-play.o: mod-play.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(play_mod_CFLAGS) -c -o $@ $<
+
+mod-play.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'play' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(play_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-play.lst: pre-play.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 play/' > $@
+else
+def-play.lst: pre-play.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 play/' > $@
+endif
+endif
+
+und-play.lst: pre-play.o
+	echo 'play' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+play_mod-commands_i386_pc_play.o: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(play_mod_CFLAGS) -MD -c -o $@ $<
+-include play_mod-commands_i386_pc_play.d
+
+clean-module-play_mod-commands_i386_pc_play-extra.1:
+	rm -f cmd-play_mod-commands_i386_pc_play.lst fs-play_mod-commands_i386_pc_play.lst partmap-play_mod-commands_i386_pc_play.lst handler-play_mod-commands_i386_pc_play.lst parttool-play_mod-commands_i386_pc_play.lst
+
+CLEAN_MODULE_TARGETS += clean-module-play_mod-commands_i386_pc_play-extra.1
+
+COMMANDFILES += cmd-play_mod-commands_i386_pc_play.lst
+FSFILES += fs-play_mod-commands_i386_pc_play.lst
+PARTTOOLFILES += parttool-play_mod-commands_i386_pc_play.lst
+PARTMAPFILES += partmap-play_mod-commands_i386_pc_play.lst
+HANDLERFILES += handler-play_mod-commands_i386_pc_play.lst
+
+cmd-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh play > $@ || (rm -f $@; exit 1)
+
+fs-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh play > $@ || (rm -f $@; exit 1)
+
+parttool-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh play > $@ || (rm -f $@; exit 1)
+
+partmap-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh play > $@ || (rm -f $@; exit 1)
+
+handler-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh play > $@ || (rm -f $@; exit 1)
+
+play_mod_CFLAGS = $(COMMON_CFLAGS)
+play_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ata.mod.
+ata_mod_SOURCES = disk/ata.c
+
+clean-module-ata.mod.1:
+	rm -f ata.mod mod-ata.o mod-ata.c pre-ata.o ata_mod-disk_ata.o und-ata.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ata.mod.1
+
+ifneq ($(ata_mod_EXPORTS),no)
+clean-module-ata.mod-symbol.1:
+	rm -f def-ata.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ata.mod-symbol.1
+DEFSYMFILES += def-ata.lst
+endif
+mostlyclean-module-ata.mod.1:
+	rm -f ata_mod-disk_ata.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-ata.mod.1
+UNDSYMFILES += und-ata.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+ata.mod: pre-ata.o mod-ata.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(ata_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-ata.o mod-ata.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+ata.mod: pre-ata.o mod-ata.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(ata_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-ata.o mod-ata.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-ata.o: $(ata_mod_DEPENDENCIES) ata_mod-disk_ata.o
+	-rm -f $@
+	$(TARGET_CC) $(ata_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ata_mod-disk_ata.o
+
+mod-ata.o: mod-ata.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -c -o $@ $<
+
+mod-ata.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'ata' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(ata_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-ata.lst: pre-ata.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ata/' > $@
+else
+def-ata.lst: pre-ata.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 ata/' > $@
+endif
+endif
+
+und-ata.lst: pre-ata.o
+	echo 'ata' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+ata_mod-disk_ata.o: disk/ata.c $(disk/ata.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -MD -c -o $@ $<
+-include ata_mod-disk_ata.d
+
+clean-module-ata_mod-disk_ata-extra.1:
+	rm -f cmd-ata_mod-disk_ata.lst fs-ata_mod-disk_ata.lst partmap-ata_mod-disk_ata.lst handler-ata_mod-disk_ata.lst parttool-ata_mod-disk_ata.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ata_mod-disk_ata-extra.1
+
+COMMANDFILES += cmd-ata_mod-disk_ata.lst
+FSFILES += fs-ata_mod-disk_ata.lst
+PARTTOOLFILES += parttool-ata_mod-disk_ata.lst
+PARTMAPFILES += partmap-ata_mod-disk_ata.lst
+HANDLERFILES += handler-ata_mod-disk_ata.lst
+
+cmd-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh ata > $@ || (rm -f $@; exit 1)
+
+fs-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh ata > $@ || (rm -f $@; exit 1)
+
+parttool-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh ata > $@ || (rm -f $@; exit 1)
+
+partmap-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh ata > $@ || (rm -f $@; exit 1)
+
+handler-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh ata > $@ || (rm -f $@; exit 1)
+
+ata_mod_CFLAGS = $(COMMON_CFLAGS)
+ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memdisk.mod.
+memdisk_mod_SOURCES = disk/memdisk.c
+
+clean-module-memdisk.mod.1:
+	rm -f memdisk.mod mod-memdisk.o mod-memdisk.c pre-memdisk.o memdisk_mod-disk_memdisk.o und-memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk.mod.1
+
+ifneq ($(memdisk_mod_EXPORTS),no)
+clean-module-memdisk.mod-symbol.1:
+	rm -f def-memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk.mod-symbol.1
+DEFSYMFILES += def-memdisk.lst
+endif
+mostlyclean-module-memdisk.mod.1:
+	rm -f memdisk_mod-disk_memdisk.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-memdisk.mod.1
+UNDSYMFILES += und-memdisk.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-memdisk.o mod-memdisk.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-memdisk.o mod-memdisk.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-memdisk.o: $(memdisk_mod_DEPENDENCIES) memdisk_mod-disk_memdisk.o
+	-rm -f $@
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memdisk_mod-disk_memdisk.o
+
+mod-memdisk.o: mod-memdisk.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -c -o $@ $<
+
+mod-memdisk.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'memdisk' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(memdisk_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-memdisk.lst: pre-memdisk.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@
+else
+def-memdisk.lst: pre-memdisk.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@
+endif
+endif
+
+und-memdisk.lst: pre-memdisk.o
+	echo 'memdisk' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+memdisk_mod-disk_memdisk.o: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -MD -c -o $@ $<
+-include memdisk_mod-disk_memdisk.d
+
+clean-module-memdisk_mod-disk_memdisk-extra.1:
+	rm -f cmd-memdisk_mod-disk_memdisk.lst fs-memdisk_mod-disk_memdisk.lst partmap-memdisk_mod-disk_memdisk.lst handler-memdisk_mod-disk_memdisk.lst parttool-memdisk_mod-disk_memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk_mod-disk_memdisk-extra.1
+
+COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst
+FSFILES += fs-memdisk_mod-disk_memdisk.lst
+PARTTOOLFILES += parttool-memdisk_mod-disk_memdisk.lst
+PARTMAPFILES += partmap-memdisk_mod-disk_memdisk.lst
+HANDLERFILES += handler-memdisk_mod-disk_memdisk.lst
+
+cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+fs-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+parttool-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+partmap-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+handler-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pci.mod
+pci_mod_SOURCES = bus/pci.c
+
+clean-module-pci.mod.1:
+	rm -f pci.mod mod-pci.o mod-pci.c pre-pci.o pci_mod-bus_pci.o und-pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci.mod.1
+
+ifneq ($(pci_mod_EXPORTS),no)
+clean-module-pci.mod-symbol.1:
+	rm -f def-pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci.mod-symbol.1
+DEFSYMFILES += def-pci.lst
+endif
+mostlyclean-module-pci.mod.1:
+	rm -f pci_mod-bus_pci.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-pci.mod.1
+UNDSYMFILES += und-pci.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-pci.o mod-pci.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-pci.o mod-pci.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-pci.o: $(pci_mod_DEPENDENCIES) pci_mod-bus_pci.o
+	-rm -f $@
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pci_mod-bus_pci.o
+
+mod-pci.o: mod-pci.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -c -o $@ $<
+
+mod-pci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'pci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(pci_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-pci.lst: pre-pci.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pci/' > $@
+else
+def-pci.lst: pre-pci.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 pci/' > $@
+endif
+endif
+
+und-pci.lst: pre-pci.o
+	echo 'pci' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+pci_mod-bus_pci.o: bus/pci.c $(bus/pci.c_DEPENDENCIES)
+	$(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -MD -c -o $@ $<
+-include pci_mod-bus_pci.d
+
+clean-module-pci_mod-bus_pci-extra.1:
+	rm -f cmd-pci_mod-bus_pci.lst fs-pci_mod-bus_pci.lst partmap-pci_mod-bus_pci.lst handler-pci_mod-bus_pci.lst parttool-pci_mod-bus_pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci_mod-bus_pci-extra.1
+
+COMMANDFILES += cmd-pci_mod-bus_pci.lst
+FSFILES += fs-pci_mod-bus_pci.lst
+PARTTOOLFILES += parttool-pci_mod-bus_pci.lst
+PARTMAPFILES += partmap-pci_mod-bus_pci.lst
+HANDLERFILES += handler-pci_mod-bus_pci.lst
+
+cmd-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh pci > $@ || (rm -f $@; exit 1)
+
+fs-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh pci > $@ || (rm -f $@; exit 1)
+
+parttool-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh pci > $@ || (rm -f $@; exit 1)
+
+partmap-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh pci > $@ || (rm -f $@; exit 1)
+
+handler-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh pci > $@ || (rm -f $@; exit 1)
+
+pci_mod_CFLAGS = $(COMMON_CFLAGS)
+pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lspci.mod
+lspci_mod_SOURCES = commands/lspci.c
+
+clean-module-lspci.mod.1:
+	rm -f lspci.mod mod-lspci.o mod-lspci.c pre-lspci.o lspci_mod-commands_lspci.o und-lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci.mod.1
+
+ifneq ($(lspci_mod_EXPORTS),no)
+clean-module-lspci.mod-symbol.1:
+	rm -f def-lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci.mod-symbol.1
+DEFSYMFILES += def-lspci.lst
+endif
+mostlyclean-module-lspci.mod.1:
+	rm -f lspci_mod-commands_lspci.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-lspci.mod.1
+UNDSYMFILES += und-lspci.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-lspci.o mod-lspci.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-lspci.o mod-lspci.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-lspci.o: $(lspci_mod_DEPENDENCIES) lspci_mod-commands_lspci.o
+	-rm -f $@
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lspci_mod-commands_lspci.o
+
+mod-lspci.o: mod-lspci.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -c -o $@ $<
+
+mod-lspci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'lspci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(lspci_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-lspci.lst: pre-lspci.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lspci/' > $@
+else
+def-lspci.lst: pre-lspci.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 lspci/' > $@
+endif
+endif
+
+und-lspci.lst: pre-lspci.o
+	echo 'lspci' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+lspci_mod-commands_lspci.o: commands/lspci.c $(commands/lspci.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -MD -c -o $@ $<
+-include lspci_mod-commands_lspci.d
+
+clean-module-lspci_mod-commands_lspci-extra.1:
+	rm -f cmd-lspci_mod-commands_lspci.lst fs-lspci_mod-commands_lspci.lst partmap-lspci_mod-commands_lspci.lst handler-lspci_mod-commands_lspci.lst parttool-lspci_mod-commands_lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci_mod-commands_lspci-extra.1
+
+COMMANDFILES += cmd-lspci_mod-commands_lspci.lst
+FSFILES += fs-lspci_mod-commands_lspci.lst
+PARTTOOLFILES += parttool-lspci_mod-commands_lspci.lst
+PARTMAPFILES += partmap-lspci_mod-commands_lspci.lst
+HANDLERFILES += handler-lspci_mod-commands_lspci.lst
+
+cmd-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh lspci > $@ || (rm -f $@; exit 1)
+
+fs-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh lspci > $@ || (rm -f $@; exit 1)
+
+parttool-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh lspci > $@ || (rm -f $@; exit 1)
+
+partmap-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh lspci > $@ || (rm -f $@; exit 1)
+
+handler-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh lspci > $@ || (rm -f $@; exit 1)
+
+lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/i386/datetime.c
+
+clean-module-datetime.mod.1:
+	rm -f datetime.mod mod-datetime.o mod-datetime.c pre-datetime.o datetime_mod-lib_i386_datetime.o und-datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime.mod.1
+
+ifneq ($(datetime_mod_EXPORTS),no)
+clean-module-datetime.mod-symbol.1:
+	rm -f def-datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime.mod-symbol.1
+DEFSYMFILES += def-datetime.lst
+endif
+mostlyclean-module-datetime.mod.1:
+	rm -f datetime_mod-lib_i386_datetime.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-datetime.mod.1
+UNDSYMFILES += und-datetime.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-datetime.o mod-datetime.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-datetime.o mod-datetime.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-datetime.o: $(datetime_mod_DEPENDENCIES) datetime_mod-lib_i386_datetime.o
+	-rm -f $@
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datetime_mod-lib_i386_datetime.o
+
+mod-datetime.o: mod-datetime.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -c -o $@ $<
+
+mod-datetime.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'datetime' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(datetime_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-datetime.lst: pre-datetime.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datetime/' > $@
+else
+def-datetime.lst: pre-datetime.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 datetime/' > $@
+endif
+endif
+
+und-datetime.lst: pre-datetime.o
+	echo 'datetime' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+datetime_mod-lib_i386_datetime.o: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $<
+-include datetime_mod-lib_i386_datetime.d
+
+clean-module-datetime_mod-lib_i386_datetime-extra.1:
+	rm -f cmd-datetime_mod-lib_i386_datetime.lst fs-datetime_mod-lib_i386_datetime.lst partmap-datetime_mod-lib_i386_datetime.lst handler-datetime_mod-lib_i386_datetime.lst parttool-datetime_mod-lib_i386_datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime_mod-lib_i386_datetime-extra.1
+
+COMMANDFILES += cmd-datetime_mod-lib_i386_datetime.lst
+FSFILES += fs-datetime_mod-lib_i386_datetime.lst
+PARTTOOLFILES += parttool-datetime_mod-lib_i386_datetime.lst
+PARTMAPFILES += partmap-datetime_mod-lib_i386_datetime.lst
+HANDLERFILES += handler-datetime_mod-lib_i386_datetime.lst
+
+cmd-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1)
+
+fs-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1)
+
+parttool-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh datetime > $@ || (rm -f $@; exit 1)
+
+partmap-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1)
+
+handler-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh datetime > $@ || (rm -f $@; exit 1)
+
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For date.mod
+date_mod_SOURCES = commands/date.c
+
+clean-module-date.mod.1:
+	rm -f date.mod mod-date.o mod-date.c pre-date.o date_mod-commands_date.o und-date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date.mod.1
+
+ifneq ($(date_mod_EXPORTS),no)
+clean-module-date.mod-symbol.1:
+	rm -f def-date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date.mod-symbol.1
+DEFSYMFILES += def-date.lst
+endif
+mostlyclean-module-date.mod.1:
+	rm -f date_mod-commands_date.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-date.mod.1
+UNDSYMFILES += und-date.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-date.o mod-date.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-date.o mod-date.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-date.o: $(date_mod_DEPENDENCIES) date_mod-commands_date.o
+	-rm -f $@
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ date_mod-commands_date.o
+
+mod-date.o: mod-date.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -c -o $@ $<
+
+mod-date.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'date' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(date_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-date.lst: pre-date.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 date/' > $@
+else
+def-date.lst: pre-date.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 date/' > $@
+endif
+endif
+
+und-date.lst: pre-date.o
+	echo 'date' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+date_mod-commands_date.o: commands/date.c $(commands/date.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -MD -c -o $@ $<
+-include date_mod-commands_date.d
+
+clean-module-date_mod-commands_date-extra.1:
+	rm -f cmd-date_mod-commands_date.lst fs-date_mod-commands_date.lst partmap-date_mod-commands_date.lst handler-date_mod-commands_date.lst parttool-date_mod-commands_date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date_mod-commands_date-extra.1
+
+COMMANDFILES += cmd-date_mod-commands_date.lst
+FSFILES += fs-date_mod-commands_date.lst
+PARTTOOLFILES += parttool-date_mod-commands_date.lst
+PARTMAPFILES += partmap-date_mod-commands_date.lst
+HANDLERFILES += handler-date_mod-commands_date.lst
+
+cmd-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh date > $@ || (rm -f $@; exit 1)
+
+fs-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh date > $@ || (rm -f $@; exit 1)
+
+parttool-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh date > $@ || (rm -f $@; exit 1)
+
+partmap-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh date > $@ || (rm -f $@; exit 1)
+
+handler-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh date > $@ || (rm -f $@; exit 1)
+
+date_mod_CFLAGS = $(COMMON_CFLAGS)
+date_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datehook.mod
+datehook_mod_SOURCES = hook/datehook.c
+
+clean-module-datehook.mod.1:
+	rm -f datehook.mod mod-datehook.o mod-datehook.c pre-datehook.o datehook_mod-hook_datehook.o und-datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook.mod.1
+
+ifneq ($(datehook_mod_EXPORTS),no)
+clean-module-datehook.mod-symbol.1:
+	rm -f def-datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook.mod-symbol.1
+DEFSYMFILES += def-datehook.lst
+endif
+mostlyclean-module-datehook.mod.1:
+	rm -f datehook_mod-hook_datehook.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-datehook.mod.1
+UNDSYMFILES += und-datehook.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-datehook.o mod-datehook.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-datehook.o mod-datehook.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-datehook.o: $(datehook_mod_DEPENDENCIES) datehook_mod-hook_datehook.o
+	-rm -f $@
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datehook_mod-hook_datehook.o
+
+mod-datehook.o: mod-datehook.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -c -o $@ $<
+
+mod-datehook.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'datehook' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(datehook_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-datehook.lst: pre-datehook.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datehook/' > $@
+else
+def-datehook.lst: pre-datehook.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 datehook/' > $@
+endif
+endif
+
+und-datehook.lst: pre-datehook.o
+	echo 'datehook' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+datehook_mod-hook_datehook.o: hook/datehook.c $(hook/datehook.c_DEPENDENCIES)
+	$(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -MD -c -o $@ $<
+-include datehook_mod-hook_datehook.d
+
+clean-module-datehook_mod-hook_datehook-extra.1:
+	rm -f cmd-datehook_mod-hook_datehook.lst fs-datehook_mod-hook_datehook.lst partmap-datehook_mod-hook_datehook.lst handler-datehook_mod-hook_datehook.lst parttool-datehook_mod-hook_datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook_mod-hook_datehook-extra.1
+
+COMMANDFILES += cmd-datehook_mod-hook_datehook.lst
+FSFILES += fs-datehook_mod-hook_datehook.lst
+PARTTOOLFILES += parttool-datehook_mod-hook_datehook.lst
+PARTMAPFILES += partmap-datehook_mod-hook_datehook.lst
+HANDLERFILES += handler-datehook_mod-hook_datehook.lst
+
+cmd-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh datehook > $@ || (rm -f $@; exit 1)
+
+fs-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh datehook > $@ || (rm -f $@; exit 1)
+
+parttool-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh datehook > $@ || (rm -f $@; exit 1)
+
+partmap-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh datehook > $@ || (rm -f $@; exit 1)
+
+handler-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh datehook > $@ || (rm -f $@; exit 1)
+
+datehook_mod_CFLAGS = $(COMMON_CFLAGS)
+datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+
+clean-module-lsmmap.mod.1:
+	rm -f lsmmap.mod mod-lsmmap.o mod-lsmmap.c pre-lsmmap.o lsmmap_mod-commands_lsmmap.o und-lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap.mod.1
+
+ifneq ($(lsmmap_mod_EXPORTS),no)
+clean-module-lsmmap.mod-symbol.1:
+	rm -f def-lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap.mod-symbol.1
+DEFSYMFILES += def-lsmmap.lst
+endif
+mostlyclean-module-lsmmap.mod.1:
+	rm -f lsmmap_mod-commands_lsmmap.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-lsmmap.mod.1
+UNDSYMFILES += und-lsmmap.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-lsmmap.o mod-lsmmap.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-lsmmap.o mod-lsmmap.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-lsmmap.o: $(lsmmap_mod_DEPENDENCIES) lsmmap_mod-commands_lsmmap.o
+	-rm -f $@
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lsmmap_mod-commands_lsmmap.o
+
+mod-lsmmap.o: mod-lsmmap.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -c -o $@ $<
+
+mod-lsmmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'lsmmap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(lsmmap_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-lsmmap.lst: pre-lsmmap.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@
+else
+def-lsmmap.lst: pre-lsmmap.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@
+endif
+endif
+
+und-lsmmap.lst: pre-lsmmap.o
+	echo 'lsmmap' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+lsmmap_mod-commands_lsmmap.o: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -MD -c -o $@ $<
+-include lsmmap_mod-commands_lsmmap.d
+
+clean-module-lsmmap_mod-commands_lsmmap-extra.1:
+	rm -f cmd-lsmmap_mod-commands_lsmmap.lst fs-lsmmap_mod-commands_lsmmap.lst partmap-lsmmap_mod-commands_lsmmap.lst handler-lsmmap_mod-commands_lsmmap.lst parttool-lsmmap_mod-commands_lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap_mod-commands_lsmmap-extra.1
+
+COMMANDFILES += cmd-lsmmap_mod-commands_lsmmap.lst
+FSFILES += fs-lsmmap_mod-commands_lsmmap.lst
+PARTTOOLFILES += parttool-lsmmap_mod-commands_lsmmap.lst
+PARTMAPFILES += partmap-lsmmap_mod-commands_lsmmap.lst
+HANDLERFILES += handler-lsmmap_mod-commands_lsmmap.lst
+
+cmd-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+fs-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+parttool-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+partmap-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+handler-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
+grub-mkimage: $(grub_mkimage_DEPENDENCIES) $(grub_mkimage_OBJECTS)
+	$(CC) -o $@ $(grub_mkimage_OBJECTS) $(LDFLAGS) $(grub_mkimage_LDFLAGS)
+
+grub-mkdevicemap: $(grub_mkdevicemap_DEPENDENCIES) $(grub_mkdevicemap_OBJECTS)
+	$(CC) -o $@ $(grub_mkdevicemap_OBJECTS) $(LDFLAGS) $(grub_mkdevicemap_LDFLAGS)
+
+grub-emu: $(grub_emu_DEPENDENCIES) $(grub_emu_OBJECTS)
+	$(CC) -o $@ $(grub_emu_OBJECTS) $(LDFLAGS) $(grub_emu_LDFLAGS)
+
diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk
new file mode 100644
index 0000000..09ec778
--- /dev/null
+++ b/conf/i386-coreboot.rmk
@@ -0,0 +1,262 @@
+# -*- makefile -*-
+
+COMMON_ASFLAGS	= -nostdinc -fno-builtin -m32
+COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32
+COMMON_LDFLAGS	= -m32 -nostdlib
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Images.
+
+GRUB_KERNEL_MACHINE_LINK_ADDR	= 0x8200
+
+ifeq ($(platform), coreboot)
+
+pkglib_PROGRAMS += kernel.img
+kernel_img_SOURCES = kern/i386/coreboot/startup.S \
+	kern/i386/misc.S \
+	kern/i386/coreboot/init.c \
+	kern/i386/multiboot_mmap.c \
+	kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+	kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
+	kern/i386/tsc.c kern/i386/pit.c \
+	kern/generic/rtc_get_time_ms.c \
+	kern/generic/millisleep.c \
+	kern/env.c \
+	term/i386/pc/vga_text.c term/i386/vga_common.c \
+	symlist.c
+kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	machine/boot.h machine/console.h machine/init.h \
+	machine/memory.h machine/loader.h list.h handler.h command.h
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic
+
+endif
+
+ifeq ($(platform), qemu)
+
+GRUB_BOOT_MACHINE_LINK_ADDR	= 0xffe00
+
+pkglib_IMAGES += boot.img
+boot_img_SOURCES = boot/i386/qemu/boot.S
+boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)
+boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR)
+boot_img_FORMAT = binary
+
+bin_UTILITIES += grub-mkimage
+grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \
+	util/resolve.c
+grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
+
+pkglib_IMAGES += kernel.img
+kernel_img_SOURCES = kern/i386/qemu/startup.S \
+	kern/i386/misc.S \
+	kern/i386/coreboot/init.c \
+	kern/i386/qemu/mmap.c \
+	kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+	kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
+	kern/i386/tsc.c kern/i386/pit.c \
+	kern/generic/rtc_get_time_ms.c \
+	kern/generic/millisleep.c \
+	kern/env.c \
+	term/i386/pc/vga_text.c term/i386/vga_common.c \
+	symlist.c
+kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	machine/boot.h machine/console.h machine/init.h \
+	machine/memory.h machine/loader.h list.h handler.h command.h
+kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR)
+kernel_img_FORMAT = binary
+endif
+
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# Utilities.
+sbin_UTILITIES = grub-mkdevicemap
+ifeq ($(enable_grub_emu), yes)
+sbin_UTILITIES += grub-emu
+endif
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/devicemap.c util/misc.c
+
+# For grub-emu.
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c	\
+	commands/configfile.c commands/echo.c commands/help.c		\
+	commands/handler.c commands/ls.c commands/test.c 		\
+	commands/search.c commands/blocklist.c commands/hexdump.c	\
+	commands/gptsync.c commands/probe.c commands/xnu_uuid.c		\
+	commands/password.c commands/keystatus.c			\
+	lib/hexdump.c commands/i386/cpuid.c				\
+	lib/envblk.c commands/loadenv.c					\
+	disk/host.c disk/loopback.c					\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c  fs/hfs.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c		\
+	fs/befs.c fs/befs_be.c fs/tar.c				\
+	\
+	fs/fshelp.c							\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/list.c kern/handler.c				\
+	kern/command.c kern/corecmd.c commands/extcmd.c kern/file.c	\
+	kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c	\
+	kern/partition.c kern/reader.c kern/term.c			\
+	kern/rescue_reader.c kern/rescue_parser.c                       \
+	lib/arg.c normal/cmdline.c normal/misc.c			\
+	normal/handler.c normal/auth.c normal/autofs.c			\
+	normal/completion.c normal/datetime.c normal/main.c 		\
+	normal/menu_text.c						\
+	normal/menu.c normal/menu_entry.c normal/menu_viewer.c		\
+	normal/color.c							\
+	script/sh/main.c script/sh/execute.c script/sh/function.c       \
+	script/sh/lexer.c script/sh/script.c grub_script.tab.c          \
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c partmap/gpt.c					\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	commands/parttool.c parttool/msdospart.c				\
+	grub_emu_init.c
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+sbin_SCRIPTS += grub-install
+grub_install_SOURCES = util/i386/pc/grub-install.in
+
+# Modules.
+pkglib_MODULES = linux.mod multiboot.mod 		\
+	aout.mod play.mod serial.mod ata.mod		\
+	memdisk.mod pci.mod lspci.mod reboot.mod	\
+	halt.mod datetime.mod date.mod datehook.mod	\
+	lsmmap.mod mmap.mod
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/i386/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod.
+reboot_mod_SOURCES = commands/reboot.c kern/i386/reboot.c
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/halt.c kern/i386/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For serial.mod.
+serial_mod_SOURCES = term/i386/pc/serial.c
+serial_mod_CFLAGS = $(COMMON_CFLAGS)
+serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For multiboot.mod.
+multiboot_mod_SOURCES = loader/i386/multiboot.c \
+			loader/i386/multiboot_helper.S \
+                         loader/i386/pc/multiboot2.c \
+                         loader/multiboot2.c \
+                         loader/multiboot_loader.c
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For aout.mod.
+aout_mod_SOURCES = loader/aout.c
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bsd.mod
+pkglib_MODULES += bsd.mod
+bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
+bsd_mod_CFLAGS = $(COMMON_CFLAGS)
+bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For play.mod.
+play_mod_SOURCES = commands/i386/pc/play.c
+play_mod_CFLAGS = $(COMMON_CFLAGS)
+play_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ata.mod.
+ata_mod_SOURCES = disk/ata.c
+ata_mod_CFLAGS = $(COMMON_CFLAGS)
+ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memdisk.mod.
+memdisk_mod_SOURCES = disk/memdisk.c
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pci.mod
+pci_mod_SOURCES = bus/pci.c
+pci_mod_CFLAGS = $(COMMON_CFLAGS)
+pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lspci.mod
+lspci_mod_SOURCES = commands/lspci.c
+lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/i386/datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For date.mod
+date_mod_SOURCES = commands/date.c
+date_mod_CFLAGS = $(COMMON_CFLAGS)
+date_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datehook.mod
+datehook_mod_SOURCES = hook/datehook.c
+datehook_mod_CFLAGS = $(COMMON_CFLAGS)
+datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
diff --git a/conf/i386-efi.mk b/conf/i386-efi.mk
new file mode 100644
index 0000000..e8ec4cd
--- /dev/null
+++ b/conf/i386-efi.mk
@@ -0,0 +1,3030 @@
+# -*- makefile -*-
+# Generated by genmk.rb, please don't edit!
+
+COMMON_ASFLAGS = -nostdinc -fno-builtin -m32
+COMMON_CFLAGS = -fno-builtin -m32
+COMMON_LDFLAGS = -melf_i386 -nostdlib
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Utilities.
+bin_UTILITIES = grub-mkimage
+sbin_UTILITIES = grub-mkdevicemap
+#ifeq ($(enable_grub_emu), yes)
+#sbin_UTILITIES += grub-emu
+#endif
+
+# For grub-mkimage.
+grub_mkimage_SOURCES = util/i386/efi/grub-mkimage.c util/misc.c \
+	util/resolve.c
+
+clean-utility-grub-mkimage.1:
+	rm -f grub-mkimage$(EXEEXT) grub_mkimage-util_i386_efi_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkimage.1
+
+mostlyclean-utility-grub-mkimage.1:
+	rm -f grub_mkimage-util_i386_efi_grub_mkimage.d grub_mkimage-util_misc.d grub_mkimage-util_resolve.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkimage.1
+
+grub_mkimage_OBJECTS += grub_mkimage-util_i386_efi_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o
+
+grub_mkimage-util_i386_efi_grub_mkimage.o: util/i386/efi/grub-mkimage.c $(util/i386/efi/grub-mkimage.c_DEPENDENCIES)
+	$(CC) -Iutil/i386/efi -I$(srcdir)/util/i386/efi $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_i386_efi_grub_mkimage.d
+
+grub_mkimage-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_misc.d
+
+grub_mkimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_resolve.d
+
+util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile
+
+# For grub-setup.
+#grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c	\
+#	util/misc.c util/getroot.c kern/device.c kern/disk.c	\
+#	kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c	\
+#	fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c		\
+#	fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c	\
+#	kern/fs.c kern/env.c fs/fshelp.c
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/devicemap.c util/misc.c
+
+clean-utility-grub-mkdevicemap.1:
+	rm -f grub-mkdevicemap$(EXEEXT) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_devicemap.o grub_mkdevicemap-util_misc.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkdevicemap.1
+
+mostlyclean-utility-grub-mkdevicemap.1:
+	rm -f grub_mkdevicemap-util_grub_mkdevicemap.d grub_mkdevicemap-util_deviceiter.d grub_mkdevicemap-util_devicemap.d grub_mkdevicemap-util_misc.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkdevicemap.1
+
+grub_mkdevicemap_OBJECTS += grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_devicemap.o grub_mkdevicemap-util_misc.o
+
+grub_mkdevicemap-util_grub_mkdevicemap.o: util/grub-mkdevicemap.c $(util/grub-mkdevicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_grub_mkdevicemap.d
+
+grub_mkdevicemap-util_deviceiter.o: util/deviceiter.c $(util/deviceiter.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_deviceiter.d
+
+grub_mkdevicemap-util_devicemap.o: util/devicemap.c $(util/devicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_devicemap.d
+
+grub_mkdevicemap-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_misc.d
+
+
+# For grub-emu.
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c 	\
+	commands/configfile.c commands/help.c				\
+	commands/handler.c commands/ls.c commands/test.c 		\
+	commands/search.c commands/hexdump.c lib/hexdump.c		\
+	commands/halt.c commands/reboot.c commands/keystatus.c		\
+	commands/i386/cpuid.c						\
+	commands/password.c						\
+	lib/envblk.c commands/loadenv.c					\
+	disk/loopback.c							\
+	\
+	fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c		\
+	fs/befs.c fs/befs_be.c fs/tar.c				\
+	\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/list.c kern/handler.c				\
+	kern/command.c kern/corecmd.c commands/extcmd.c kern/file.c	\
+	kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c	\
+	kern/partition.c kern/reader.c kern/term.c			\
+	kern/rescue_reader.c kern/rescue_parser.c                       \
+	lib/arg.c normal/cmdline.c normal/command.c normal/datetime.c 	\
+	normal/auth.c normal/autofs.c					\
+	normal/completion.c normal/context.c normal/main.c		\
+	normal/menu.c normal/menu_entry.c normal/menu_viewer.c		\
+	normal/menu_text.c						\
+	normal/color.c							\
+	script/sh/main.c script/sh/execute.c script/sh/function.c       \
+	script/sh/lexer.c script/sh/script.c grub_script.tab.c          \
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c partmap/gpt.c					\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	commands/parttool.c parttool/msdospart.c				\
+	grub_emu_init.c
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/i386/efi/grub-install.in
+CLEANFILES += grub-install
+
+grub-install: util/i386/efi/grub-install.in $(util/i386/efi/grub-install.in_DEPENDENCIES) config.status
+	./config.status --file=grub-install:util/i386/efi/grub-install.in
+	chmod +x $@
+
+
+# Modules.
+pkglib_MODULES = kernel.mod chain.mod appleldr.mod \
+	linux.mod halt.mod reboot.mod pci.mod lspci.mod \
+	datetime.mod date.mod datehook.mod loadbios.mod \
+	fixvideo.mod mmap.mod acpi.mod
+
+# For kernel.mod.
+kernel_mod_EXPORTS = no
+kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
+	kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
+	term/efi/console.c disk/efi/efidisk.c \
+	kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+	kern/i386/tsc.c kern/i386/pit.c \
+	kern/generic/rtc_get_time_ms.c \
+	kern/generic/millisleep.c
+
+clean-module-kernel.mod.1:
+	rm -f kernel.mod mod-kernel.o mod-kernel.c pre-kernel.o kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_reader.o kernel_mod-kern_term.o kernel_mod-kern_rescue_parser.o kernel_mod-kern_rescue_reader.o kernel_mod-kern___target_cpu__dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o kernel_mod-kern_time.o kernel_mod-kern_list.o kernel_mod-kern_handler.o kernel_mod-kern_command.o kernel_mod-kern_corecmd.o kernel_mod-kern_i386_tsc.o kernel_mod-kern_i386_pit.o kernel_mod-kern_generic_rtc_get_time_ms.o kernel_mod-kern_generic_millisleep.o und-kernel.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel.mod.1
+
+ifneq ($(kernel_mod_EXPORTS),no)
+clean-module-kernel.mod-symbol.1:
+	rm -f def-kernel.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel.mod-symbol.1
+DEFSYMFILES += def-kernel.lst
+endif
+mostlyclean-module-kernel.mod.1:
+	rm -f kernel_mod-kern_i386_efi_startup.d kernel_mod-kern_main.d kernel_mod-kern_device.d kernel_mod-kern_disk.d kernel_mod-kern_dl.d kernel_mod-kern_file.d kernel_mod-kern_fs.d kernel_mod-kern_err.d kernel_mod-kern_misc.d kernel_mod-kern_mm.d kernel_mod-kern_reader.d kernel_mod-kern_term.d kernel_mod-kern_rescue_parser.d kernel_mod-kern_rescue_reader.d kernel_mod-kern___target_cpu__dl.d kernel_mod-kern_i386_efi_init.d kernel_mod-kern_parser.d kernel_mod-kern_partition.d kernel_mod-kern_env.d kernel_mod-symlist.d kernel_mod-kern_efi_efi.d kernel_mod-kern_efi_init.d kernel_mod-kern_efi_mm.d kernel_mod-term_efi_console.d kernel_mod-disk_efi_efidisk.d kernel_mod-kern_time.d kernel_mod-kern_list.d kernel_mod-kern_handler.d kernel_mod-kern_command.d kernel_mod-kern_corecmd.d kernel_mod-kern_i386_tsc.d kernel_mod-kern_i386_pit.d kernel_mod-kern_generic_rtc_get_time_ms.d kernel_mod-kern_generic_millisleep.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-kernel.mod.1
+UNDSYMFILES += und-kernel.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+kernel.mod: pre-kernel.o mod-kernel.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(kernel_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-kernel.o mod-kernel.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+kernel.mod: pre-kernel.o mod-kernel.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(kernel_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-kernel.o mod-kernel.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-kernel.o: $(kernel_mod_DEPENDENCIES) kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_reader.o kernel_mod-kern_term.o kernel_mod-kern_rescue_parser.o kernel_mod-kern_rescue_reader.o kernel_mod-kern___target_cpu__dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o kernel_mod-kern_time.o kernel_mod-kern_list.o kernel_mod-kern_handler.o kernel_mod-kern_command.o kernel_mod-kern_corecmd.o kernel_mod-kern_i386_tsc.o kernel_mod-kern_i386_pit.o kernel_mod-kern_generic_rtc_get_time_ms.o kernel_mod-kern_generic_millisleep.o
+	-rm -f $@
+	$(TARGET_CC) $(kernel_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_reader.o kernel_mod-kern_term.o kernel_mod-kern_rescue_parser.o kernel_mod-kern_rescue_reader.o kernel_mod-kern___target_cpu__dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o kernel_mod-kern_time.o kernel_mod-kern_list.o kernel_mod-kern_handler.o kernel_mod-kern_command.o kernel_mod-kern_corecmd.o kernel_mod-kern_i386_tsc.o kernel_mod-kern_i386_pit.o kernel_mod-kern_generic_rtc_get_time_ms.o kernel_mod-kern_generic_millisleep.o
+
+mod-kernel.o: mod-kernel.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -c -o $@ $<
+
+mod-kernel.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'kernel' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(kernel_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-kernel.lst: pre-kernel.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 kernel/' > $@
+else
+def-kernel.lst: pre-kernel.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 kernel/' > $@
+endif
+endif
+
+und-kernel.lst: pre-kernel.o
+	echo 'kernel' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+kernel_mod-kern_i386_efi_startup.o: kern/i386/efi/startup.S $(kern/i386/efi/startup.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_i386_efi_startup.d
+
+clean-module-kernel_mod-kern_i386_efi_startup-extra.1:
+	rm -f cmd-kernel_mod-kern_i386_efi_startup.lst fs-kernel_mod-kern_i386_efi_startup.lst partmap-kernel_mod-kern_i386_efi_startup.lst handler-kernel_mod-kern_i386_efi_startup.lst parttool-kernel_mod-kern_i386_efi_startup.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_i386_efi_startup-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_i386_efi_startup.lst
+FSFILES += fs-kernel_mod-kern_i386_efi_startup.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_i386_efi_startup.lst
+PARTMAPFILES += partmap-kernel_mod-kern_i386_efi_startup.lst
+HANDLERFILES += handler-kernel_mod-kern_i386_efi_startup.lst
+
+cmd-kernel_mod-kern_i386_efi_startup.lst: kern/i386/efi/startup.S $(kern/i386/efi/startup.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_i386_efi_startup.lst: kern/i386/efi/startup.S $(kern/i386/efi/startup.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_i386_efi_startup.lst: kern/i386/efi/startup.S $(kern/i386/efi/startup.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_i386_efi_startup.lst: kern/i386/efi/startup.S $(kern/i386/efi/startup.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_i386_efi_startup.lst: kern/i386/efi/startup.S $(kern/i386/efi/startup.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_main.d
+
+clean-module-kernel_mod-kern_main-extra.1:
+	rm -f cmd-kernel_mod-kern_main.lst fs-kernel_mod-kern_main.lst partmap-kernel_mod-kern_main.lst handler-kernel_mod-kern_main.lst parttool-kernel_mod-kern_main.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_main-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_main.lst
+FSFILES += fs-kernel_mod-kern_main.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_main.lst
+PARTMAPFILES += partmap-kernel_mod-kern_main.lst
+HANDLERFILES += handler-kernel_mod-kern_main.lst
+
+cmd-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_device.d
+
+clean-module-kernel_mod-kern_device-extra.1:
+	rm -f cmd-kernel_mod-kern_device.lst fs-kernel_mod-kern_device.lst partmap-kernel_mod-kern_device.lst handler-kernel_mod-kern_device.lst parttool-kernel_mod-kern_device.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_device-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_device.lst
+FSFILES += fs-kernel_mod-kern_device.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_device.lst
+PARTMAPFILES += partmap-kernel_mod-kern_device.lst
+HANDLERFILES += handler-kernel_mod-kern_device.lst
+
+cmd-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_disk.d
+
+clean-module-kernel_mod-kern_disk-extra.1:
+	rm -f cmd-kernel_mod-kern_disk.lst fs-kernel_mod-kern_disk.lst partmap-kernel_mod-kern_disk.lst handler-kernel_mod-kern_disk.lst parttool-kernel_mod-kern_disk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_disk-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_disk.lst
+FSFILES += fs-kernel_mod-kern_disk.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_disk.lst
+PARTMAPFILES += partmap-kernel_mod-kern_disk.lst
+HANDLERFILES += handler-kernel_mod-kern_disk.lst
+
+cmd-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_dl.d
+
+clean-module-kernel_mod-kern_dl-extra.1:
+	rm -f cmd-kernel_mod-kern_dl.lst fs-kernel_mod-kern_dl.lst partmap-kernel_mod-kern_dl.lst handler-kernel_mod-kern_dl.lst parttool-kernel_mod-kern_dl.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_dl-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_dl.lst
+FSFILES += fs-kernel_mod-kern_dl.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_dl.lst
+PARTMAPFILES += partmap-kernel_mod-kern_dl.lst
+HANDLERFILES += handler-kernel_mod-kern_dl.lst
+
+cmd-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_file.d
+
+clean-module-kernel_mod-kern_file-extra.1:
+	rm -f cmd-kernel_mod-kern_file.lst fs-kernel_mod-kern_file.lst partmap-kernel_mod-kern_file.lst handler-kernel_mod-kern_file.lst parttool-kernel_mod-kern_file.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_file-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_file.lst
+FSFILES += fs-kernel_mod-kern_file.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_file.lst
+PARTMAPFILES += partmap-kernel_mod-kern_file.lst
+HANDLERFILES += handler-kernel_mod-kern_file.lst
+
+cmd-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_fs.d
+
+clean-module-kernel_mod-kern_fs-extra.1:
+	rm -f cmd-kernel_mod-kern_fs.lst fs-kernel_mod-kern_fs.lst partmap-kernel_mod-kern_fs.lst handler-kernel_mod-kern_fs.lst parttool-kernel_mod-kern_fs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_fs-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_fs.lst
+FSFILES += fs-kernel_mod-kern_fs.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_fs.lst
+PARTMAPFILES += partmap-kernel_mod-kern_fs.lst
+HANDLERFILES += handler-kernel_mod-kern_fs.lst
+
+cmd-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_err.d
+
+clean-module-kernel_mod-kern_err-extra.1:
+	rm -f cmd-kernel_mod-kern_err.lst fs-kernel_mod-kern_err.lst partmap-kernel_mod-kern_err.lst handler-kernel_mod-kern_err.lst parttool-kernel_mod-kern_err.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_err-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_err.lst
+FSFILES += fs-kernel_mod-kern_err.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_err.lst
+PARTMAPFILES += partmap-kernel_mod-kern_err.lst
+HANDLERFILES += handler-kernel_mod-kern_err.lst
+
+cmd-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_misc.d
+
+clean-module-kernel_mod-kern_misc-extra.1:
+	rm -f cmd-kernel_mod-kern_misc.lst fs-kernel_mod-kern_misc.lst partmap-kernel_mod-kern_misc.lst handler-kernel_mod-kern_misc.lst parttool-kernel_mod-kern_misc.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_misc-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_misc.lst
+FSFILES += fs-kernel_mod-kern_misc.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_misc.lst
+PARTMAPFILES += partmap-kernel_mod-kern_misc.lst
+HANDLERFILES += handler-kernel_mod-kern_misc.lst
+
+cmd-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_mm.d
+
+clean-module-kernel_mod-kern_mm-extra.1:
+	rm -f cmd-kernel_mod-kern_mm.lst fs-kernel_mod-kern_mm.lst partmap-kernel_mod-kern_mm.lst handler-kernel_mod-kern_mm.lst parttool-kernel_mod-kern_mm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_mm-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_mm.lst
+FSFILES += fs-kernel_mod-kern_mm.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_mm.lst
+PARTMAPFILES += partmap-kernel_mod-kern_mm.lst
+HANDLERFILES += handler-kernel_mod-kern_mm.lst
+
+cmd-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_reader.d
+
+clean-module-kernel_mod-kern_reader-extra.1:
+	rm -f cmd-kernel_mod-kern_reader.lst fs-kernel_mod-kern_reader.lst partmap-kernel_mod-kern_reader.lst handler-kernel_mod-kern_reader.lst parttool-kernel_mod-kern_reader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_reader-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_reader.lst
+FSFILES += fs-kernel_mod-kern_reader.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_reader.lst
+PARTMAPFILES += partmap-kernel_mod-kern_reader.lst
+HANDLERFILES += handler-kernel_mod-kern_reader.lst
+
+cmd-kernel_mod-kern_reader.lst: kern/reader.c $(kern/reader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_reader.lst: kern/reader.c $(kern/reader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_reader.lst: kern/reader.c $(kern/reader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_reader.lst: kern/reader.c $(kern/reader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_reader.lst: kern/reader.c $(kern/reader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_term.d
+
+clean-module-kernel_mod-kern_term-extra.1:
+	rm -f cmd-kernel_mod-kern_term.lst fs-kernel_mod-kern_term.lst partmap-kernel_mod-kern_term.lst handler-kernel_mod-kern_term.lst parttool-kernel_mod-kern_term.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_term-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_term.lst
+FSFILES += fs-kernel_mod-kern_term.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_term.lst
+PARTMAPFILES += partmap-kernel_mod-kern_term.lst
+HANDLERFILES += handler-kernel_mod-kern_term.lst
+
+cmd-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_rescue_parser.d
+
+clean-module-kernel_mod-kern_rescue_parser-extra.1:
+	rm -f cmd-kernel_mod-kern_rescue_parser.lst fs-kernel_mod-kern_rescue_parser.lst partmap-kernel_mod-kern_rescue_parser.lst handler-kernel_mod-kern_rescue_parser.lst parttool-kernel_mod-kern_rescue_parser.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_rescue_parser-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_rescue_parser.lst
+FSFILES += fs-kernel_mod-kern_rescue_parser.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_rescue_parser.lst
+PARTMAPFILES += partmap-kernel_mod-kern_rescue_parser.lst
+HANDLERFILES += handler-kernel_mod-kern_rescue_parser.lst
+
+cmd-kernel_mod-kern_rescue_parser.lst: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_rescue_parser.lst: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_rescue_parser.lst: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_rescue_parser.lst: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_rescue_parser.lst: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_rescue_reader.d
+
+clean-module-kernel_mod-kern_rescue_reader-extra.1:
+	rm -f cmd-kernel_mod-kern_rescue_reader.lst fs-kernel_mod-kern_rescue_reader.lst partmap-kernel_mod-kern_rescue_reader.lst handler-kernel_mod-kern_rescue_reader.lst parttool-kernel_mod-kern_rescue_reader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_rescue_reader-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_rescue_reader.lst
+FSFILES += fs-kernel_mod-kern_rescue_reader.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_rescue_reader.lst
+PARTMAPFILES += partmap-kernel_mod-kern_rescue_reader.lst
+HANDLERFILES += handler-kernel_mod-kern_rescue_reader.lst
+
+cmd-kernel_mod-kern_rescue_reader.lst: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_rescue_reader.lst: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_rescue_reader.lst: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_rescue_reader.lst: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_rescue_reader.lst: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern___target_cpu__dl.o: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern___target_cpu__dl.d
+
+clean-module-kernel_mod-kern___target_cpu__dl-extra.1:
+	rm -f cmd-kernel_mod-kern___target_cpu__dl.lst fs-kernel_mod-kern___target_cpu__dl.lst partmap-kernel_mod-kern___target_cpu__dl.lst handler-kernel_mod-kern___target_cpu__dl.lst parttool-kernel_mod-kern___target_cpu__dl.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern___target_cpu__dl-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern___target_cpu__dl.lst
+FSFILES += fs-kernel_mod-kern___target_cpu__dl.lst
+PARTTOOLFILES += parttool-kernel_mod-kern___target_cpu__dl.lst
+PARTMAPFILES += partmap-kernel_mod-kern___target_cpu__dl.lst
+HANDLERFILES += handler-kernel_mod-kern___target_cpu__dl.lst
+
+cmd-kernel_mod-kern___target_cpu__dl.lst: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern___target_cpu__dl.lst: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern___target_cpu__dl.lst: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern___target_cpu__dl.lst: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern___target_cpu__dl.lst: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_i386_efi_init.o: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_i386_efi_init.d
+
+clean-module-kernel_mod-kern_i386_efi_init-extra.1:
+	rm -f cmd-kernel_mod-kern_i386_efi_init.lst fs-kernel_mod-kern_i386_efi_init.lst partmap-kernel_mod-kern_i386_efi_init.lst handler-kernel_mod-kern_i386_efi_init.lst parttool-kernel_mod-kern_i386_efi_init.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_i386_efi_init-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_i386_efi_init.lst
+FSFILES += fs-kernel_mod-kern_i386_efi_init.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_i386_efi_init.lst
+PARTMAPFILES += partmap-kernel_mod-kern_i386_efi_init.lst
+HANDLERFILES += handler-kernel_mod-kern_i386_efi_init.lst
+
+cmd-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_parser.d
+
+clean-module-kernel_mod-kern_parser-extra.1:
+	rm -f cmd-kernel_mod-kern_parser.lst fs-kernel_mod-kern_parser.lst partmap-kernel_mod-kern_parser.lst handler-kernel_mod-kern_parser.lst parttool-kernel_mod-kern_parser.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_parser-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_parser.lst
+FSFILES += fs-kernel_mod-kern_parser.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_parser.lst
+PARTMAPFILES += partmap-kernel_mod-kern_parser.lst
+HANDLERFILES += handler-kernel_mod-kern_parser.lst
+
+cmd-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_partition.d
+
+clean-module-kernel_mod-kern_partition-extra.1:
+	rm -f cmd-kernel_mod-kern_partition.lst fs-kernel_mod-kern_partition.lst partmap-kernel_mod-kern_partition.lst handler-kernel_mod-kern_partition.lst parttool-kernel_mod-kern_partition.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_partition-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_partition.lst
+FSFILES += fs-kernel_mod-kern_partition.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_partition.lst
+PARTMAPFILES += partmap-kernel_mod-kern_partition.lst
+HANDLERFILES += handler-kernel_mod-kern_partition.lst
+
+cmd-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_env.d
+
+clean-module-kernel_mod-kern_env-extra.1:
+	rm -f cmd-kernel_mod-kern_env.lst fs-kernel_mod-kern_env.lst partmap-kernel_mod-kern_env.lst handler-kernel_mod-kern_env.lst parttool-kernel_mod-kern_env.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_env-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_env.lst
+FSFILES += fs-kernel_mod-kern_env.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_env.lst
+PARTMAPFILES += partmap-kernel_mod-kern_env.lst
+HANDLERFILES += handler-kernel_mod-kern_env.lst
+
+cmd-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-symlist.o: symlist.c $(symlist.c_DEPENDENCIES)
+	$(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-symlist.d
+
+clean-module-kernel_mod-symlist-extra.1:
+	rm -f cmd-kernel_mod-symlist.lst fs-kernel_mod-symlist.lst partmap-kernel_mod-symlist.lst handler-kernel_mod-symlist.lst parttool-kernel_mod-symlist.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-symlist-extra.1
+
+COMMANDFILES += cmd-kernel_mod-symlist.lst
+FSFILES += fs-kernel_mod-symlist.lst
+PARTTOOLFILES += parttool-kernel_mod-symlist.lst
+PARTMAPFILES += partmap-kernel_mod-symlist.lst
+HANDLERFILES += handler-kernel_mod-symlist.lst
+
+cmd-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_efi_efi.o: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_efi_efi.d
+
+clean-module-kernel_mod-kern_efi_efi-extra.1:
+	rm -f cmd-kernel_mod-kern_efi_efi.lst fs-kernel_mod-kern_efi_efi.lst partmap-kernel_mod-kern_efi_efi.lst handler-kernel_mod-kern_efi_efi.lst parttool-kernel_mod-kern_efi_efi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_efi_efi-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_efi_efi.lst
+FSFILES += fs-kernel_mod-kern_efi_efi.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_efi_efi.lst
+PARTMAPFILES += partmap-kernel_mod-kern_efi_efi.lst
+HANDLERFILES += handler-kernel_mod-kern_efi_efi.lst
+
+cmd-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_efi_init.o: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_efi_init.d
+
+clean-module-kernel_mod-kern_efi_init-extra.1:
+	rm -f cmd-kernel_mod-kern_efi_init.lst fs-kernel_mod-kern_efi_init.lst partmap-kernel_mod-kern_efi_init.lst handler-kernel_mod-kern_efi_init.lst parttool-kernel_mod-kern_efi_init.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_efi_init-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_efi_init.lst
+FSFILES += fs-kernel_mod-kern_efi_init.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_efi_init.lst
+PARTMAPFILES += partmap-kernel_mod-kern_efi_init.lst
+HANDLERFILES += handler-kernel_mod-kern_efi_init.lst
+
+cmd-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_efi_mm.o: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_efi_mm.d
+
+clean-module-kernel_mod-kern_efi_mm-extra.1:
+	rm -f cmd-kernel_mod-kern_efi_mm.lst fs-kernel_mod-kern_efi_mm.lst partmap-kernel_mod-kern_efi_mm.lst handler-kernel_mod-kern_efi_mm.lst parttool-kernel_mod-kern_efi_mm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_efi_mm-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_efi_mm.lst
+FSFILES += fs-kernel_mod-kern_efi_mm.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_efi_mm.lst
+PARTMAPFILES += partmap-kernel_mod-kern_efi_mm.lst
+HANDLERFILES += handler-kernel_mod-kern_efi_mm.lst
+
+cmd-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-term_efi_console.o: term/efi/console.c $(term/efi/console.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-term_efi_console.d
+
+clean-module-kernel_mod-term_efi_console-extra.1:
+	rm -f cmd-kernel_mod-term_efi_console.lst fs-kernel_mod-term_efi_console.lst partmap-kernel_mod-term_efi_console.lst handler-kernel_mod-term_efi_console.lst parttool-kernel_mod-term_efi_console.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-term_efi_console-extra.1
+
+COMMANDFILES += cmd-kernel_mod-term_efi_console.lst
+FSFILES += fs-kernel_mod-term_efi_console.lst
+PARTTOOLFILES += parttool-kernel_mod-term_efi_console.lst
+PARTMAPFILES += partmap-kernel_mod-term_efi_console.lst
+HANDLERFILES += handler-kernel_mod-term_efi_console.lst
+
+cmd-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-disk_efi_efidisk.o: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-disk_efi_efidisk.d
+
+clean-module-kernel_mod-disk_efi_efidisk-extra.1:
+	rm -f cmd-kernel_mod-disk_efi_efidisk.lst fs-kernel_mod-disk_efi_efidisk.lst partmap-kernel_mod-disk_efi_efidisk.lst handler-kernel_mod-disk_efi_efidisk.lst parttool-kernel_mod-disk_efi_efidisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-disk_efi_efidisk-extra.1
+
+COMMANDFILES += cmd-kernel_mod-disk_efi_efidisk.lst
+FSFILES += fs-kernel_mod-disk_efi_efidisk.lst
+PARTTOOLFILES += parttool-kernel_mod-disk_efi_efidisk.lst
+PARTMAPFILES += partmap-kernel_mod-disk_efi_efidisk.lst
+HANDLERFILES += handler-kernel_mod-disk_efi_efidisk.lst
+
+cmd-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_time.d
+
+clean-module-kernel_mod-kern_time-extra.1:
+	rm -f cmd-kernel_mod-kern_time.lst fs-kernel_mod-kern_time.lst partmap-kernel_mod-kern_time.lst handler-kernel_mod-kern_time.lst parttool-kernel_mod-kern_time.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_time-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_time.lst
+FSFILES += fs-kernel_mod-kern_time.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_time.lst
+PARTMAPFILES += partmap-kernel_mod-kern_time.lst
+HANDLERFILES += handler-kernel_mod-kern_time.lst
+
+cmd-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_list.d
+
+clean-module-kernel_mod-kern_list-extra.1:
+	rm -f cmd-kernel_mod-kern_list.lst fs-kernel_mod-kern_list.lst partmap-kernel_mod-kern_list.lst handler-kernel_mod-kern_list.lst parttool-kernel_mod-kern_list.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_list-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_list.lst
+FSFILES += fs-kernel_mod-kern_list.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_list.lst
+PARTMAPFILES += partmap-kernel_mod-kern_list.lst
+HANDLERFILES += handler-kernel_mod-kern_list.lst
+
+cmd-kernel_mod-kern_list.lst: kern/list.c $(kern/list.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_list.lst: kern/list.c $(kern/list.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_list.lst: kern/list.c $(kern/list.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_list.lst: kern/list.c $(kern/list.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_list.lst: kern/list.c $(kern/list.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_handler.d
+
+clean-module-kernel_mod-kern_handler-extra.1:
+	rm -f cmd-kernel_mod-kern_handler.lst fs-kernel_mod-kern_handler.lst partmap-kernel_mod-kern_handler.lst handler-kernel_mod-kern_handler.lst parttool-kernel_mod-kern_handler.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_handler-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_handler.lst
+FSFILES += fs-kernel_mod-kern_handler.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_handler.lst
+PARTMAPFILES += partmap-kernel_mod-kern_handler.lst
+HANDLERFILES += handler-kernel_mod-kern_handler.lst
+
+cmd-kernel_mod-kern_handler.lst: kern/handler.c $(kern/handler.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_handler.lst: kern/handler.c $(kern/handler.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_handler.lst: kern/handler.c $(kern/handler.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_handler.lst: kern/handler.c $(kern/handler.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_handler.lst: kern/handler.c $(kern/handler.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_command.d
+
+clean-module-kernel_mod-kern_command-extra.1:
+	rm -f cmd-kernel_mod-kern_command.lst fs-kernel_mod-kern_command.lst partmap-kernel_mod-kern_command.lst handler-kernel_mod-kern_command.lst parttool-kernel_mod-kern_command.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_command-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_command.lst
+FSFILES += fs-kernel_mod-kern_command.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_command.lst
+PARTMAPFILES += partmap-kernel_mod-kern_command.lst
+HANDLERFILES += handler-kernel_mod-kern_command.lst
+
+cmd-kernel_mod-kern_command.lst: kern/command.c $(kern/command.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_command.lst: kern/command.c $(kern/command.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_command.lst: kern/command.c $(kern/command.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_command.lst: kern/command.c $(kern/command.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_command.lst: kern/command.c $(kern/command.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_corecmd.d
+
+clean-module-kernel_mod-kern_corecmd-extra.1:
+	rm -f cmd-kernel_mod-kern_corecmd.lst fs-kernel_mod-kern_corecmd.lst partmap-kernel_mod-kern_corecmd.lst handler-kernel_mod-kern_corecmd.lst parttool-kernel_mod-kern_corecmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_corecmd-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_corecmd.lst
+FSFILES += fs-kernel_mod-kern_corecmd.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_corecmd.lst
+PARTMAPFILES += partmap-kernel_mod-kern_corecmd.lst
+HANDLERFILES += handler-kernel_mod-kern_corecmd.lst
+
+cmd-kernel_mod-kern_corecmd.lst: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_corecmd.lst: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_corecmd.lst: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_corecmd.lst: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_corecmd.lst: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_i386_tsc.o: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_i386_tsc.d
+
+clean-module-kernel_mod-kern_i386_tsc-extra.1:
+	rm -f cmd-kernel_mod-kern_i386_tsc.lst fs-kernel_mod-kern_i386_tsc.lst partmap-kernel_mod-kern_i386_tsc.lst handler-kernel_mod-kern_i386_tsc.lst parttool-kernel_mod-kern_i386_tsc.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_i386_tsc-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_i386_tsc.lst
+FSFILES += fs-kernel_mod-kern_i386_tsc.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_i386_tsc.lst
+PARTMAPFILES += partmap-kernel_mod-kern_i386_tsc.lst
+HANDLERFILES += handler-kernel_mod-kern_i386_tsc.lst
+
+cmd-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_i386_pit.o: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_i386_pit.d
+
+clean-module-kernel_mod-kern_i386_pit-extra.1:
+	rm -f cmd-kernel_mod-kern_i386_pit.lst fs-kernel_mod-kern_i386_pit.lst partmap-kernel_mod-kern_i386_pit.lst handler-kernel_mod-kern_i386_pit.lst parttool-kernel_mod-kern_i386_pit.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_i386_pit-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_i386_pit.lst
+FSFILES += fs-kernel_mod-kern_i386_pit.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_i386_pit.lst
+PARTMAPFILES += partmap-kernel_mod-kern_i386_pit.lst
+HANDLERFILES += handler-kernel_mod-kern_i386_pit.lst
+
+cmd-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_generic_rtc_get_time_ms.o: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_generic_rtc_get_time_ms.d
+
+clean-module-kernel_mod-kern_generic_rtc_get_time_ms-extra.1:
+	rm -f cmd-kernel_mod-kern_generic_rtc_get_time_ms.lst fs-kernel_mod-kern_generic_rtc_get_time_ms.lst partmap-kernel_mod-kern_generic_rtc_get_time_ms.lst handler-kernel_mod-kern_generic_rtc_get_time_ms.lst parttool-kernel_mod-kern_generic_rtc_get_time_ms.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_generic_rtc_get_time_ms-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_generic_rtc_get_time_ms.lst
+FSFILES += fs-kernel_mod-kern_generic_rtc_get_time_ms.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_generic_rtc_get_time_ms.lst
+PARTMAPFILES += partmap-kernel_mod-kern_generic_rtc_get_time_ms.lst
+HANDLERFILES += handler-kernel_mod-kern_generic_rtc_get_time_ms.lst
+
+cmd-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_generic_millisleep.d
+
+clean-module-kernel_mod-kern_generic_millisleep-extra.1:
+	rm -f cmd-kernel_mod-kern_generic_millisleep.lst fs-kernel_mod-kern_generic_millisleep.lst partmap-kernel_mod-kern_generic_millisleep.lst handler-kernel_mod-kern_generic_millisleep.lst parttool-kernel_mod-kern_generic_millisleep.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_generic_millisleep-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_generic_millisleep.lst
+FSFILES += fs-kernel_mod-kern_generic_millisleep.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_generic_millisleep.lst
+PARTMAPFILES += partmap-kernel_mod-kern_generic_millisleep.lst
+HANDLERFILES += handler-kernel_mod-kern_generic_millisleep.lst
+
+cmd-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h
+kernel_mod_CFLAGS = $(COMMON_CFLAGS)
+kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+MOSTLYCLEANFILES += symlist.c
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c
+
+clean-module-boot.mod.1:
+	rm -f boot.mod mod-boot.o mod-boot.c pre-boot.o boot_mod-commands_boot.o und-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod.1
+
+ifneq ($(boot_mod_EXPORTS),no)
+clean-module-boot.mod-symbol.1:
+	rm -f def-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod-symbol.1
+DEFSYMFILES += def-boot.lst
+endif
+mostlyclean-module-boot.mod.1:
+	rm -f boot_mod-commands_boot.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-boot.mod.1
+UNDSYMFILES += und-boot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-boot.o mod-boot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-boot.o mod-boot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-boot.o: $(boot_mod_DEPENDENCIES) boot_mod-commands_boot.o
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ boot_mod-commands_boot.o
+
+mod-boot.o: mod-boot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -c -o $@ $<
+
+mod-boot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'boot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(boot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-boot.lst: pre-boot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+else
+def-boot.lst: pre-boot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+endif
+endif
+
+und-boot.lst: pre-boot.o
+	echo 'boot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+boot_mod-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $<
+-include boot_mod-commands_boot.d
+
+clean-module-boot_mod-commands_boot-extra.1:
+	rm -f cmd-boot_mod-commands_boot.lst fs-boot_mod-commands_boot.lst partmap-boot_mod-commands_boot.lst handler-boot_mod-commands_boot.lst parttool-boot_mod-commands_boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot_mod-commands_boot-extra.1
+
+COMMANDFILES += cmd-boot_mod-commands_boot.lst
+FSFILES += fs-boot_mod-commands_boot.lst
+PARTTOOLFILES += parttool-boot_mod-commands_boot.lst
+PARTMAPFILES += partmap-boot_mod-commands_boot.lst
+HANDLERFILES += handler-boot_mod-commands_boot.lst
+
+cmd-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1)
+
+fs-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1)
+
+parttool-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh boot > $@ || (rm -f $@; exit 1)
+
+partmap-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1)
+
+handler-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh boot > $@ || (rm -f $@; exit 1)
+
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For acpi.mod.
+acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c
+
+clean-module-acpi.mod.1:
+	rm -f acpi.mod mod-acpi.o mod-acpi.c pre-acpi.o acpi_mod-commands_acpi.o acpi_mod-commands_efi_acpi.o und-acpi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-acpi.mod.1
+
+ifneq ($(acpi_mod_EXPORTS),no)
+clean-module-acpi.mod-symbol.1:
+	rm -f def-acpi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-acpi.mod-symbol.1
+DEFSYMFILES += def-acpi.lst
+endif
+mostlyclean-module-acpi.mod.1:
+	rm -f acpi_mod-commands_acpi.d acpi_mod-commands_efi_acpi.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-acpi.mod.1
+UNDSYMFILES += und-acpi.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+acpi.mod: pre-acpi.o mod-acpi.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(acpi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-acpi.o mod-acpi.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+acpi.mod: pre-acpi.o mod-acpi.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(acpi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-acpi.o mod-acpi.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-acpi.o: $(acpi_mod_DEPENDENCIES) acpi_mod-commands_acpi.o acpi_mod-commands_efi_acpi.o
+	-rm -f $@
+	$(TARGET_CC) $(acpi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ acpi_mod-commands_acpi.o acpi_mod-commands_efi_acpi.o
+
+mod-acpi.o: mod-acpi.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -c -o $@ $<
+
+mod-acpi.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'acpi' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(acpi_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-acpi.lst: pre-acpi.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 acpi/' > $@
+else
+def-acpi.lst: pre-acpi.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 acpi/' > $@
+endif
+endif
+
+und-acpi.lst: pre-acpi.o
+	echo 'acpi' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+acpi_mod-commands_acpi.o: commands/acpi.c $(commands/acpi.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -MD -c -o $@ $<
+-include acpi_mod-commands_acpi.d
+
+clean-module-acpi_mod-commands_acpi-extra.1:
+	rm -f cmd-acpi_mod-commands_acpi.lst fs-acpi_mod-commands_acpi.lst partmap-acpi_mod-commands_acpi.lst handler-acpi_mod-commands_acpi.lst parttool-acpi_mod-commands_acpi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-acpi_mod-commands_acpi-extra.1
+
+COMMANDFILES += cmd-acpi_mod-commands_acpi.lst
+FSFILES += fs-acpi_mod-commands_acpi.lst
+PARTTOOLFILES += parttool-acpi_mod-commands_acpi.lst
+PARTMAPFILES += partmap-acpi_mod-commands_acpi.lst
+HANDLERFILES += handler-acpi_mod-commands_acpi.lst
+
+cmd-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh acpi > $@ || (rm -f $@; exit 1)
+
+fs-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh acpi > $@ || (rm -f $@; exit 1)
+
+parttool-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh acpi > $@ || (rm -f $@; exit 1)
+
+partmap-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh acpi > $@ || (rm -f $@; exit 1)
+
+handler-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh acpi > $@ || (rm -f $@; exit 1)
+
+acpi_mod-commands_efi_acpi.o: commands/efi/acpi.c $(commands/efi/acpi.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -MD -c -o $@ $<
+-include acpi_mod-commands_efi_acpi.d
+
+clean-module-acpi_mod-commands_efi_acpi-extra.1:
+	rm -f cmd-acpi_mod-commands_efi_acpi.lst fs-acpi_mod-commands_efi_acpi.lst partmap-acpi_mod-commands_efi_acpi.lst handler-acpi_mod-commands_efi_acpi.lst parttool-acpi_mod-commands_efi_acpi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-acpi_mod-commands_efi_acpi-extra.1
+
+COMMANDFILES += cmd-acpi_mod-commands_efi_acpi.lst
+FSFILES += fs-acpi_mod-commands_efi_acpi.lst
+PARTTOOLFILES += parttool-acpi_mod-commands_efi_acpi.lst
+PARTMAPFILES += partmap-acpi_mod-commands_efi_acpi.lst
+HANDLERFILES += handler-acpi_mod-commands_efi_acpi.lst
+
+cmd-acpi_mod-commands_efi_acpi.lst: commands/efi/acpi.c $(commands/efi/acpi.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh acpi > $@ || (rm -f $@; exit 1)
+
+fs-acpi_mod-commands_efi_acpi.lst: commands/efi/acpi.c $(commands/efi/acpi.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh acpi > $@ || (rm -f $@; exit 1)
+
+parttool-acpi_mod-commands_efi_acpi.lst: commands/efi/acpi.c $(commands/efi/acpi.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh acpi > $@ || (rm -f $@; exit 1)
+
+partmap-acpi_mod-commands_efi_acpi.lst: commands/efi/acpi.c $(commands/efi/acpi.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh acpi > $@ || (rm -f $@; exit 1)
+
+handler-acpi_mod-commands_efi_acpi.lst: commands/efi/acpi.c $(commands/efi/acpi.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh acpi > $@ || (rm -f $@; exit 1)
+
+acpi_mod_CFLAGS = $(COMMON_CFLAGS)
+acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
+		   mmap/efi/mmap.c
+
+clean-module-mmap.mod.1:
+	rm -f mmap.mod mod-mmap.o mod-mmap.c pre-mmap.o mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o mmap_mod-mmap_efi_mmap.o und-mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap.mod.1
+
+ifneq ($(mmap_mod_EXPORTS),no)
+clean-module-mmap.mod-symbol.1:
+	rm -f def-mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap.mod-symbol.1
+DEFSYMFILES += def-mmap.lst
+endif
+mostlyclean-module-mmap.mod.1:
+	rm -f mmap_mod-mmap_mmap.d mmap_mod-mmap_i386_uppermem.d mmap_mod-mmap_i386_mmap.d mmap_mod-mmap_efi_mmap.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-mmap.mod.1
+UNDSYMFILES += und-mmap.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+mmap.mod: pre-mmap.o mod-mmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-mmap.o mod-mmap.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+mmap.mod: pre-mmap.o mod-mmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-mmap.o mod-mmap.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-mmap.o: $(mmap_mod_DEPENDENCIES) mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o mmap_mod-mmap_efi_mmap.o
+	-rm -f $@
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o mmap_mod-mmap_efi_mmap.o
+
+mod-mmap.o: mod-mmap.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -c -o $@ $<
+
+mod-mmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'mmap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(mmap_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-mmap.lst: pre-mmap.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 mmap/' > $@
+else
+def-mmap.lst: pre-mmap.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 mmap/' > $@
+endif
+endif
+
+und-mmap.lst: pre-mmap.o
+	echo 'mmap' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+mmap_mod-mmap_mmap.o: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_mmap.d
+
+clean-module-mmap_mod-mmap_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_mmap.lst fs-mmap_mod-mmap_mmap.lst partmap-mmap_mod-mmap_mmap.lst handler-mmap_mod-mmap_mmap.lst parttool-mmap_mod-mmap_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_mmap.lst
+FSFILES += fs-mmap_mod-mmap_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_mmap.lst
+
+cmd-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_i386_uppermem.o: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_i386_uppermem.d
+
+clean-module-mmap_mod-mmap_i386_uppermem-extra.1:
+	rm -f cmd-mmap_mod-mmap_i386_uppermem.lst fs-mmap_mod-mmap_i386_uppermem.lst partmap-mmap_mod-mmap_i386_uppermem.lst handler-mmap_mod-mmap_i386_uppermem.lst parttool-mmap_mod-mmap_i386_uppermem.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_i386_uppermem-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_i386_uppermem.lst
+FSFILES += fs-mmap_mod-mmap_i386_uppermem.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_i386_uppermem.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_i386_uppermem.lst
+HANDLERFILES += handler-mmap_mod-mmap_i386_uppermem.lst
+
+cmd-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_i386_mmap.o: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_i386_mmap.d
+
+clean-module-mmap_mod-mmap_i386_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_i386_mmap.lst fs-mmap_mod-mmap_i386_mmap.lst partmap-mmap_mod-mmap_i386_mmap.lst handler-mmap_mod-mmap_i386_mmap.lst parttool-mmap_mod-mmap_i386_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_i386_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_i386_mmap.lst
+FSFILES += fs-mmap_mod-mmap_i386_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_i386_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_i386_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_i386_mmap.lst
+
+cmd-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_efi_mmap.o: mmap/efi/mmap.c $(mmap/efi/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/efi -I$(srcdir)/mmap/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_efi_mmap.d
+
+clean-module-mmap_mod-mmap_efi_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_efi_mmap.lst fs-mmap_mod-mmap_efi_mmap.lst partmap-mmap_mod-mmap_efi_mmap.lst handler-mmap_mod-mmap_efi_mmap.lst parttool-mmap_mod-mmap_efi_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_efi_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_efi_mmap.lst
+FSFILES += fs-mmap_mod-mmap_efi_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_efi_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_efi_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_efi_mmap.lst
+
+cmd-mmap_mod-mmap_efi_mmap.lst: mmap/efi/mmap.c $(mmap/efi/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/efi -I$(srcdir)/mmap/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_efi_mmap.lst: mmap/efi/mmap.c $(mmap/efi/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/efi -I$(srcdir)/mmap/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_efi_mmap.lst: mmap/efi/mmap.c $(mmap/efi/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/efi -I$(srcdir)/mmap/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_efi_mmap.lst: mmap/efi/mmap.c $(mmap/efi/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/efi -I$(srcdir)/mmap/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_efi_mmap.lst: mmap/efi/mmap.c $(mmap/efi/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/efi -I$(srcdir)/mmap/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For chain.mod.
+chain_mod_SOURCES = loader/efi/chainloader.c
+
+clean-module-chain.mod.1:
+	rm -f chain.mod mod-chain.o mod-chain.c pre-chain.o chain_mod-loader_efi_chainloader.o und-chain.lst
+
+CLEAN_MODULE_TARGETS += clean-module-chain.mod.1
+
+ifneq ($(chain_mod_EXPORTS),no)
+clean-module-chain.mod-symbol.1:
+	rm -f def-chain.lst
+
+CLEAN_MODULE_TARGETS += clean-module-chain.mod-symbol.1
+DEFSYMFILES += def-chain.lst
+endif
+mostlyclean-module-chain.mod.1:
+	rm -f chain_mod-loader_efi_chainloader.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-chain.mod.1
+UNDSYMFILES += und-chain.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+chain.mod: pre-chain.o mod-chain.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-chain.o mod-chain.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+chain.mod: pre-chain.o mod-chain.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-chain.o mod-chain.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-chain.o: $(chain_mod_DEPENDENCIES) chain_mod-loader_efi_chainloader.o
+	-rm -f $@
+	$(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ chain_mod-loader_efi_chainloader.o
+
+mod-chain.o: mod-chain.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -c -o $@ $<
+
+mod-chain.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'chain' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(chain_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-chain.lst: pre-chain.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 chain/' > $@
+else
+def-chain.lst: pre-chain.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 chain/' > $@
+endif
+endif
+
+und-chain.lst: pre-chain.o
+	echo 'chain' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+chain_mod-loader_efi_chainloader.o: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -MD -c -o $@ $<
+-include chain_mod-loader_efi_chainloader.d
+
+clean-module-chain_mod-loader_efi_chainloader-extra.1:
+	rm -f cmd-chain_mod-loader_efi_chainloader.lst fs-chain_mod-loader_efi_chainloader.lst partmap-chain_mod-loader_efi_chainloader.lst handler-chain_mod-loader_efi_chainloader.lst parttool-chain_mod-loader_efi_chainloader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-chain_mod-loader_efi_chainloader-extra.1
+
+COMMANDFILES += cmd-chain_mod-loader_efi_chainloader.lst
+FSFILES += fs-chain_mod-loader_efi_chainloader.lst
+PARTTOOLFILES += parttool-chain_mod-loader_efi_chainloader.lst
+PARTMAPFILES += partmap-chain_mod-loader_efi_chainloader.lst
+HANDLERFILES += handler-chain_mod-loader_efi_chainloader.lst
+
+cmd-chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh chain > $@ || (rm -f $@; exit 1)
+
+fs-chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh chain > $@ || (rm -f $@; exit 1)
+
+parttool-chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh chain > $@ || (rm -f $@; exit 1)
+
+partmap-chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh chain > $@ || (rm -f $@; exit 1)
+
+handler-chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh chain > $@ || (rm -f $@; exit 1)
+
+chain_mod_CFLAGS = $(COMMON_CFLAGS)
+chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For appleldr.mod.
+appleldr_mod_SOURCES = loader/efi/appleloader.c
+
+clean-module-appleldr.mod.1:
+	rm -f appleldr.mod mod-appleldr.o mod-appleldr.c pre-appleldr.o appleldr_mod-loader_efi_appleloader.o und-appleldr.lst
+
+CLEAN_MODULE_TARGETS += clean-module-appleldr.mod.1
+
+ifneq ($(appleldr_mod_EXPORTS),no)
+clean-module-appleldr.mod-symbol.1:
+	rm -f def-appleldr.lst
+
+CLEAN_MODULE_TARGETS += clean-module-appleldr.mod-symbol.1
+DEFSYMFILES += def-appleldr.lst
+endif
+mostlyclean-module-appleldr.mod.1:
+	rm -f appleldr_mod-loader_efi_appleloader.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-appleldr.mod.1
+UNDSYMFILES += und-appleldr.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+appleldr.mod: pre-appleldr.o mod-appleldr.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(appleldr_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-appleldr.o mod-appleldr.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+appleldr.mod: pre-appleldr.o mod-appleldr.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(appleldr_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-appleldr.o mod-appleldr.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-appleldr.o: $(appleldr_mod_DEPENDENCIES) appleldr_mod-loader_efi_appleloader.o
+	-rm -f $@
+	$(TARGET_CC) $(appleldr_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ appleldr_mod-loader_efi_appleloader.o
+
+mod-appleldr.o: mod-appleldr.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -c -o $@ $<
+
+mod-appleldr.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'appleldr' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(appleldr_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-appleldr.lst: pre-appleldr.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 appleldr/' > $@
+else
+def-appleldr.lst: pre-appleldr.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 appleldr/' > $@
+endif
+endif
+
+und-appleldr.lst: pre-appleldr.o
+	echo 'appleldr' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+appleldr_mod-loader_efi_appleloader.o: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -MD -c -o $@ $<
+-include appleldr_mod-loader_efi_appleloader.d
+
+clean-module-appleldr_mod-loader_efi_appleloader-extra.1:
+	rm -f cmd-appleldr_mod-loader_efi_appleloader.lst fs-appleldr_mod-loader_efi_appleloader.lst partmap-appleldr_mod-loader_efi_appleloader.lst handler-appleldr_mod-loader_efi_appleloader.lst parttool-appleldr_mod-loader_efi_appleloader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-appleldr_mod-loader_efi_appleloader-extra.1
+
+COMMANDFILES += cmd-appleldr_mod-loader_efi_appleloader.lst
+FSFILES += fs-appleldr_mod-loader_efi_appleloader.lst
+PARTTOOLFILES += parttool-appleldr_mod-loader_efi_appleloader.lst
+PARTMAPFILES += partmap-appleldr_mod-loader_efi_appleloader.lst
+HANDLERFILES += handler-appleldr_mod-loader_efi_appleloader.lst
+
+cmd-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh appleldr > $@ || (rm -f $@; exit 1)
+
+fs-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh appleldr > $@ || (rm -f $@; exit 1)
+
+parttool-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh appleldr > $@ || (rm -f $@; exit 1)
+
+partmap-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh appleldr > $@ || (rm -f $@; exit 1)
+
+handler-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh appleldr > $@ || (rm -f $@; exit 1)
+
+appleldr_mod_CFLAGS = $(COMMON_CFLAGS)
+appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/i386/efi/linux.c
+
+clean-module-linux.mod.1:
+	rm -f linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_i386_efi_linux.o und-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod.1
+
+ifneq ($(linux_mod_EXPORTS),no)
+clean-module-linux.mod-symbol.1:
+	rm -f def-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod-symbol.1
+DEFSYMFILES += def-linux.lst
+endif
+mostlyclean-module-linux.mod.1:
+	rm -f linux_mod-loader_i386_efi_linux.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-linux.mod.1
+UNDSYMFILES += und-linux.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-linux.o mod-linux.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_i386_efi_linux.o
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_i386_efi_linux.o
+
+mod-linux.o: mod-linux.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $<
+
+mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(linux_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-linux.lst: pre-linux.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+else
+def-linux.lst: pre-linux.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+endif
+endif
+
+und-linux.lst: pre-linux.o
+	echo 'linux' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+linux_mod-loader_i386_efi_linux.o: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $<
+-include linux_mod-loader_i386_efi_linux.d
+
+clean-module-linux_mod-loader_i386_efi_linux-extra.1:
+	rm -f cmd-linux_mod-loader_i386_efi_linux.lst fs-linux_mod-loader_i386_efi_linux.lst partmap-linux_mod-loader_i386_efi_linux.lst handler-linux_mod-loader_i386_efi_linux.lst parttool-linux_mod-loader_i386_efi_linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux_mod-loader_i386_efi_linux-extra.1
+
+COMMANDFILES += cmd-linux_mod-loader_i386_efi_linux.lst
+FSFILES += fs-linux_mod-loader_i386_efi_linux.lst
+PARTTOOLFILES += parttool-linux_mod-loader_i386_efi_linux.lst
+PARTMAPFILES += partmap-linux_mod-loader_i386_efi_linux.lst
+HANDLERFILES += handler-linux_mod-loader_i386_efi_linux.lst
+
+cmd-linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1)
+
+fs-linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1)
+
+parttool-linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh linux > $@ || (rm -f $@; exit 1)
+
+partmap-linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1)
+
+handler-linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh linux > $@ || (rm -f $@; exit 1)
+
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/halt.c
+
+clean-module-halt.mod.1:
+	rm -f halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_halt.o und-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod.1
+
+ifneq ($(halt_mod_EXPORTS),no)
+clean-module-halt.mod-symbol.1:
+	rm -f def-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod-symbol.1
+DEFSYMFILES += def-halt.lst
+endif
+mostlyclean-module-halt.mod.1:
+	rm -f halt_mod-commands_halt.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-halt.mod.1
+UNDSYMFILES += und-halt.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-halt.o mod-halt.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_halt.o
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_halt.o
+
+mod-halt.o: mod-halt.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $<
+
+mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(halt_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-halt.lst: pre-halt.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+else
+def-halt.lst: pre-halt.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+endif
+endif
+
+und-halt.lst: pre-halt.o
+	echo 'halt' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+halt_mod-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $<
+-include halt_mod-commands_halt.d
+
+clean-module-halt_mod-commands_halt-extra.1:
+	rm -f cmd-halt_mod-commands_halt.lst fs-halt_mod-commands_halt.lst partmap-halt_mod-commands_halt.lst handler-halt_mod-commands_halt.lst parttool-halt_mod-commands_halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt_mod-commands_halt-extra.1
+
+COMMANDFILES += cmd-halt_mod-commands_halt.lst
+FSFILES += fs-halt_mod-commands_halt.lst
+PARTTOOLFILES += parttool-halt_mod-commands_halt.lst
+PARTMAPFILES += partmap-halt_mod-commands_halt.lst
+HANDLERFILES += handler-halt_mod-commands_halt.lst
+
+cmd-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1)
+
+fs-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1)
+
+parttool-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh halt > $@ || (rm -f $@; exit 1)
+
+partmap-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1)
+
+handler-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh halt > $@ || (rm -f $@; exit 1)
+
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod.
+reboot_mod_SOURCES = commands/reboot.c
+
+clean-module-reboot.mod.1:
+	rm -f reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o und-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod.1
+
+ifneq ($(reboot_mod_EXPORTS),no)
+clean-module-reboot.mod-symbol.1:
+	rm -f def-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod-symbol.1
+DEFSYMFILES += def-reboot.lst
+endif
+mostlyclean-module-reboot.mod.1:
+	rm -f reboot_mod-commands_reboot.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-reboot.mod.1
+UNDSYMFILES += und-reboot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-reboot.o mod-reboot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o
+
+mod-reboot.o: mod-reboot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $<
+
+mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(reboot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-reboot.lst: pre-reboot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+else
+def-reboot.lst: pre-reboot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+endif
+endif
+
+und-reboot.lst: pre-reboot.o
+	echo 'reboot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $<
+-include reboot_mod-commands_reboot.d
+
+clean-module-reboot_mod-commands_reboot-extra.1:
+	rm -f cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst handler-reboot_mod-commands_reboot.lst parttool-reboot_mod-commands_reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot_mod-commands_reboot-extra.1
+
+COMMANDFILES += cmd-reboot_mod-commands_reboot.lst
+FSFILES += fs-reboot_mod-commands_reboot.lst
+PARTTOOLFILES += parttool-reboot_mod-commands_reboot.lst
+PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst
+HANDLERFILES += handler-reboot_mod-commands_reboot.lst
+
+cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1)
+
+parttool-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh reboot > $@ || (rm -f $@; exit 1)
+
+partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1)
+
+handler-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pci.mod
+pci_mod_SOURCES = bus/pci.c
+
+clean-module-pci.mod.1:
+	rm -f pci.mod mod-pci.o mod-pci.c pre-pci.o pci_mod-bus_pci.o und-pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci.mod.1
+
+ifneq ($(pci_mod_EXPORTS),no)
+clean-module-pci.mod-symbol.1:
+	rm -f def-pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci.mod-symbol.1
+DEFSYMFILES += def-pci.lst
+endif
+mostlyclean-module-pci.mod.1:
+	rm -f pci_mod-bus_pci.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-pci.mod.1
+UNDSYMFILES += und-pci.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-pci.o mod-pci.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-pci.o mod-pci.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-pci.o: $(pci_mod_DEPENDENCIES) pci_mod-bus_pci.o
+	-rm -f $@
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pci_mod-bus_pci.o
+
+mod-pci.o: mod-pci.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -c -o $@ $<
+
+mod-pci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'pci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(pci_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-pci.lst: pre-pci.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pci/' > $@
+else
+def-pci.lst: pre-pci.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 pci/' > $@
+endif
+endif
+
+und-pci.lst: pre-pci.o
+	echo 'pci' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+pci_mod-bus_pci.o: bus/pci.c $(bus/pci.c_DEPENDENCIES)
+	$(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -MD -c -o $@ $<
+-include pci_mod-bus_pci.d
+
+clean-module-pci_mod-bus_pci-extra.1:
+	rm -f cmd-pci_mod-bus_pci.lst fs-pci_mod-bus_pci.lst partmap-pci_mod-bus_pci.lst handler-pci_mod-bus_pci.lst parttool-pci_mod-bus_pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci_mod-bus_pci-extra.1
+
+COMMANDFILES += cmd-pci_mod-bus_pci.lst
+FSFILES += fs-pci_mod-bus_pci.lst
+PARTTOOLFILES += parttool-pci_mod-bus_pci.lst
+PARTMAPFILES += partmap-pci_mod-bus_pci.lst
+HANDLERFILES += handler-pci_mod-bus_pci.lst
+
+cmd-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh pci > $@ || (rm -f $@; exit 1)
+
+fs-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh pci > $@ || (rm -f $@; exit 1)
+
+parttool-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh pci > $@ || (rm -f $@; exit 1)
+
+partmap-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh pci > $@ || (rm -f $@; exit 1)
+
+handler-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh pci > $@ || (rm -f $@; exit 1)
+
+pci_mod_CFLAGS = $(COMMON_CFLAGS)
+pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lspci.mod
+lspci_mod_SOURCES = commands/lspci.c
+
+clean-module-lspci.mod.1:
+	rm -f lspci.mod mod-lspci.o mod-lspci.c pre-lspci.o lspci_mod-commands_lspci.o und-lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci.mod.1
+
+ifneq ($(lspci_mod_EXPORTS),no)
+clean-module-lspci.mod-symbol.1:
+	rm -f def-lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci.mod-symbol.1
+DEFSYMFILES += def-lspci.lst
+endif
+mostlyclean-module-lspci.mod.1:
+	rm -f lspci_mod-commands_lspci.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-lspci.mod.1
+UNDSYMFILES += und-lspci.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-lspci.o mod-lspci.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-lspci.o mod-lspci.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-lspci.o: $(lspci_mod_DEPENDENCIES) lspci_mod-commands_lspci.o
+	-rm -f $@
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lspci_mod-commands_lspci.o
+
+mod-lspci.o: mod-lspci.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -c -o $@ $<
+
+mod-lspci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'lspci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(lspci_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-lspci.lst: pre-lspci.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lspci/' > $@
+else
+def-lspci.lst: pre-lspci.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 lspci/' > $@
+endif
+endif
+
+und-lspci.lst: pre-lspci.o
+	echo 'lspci' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+lspci_mod-commands_lspci.o: commands/lspci.c $(commands/lspci.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -MD -c -o $@ $<
+-include lspci_mod-commands_lspci.d
+
+clean-module-lspci_mod-commands_lspci-extra.1:
+	rm -f cmd-lspci_mod-commands_lspci.lst fs-lspci_mod-commands_lspci.lst partmap-lspci_mod-commands_lspci.lst handler-lspci_mod-commands_lspci.lst parttool-lspci_mod-commands_lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci_mod-commands_lspci-extra.1
+
+COMMANDFILES += cmd-lspci_mod-commands_lspci.lst
+FSFILES += fs-lspci_mod-commands_lspci.lst
+PARTTOOLFILES += parttool-lspci_mod-commands_lspci.lst
+PARTMAPFILES += partmap-lspci_mod-commands_lspci.lst
+HANDLERFILES += handler-lspci_mod-commands_lspci.lst
+
+cmd-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh lspci > $@ || (rm -f $@; exit 1)
+
+fs-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh lspci > $@ || (rm -f $@; exit 1)
+
+parttool-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh lspci > $@ || (rm -f $@; exit 1)
+
+partmap-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh lspci > $@ || (rm -f $@; exit 1)
+
+handler-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh lspci > $@ || (rm -f $@; exit 1)
+
+lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/efi/datetime.c
+
+clean-module-datetime.mod.1:
+	rm -f datetime.mod mod-datetime.o mod-datetime.c pre-datetime.o datetime_mod-lib_efi_datetime.o und-datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime.mod.1
+
+ifneq ($(datetime_mod_EXPORTS),no)
+clean-module-datetime.mod-symbol.1:
+	rm -f def-datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime.mod-symbol.1
+DEFSYMFILES += def-datetime.lst
+endif
+mostlyclean-module-datetime.mod.1:
+	rm -f datetime_mod-lib_efi_datetime.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-datetime.mod.1
+UNDSYMFILES += und-datetime.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-datetime.o mod-datetime.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-datetime.o mod-datetime.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-datetime.o: $(datetime_mod_DEPENDENCIES) datetime_mod-lib_efi_datetime.o
+	-rm -f $@
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datetime_mod-lib_efi_datetime.o
+
+mod-datetime.o: mod-datetime.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -c -o $@ $<
+
+mod-datetime.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'datetime' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(datetime_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-datetime.lst: pre-datetime.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datetime/' > $@
+else
+def-datetime.lst: pre-datetime.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 datetime/' > $@
+endif
+endif
+
+und-datetime.lst: pre-datetime.o
+	echo 'datetime' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+datetime_mod-lib_efi_datetime.o: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $<
+-include datetime_mod-lib_efi_datetime.d
+
+clean-module-datetime_mod-lib_efi_datetime-extra.1:
+	rm -f cmd-datetime_mod-lib_efi_datetime.lst fs-datetime_mod-lib_efi_datetime.lst partmap-datetime_mod-lib_efi_datetime.lst handler-datetime_mod-lib_efi_datetime.lst parttool-datetime_mod-lib_efi_datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime_mod-lib_efi_datetime-extra.1
+
+COMMANDFILES += cmd-datetime_mod-lib_efi_datetime.lst
+FSFILES += fs-datetime_mod-lib_efi_datetime.lst
+PARTTOOLFILES += parttool-datetime_mod-lib_efi_datetime.lst
+PARTMAPFILES += partmap-datetime_mod-lib_efi_datetime.lst
+HANDLERFILES += handler-datetime_mod-lib_efi_datetime.lst
+
+cmd-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1)
+
+fs-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1)
+
+parttool-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh datetime > $@ || (rm -f $@; exit 1)
+
+partmap-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1)
+
+handler-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh datetime > $@ || (rm -f $@; exit 1)
+
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For date.mod
+date_mod_SOURCES = commands/date.c
+
+clean-module-date.mod.1:
+	rm -f date.mod mod-date.o mod-date.c pre-date.o date_mod-commands_date.o und-date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date.mod.1
+
+ifneq ($(date_mod_EXPORTS),no)
+clean-module-date.mod-symbol.1:
+	rm -f def-date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date.mod-symbol.1
+DEFSYMFILES += def-date.lst
+endif
+mostlyclean-module-date.mod.1:
+	rm -f date_mod-commands_date.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-date.mod.1
+UNDSYMFILES += und-date.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-date.o mod-date.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-date.o mod-date.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-date.o: $(date_mod_DEPENDENCIES) date_mod-commands_date.o
+	-rm -f $@
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ date_mod-commands_date.o
+
+mod-date.o: mod-date.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -c -o $@ $<
+
+mod-date.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'date' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(date_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-date.lst: pre-date.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 date/' > $@
+else
+def-date.lst: pre-date.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 date/' > $@
+endif
+endif
+
+und-date.lst: pre-date.o
+	echo 'date' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+date_mod-commands_date.o: commands/date.c $(commands/date.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -MD -c -o $@ $<
+-include date_mod-commands_date.d
+
+clean-module-date_mod-commands_date-extra.1:
+	rm -f cmd-date_mod-commands_date.lst fs-date_mod-commands_date.lst partmap-date_mod-commands_date.lst handler-date_mod-commands_date.lst parttool-date_mod-commands_date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date_mod-commands_date-extra.1
+
+COMMANDFILES += cmd-date_mod-commands_date.lst
+FSFILES += fs-date_mod-commands_date.lst
+PARTTOOLFILES += parttool-date_mod-commands_date.lst
+PARTMAPFILES += partmap-date_mod-commands_date.lst
+HANDLERFILES += handler-date_mod-commands_date.lst
+
+cmd-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh date > $@ || (rm -f $@; exit 1)
+
+fs-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh date > $@ || (rm -f $@; exit 1)
+
+parttool-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh date > $@ || (rm -f $@; exit 1)
+
+partmap-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh date > $@ || (rm -f $@; exit 1)
+
+handler-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh date > $@ || (rm -f $@; exit 1)
+
+date_mod_CFLAGS = $(COMMON_CFLAGS)
+date_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datehook.mod
+datehook_mod_SOURCES = hook/datehook.c
+
+clean-module-datehook.mod.1:
+	rm -f datehook.mod mod-datehook.o mod-datehook.c pre-datehook.o datehook_mod-hook_datehook.o und-datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook.mod.1
+
+ifneq ($(datehook_mod_EXPORTS),no)
+clean-module-datehook.mod-symbol.1:
+	rm -f def-datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook.mod-symbol.1
+DEFSYMFILES += def-datehook.lst
+endif
+mostlyclean-module-datehook.mod.1:
+	rm -f datehook_mod-hook_datehook.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-datehook.mod.1
+UNDSYMFILES += und-datehook.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-datehook.o mod-datehook.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-datehook.o mod-datehook.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-datehook.o: $(datehook_mod_DEPENDENCIES) datehook_mod-hook_datehook.o
+	-rm -f $@
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datehook_mod-hook_datehook.o
+
+mod-datehook.o: mod-datehook.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -c -o $@ $<
+
+mod-datehook.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'datehook' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(datehook_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-datehook.lst: pre-datehook.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datehook/' > $@
+else
+def-datehook.lst: pre-datehook.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 datehook/' > $@
+endif
+endif
+
+und-datehook.lst: pre-datehook.o
+	echo 'datehook' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+datehook_mod-hook_datehook.o: hook/datehook.c $(hook/datehook.c_DEPENDENCIES)
+	$(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -MD -c -o $@ $<
+-include datehook_mod-hook_datehook.d
+
+clean-module-datehook_mod-hook_datehook-extra.1:
+	rm -f cmd-datehook_mod-hook_datehook.lst fs-datehook_mod-hook_datehook.lst partmap-datehook_mod-hook_datehook.lst handler-datehook_mod-hook_datehook.lst parttool-datehook_mod-hook_datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook_mod-hook_datehook-extra.1
+
+COMMANDFILES += cmd-datehook_mod-hook_datehook.lst
+FSFILES += fs-datehook_mod-hook_datehook.lst
+PARTTOOLFILES += parttool-datehook_mod-hook_datehook.lst
+PARTMAPFILES += partmap-datehook_mod-hook_datehook.lst
+HANDLERFILES += handler-datehook_mod-hook_datehook.lst
+
+cmd-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh datehook > $@ || (rm -f $@; exit 1)
+
+fs-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh datehook > $@ || (rm -f $@; exit 1)
+
+parttool-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh datehook > $@ || (rm -f $@; exit 1)
+
+partmap-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh datehook > $@ || (rm -f $@; exit 1)
+
+handler-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh datehook > $@ || (rm -f $@; exit 1)
+
+datehook_mod_CFLAGS = $(COMMON_CFLAGS)
+datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For loadbios.mod
+loadbios_mod_SOURCES = commands/efi/loadbios.c
+
+clean-module-loadbios.mod.1:
+	rm -f loadbios.mod mod-loadbios.o mod-loadbios.c pre-loadbios.o loadbios_mod-commands_efi_loadbios.o und-loadbios.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loadbios.mod.1
+
+ifneq ($(loadbios_mod_EXPORTS),no)
+clean-module-loadbios.mod-symbol.1:
+	rm -f def-loadbios.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loadbios.mod-symbol.1
+DEFSYMFILES += def-loadbios.lst
+endif
+mostlyclean-module-loadbios.mod.1:
+	rm -f loadbios_mod-commands_efi_loadbios.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-loadbios.mod.1
+UNDSYMFILES += und-loadbios.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+loadbios.mod: pre-loadbios.o mod-loadbios.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(loadbios_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-loadbios.o mod-loadbios.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+loadbios.mod: pre-loadbios.o mod-loadbios.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(loadbios_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-loadbios.o mod-loadbios.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-loadbios.o: $(loadbios_mod_DEPENDENCIES) loadbios_mod-commands_efi_loadbios.o
+	-rm -f $@
+	$(TARGET_CC) $(loadbios_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ loadbios_mod-commands_efi_loadbios.o
+
+mod-loadbios.o: mod-loadbios.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -c -o $@ $<
+
+mod-loadbios.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'loadbios' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(loadbios_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-loadbios.lst: pre-loadbios.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 loadbios/' > $@
+else
+def-loadbios.lst: pre-loadbios.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 loadbios/' > $@
+endif
+endif
+
+und-loadbios.lst: pre-loadbios.o
+	echo 'loadbios' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+loadbios_mod-commands_efi_loadbios.o: commands/efi/loadbios.c $(commands/efi/loadbios.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -MD -c -o $@ $<
+-include loadbios_mod-commands_efi_loadbios.d
+
+clean-module-loadbios_mod-commands_efi_loadbios-extra.1:
+	rm -f cmd-loadbios_mod-commands_efi_loadbios.lst fs-loadbios_mod-commands_efi_loadbios.lst partmap-loadbios_mod-commands_efi_loadbios.lst handler-loadbios_mod-commands_efi_loadbios.lst parttool-loadbios_mod-commands_efi_loadbios.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loadbios_mod-commands_efi_loadbios-extra.1
+
+COMMANDFILES += cmd-loadbios_mod-commands_efi_loadbios.lst
+FSFILES += fs-loadbios_mod-commands_efi_loadbios.lst
+PARTTOOLFILES += parttool-loadbios_mod-commands_efi_loadbios.lst
+PARTMAPFILES += partmap-loadbios_mod-commands_efi_loadbios.lst
+HANDLERFILES += handler-loadbios_mod-commands_efi_loadbios.lst
+
+cmd-loadbios_mod-commands_efi_loadbios.lst: commands/efi/loadbios.c $(commands/efi/loadbios.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh loadbios > $@ || (rm -f $@; exit 1)
+
+fs-loadbios_mod-commands_efi_loadbios.lst: commands/efi/loadbios.c $(commands/efi/loadbios.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh loadbios > $@ || (rm -f $@; exit 1)
+
+parttool-loadbios_mod-commands_efi_loadbios.lst: commands/efi/loadbios.c $(commands/efi/loadbios.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh loadbios > $@ || (rm -f $@; exit 1)
+
+partmap-loadbios_mod-commands_efi_loadbios.lst: commands/efi/loadbios.c $(commands/efi/loadbios.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh loadbios > $@ || (rm -f $@; exit 1)
+
+handler-loadbios_mod-commands_efi_loadbios.lst: commands/efi/loadbios.c $(commands/efi/loadbios.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh loadbios > $@ || (rm -f $@; exit 1)
+
+loadbios_mod_CFLAGS = $(COMMON_CFLAGS)
+loadbios_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For fixvideo.mod
+fixvideo_mod_SOURCES = commands/efi/fixvideo.c
+
+clean-module-fixvideo.mod.1:
+	rm -f fixvideo.mod mod-fixvideo.o mod-fixvideo.c pre-fixvideo.o fixvideo_mod-commands_efi_fixvideo.o und-fixvideo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fixvideo.mod.1
+
+ifneq ($(fixvideo_mod_EXPORTS),no)
+clean-module-fixvideo.mod-symbol.1:
+	rm -f def-fixvideo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fixvideo.mod-symbol.1
+DEFSYMFILES += def-fixvideo.lst
+endif
+mostlyclean-module-fixvideo.mod.1:
+	rm -f fixvideo_mod-commands_efi_fixvideo.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-fixvideo.mod.1
+UNDSYMFILES += und-fixvideo.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+fixvideo.mod: pre-fixvideo.o mod-fixvideo.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(fixvideo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-fixvideo.o mod-fixvideo.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+fixvideo.mod: pre-fixvideo.o mod-fixvideo.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(fixvideo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-fixvideo.o mod-fixvideo.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-fixvideo.o: $(fixvideo_mod_DEPENDENCIES) fixvideo_mod-commands_efi_fixvideo.o
+	-rm -f $@
+	$(TARGET_CC) $(fixvideo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ fixvideo_mod-commands_efi_fixvideo.o
+
+mod-fixvideo.o: mod-fixvideo.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -c -o $@ $<
+
+mod-fixvideo.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'fixvideo' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(fixvideo_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-fixvideo.lst: pre-fixvideo.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fixvideo/' > $@
+else
+def-fixvideo.lst: pre-fixvideo.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 fixvideo/' > $@
+endif
+endif
+
+und-fixvideo.lst: pre-fixvideo.o
+	echo 'fixvideo' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+fixvideo_mod-commands_efi_fixvideo.o: commands/efi/fixvideo.c $(commands/efi/fixvideo.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -MD -c -o $@ $<
+-include fixvideo_mod-commands_efi_fixvideo.d
+
+clean-module-fixvideo_mod-commands_efi_fixvideo-extra.1:
+	rm -f cmd-fixvideo_mod-commands_efi_fixvideo.lst fs-fixvideo_mod-commands_efi_fixvideo.lst partmap-fixvideo_mod-commands_efi_fixvideo.lst handler-fixvideo_mod-commands_efi_fixvideo.lst parttool-fixvideo_mod-commands_efi_fixvideo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fixvideo_mod-commands_efi_fixvideo-extra.1
+
+COMMANDFILES += cmd-fixvideo_mod-commands_efi_fixvideo.lst
+FSFILES += fs-fixvideo_mod-commands_efi_fixvideo.lst
+PARTTOOLFILES += parttool-fixvideo_mod-commands_efi_fixvideo.lst
+PARTMAPFILES += partmap-fixvideo_mod-commands_efi_fixvideo.lst
+HANDLERFILES += handler-fixvideo_mod-commands_efi_fixvideo.lst
+
+cmd-fixvideo_mod-commands_efi_fixvideo.lst: commands/efi/fixvideo.c $(commands/efi/fixvideo.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh fixvideo > $@ || (rm -f $@; exit 1)
+
+fs-fixvideo_mod-commands_efi_fixvideo.lst: commands/efi/fixvideo.c $(commands/efi/fixvideo.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh fixvideo > $@ || (rm -f $@; exit 1)
+
+parttool-fixvideo_mod-commands_efi_fixvideo.lst: commands/efi/fixvideo.c $(commands/efi/fixvideo.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh fixvideo > $@ || (rm -f $@; exit 1)
+
+partmap-fixvideo_mod-commands_efi_fixvideo.lst: commands/efi/fixvideo.c $(commands/efi/fixvideo.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh fixvideo > $@ || (rm -f $@; exit 1)
+
+handler-fixvideo_mod-commands_efi_fixvideo.lst: commands/efi/fixvideo.c $(commands/efi/fixvideo.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh fixvideo > $@ || (rm -f $@; exit 1)
+
+fixvideo_mod_CFLAGS = $(COMMON_CFLAGS)
+fixvideo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += xnu.mod
+xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\
+	 loader/macho.c loader/xnu.c loader/i386/xnu_helper.S
+
+clean-module-xnu.mod.1:
+	rm -f xnu.mod mod-xnu.o mod-xnu.c pre-xnu.o xnu_mod-loader_xnu_resume.o xnu_mod-loader_i386_xnu.o xnu_mod-loader_i386_efi_xnu.o xnu_mod-loader_macho.o xnu_mod-loader_xnu.o xnu_mod-loader_i386_xnu_helper.o und-xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu.mod.1
+
+ifneq ($(xnu_mod_EXPORTS),no)
+clean-module-xnu.mod-symbol.1:
+	rm -f def-xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu.mod-symbol.1
+DEFSYMFILES += def-xnu.lst
+endif
+mostlyclean-module-xnu.mod.1:
+	rm -f xnu_mod-loader_xnu_resume.d xnu_mod-loader_i386_xnu.d xnu_mod-loader_i386_efi_xnu.d xnu_mod-loader_macho.d xnu_mod-loader_xnu.d xnu_mod-loader_i386_xnu_helper.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-xnu.mod.1
+UNDSYMFILES += und-xnu.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+xnu.mod: pre-xnu.o mod-xnu.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(xnu_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-xnu.o mod-xnu.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+xnu.mod: pre-xnu.o mod-xnu.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(xnu_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-xnu.o mod-xnu.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-xnu.o: $(xnu_mod_DEPENDENCIES) xnu_mod-loader_xnu_resume.o xnu_mod-loader_i386_xnu.o xnu_mod-loader_i386_efi_xnu.o xnu_mod-loader_macho.o xnu_mod-loader_xnu.o xnu_mod-loader_i386_xnu_helper.o
+	-rm -f $@
+	$(TARGET_CC) $(xnu_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ xnu_mod-loader_xnu_resume.o xnu_mod-loader_i386_xnu.o xnu_mod-loader_i386_efi_xnu.o xnu_mod-loader_macho.o xnu_mod-loader_xnu.o xnu_mod-loader_i386_xnu_helper.o
+
+mod-xnu.o: mod-xnu.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -c -o $@ $<
+
+mod-xnu.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'xnu' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(xnu_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-xnu.lst: pre-xnu.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 xnu/' > $@
+else
+def-xnu.lst: pre-xnu.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 xnu/' > $@
+endif
+endif
+
+und-xnu.lst: pre-xnu.o
+	echo 'xnu' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+xnu_mod-loader_xnu_resume.o: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_xnu_resume.d
+
+clean-module-xnu_mod-loader_xnu_resume-extra.1:
+	rm -f cmd-xnu_mod-loader_xnu_resume.lst fs-xnu_mod-loader_xnu_resume.lst partmap-xnu_mod-loader_xnu_resume.lst handler-xnu_mod-loader_xnu_resume.lst parttool-xnu_mod-loader_xnu_resume.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_xnu_resume-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_xnu_resume.lst
+FSFILES += fs-xnu_mod-loader_xnu_resume.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_xnu_resume.lst
+PARTMAPFILES += partmap-xnu_mod-loader_xnu_resume.lst
+HANDLERFILES += handler-xnu_mod-loader_xnu_resume.lst
+
+cmd-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_i386_xnu.o: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_i386_xnu.d
+
+clean-module-xnu_mod-loader_i386_xnu-extra.1:
+	rm -f cmd-xnu_mod-loader_i386_xnu.lst fs-xnu_mod-loader_i386_xnu.lst partmap-xnu_mod-loader_i386_xnu.lst handler-xnu_mod-loader_i386_xnu.lst parttool-xnu_mod-loader_i386_xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_i386_xnu-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_i386_xnu.lst
+FSFILES += fs-xnu_mod-loader_i386_xnu.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_i386_xnu.lst
+PARTMAPFILES += partmap-xnu_mod-loader_i386_xnu.lst
+HANDLERFILES += handler-xnu_mod-loader_i386_xnu.lst
+
+cmd-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_i386_efi_xnu.o: loader/i386/efi/xnu.c $(loader/i386/efi/xnu.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_i386_efi_xnu.d
+
+clean-module-xnu_mod-loader_i386_efi_xnu-extra.1:
+	rm -f cmd-xnu_mod-loader_i386_efi_xnu.lst fs-xnu_mod-loader_i386_efi_xnu.lst partmap-xnu_mod-loader_i386_efi_xnu.lst handler-xnu_mod-loader_i386_efi_xnu.lst parttool-xnu_mod-loader_i386_efi_xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_i386_efi_xnu-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_i386_efi_xnu.lst
+FSFILES += fs-xnu_mod-loader_i386_efi_xnu.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_i386_efi_xnu.lst
+PARTMAPFILES += partmap-xnu_mod-loader_i386_efi_xnu.lst
+HANDLERFILES += handler-xnu_mod-loader_i386_efi_xnu.lst
+
+cmd-xnu_mod-loader_i386_efi_xnu.lst: loader/i386/efi/xnu.c $(loader/i386/efi/xnu.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_i386_efi_xnu.lst: loader/i386/efi/xnu.c $(loader/i386/efi/xnu.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_i386_efi_xnu.lst: loader/i386/efi/xnu.c $(loader/i386/efi/xnu.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_i386_efi_xnu.lst: loader/i386/efi/xnu.c $(loader/i386/efi/xnu.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_i386_efi_xnu.lst: loader/i386/efi/xnu.c $(loader/i386/efi/xnu.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_macho.o: loader/macho.c $(loader/macho.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_macho.d
+
+clean-module-xnu_mod-loader_macho-extra.1:
+	rm -f cmd-xnu_mod-loader_macho.lst fs-xnu_mod-loader_macho.lst partmap-xnu_mod-loader_macho.lst handler-xnu_mod-loader_macho.lst parttool-xnu_mod-loader_macho.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_macho-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_macho.lst
+FSFILES += fs-xnu_mod-loader_macho.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_macho.lst
+PARTMAPFILES += partmap-xnu_mod-loader_macho.lst
+HANDLERFILES += handler-xnu_mod-loader_macho.lst
+
+cmd-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_xnu.o: loader/xnu.c $(loader/xnu.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_xnu.d
+
+clean-module-xnu_mod-loader_xnu-extra.1:
+	rm -f cmd-xnu_mod-loader_xnu.lst fs-xnu_mod-loader_xnu.lst partmap-xnu_mod-loader_xnu.lst handler-xnu_mod-loader_xnu.lst parttool-xnu_mod-loader_xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_xnu-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_xnu.lst
+FSFILES += fs-xnu_mod-loader_xnu.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_xnu.lst
+PARTMAPFILES += partmap-xnu_mod-loader_xnu.lst
+HANDLERFILES += handler-xnu_mod-loader_xnu.lst
+
+cmd-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_i386_xnu_helper.o: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_i386_xnu_helper.d
+
+clean-module-xnu_mod-loader_i386_xnu_helper-extra.1:
+	rm -f cmd-xnu_mod-loader_i386_xnu_helper.lst fs-xnu_mod-loader_i386_xnu_helper.lst partmap-xnu_mod-loader_i386_xnu_helper.lst handler-xnu_mod-loader_i386_xnu_helper.lst parttool-xnu_mod-loader_i386_xnu_helper.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_i386_xnu_helper-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_i386_xnu_helper.lst
+FSFILES += fs-xnu_mod-loader_i386_xnu_helper.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_i386_xnu_helper.lst
+PARTMAPFILES += partmap-xnu_mod-loader_i386_xnu_helper.lst
+HANDLERFILES += handler-xnu_mod-loader_i386_xnu_helper.lst
+
+cmd-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod_CFLAGS = $(COMMON_CFLAGS)
+xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
+grub-mkimage: $(grub_mkimage_DEPENDENCIES) $(grub_mkimage_OBJECTS)
+	$(CC) -o $@ $(grub_mkimage_OBJECTS) $(LDFLAGS) $(grub_mkimage_LDFLAGS)
+
+grub-mkdevicemap: $(grub_mkdevicemap_DEPENDENCIES) $(grub_mkdevicemap_OBJECTS)
+	$(CC) -o $@ $(grub_mkdevicemap_OBJECTS) $(LDFLAGS) $(grub_mkdevicemap_LDFLAGS)
+
diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk
new file mode 100644
index 0000000..99ab06f
--- /dev/null
+++ b/conf/i386-efi.rmk
@@ -0,0 +1,207 @@
+# -*- makefile -*-
+
+COMMON_ASFLAGS = -nostdinc -fno-builtin -m32
+COMMON_CFLAGS = -fno-builtin -m32
+COMMON_LDFLAGS = -melf_i386 -nostdlib
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Utilities.
+bin_UTILITIES = grub-mkimage
+sbin_UTILITIES = grub-mkdevicemap
+#ifeq ($(enable_grub_emu), yes)
+#sbin_UTILITIES += grub-emu
+#endif
+
+# For grub-mkimage.
+grub_mkimage_SOURCES = util/i386/efi/grub-mkimage.c util/misc.c \
+	util/resolve.c
+util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile
+
+# For grub-setup.
+#grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c	\
+#	util/misc.c util/getroot.c kern/device.c kern/disk.c	\
+#	kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c	\
+#	fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c		\
+#	fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c	\
+#	kern/fs.c kern/env.c fs/fshelp.c
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/devicemap.c util/misc.c
+
+# For grub-emu.
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c 	\
+	commands/configfile.c commands/help.c				\
+	commands/handler.c commands/ls.c commands/test.c 		\
+	commands/search.c commands/hexdump.c lib/hexdump.c		\
+	commands/halt.c commands/reboot.c commands/keystatus.c		\
+	commands/i386/cpuid.c						\
+	commands/password.c						\
+	lib/envblk.c commands/loadenv.c					\
+	disk/loopback.c							\
+	\
+	fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c		\
+	fs/befs.c fs/befs_be.c fs/tar.c				\
+	\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/list.c kern/handler.c				\
+	kern/command.c kern/corecmd.c commands/extcmd.c kern/file.c	\
+	kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c	\
+	kern/partition.c kern/reader.c kern/term.c			\
+	kern/rescue_reader.c kern/rescue_parser.c                       \
+	lib/arg.c normal/cmdline.c normal/command.c normal/datetime.c 	\
+	normal/auth.c normal/autofs.c					\
+	normal/completion.c normal/context.c normal/main.c		\
+	normal/menu.c normal/menu_entry.c normal/menu_viewer.c		\
+	normal/menu_text.c						\
+	normal/color.c							\
+	script/sh/main.c script/sh/execute.c script/sh/function.c       \
+	script/sh/lexer.c script/sh/script.c grub_script.tab.c          \
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c partmap/gpt.c					\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	commands/parttool.c parttool/msdospart.c				\
+	grub_emu_init.c
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/i386/efi/grub-install.in
+
+# Modules.
+pkglib_MODULES = kernel.mod chain.mod appleldr.mod \
+	linux.mod halt.mod reboot.mod pci.mod lspci.mod \
+	datetime.mod date.mod datehook.mod loadbios.mod \
+	fixvideo.mod mmap.mod acpi.mod
+
+# For kernel.mod.
+kernel_mod_EXPORTS = no
+kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
+	kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
+	term/efi/console.c disk/efi/efidisk.c \
+	kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+	kern/i386/tsc.c kern/i386/pit.c \
+	kern/generic/rtc_get_time_ms.c \
+	kern/generic/millisleep.c
+kernel_mod_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h
+kernel_mod_CFLAGS = $(COMMON_CFLAGS)
+kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+MOSTLYCLEANFILES += symlist.c
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For acpi.mod.
+acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c
+acpi_mod_CFLAGS = $(COMMON_CFLAGS)
+acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
+		   mmap/efi/mmap.c
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For chain.mod.
+chain_mod_SOURCES = loader/efi/chainloader.c
+chain_mod_CFLAGS = $(COMMON_CFLAGS)
+chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For appleldr.mod.
+appleldr_mod_SOURCES = loader/efi/appleloader.c
+appleldr_mod_CFLAGS = $(COMMON_CFLAGS)
+appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/i386/efi/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod.
+reboot_mod_SOURCES = commands/reboot.c
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pci.mod
+pci_mod_SOURCES = bus/pci.c
+pci_mod_CFLAGS = $(COMMON_CFLAGS)
+pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lspci.mod
+lspci_mod_SOURCES = commands/lspci.c
+lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/efi/datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For date.mod
+date_mod_SOURCES = commands/date.c
+date_mod_CFLAGS = $(COMMON_CFLAGS)
+date_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datehook.mod
+datehook_mod_SOURCES = hook/datehook.c
+datehook_mod_CFLAGS = $(COMMON_CFLAGS)
+datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For loadbios.mod
+loadbios_mod_SOURCES = commands/efi/loadbios.c
+loadbios_mod_CFLAGS = $(COMMON_CFLAGS)
+loadbios_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For fixvideo.mod
+fixvideo_mod_SOURCES = commands/efi/fixvideo.c
+fixvideo_mod_CFLAGS = $(COMMON_CFLAGS)
+fixvideo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += xnu.mod
+xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\
+	 loader/macho.c loader/xnu.c loader/i386/xnu_helper.S
+xnu_mod_CFLAGS = $(COMMON_CFLAGS)
+xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
diff --git a/conf/i386-ieee1275.mk b/conf/i386-ieee1275.mk
new file mode 100644
index 0000000..f4dee6b
--- /dev/null
+++ b/conf/i386-ieee1275.mk
@@ -0,0 +1,2492 @@
+# -*- makefile -*-
+# Generated by genmk.rb, please don't edit!
+
+COMMON_ASFLAGS	= -m32 -nostdinc -fno-builtin
+COMMON_CFLAGS	= -ffreestanding -mrtd -mregparm=3
+COMMON_LDFLAGS	= -nostdlib
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Images.
+pkglib_PROGRAMS = kernel.img
+
+# For kernel.img.
+kernel_img_SOURCES = kern/i386/ieee1275/startup.S \
+	kern/i386/misc.S \
+	kern/i386/ieee1275/init.c \
+	kern/ieee1275/init.c \
+	kern/ieee1275/mmap.c \
+	kern/ieee1275/cmain.c kern/ieee1275/openfw.c \
+	kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
+	kern/env.c \
+	kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+	kern/generic/millisleep.c \
+	kern/ieee1275/ieee1275.c \
+	term/ieee1275/ofconsole.c \
+	disk/ieee1275/ofdisk.c \
+	symlist.c
+CLEANFILES += kernel.img kernel_img-kern_i386_ieee1275_startup.o kernel_img-kern_i386_misc.o kernel_img-kern_i386_ieee1275_init.o kernel_img-kern_ieee1275_init.o kernel_img-kern_ieee1275_mmap.o kernel_img-kern_ieee1275_cmain.o kernel_img-kern_ieee1275_openfw.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_env.o kernel_img-kern_time.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern_generic_millisleep.o kernel_img-kern_ieee1275_ieee1275.o kernel_img-term_ieee1275_ofconsole.o kernel_img-disk_ieee1275_ofdisk.o kernel_img-symlist.o
+MOSTLYCLEANFILES += kernel_img-kern_i386_ieee1275_startup.d kernel_img-kern_i386_misc.d kernel_img-kern_i386_ieee1275_init.d kernel_img-kern_ieee1275_init.d kernel_img-kern_ieee1275_mmap.d kernel_img-kern_ieee1275_cmain.d kernel_img-kern_ieee1275_openfw.d kernel_img-kern_main.d kernel_img-kern_device.d kernel_img-kern_disk.d kernel_img-kern_dl.d kernel_img-kern_file.d kernel_img-kern_fs.d kernel_img-kern_err.d kernel_img-kern_misc.d kernel_img-kern_mm.d kernel_img-kern_reader.d kernel_img-kern_term.d kernel_img-kern_rescue_parser.d kernel_img-kern_rescue_reader.d kernel_img-kern___target_cpu__dl.d kernel_img-kern_parser.d kernel_img-kern_partition.d kernel_img-kern_env.d kernel_img-kern_time.d kernel_img-kern_list.d kernel_img-kern_handler.d kernel_img-kern_command.d kernel_img-kern_corecmd.d kernel_img-kern_generic_millisleep.d kernel_img-kern_ieee1275_ieee1275.d kernel_img-term_ieee1275_ofconsole.d kernel_img-disk_ieee1275_ofdisk.d kernel_img-symlist.d
+
+kernel.img: $(kernel_img_DEPENDENCIES) kernel_img-kern_i386_ieee1275_startup.o kernel_img-kern_i386_misc.o kernel_img-kern_i386_ieee1275_init.o kernel_img-kern_ieee1275_init.o kernel_img-kern_ieee1275_mmap.o kernel_img-kern_ieee1275_cmain.o kernel_img-kern_ieee1275_openfw.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_env.o kernel_img-kern_time.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern_generic_millisleep.o kernel_img-kern_ieee1275_ieee1275.o kernel_img-term_ieee1275_ofconsole.o kernel_img-disk_ieee1275_ofdisk.o kernel_img-symlist.o
+	$(TARGET_CC) -o $@ kernel_img-kern_i386_ieee1275_startup.o kernel_img-kern_i386_misc.o kernel_img-kern_i386_ieee1275_init.o kernel_img-kern_ieee1275_init.o kernel_img-kern_ieee1275_mmap.o kernel_img-kern_ieee1275_cmain.o kernel_img-kern_ieee1275_openfw.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_env.o kernel_img-kern_time.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern_generic_millisleep.o kernel_img-kern_ieee1275_ieee1275.o kernel_img-term_ieee1275_ofconsole.o kernel_img-disk_ieee1275_ofdisk.o kernel_img-symlist.o $(TARGET_LDFLAGS) $(kernel_img_LDFLAGS)
+
+kernel_img-kern_i386_ieee1275_startup.o: kern/i386/ieee1275/startup.S $(kern/i386/ieee1275/startup.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/ieee1275 -I$(srcdir)/kern/i386/ieee1275 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_ieee1275_startup.d
+
+kernel_img-kern_i386_misc.o: kern/i386/misc.S $(kern/i386/misc.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_misc.d
+
+kernel_img-kern_i386_ieee1275_init.o: kern/i386/ieee1275/init.c $(kern/i386/ieee1275/init.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/ieee1275 -I$(srcdir)/kern/i386/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_ieee1275_init.d
+
+kernel_img-kern_ieee1275_init.o: kern/ieee1275/init.c $(kern/ieee1275/init.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_init.d
+
+kernel_img-kern_ieee1275_mmap.o: kern/ieee1275/mmap.c $(kern/ieee1275/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_mmap.d
+
+kernel_img-kern_ieee1275_cmain.o: kern/ieee1275/cmain.c $(kern/ieee1275/cmain.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_cmain.d
+
+kernel_img-kern_ieee1275_openfw.o: kern/ieee1275/openfw.c $(kern/ieee1275/openfw.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_openfw.d
+
+kernel_img-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_main.d
+
+kernel_img-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_device.d
+
+kernel_img-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_disk.d
+
+kernel_img-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_dl.d
+
+kernel_img-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_file.d
+
+kernel_img-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_fs.d
+
+kernel_img-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_err.d
+
+kernel_img-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_misc.d
+
+kernel_img-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_mm.d
+
+kernel_img-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_reader.d
+
+kernel_img-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_term.d
+
+kernel_img-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_rescue_parser.d
+
+kernel_img-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_rescue_reader.d
+
+kernel_img-kern___target_cpu__dl.o: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern___target_cpu__dl.d
+
+kernel_img-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_parser.d
+
+kernel_img-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_partition.d
+
+kernel_img-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_env.d
+
+kernel_img-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_time.d
+
+kernel_img-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_list.d
+
+kernel_img-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_handler.d
+
+kernel_img-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_command.d
+
+kernel_img-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_corecmd.d
+
+kernel_img-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_generic_millisleep.d
+
+kernel_img-kern_ieee1275_ieee1275.o: kern/ieee1275/ieee1275.c $(kern/ieee1275/ieee1275.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_ieee1275.d
+
+kernel_img-term_ieee1275_ofconsole.o: term/ieee1275/ofconsole.c $(term/ieee1275/ofconsole.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/ieee1275 -I$(srcdir)/term/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-term_ieee1275_ofconsole.d
+
+kernel_img-disk_ieee1275_ofdisk.o: disk/ieee1275/ofdisk.c $(disk/ieee1275/ofdisk.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-disk_ieee1275_ofdisk.d
+
+kernel_img-symlist.o: symlist.c $(symlist.c_DEPENDENCIES)
+	$(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-symlist.d
+
+kernel_img_HEADERS = cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \
+	list.h handler.h command.h
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
+
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# Utilities.
+sbin_UTILITIES = grub-mkdevicemap
+ifeq ($(enable_grub_emu), yes)
+sbin_UTILITIES += grub-emu
+endif
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/devicemap.c util/misc.c
+
+clean-utility-grub-mkdevicemap.1:
+	rm -f grub-mkdevicemap$(EXEEXT) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_devicemap.o grub_mkdevicemap-util_misc.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkdevicemap.1
+
+mostlyclean-utility-grub-mkdevicemap.1:
+	rm -f grub_mkdevicemap-util_grub_mkdevicemap.d grub_mkdevicemap-util_deviceiter.d grub_mkdevicemap-util_devicemap.d grub_mkdevicemap-util_misc.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkdevicemap.1
+
+grub_mkdevicemap_OBJECTS += grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_devicemap.o grub_mkdevicemap-util_misc.o
+
+grub_mkdevicemap-util_grub_mkdevicemap.o: util/grub-mkdevicemap.c $(util/grub-mkdevicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_grub_mkdevicemap.d
+
+grub_mkdevicemap-util_deviceiter.o: util/deviceiter.c $(util/deviceiter.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_deviceiter.d
+
+grub_mkdevicemap-util_devicemap.o: util/devicemap.c $(util/devicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_devicemap.d
+
+grub_mkdevicemap-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_misc.d
+
+
+# For grub-emu.
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c	\
+	commands/configfile.c commands/echo.c commands/help.c		\
+	commands/handler.c commands/ls.c commands/test.c 		\
+	commands/search.c commands/blocklist.c commands/hexdump.c	\
+	lib/hexdump.c commands/halt.c commands/reboot.c			\
+	lib/envblk.c commands/loadenv.c					\
+	commands/gptsync.c commands/probe.c  commands/xnu_uuid.c	\
+	commands/i386/cpuid.c	\
+	commands/password.c commands/keystatus.c			\
+	disk/host.c disk/loopback.c					\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c	\
+	fs/befs_be.c fs/tar.c				\
+	\
+	fs/fshelp.c							\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/list.c kern/handler.c				\
+	kern/command.c kern/corecmd.c commands/extcmd.c	kern/file.c 	\
+	kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c	\
+	kern/partition.c kern/reader.c kern/term.c			\
+	kern/rescue_reader.c kern/rescue_parser.c 			\
+	lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.c	\
+	normal/handler.c normal/auth.c normal/autofs.c			\
+	normal/completion.c normal/main.c normal/menu_text.c		\
+	normal/menu.c normal/menu_entry.c normal/menu_viewer.c		\
+	normal/color.c							\
+	script/sh/main.c script/sh/execute.c script/sh/function.c	\
+	script/sh/lexer.c script/sh/script.c grub_script.tab.c		\
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c partmap/gpt.c					\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	grub_emu_init.c
+
+clean-utility-grub-emu.1:
+	rm -f grub-emu$(EXEEXT) grub_emu-commands_minicmd.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_handler.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_halt.o grub_emu-commands_reboot.o grub_emu-lib_envblk.o grub_emu-commands_loadenv.o grub_emu-commands_gptsync.o grub_emu-commands_probe.o grub_emu-commands_xnu_uuid.o grub_emu-commands_i386_cpuid.o grub_emu-commands_password.o grub_emu-commands_keystatus.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_ufs2.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_afs_be.o grub_emu-fs_befs.o grub_emu-fs_befs_be.o grub_emu-fs_tar.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_list.o grub_emu-kern_handler.o grub_emu-kern_command.o grub_emu-kern_corecmd.o grub_emu-commands_extcmd.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-commands_boot.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_reader.o grub_emu-kern_term.o grub_emu-kern_rescue_reader.o grub_emu-kern_rescue_parser.o grub_emu-lib_arg.o grub_emu-normal_cmdline.o grub_emu-normal_datetime.o grub_emu-normal_misc.o grub_emu-normal_handler.o grub_emu-normal_auth.o grub_emu-normal_autofs.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu_text.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_color.o grub_emu-script_sh_main.o grub_emu-script_sh_execute.o grub_emu-script_sh_function.o grub_emu-script_sh_lexer.o grub_emu-script_sh_script.o grub_emu-grub_script_tab.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_msdos.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-emu.1
+
+mostlyclean-utility-grub-emu.1:
+	rm -f grub_emu-commands_minicmd.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_echo.d grub_emu-commands_help.d grub_emu-commands_handler.d grub_emu-commands_ls.d grub_emu-commands_test.d grub_emu-commands_search.d grub_emu-commands_blocklist.d grub_emu-commands_hexdump.d grub_emu-lib_hexdump.d grub_emu-commands_halt.d grub_emu-commands_reboot.d grub_emu-lib_envblk.d grub_emu-commands_loadenv.d grub_emu-commands_gptsync.d grub_emu-commands_probe.d grub_emu-commands_xnu_uuid.d grub_emu-commands_i386_cpuid.d grub_emu-commands_password.d grub_emu-commands_keystatus.d grub_emu-disk_host.d grub_emu-disk_loopback.d grub_emu-fs_affs.d grub_emu-fs_cpio.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_hfs.d grub_emu-fs_hfsplus.d grub_emu-fs_iso9660.d grub_emu-fs_udf.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ntfs.d grub_emu-fs_ntfscomp.d grub_emu-fs_reiserfs.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_ufs2.d grub_emu-fs_xfs.d grub_emu-fs_afs.d grub_emu-fs_afs_be.d grub_emu-fs_befs.d grub_emu-fs_befs_be.d grub_emu-fs_tar.d grub_emu-fs_fshelp.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_elf.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-kern_list.d grub_emu-kern_handler.d grub_emu-kern_command.d grub_emu-kern_corecmd.d grub_emu-commands_extcmd.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-commands_boot.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-kern_partition.d grub_emu-kern_reader.d grub_emu-kern_term.d grub_emu-kern_rescue_reader.d grub_emu-kern_rescue_parser.d grub_emu-lib_arg.d grub_emu-normal_cmdline.d grub_emu-normal_datetime.d grub_emu-normal_misc.d grub_emu-normal_handler.d grub_emu-normal_auth.d grub_emu-normal_autofs.d grub_emu-normal_completion.d grub_emu-normal_main.d grub_emu-normal_menu_text.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d grub_emu-normal_menu_viewer.d grub_emu-normal_color.d grub_emu-script_sh_main.d grub_emu-script_sh_execute.d grub_emu-script_sh_function.d grub_emu-script_sh_lexer.d grub_emu-script_sh_script.d grub_emu-grub_script_tab.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_msdos.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-partmap_gpt.d grub_emu-util_console.d grub_emu-util_hostfs.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_hostdisk.d grub_emu-util_getroot.d grub_emu-disk_raid.d grub_emu-disk_raid5_recover.d grub_emu-disk_raid6_recover.d grub_emu-disk_mdraid_linux.d grub_emu-disk_dmraid_nvidia.d grub_emu-disk_lvm.d grub_emu-grub_emu_init.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-emu.1
+
+grub_emu_OBJECTS += grub_emu-commands_minicmd.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_handler.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_halt.o grub_emu-commands_reboot.o grub_emu-lib_envblk.o grub_emu-commands_loadenv.o grub_emu-commands_gptsync.o grub_emu-commands_probe.o grub_emu-commands_xnu_uuid.o grub_emu-commands_i386_cpuid.o grub_emu-commands_password.o grub_emu-commands_keystatus.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_ufs2.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_afs_be.o grub_emu-fs_befs.o grub_emu-fs_befs_be.o grub_emu-fs_tar.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_list.o grub_emu-kern_handler.o grub_emu-kern_command.o grub_emu-kern_corecmd.o grub_emu-commands_extcmd.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-commands_boot.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_reader.o grub_emu-kern_term.o grub_emu-kern_rescue_reader.o grub_emu-kern_rescue_parser.o grub_emu-lib_arg.o grub_emu-normal_cmdline.o grub_emu-normal_datetime.o grub_emu-normal_misc.o grub_emu-normal_handler.o grub_emu-normal_auth.o grub_emu-normal_autofs.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu_text.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_color.o grub_emu-script_sh_main.o grub_emu-script_sh_execute.o grub_emu-script_sh_function.o grub_emu-script_sh_lexer.o grub_emu-script_sh_script.o grub_emu-grub_script_tab.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_msdos.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o
+
+grub_emu-commands_minicmd.o: commands/minicmd.c $(commands/minicmd.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_minicmd.d
+
+grub_emu-commands_cat.o: commands/cat.c $(commands/cat.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_cat.d
+
+grub_emu-commands_cmp.o: commands/cmp.c $(commands/cmp.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_cmp.d
+
+grub_emu-commands_configfile.o: commands/configfile.c $(commands/configfile.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_configfile.d
+
+grub_emu-commands_echo.o: commands/echo.c $(commands/echo.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_echo.d
+
+grub_emu-commands_help.o: commands/help.c $(commands/help.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_help.d
+
+grub_emu-commands_handler.o: commands/handler.c $(commands/handler.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_handler.d
+
+grub_emu-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_ls.d
+
+grub_emu-commands_test.o: commands/test.c $(commands/test.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_test.d
+
+grub_emu-commands_search.o: commands/search.c $(commands/search.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_search.d
+
+grub_emu-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_blocklist.d
+
+grub_emu-commands_hexdump.o: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_hexdump.d
+
+grub_emu-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_hexdump.d
+
+grub_emu-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_halt.d
+
+grub_emu-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_reboot.d
+
+grub_emu-lib_envblk.o: lib/envblk.c $(lib/envblk.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_envblk.d
+
+grub_emu-commands_loadenv.o: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_loadenv.d
+
+grub_emu-commands_gptsync.o: commands/gptsync.c $(commands/gptsync.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_gptsync.d
+
+grub_emu-commands_probe.o: commands/probe.c $(commands/probe.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_probe.d
+
+grub_emu-commands_xnu_uuid.o: commands/xnu_uuid.c $(commands/xnu_uuid.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_xnu_uuid.d
+
+grub_emu-commands_i386_cpuid.o: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES)
+	$(CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_i386_cpuid.d
+
+grub_emu-commands_password.o: commands/password.c $(commands/password.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_password.d
+
+grub_emu-commands_keystatus.o: commands/keystatus.c $(commands/keystatus.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_keystatus.d
+
+grub_emu-disk_host.o: disk/host.c $(disk/host.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_host.d
+
+grub_emu-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_loopback.d
+
+grub_emu-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_affs.d
+
+grub_emu-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_cpio.d
+
+grub_emu-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_fat.d
+
+grub_emu-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ext2.d
+
+grub_emu-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_hfs.d
+
+grub_emu-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_hfsplus.d
+
+grub_emu-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_iso9660.d
+
+grub_emu-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_udf.d
+
+grub_emu-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_jfs.d
+
+grub_emu-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_minix.d
+
+grub_emu-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ntfs.d
+
+grub_emu-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ntfscomp.d
+
+grub_emu-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_reiserfs.d
+
+grub_emu-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_sfs.d
+
+grub_emu-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ufs.d
+
+grub_emu-fs_ufs2.o: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ufs2.d
+
+grub_emu-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_xfs.d
+
+grub_emu-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_afs.d
+
+grub_emu-fs_afs_be.o: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_afs_be.d
+
+grub_emu-fs_befs.o: fs/befs.c $(fs/befs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_befs.d
+
+grub_emu-fs_befs_be.o: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_befs_be.d
+
+grub_emu-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_tar.d
+
+grub_emu-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_fshelp.d
+
+grub_emu-io_gzio.o: io/gzio.c $(io/gzio.c_DEPENDENCIES)
+	$(CC) -Iio -I$(srcdir)/io $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-io_gzio.d
+
+grub_emu-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_device.d
+
+grub_emu-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_disk.d
+
+grub_emu-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_dl.d
+
+grub_emu-kern_elf.o: kern/elf.c $(kern/elf.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_elf.d
+
+grub_emu-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_env.d
+
+grub_emu-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_err.d
+
+grub_emu-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_list.d
+
+grub_emu-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_handler.d
+
+grub_emu-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_command.d
+
+grub_emu-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_corecmd.d
+
+grub_emu-commands_extcmd.o: commands/extcmd.c $(commands/extcmd.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_extcmd.d
+
+grub_emu-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_file.d
+
+grub_emu-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_fs.d
+
+grub_emu-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_boot.d
+
+grub_emu-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_main.d
+
+grub_emu-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_misc.d
+
+grub_emu-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_parser.d
+
+grub_emu-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_partition.d
+
+grub_emu-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_reader.d
+
+grub_emu-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_term.d
+
+grub_emu-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_rescue_reader.d
+
+grub_emu-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_rescue_parser.d
+
+grub_emu-lib_arg.o: lib/arg.c $(lib/arg.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_arg.d
+
+grub_emu-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_cmdline.d
+
+grub_emu-normal_datetime.o: normal/datetime.c $(normal/datetime.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_datetime.d
+
+grub_emu-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_misc.d
+
+grub_emu-normal_handler.o: normal/handler.c $(normal/handler.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_handler.d
+
+grub_emu-normal_auth.o: normal/auth.c $(normal/auth.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_auth.d
+
+grub_emu-normal_autofs.o: normal/autofs.c $(normal/autofs.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_autofs.d
+
+grub_emu-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_completion.d
+
+grub_emu-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_main.d
+
+grub_emu-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_text.d
+
+grub_emu-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu.d
+
+grub_emu-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_entry.d
+
+grub_emu-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_viewer.d
+
+grub_emu-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_color.d
+
+grub_emu-script_sh_main.o: script/sh/main.c $(script/sh/main.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_main.d
+
+grub_emu-script_sh_execute.o: script/sh/execute.c $(script/sh/execute.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_execute.d
+
+grub_emu-script_sh_function.o: script/sh/function.c $(script/sh/function.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_function.d
+
+grub_emu-script_sh_lexer.o: script/sh/lexer.c $(script/sh/lexer.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_lexer.d
+
+grub_emu-script_sh_script.o: script/sh/script.c $(script/sh/script.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_script.d
+
+grub_emu-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-grub_script_tab.d
+
+grub_emu-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_amiga.d
+
+grub_emu-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_apple.d
+
+grub_emu-partmap_msdos.o: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_msdos.d
+
+grub_emu-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_sun.d
+
+grub_emu-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_acorn.d
+
+grub_emu-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_gpt.d
+
+grub_emu-util_console.o: util/console.c $(util/console.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_console.d
+
+grub_emu-util_hostfs.o: util/hostfs.c $(util/hostfs.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_hostfs.d
+
+grub_emu-util_grub_emu.o: util/grub-emu.c $(util/grub-emu.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_grub_emu.d
+
+grub_emu-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_misc.d
+
+grub_emu-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_hostdisk.d
+
+grub_emu-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_getroot.d
+
+grub_emu-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid.d
+
+grub_emu-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid5_recover.d
+
+grub_emu-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid6_recover.d
+
+grub_emu-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_mdraid_linux.d
+
+grub_emu-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_dmraid_nvidia.d
+
+grub_emu-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_lvm.d
+
+grub_emu-grub_emu_init.o: grub_emu_init.c $(grub_emu_init.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-grub_emu_init.d
+
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/ieee1275/grub-install.in
+CLEANFILES += grub-install
+
+grub-install: util/ieee1275/grub-install.in $(util/ieee1275/grub-install.in_DEPENDENCIES) config.status
+	./config.status --file=grub-install:util/ieee1275/grub-install.in
+	chmod +x $@
+
+
+# Modules.
+pkglib_MODULES = halt.mod reboot.mod suspend.mod		\
+	multiboot.mod aout.mod serial.mod linux.mod		\
+	nand.mod memdisk.mod pci.mod lspci.mod datetime.mod	\
+	date.mod datehook.mod lsmmap.mod mmap.mod
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c
+
+clean-module-boot.mod.1:
+	rm -f boot.mod mod-boot.o mod-boot.c pre-boot.o boot_mod-commands_boot.o und-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod.1
+
+ifneq ($(boot_mod_EXPORTS),no)
+clean-module-boot.mod-symbol.1:
+	rm -f def-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod-symbol.1
+DEFSYMFILES += def-boot.lst
+endif
+mostlyclean-module-boot.mod.1:
+	rm -f boot_mod-commands_boot.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-boot.mod.1
+UNDSYMFILES += und-boot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-boot.o mod-boot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-boot.o mod-boot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-boot.o: $(boot_mod_DEPENDENCIES) boot_mod-commands_boot.o
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ boot_mod-commands_boot.o
+
+mod-boot.o: mod-boot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -c -o $@ $<
+
+mod-boot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'boot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(boot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-boot.lst: pre-boot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+else
+def-boot.lst: pre-boot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+endif
+endif
+
+und-boot.lst: pre-boot.o
+	echo 'boot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+boot_mod-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $<
+-include boot_mod-commands_boot.d
+
+clean-module-boot_mod-commands_boot-extra.1:
+	rm -f cmd-boot_mod-commands_boot.lst fs-boot_mod-commands_boot.lst partmap-boot_mod-commands_boot.lst handler-boot_mod-commands_boot.lst parttool-boot_mod-commands_boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot_mod-commands_boot-extra.1
+
+COMMANDFILES += cmd-boot_mod-commands_boot.lst
+FSFILES += fs-boot_mod-commands_boot.lst
+PARTTOOLFILES += parttool-boot_mod-commands_boot.lst
+PARTMAPFILES += partmap-boot_mod-commands_boot.lst
+HANDLERFILES += handler-boot_mod-commands_boot.lst
+
+cmd-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1)
+
+fs-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1)
+
+parttool-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh boot > $@ || (rm -f $@; exit 1)
+
+partmap-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1)
+
+handler-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh boot > $@ || (rm -f $@; exit 1)
+
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
+
+clean-module-mmap.mod.1:
+	rm -f mmap.mod mod-mmap.o mod-mmap.c pre-mmap.o mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o und-mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap.mod.1
+
+ifneq ($(mmap_mod_EXPORTS),no)
+clean-module-mmap.mod-symbol.1:
+	rm -f def-mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap.mod-symbol.1
+DEFSYMFILES += def-mmap.lst
+endif
+mostlyclean-module-mmap.mod.1:
+	rm -f mmap_mod-mmap_mmap.d mmap_mod-mmap_i386_uppermem.d mmap_mod-mmap_i386_mmap.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-mmap.mod.1
+UNDSYMFILES += und-mmap.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+mmap.mod: pre-mmap.o mod-mmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-mmap.o mod-mmap.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+mmap.mod: pre-mmap.o mod-mmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-mmap.o mod-mmap.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-mmap.o: $(mmap_mod_DEPENDENCIES) mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o
+	-rm -f $@
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o
+
+mod-mmap.o: mod-mmap.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -c -o $@ $<
+
+mod-mmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'mmap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(mmap_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-mmap.lst: pre-mmap.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 mmap/' > $@
+else
+def-mmap.lst: pre-mmap.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 mmap/' > $@
+endif
+endif
+
+und-mmap.lst: pre-mmap.o
+	echo 'mmap' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+mmap_mod-mmap_mmap.o: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_mmap.d
+
+clean-module-mmap_mod-mmap_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_mmap.lst fs-mmap_mod-mmap_mmap.lst partmap-mmap_mod-mmap_mmap.lst handler-mmap_mod-mmap_mmap.lst parttool-mmap_mod-mmap_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_mmap.lst
+FSFILES += fs-mmap_mod-mmap_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_mmap.lst
+
+cmd-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_i386_uppermem.o: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_i386_uppermem.d
+
+clean-module-mmap_mod-mmap_i386_uppermem-extra.1:
+	rm -f cmd-mmap_mod-mmap_i386_uppermem.lst fs-mmap_mod-mmap_i386_uppermem.lst partmap-mmap_mod-mmap_i386_uppermem.lst handler-mmap_mod-mmap_i386_uppermem.lst parttool-mmap_mod-mmap_i386_uppermem.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_i386_uppermem-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_i386_uppermem.lst
+FSFILES += fs-mmap_mod-mmap_i386_uppermem.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_i386_uppermem.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_i386_uppermem.lst
+HANDLERFILES += handler-mmap_mod-mmap_i386_uppermem.lst
+
+cmd-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_i386_mmap.o: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_i386_mmap.d
+
+clean-module-mmap_mod-mmap_i386_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_i386_mmap.lst fs-mmap_mod-mmap_i386_mmap.lst partmap-mmap_mod-mmap_i386_mmap.lst handler-mmap_mod-mmap_i386_mmap.lst parttool-mmap_mod-mmap_i386_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_i386_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_i386_mmap.lst
+FSFILES += fs-mmap_mod-mmap_i386_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_i386_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_i386_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_i386_mmap.lst
+
+cmd-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For multiboot.mod.
+multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \
+			loader/i386/multiboot_helper.S \
+			 loader/multiboot2.c \
+			 loader/multiboot_loader.c
+
+clean-module-multiboot.mod.1:
+	rm -f multiboot.mod mod-multiboot.o mod-multiboot.c pre-multiboot.o multiboot_mod-loader_ieee1275_multiboot2.o multiboot_mod-loader_i386_multiboot_helper.o multiboot_mod-loader_multiboot2.o multiboot_mod-loader_multiboot_loader.o und-multiboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot.mod.1
+
+ifneq ($(multiboot_mod_EXPORTS),no)
+clean-module-multiboot.mod-symbol.1:
+	rm -f def-multiboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot.mod-symbol.1
+DEFSYMFILES += def-multiboot.lst
+endif
+mostlyclean-module-multiboot.mod.1:
+	rm -f multiboot_mod-loader_ieee1275_multiboot2.d multiboot_mod-loader_i386_multiboot_helper.d multiboot_mod-loader_multiboot2.d multiboot_mod-loader_multiboot_loader.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-multiboot.mod.1
+UNDSYMFILES += und-multiboot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+multiboot.mod: pre-multiboot.o mod-multiboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-multiboot.o mod-multiboot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+multiboot.mod: pre-multiboot.o mod-multiboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-multiboot.o mod-multiboot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-multiboot.o: $(multiboot_mod_DEPENDENCIES) multiboot_mod-loader_ieee1275_multiboot2.o multiboot_mod-loader_i386_multiboot_helper.o multiboot_mod-loader_multiboot2.o multiboot_mod-loader_multiboot_loader.o
+	-rm -f $@
+	$(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ multiboot_mod-loader_ieee1275_multiboot2.o multiboot_mod-loader_i386_multiboot_helper.o multiboot_mod-loader_multiboot2.o multiboot_mod-loader_multiboot_loader.o
+
+mod-multiboot.o: mod-multiboot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -c -o $@ $<
+
+mod-multiboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'multiboot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(multiboot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-multiboot.lst: pre-multiboot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@
+else
+def-multiboot.lst: pre-multiboot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@
+endif
+endif
+
+und-multiboot.lst: pre-multiboot.o
+	echo 'multiboot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+multiboot_mod-loader_ieee1275_multiboot2.o: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_ieee1275_multiboot2.d
+
+clean-module-multiboot_mod-loader_ieee1275_multiboot2-extra.1:
+	rm -f cmd-multiboot_mod-loader_ieee1275_multiboot2.lst fs-multiboot_mod-loader_ieee1275_multiboot2.lst partmap-multiboot_mod-loader_ieee1275_multiboot2.lst handler-multiboot_mod-loader_ieee1275_multiboot2.lst parttool-multiboot_mod-loader_ieee1275_multiboot2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_ieee1275_multiboot2-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_ieee1275_multiboot2.lst
+FSFILES += fs-multiboot_mod-loader_ieee1275_multiboot2.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_ieee1275_multiboot2.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_ieee1275_multiboot2.lst
+HANDLERFILES += handler-multiboot_mod-loader_ieee1275_multiboot2.lst
+
+cmd-multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_i386_multiboot_helper.o: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_i386_multiboot_helper.d
+
+clean-module-multiboot_mod-loader_i386_multiboot_helper-extra.1:
+	rm -f cmd-multiboot_mod-loader_i386_multiboot_helper.lst fs-multiboot_mod-loader_i386_multiboot_helper.lst partmap-multiboot_mod-loader_i386_multiboot_helper.lst handler-multiboot_mod-loader_i386_multiboot_helper.lst parttool-multiboot_mod-loader_i386_multiboot_helper.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_i386_multiboot_helper-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_i386_multiboot_helper.lst
+FSFILES += fs-multiboot_mod-loader_i386_multiboot_helper.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_i386_multiboot_helper.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_i386_multiboot_helper.lst
+HANDLERFILES += handler-multiboot_mod-loader_i386_multiboot_helper.lst
+
+cmd-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_multiboot2.o: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_multiboot2.d
+
+clean-module-multiboot_mod-loader_multiboot2-extra.1:
+	rm -f cmd-multiboot_mod-loader_multiboot2.lst fs-multiboot_mod-loader_multiboot2.lst partmap-multiboot_mod-loader_multiboot2.lst handler-multiboot_mod-loader_multiboot2.lst parttool-multiboot_mod-loader_multiboot2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_multiboot2-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_multiboot2.lst
+FSFILES += fs-multiboot_mod-loader_multiboot2.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_multiboot2.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_multiboot2.lst
+HANDLERFILES += handler-multiboot_mod-loader_multiboot2.lst
+
+cmd-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_multiboot_loader.o: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_multiboot_loader.d
+
+clean-module-multiboot_mod-loader_multiboot_loader-extra.1:
+	rm -f cmd-multiboot_mod-loader_multiboot_loader.lst fs-multiboot_mod-loader_multiboot_loader.lst partmap-multiboot_mod-loader_multiboot_loader.lst handler-multiboot_mod-loader_multiboot_loader.lst parttool-multiboot_mod-loader_multiboot_loader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_multiboot_loader-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_multiboot_loader.lst
+FSFILES += fs-multiboot_mod-loader_multiboot_loader.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_multiboot_loader.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_multiboot_loader.lst
+HANDLERFILES += handler-multiboot_mod-loader_multiboot_loader.lst
+
+cmd-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For aout.mod.
+aout_mod_SOURCES = loader/aout.c
+
+clean-module-aout.mod.1:
+	rm -f aout.mod mod-aout.o mod-aout.c pre-aout.o aout_mod-loader_aout.o und-aout.lst
+
+CLEAN_MODULE_TARGETS += clean-module-aout.mod.1
+
+ifneq ($(aout_mod_EXPORTS),no)
+clean-module-aout.mod-symbol.1:
+	rm -f def-aout.lst
+
+CLEAN_MODULE_TARGETS += clean-module-aout.mod-symbol.1
+DEFSYMFILES += def-aout.lst
+endif
+mostlyclean-module-aout.mod.1:
+	rm -f aout_mod-loader_aout.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-aout.mod.1
+UNDSYMFILES += und-aout.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+aout.mod: pre-aout.o mod-aout.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-aout.o mod-aout.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+aout.mod: pre-aout.o mod-aout.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-aout.o mod-aout.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-aout.o: $(aout_mod_DEPENDENCIES) aout_mod-loader_aout.o
+	-rm -f $@
+	$(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ aout_mod-loader_aout.o
+
+mod-aout.o: mod-aout.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -c -o $@ $<
+
+mod-aout.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'aout' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(aout_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-aout.lst: pre-aout.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 aout/' > $@
+else
+def-aout.lst: pre-aout.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 aout/' > $@
+endif
+endif
+
+und-aout.lst: pre-aout.o
+	echo 'aout' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+aout_mod-loader_aout.o: loader/aout.c $(loader/aout.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -MD -c -o $@ $<
+-include aout_mod-loader_aout.d
+
+clean-module-aout_mod-loader_aout-extra.1:
+	rm -f cmd-aout_mod-loader_aout.lst fs-aout_mod-loader_aout.lst partmap-aout_mod-loader_aout.lst handler-aout_mod-loader_aout.lst parttool-aout_mod-loader_aout.lst
+
+CLEAN_MODULE_TARGETS += clean-module-aout_mod-loader_aout-extra.1
+
+COMMANDFILES += cmd-aout_mod-loader_aout.lst
+FSFILES += fs-aout_mod-loader_aout.lst
+PARTTOOLFILES += parttool-aout_mod-loader_aout.lst
+PARTMAPFILES += partmap-aout_mod-loader_aout.lst
+HANDLERFILES += handler-aout_mod-loader_aout.lst
+
+cmd-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh aout > $@ || (rm -f $@; exit 1)
+
+fs-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh aout > $@ || (rm -f $@; exit 1)
+
+parttool-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh aout > $@ || (rm -f $@; exit 1)
+
+partmap-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh aout > $@ || (rm -f $@; exit 1)
+
+handler-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh aout > $@ || (rm -f $@; exit 1)
+
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For suspend.mod
+suspend_mod_SOURCES = commands/ieee1275/suspend.c
+
+clean-module-suspend.mod.1:
+	rm -f suspend.mod mod-suspend.o mod-suspend.c pre-suspend.o suspend_mod-commands_ieee1275_suspend.o und-suspend.lst
+
+CLEAN_MODULE_TARGETS += clean-module-suspend.mod.1
+
+ifneq ($(suspend_mod_EXPORTS),no)
+clean-module-suspend.mod-symbol.1:
+	rm -f def-suspend.lst
+
+CLEAN_MODULE_TARGETS += clean-module-suspend.mod-symbol.1
+DEFSYMFILES += def-suspend.lst
+endif
+mostlyclean-module-suspend.mod.1:
+	rm -f suspend_mod-commands_ieee1275_suspend.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-suspend.mod.1
+UNDSYMFILES += und-suspend.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+suspend.mod: pre-suspend.o mod-suspend.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(suspend_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-suspend.o mod-suspend.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+suspend.mod: pre-suspend.o mod-suspend.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(suspend_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-suspend.o mod-suspend.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-suspend.o: $(suspend_mod_DEPENDENCIES) suspend_mod-commands_ieee1275_suspend.o
+	-rm -f $@
+	$(TARGET_CC) $(suspend_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ suspend_mod-commands_ieee1275_suspend.o
+
+mod-suspend.o: mod-suspend.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -c -o $@ $<
+
+mod-suspend.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'suspend' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(suspend_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-suspend.lst: pre-suspend.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 suspend/' > $@
+else
+def-suspend.lst: pre-suspend.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 suspend/' > $@
+endif
+endif
+
+und-suspend.lst: pre-suspend.o
+	echo 'suspend' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+suspend_mod-commands_ieee1275_suspend.o: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -MD -c -o $@ $<
+-include suspend_mod-commands_ieee1275_suspend.d
+
+clean-module-suspend_mod-commands_ieee1275_suspend-extra.1:
+	rm -f cmd-suspend_mod-commands_ieee1275_suspend.lst fs-suspend_mod-commands_ieee1275_suspend.lst partmap-suspend_mod-commands_ieee1275_suspend.lst handler-suspend_mod-commands_ieee1275_suspend.lst parttool-suspend_mod-commands_ieee1275_suspend.lst
+
+CLEAN_MODULE_TARGETS += clean-module-suspend_mod-commands_ieee1275_suspend-extra.1
+
+COMMANDFILES += cmd-suspend_mod-commands_ieee1275_suspend.lst
+FSFILES += fs-suspend_mod-commands_ieee1275_suspend.lst
+PARTTOOLFILES += parttool-suspend_mod-commands_ieee1275_suspend.lst
+PARTMAPFILES += partmap-suspend_mod-commands_ieee1275_suspend.lst
+HANDLERFILES += handler-suspend_mod-commands_ieee1275_suspend.lst
+
+cmd-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh suspend > $@ || (rm -f $@; exit 1)
+
+fs-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh suspend > $@ || (rm -f $@; exit 1)
+
+parttool-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh suspend > $@ || (rm -f $@; exit 1)
+
+partmap-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh suspend > $@ || (rm -f $@; exit 1)
+
+handler-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh suspend > $@ || (rm -f $@; exit 1)
+
+suspend_mod_CFLAGS = $(COMMON_CFLAGS)
+suspend_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod
+reboot_mod_SOURCES = commands/reboot.c
+
+clean-module-reboot.mod.1:
+	rm -f reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o und-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod.1
+
+ifneq ($(reboot_mod_EXPORTS),no)
+clean-module-reboot.mod-symbol.1:
+	rm -f def-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod-symbol.1
+DEFSYMFILES += def-reboot.lst
+endif
+mostlyclean-module-reboot.mod.1:
+	rm -f reboot_mod-commands_reboot.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-reboot.mod.1
+UNDSYMFILES += und-reboot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-reboot.o mod-reboot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o
+
+mod-reboot.o: mod-reboot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $<
+
+mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(reboot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-reboot.lst: pre-reboot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+else
+def-reboot.lst: pre-reboot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+endif
+endif
+
+und-reboot.lst: pre-reboot.o
+	echo 'reboot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $<
+-include reboot_mod-commands_reboot.d
+
+clean-module-reboot_mod-commands_reboot-extra.1:
+	rm -f cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst handler-reboot_mod-commands_reboot.lst parttool-reboot_mod-commands_reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot_mod-commands_reboot-extra.1
+
+COMMANDFILES += cmd-reboot_mod-commands_reboot.lst
+FSFILES += fs-reboot_mod-commands_reboot.lst
+PARTTOOLFILES += parttool-reboot_mod-commands_reboot.lst
+PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst
+HANDLERFILES += handler-reboot_mod-commands_reboot.lst
+
+cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1)
+
+parttool-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh reboot > $@ || (rm -f $@; exit 1)
+
+partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1)
+
+handler-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod
+halt_mod_SOURCES = commands/halt.c
+
+clean-module-halt.mod.1:
+	rm -f halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_halt.o und-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod.1
+
+ifneq ($(halt_mod_EXPORTS),no)
+clean-module-halt.mod-symbol.1:
+	rm -f def-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod-symbol.1
+DEFSYMFILES += def-halt.lst
+endif
+mostlyclean-module-halt.mod.1:
+	rm -f halt_mod-commands_halt.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-halt.mod.1
+UNDSYMFILES += und-halt.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-halt.o mod-halt.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_halt.o
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_halt.o
+
+mod-halt.o: mod-halt.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $<
+
+mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(halt_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-halt.lst: pre-halt.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+else
+def-halt.lst: pre-halt.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+endif
+endif
+
+und-halt.lst: pre-halt.o
+	echo 'halt' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+halt_mod-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $<
+-include halt_mod-commands_halt.d
+
+clean-module-halt_mod-commands_halt-extra.1:
+	rm -f cmd-halt_mod-commands_halt.lst fs-halt_mod-commands_halt.lst partmap-halt_mod-commands_halt.lst handler-halt_mod-commands_halt.lst parttool-halt_mod-commands_halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt_mod-commands_halt-extra.1
+
+COMMANDFILES += cmd-halt_mod-commands_halt.lst
+FSFILES += fs-halt_mod-commands_halt.lst
+PARTTOOLFILES += parttool-halt_mod-commands_halt.lst
+PARTMAPFILES += partmap-halt_mod-commands_halt.lst
+HANDLERFILES += handler-halt_mod-commands_halt.lst
+
+cmd-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1)
+
+fs-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1)
+
+parttool-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh halt > $@ || (rm -f $@; exit 1)
+
+partmap-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1)
+
+handler-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh halt > $@ || (rm -f $@; exit 1)
+
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For serial.mod.
+serial_mod_SOURCES = term/i386/pc/serial.c
+
+clean-module-serial.mod.1:
+	rm -f serial.mod mod-serial.o mod-serial.c pre-serial.o serial_mod-term_i386_pc_serial.o und-serial.lst
+
+CLEAN_MODULE_TARGETS += clean-module-serial.mod.1
+
+ifneq ($(serial_mod_EXPORTS),no)
+clean-module-serial.mod-symbol.1:
+	rm -f def-serial.lst
+
+CLEAN_MODULE_TARGETS += clean-module-serial.mod-symbol.1
+DEFSYMFILES += def-serial.lst
+endif
+mostlyclean-module-serial.mod.1:
+	rm -f serial_mod-term_i386_pc_serial.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-serial.mod.1
+UNDSYMFILES += und-serial.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+serial.mod: pre-serial.o mod-serial.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-serial.o mod-serial.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+serial.mod: pre-serial.o mod-serial.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-serial.o mod-serial.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-serial.o: $(serial_mod_DEPENDENCIES) serial_mod-term_i386_pc_serial.o
+	-rm -f $@
+	$(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ serial_mod-term_i386_pc_serial.o
+
+mod-serial.o: mod-serial.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -c -o $@ $<
+
+mod-serial.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'serial' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(serial_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-serial.lst: pre-serial.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 serial/' > $@
+else
+def-serial.lst: pre-serial.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 serial/' > $@
+endif
+endif
+
+und-serial.lst: pre-serial.o
+	echo 'serial' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+serial_mod-term_i386_pc_serial.o: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -MD -c -o $@ $<
+-include serial_mod-term_i386_pc_serial.d
+
+clean-module-serial_mod-term_i386_pc_serial-extra.1:
+	rm -f cmd-serial_mod-term_i386_pc_serial.lst fs-serial_mod-term_i386_pc_serial.lst partmap-serial_mod-term_i386_pc_serial.lst handler-serial_mod-term_i386_pc_serial.lst parttool-serial_mod-term_i386_pc_serial.lst
+
+CLEAN_MODULE_TARGETS += clean-module-serial_mod-term_i386_pc_serial-extra.1
+
+COMMANDFILES += cmd-serial_mod-term_i386_pc_serial.lst
+FSFILES += fs-serial_mod-term_i386_pc_serial.lst
+PARTTOOLFILES += parttool-serial_mod-term_i386_pc_serial.lst
+PARTMAPFILES += partmap-serial_mod-term_i386_pc_serial.lst
+HANDLERFILES += handler-serial_mod-term_i386_pc_serial.lst
+
+cmd-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh serial > $@ || (rm -f $@; exit 1)
+
+fs-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh serial > $@ || (rm -f $@; exit 1)
+
+parttool-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh serial > $@ || (rm -f $@; exit 1)
+
+partmap-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh serial > $@ || (rm -f $@; exit 1)
+
+handler-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh serial > $@ || (rm -f $@; exit 1)
+
+serial_mod_CFLAGS = $(COMMON_CFLAGS)
+serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/i386/ieee1275/linux.c
+
+clean-module-linux.mod.1:
+	rm -f linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_i386_ieee1275_linux.o und-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod.1
+
+ifneq ($(linux_mod_EXPORTS),no)
+clean-module-linux.mod-symbol.1:
+	rm -f def-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod-symbol.1
+DEFSYMFILES += def-linux.lst
+endif
+mostlyclean-module-linux.mod.1:
+	rm -f linux_mod-loader_i386_ieee1275_linux.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-linux.mod.1
+UNDSYMFILES += und-linux.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-linux.o mod-linux.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_i386_ieee1275_linux.o
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_i386_ieee1275_linux.o
+
+mod-linux.o: mod-linux.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $<
+
+mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(linux_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-linux.lst: pre-linux.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+else
+def-linux.lst: pre-linux.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+endif
+endif
+
+und-linux.lst: pre-linux.o
+	echo 'linux' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+linux_mod-loader_i386_ieee1275_linux.o: loader/i386/ieee1275/linux.c $(loader/i386/ieee1275/linux.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386/ieee1275 -I$(srcdir)/loader/i386/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $<
+-include linux_mod-loader_i386_ieee1275_linux.d
+
+clean-module-linux_mod-loader_i386_ieee1275_linux-extra.1:
+	rm -f cmd-linux_mod-loader_i386_ieee1275_linux.lst fs-linux_mod-loader_i386_ieee1275_linux.lst partmap-linux_mod-loader_i386_ieee1275_linux.lst handler-linux_mod-loader_i386_ieee1275_linux.lst parttool-linux_mod-loader_i386_ieee1275_linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux_mod-loader_i386_ieee1275_linux-extra.1
+
+COMMANDFILES += cmd-linux_mod-loader_i386_ieee1275_linux.lst
+FSFILES += fs-linux_mod-loader_i386_ieee1275_linux.lst
+PARTTOOLFILES += parttool-linux_mod-loader_i386_ieee1275_linux.lst
+PARTMAPFILES += partmap-linux_mod-loader_i386_ieee1275_linux.lst
+HANDLERFILES += handler-linux_mod-loader_i386_ieee1275_linux.lst
+
+cmd-linux_mod-loader_i386_ieee1275_linux.lst: loader/i386/ieee1275/linux.c $(loader/i386/ieee1275/linux.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/ieee1275 -I$(srcdir)/loader/i386/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1)
+
+fs-linux_mod-loader_i386_ieee1275_linux.lst: loader/i386/ieee1275/linux.c $(loader/i386/ieee1275/linux.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/ieee1275 -I$(srcdir)/loader/i386/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1)
+
+parttool-linux_mod-loader_i386_ieee1275_linux.lst: loader/i386/ieee1275/linux.c $(loader/i386/ieee1275/linux.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/ieee1275 -I$(srcdir)/loader/i386/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh linux > $@ || (rm -f $@; exit 1)
+
+partmap-linux_mod-loader_i386_ieee1275_linux.lst: loader/i386/ieee1275/linux.c $(loader/i386/ieee1275/linux.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/ieee1275 -I$(srcdir)/loader/i386/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1)
+
+handler-linux_mod-loader_i386_ieee1275_linux.lst: loader/i386/ieee1275/linux.c $(loader/i386/ieee1275/linux.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/ieee1275 -I$(srcdir)/loader/i386/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh linux > $@ || (rm -f $@; exit 1)
+
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For nand.mod.
+nand_mod_SOURCES = disk/ieee1275/nand.c
+
+clean-module-nand.mod.1:
+	rm -f nand.mod mod-nand.o mod-nand.c pre-nand.o nand_mod-disk_ieee1275_nand.o und-nand.lst
+
+CLEAN_MODULE_TARGETS += clean-module-nand.mod.1
+
+ifneq ($(nand_mod_EXPORTS),no)
+clean-module-nand.mod-symbol.1:
+	rm -f def-nand.lst
+
+CLEAN_MODULE_TARGETS += clean-module-nand.mod-symbol.1
+DEFSYMFILES += def-nand.lst
+endif
+mostlyclean-module-nand.mod.1:
+	rm -f nand_mod-disk_ieee1275_nand.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-nand.mod.1
+UNDSYMFILES += und-nand.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+nand.mod: pre-nand.o mod-nand.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(nand_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-nand.o mod-nand.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+nand.mod: pre-nand.o mod-nand.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(nand_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-nand.o mod-nand.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-nand.o: $(nand_mod_DEPENDENCIES) nand_mod-disk_ieee1275_nand.o
+	-rm -f $@
+	$(TARGET_CC) $(nand_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ nand_mod-disk_ieee1275_nand.o
+
+mod-nand.o: mod-nand.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(nand_mod_CFLAGS) -c -o $@ $<
+
+mod-nand.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'nand' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(nand_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-nand.lst: pre-nand.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 nand/' > $@
+else
+def-nand.lst: pre-nand.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 nand/' > $@
+endif
+endif
+
+und-nand.lst: pre-nand.o
+	echo 'nand' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+nand_mod-disk_ieee1275_nand.o: disk/ieee1275/nand.c $(disk/ieee1275/nand.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(nand_mod_CFLAGS) -MD -c -o $@ $<
+-include nand_mod-disk_ieee1275_nand.d
+
+clean-module-nand_mod-disk_ieee1275_nand-extra.1:
+	rm -f cmd-nand_mod-disk_ieee1275_nand.lst fs-nand_mod-disk_ieee1275_nand.lst partmap-nand_mod-disk_ieee1275_nand.lst handler-nand_mod-disk_ieee1275_nand.lst parttool-nand_mod-disk_ieee1275_nand.lst
+
+CLEAN_MODULE_TARGETS += clean-module-nand_mod-disk_ieee1275_nand-extra.1
+
+COMMANDFILES += cmd-nand_mod-disk_ieee1275_nand.lst
+FSFILES += fs-nand_mod-disk_ieee1275_nand.lst
+PARTTOOLFILES += parttool-nand_mod-disk_ieee1275_nand.lst
+PARTMAPFILES += partmap-nand_mod-disk_ieee1275_nand.lst
+HANDLERFILES += handler-nand_mod-disk_ieee1275_nand.lst
+
+cmd-nand_mod-disk_ieee1275_nand.lst: disk/ieee1275/nand.c $(disk/ieee1275/nand.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(nand_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh nand > $@ || (rm -f $@; exit 1)
+
+fs-nand_mod-disk_ieee1275_nand.lst: disk/ieee1275/nand.c $(disk/ieee1275/nand.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(nand_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh nand > $@ || (rm -f $@; exit 1)
+
+parttool-nand_mod-disk_ieee1275_nand.lst: disk/ieee1275/nand.c $(disk/ieee1275/nand.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(nand_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh nand > $@ || (rm -f $@; exit 1)
+
+partmap-nand_mod-disk_ieee1275_nand.lst: disk/ieee1275/nand.c $(disk/ieee1275/nand.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(nand_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh nand > $@ || (rm -f $@; exit 1)
+
+handler-nand_mod-disk_ieee1275_nand.lst: disk/ieee1275/nand.c $(disk/ieee1275/nand.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(nand_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh nand > $@ || (rm -f $@; exit 1)
+
+nand_mod_CFLAGS = $(COMMON_CFLAGS)
+nand_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memdisk.mod.
+memdisk_mod_SOURCES = disk/memdisk.c
+
+clean-module-memdisk.mod.1:
+	rm -f memdisk.mod mod-memdisk.o mod-memdisk.c pre-memdisk.o memdisk_mod-disk_memdisk.o und-memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk.mod.1
+
+ifneq ($(memdisk_mod_EXPORTS),no)
+clean-module-memdisk.mod-symbol.1:
+	rm -f def-memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk.mod-symbol.1
+DEFSYMFILES += def-memdisk.lst
+endif
+mostlyclean-module-memdisk.mod.1:
+	rm -f memdisk_mod-disk_memdisk.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-memdisk.mod.1
+UNDSYMFILES += und-memdisk.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-memdisk.o mod-memdisk.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-memdisk.o mod-memdisk.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-memdisk.o: $(memdisk_mod_DEPENDENCIES) memdisk_mod-disk_memdisk.o
+	-rm -f $@
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memdisk_mod-disk_memdisk.o
+
+mod-memdisk.o: mod-memdisk.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -c -o $@ $<
+
+mod-memdisk.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'memdisk' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(memdisk_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-memdisk.lst: pre-memdisk.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@
+else
+def-memdisk.lst: pre-memdisk.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@
+endif
+endif
+
+und-memdisk.lst: pre-memdisk.o
+	echo 'memdisk' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+memdisk_mod-disk_memdisk.o: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -MD -c -o $@ $<
+-include memdisk_mod-disk_memdisk.d
+
+clean-module-memdisk_mod-disk_memdisk-extra.1:
+	rm -f cmd-memdisk_mod-disk_memdisk.lst fs-memdisk_mod-disk_memdisk.lst partmap-memdisk_mod-disk_memdisk.lst handler-memdisk_mod-disk_memdisk.lst parttool-memdisk_mod-disk_memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk_mod-disk_memdisk-extra.1
+
+COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst
+FSFILES += fs-memdisk_mod-disk_memdisk.lst
+PARTTOOLFILES += parttool-memdisk_mod-disk_memdisk.lst
+PARTMAPFILES += partmap-memdisk_mod-disk_memdisk.lst
+HANDLERFILES += handler-memdisk_mod-disk_memdisk.lst
+
+cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+fs-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+parttool-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+partmap-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+handler-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pci.mod
+pci_mod_SOURCES = bus/pci.c
+
+clean-module-pci.mod.1:
+	rm -f pci.mod mod-pci.o mod-pci.c pre-pci.o pci_mod-bus_pci.o und-pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci.mod.1
+
+ifneq ($(pci_mod_EXPORTS),no)
+clean-module-pci.mod-symbol.1:
+	rm -f def-pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci.mod-symbol.1
+DEFSYMFILES += def-pci.lst
+endif
+mostlyclean-module-pci.mod.1:
+	rm -f pci_mod-bus_pci.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-pci.mod.1
+UNDSYMFILES += und-pci.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-pci.o mod-pci.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-pci.o mod-pci.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-pci.o: $(pci_mod_DEPENDENCIES) pci_mod-bus_pci.o
+	-rm -f $@
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pci_mod-bus_pci.o
+
+mod-pci.o: mod-pci.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -c -o $@ $<
+
+mod-pci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'pci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(pci_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-pci.lst: pre-pci.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pci/' > $@
+else
+def-pci.lst: pre-pci.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 pci/' > $@
+endif
+endif
+
+und-pci.lst: pre-pci.o
+	echo 'pci' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+pci_mod-bus_pci.o: bus/pci.c $(bus/pci.c_DEPENDENCIES)
+	$(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -MD -c -o $@ $<
+-include pci_mod-bus_pci.d
+
+clean-module-pci_mod-bus_pci-extra.1:
+	rm -f cmd-pci_mod-bus_pci.lst fs-pci_mod-bus_pci.lst partmap-pci_mod-bus_pci.lst handler-pci_mod-bus_pci.lst parttool-pci_mod-bus_pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci_mod-bus_pci-extra.1
+
+COMMANDFILES += cmd-pci_mod-bus_pci.lst
+FSFILES += fs-pci_mod-bus_pci.lst
+PARTTOOLFILES += parttool-pci_mod-bus_pci.lst
+PARTMAPFILES += partmap-pci_mod-bus_pci.lst
+HANDLERFILES += handler-pci_mod-bus_pci.lst
+
+cmd-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh pci > $@ || (rm -f $@; exit 1)
+
+fs-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh pci > $@ || (rm -f $@; exit 1)
+
+parttool-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh pci > $@ || (rm -f $@; exit 1)
+
+partmap-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh pci > $@ || (rm -f $@; exit 1)
+
+handler-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh pci > $@ || (rm -f $@; exit 1)
+
+pci_mod_CFLAGS = $(COMMON_CFLAGS)
+pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lspci.mod
+lspci_mod_SOURCES = commands/lspci.c
+
+clean-module-lspci.mod.1:
+	rm -f lspci.mod mod-lspci.o mod-lspci.c pre-lspci.o lspci_mod-commands_lspci.o und-lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci.mod.1
+
+ifneq ($(lspci_mod_EXPORTS),no)
+clean-module-lspci.mod-symbol.1:
+	rm -f def-lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci.mod-symbol.1
+DEFSYMFILES += def-lspci.lst
+endif
+mostlyclean-module-lspci.mod.1:
+	rm -f lspci_mod-commands_lspci.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-lspci.mod.1
+UNDSYMFILES += und-lspci.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-lspci.o mod-lspci.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-lspci.o mod-lspci.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-lspci.o: $(lspci_mod_DEPENDENCIES) lspci_mod-commands_lspci.o
+	-rm -f $@
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lspci_mod-commands_lspci.o
+
+mod-lspci.o: mod-lspci.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -c -o $@ $<
+
+mod-lspci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'lspci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(lspci_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-lspci.lst: pre-lspci.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lspci/' > $@
+else
+def-lspci.lst: pre-lspci.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 lspci/' > $@
+endif
+endif
+
+und-lspci.lst: pre-lspci.o
+	echo 'lspci' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+lspci_mod-commands_lspci.o: commands/lspci.c $(commands/lspci.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -MD -c -o $@ $<
+-include lspci_mod-commands_lspci.d
+
+clean-module-lspci_mod-commands_lspci-extra.1:
+	rm -f cmd-lspci_mod-commands_lspci.lst fs-lspci_mod-commands_lspci.lst partmap-lspci_mod-commands_lspci.lst handler-lspci_mod-commands_lspci.lst parttool-lspci_mod-commands_lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci_mod-commands_lspci-extra.1
+
+COMMANDFILES += cmd-lspci_mod-commands_lspci.lst
+FSFILES += fs-lspci_mod-commands_lspci.lst
+PARTTOOLFILES += parttool-lspci_mod-commands_lspci.lst
+PARTMAPFILES += partmap-lspci_mod-commands_lspci.lst
+HANDLERFILES += handler-lspci_mod-commands_lspci.lst
+
+cmd-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh lspci > $@ || (rm -f $@; exit 1)
+
+fs-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh lspci > $@ || (rm -f $@; exit 1)
+
+parttool-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh lspci > $@ || (rm -f $@; exit 1)
+
+partmap-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh lspci > $@ || (rm -f $@; exit 1)
+
+handler-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh lspci > $@ || (rm -f $@; exit 1)
+
+lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/i386/datetime.c
+
+clean-module-datetime.mod.1:
+	rm -f datetime.mod mod-datetime.o mod-datetime.c pre-datetime.o datetime_mod-lib_i386_datetime.o und-datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime.mod.1
+
+ifneq ($(datetime_mod_EXPORTS),no)
+clean-module-datetime.mod-symbol.1:
+	rm -f def-datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime.mod-symbol.1
+DEFSYMFILES += def-datetime.lst
+endif
+mostlyclean-module-datetime.mod.1:
+	rm -f datetime_mod-lib_i386_datetime.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-datetime.mod.1
+UNDSYMFILES += und-datetime.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-datetime.o mod-datetime.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-datetime.o mod-datetime.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-datetime.o: $(datetime_mod_DEPENDENCIES) datetime_mod-lib_i386_datetime.o
+	-rm -f $@
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datetime_mod-lib_i386_datetime.o
+
+mod-datetime.o: mod-datetime.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -c -o $@ $<
+
+mod-datetime.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'datetime' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(datetime_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-datetime.lst: pre-datetime.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datetime/' > $@
+else
+def-datetime.lst: pre-datetime.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 datetime/' > $@
+endif
+endif
+
+und-datetime.lst: pre-datetime.o
+	echo 'datetime' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+datetime_mod-lib_i386_datetime.o: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $<
+-include datetime_mod-lib_i386_datetime.d
+
+clean-module-datetime_mod-lib_i386_datetime-extra.1:
+	rm -f cmd-datetime_mod-lib_i386_datetime.lst fs-datetime_mod-lib_i386_datetime.lst partmap-datetime_mod-lib_i386_datetime.lst handler-datetime_mod-lib_i386_datetime.lst parttool-datetime_mod-lib_i386_datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime_mod-lib_i386_datetime-extra.1
+
+COMMANDFILES += cmd-datetime_mod-lib_i386_datetime.lst
+FSFILES += fs-datetime_mod-lib_i386_datetime.lst
+PARTTOOLFILES += parttool-datetime_mod-lib_i386_datetime.lst
+PARTMAPFILES += partmap-datetime_mod-lib_i386_datetime.lst
+HANDLERFILES += handler-datetime_mod-lib_i386_datetime.lst
+
+cmd-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1)
+
+fs-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1)
+
+parttool-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh datetime > $@ || (rm -f $@; exit 1)
+
+partmap-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1)
+
+handler-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh datetime > $@ || (rm -f $@; exit 1)
+
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For date.mod
+date_mod_SOURCES = commands/date.c
+
+clean-module-date.mod.1:
+	rm -f date.mod mod-date.o mod-date.c pre-date.o date_mod-commands_date.o und-date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date.mod.1
+
+ifneq ($(date_mod_EXPORTS),no)
+clean-module-date.mod-symbol.1:
+	rm -f def-date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date.mod-symbol.1
+DEFSYMFILES += def-date.lst
+endif
+mostlyclean-module-date.mod.1:
+	rm -f date_mod-commands_date.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-date.mod.1
+UNDSYMFILES += und-date.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-date.o mod-date.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-date.o mod-date.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-date.o: $(date_mod_DEPENDENCIES) date_mod-commands_date.o
+	-rm -f $@
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ date_mod-commands_date.o
+
+mod-date.o: mod-date.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -c -o $@ $<
+
+mod-date.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'date' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(date_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-date.lst: pre-date.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 date/' > $@
+else
+def-date.lst: pre-date.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 date/' > $@
+endif
+endif
+
+und-date.lst: pre-date.o
+	echo 'date' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+date_mod-commands_date.o: commands/date.c $(commands/date.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -MD -c -o $@ $<
+-include date_mod-commands_date.d
+
+clean-module-date_mod-commands_date-extra.1:
+	rm -f cmd-date_mod-commands_date.lst fs-date_mod-commands_date.lst partmap-date_mod-commands_date.lst handler-date_mod-commands_date.lst parttool-date_mod-commands_date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date_mod-commands_date-extra.1
+
+COMMANDFILES += cmd-date_mod-commands_date.lst
+FSFILES += fs-date_mod-commands_date.lst
+PARTTOOLFILES += parttool-date_mod-commands_date.lst
+PARTMAPFILES += partmap-date_mod-commands_date.lst
+HANDLERFILES += handler-date_mod-commands_date.lst
+
+cmd-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh date > $@ || (rm -f $@; exit 1)
+
+fs-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh date > $@ || (rm -f $@; exit 1)
+
+parttool-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh date > $@ || (rm -f $@; exit 1)
+
+partmap-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh date > $@ || (rm -f $@; exit 1)
+
+handler-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh date > $@ || (rm -f $@; exit 1)
+
+date_mod_CFLAGS = $(COMMON_CFLAGS)
+date_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datehook.mod
+datehook_mod_SOURCES = hook/datehook.c
+
+clean-module-datehook.mod.1:
+	rm -f datehook.mod mod-datehook.o mod-datehook.c pre-datehook.o datehook_mod-hook_datehook.o und-datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook.mod.1
+
+ifneq ($(datehook_mod_EXPORTS),no)
+clean-module-datehook.mod-symbol.1:
+	rm -f def-datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook.mod-symbol.1
+DEFSYMFILES += def-datehook.lst
+endif
+mostlyclean-module-datehook.mod.1:
+	rm -f datehook_mod-hook_datehook.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-datehook.mod.1
+UNDSYMFILES += und-datehook.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-datehook.o mod-datehook.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-datehook.o mod-datehook.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-datehook.o: $(datehook_mod_DEPENDENCIES) datehook_mod-hook_datehook.o
+	-rm -f $@
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datehook_mod-hook_datehook.o
+
+mod-datehook.o: mod-datehook.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -c -o $@ $<
+
+mod-datehook.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'datehook' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(datehook_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-datehook.lst: pre-datehook.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datehook/' > $@
+else
+def-datehook.lst: pre-datehook.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 datehook/' > $@
+endif
+endif
+
+und-datehook.lst: pre-datehook.o
+	echo 'datehook' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+datehook_mod-hook_datehook.o: hook/datehook.c $(hook/datehook.c_DEPENDENCIES)
+	$(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -MD -c -o $@ $<
+-include datehook_mod-hook_datehook.d
+
+clean-module-datehook_mod-hook_datehook-extra.1:
+	rm -f cmd-datehook_mod-hook_datehook.lst fs-datehook_mod-hook_datehook.lst partmap-datehook_mod-hook_datehook.lst handler-datehook_mod-hook_datehook.lst parttool-datehook_mod-hook_datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook_mod-hook_datehook-extra.1
+
+COMMANDFILES += cmd-datehook_mod-hook_datehook.lst
+FSFILES += fs-datehook_mod-hook_datehook.lst
+PARTTOOLFILES += parttool-datehook_mod-hook_datehook.lst
+PARTMAPFILES += partmap-datehook_mod-hook_datehook.lst
+HANDLERFILES += handler-datehook_mod-hook_datehook.lst
+
+cmd-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh datehook > $@ || (rm -f $@; exit 1)
+
+fs-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh datehook > $@ || (rm -f $@; exit 1)
+
+parttool-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh datehook > $@ || (rm -f $@; exit 1)
+
+partmap-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh datehook > $@ || (rm -f $@; exit 1)
+
+handler-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh datehook > $@ || (rm -f $@; exit 1)
+
+datehook_mod_CFLAGS = $(COMMON_CFLAGS)
+datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+
+clean-module-lsmmap.mod.1:
+	rm -f lsmmap.mod mod-lsmmap.o mod-lsmmap.c pre-lsmmap.o lsmmap_mod-commands_lsmmap.o und-lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap.mod.1
+
+ifneq ($(lsmmap_mod_EXPORTS),no)
+clean-module-lsmmap.mod-symbol.1:
+	rm -f def-lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap.mod-symbol.1
+DEFSYMFILES += def-lsmmap.lst
+endif
+mostlyclean-module-lsmmap.mod.1:
+	rm -f lsmmap_mod-commands_lsmmap.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-lsmmap.mod.1
+UNDSYMFILES += und-lsmmap.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-lsmmap.o mod-lsmmap.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-lsmmap.o mod-lsmmap.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-lsmmap.o: $(lsmmap_mod_DEPENDENCIES) lsmmap_mod-commands_lsmmap.o
+	-rm -f $@
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lsmmap_mod-commands_lsmmap.o
+
+mod-lsmmap.o: mod-lsmmap.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -c -o $@ $<
+
+mod-lsmmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'lsmmap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(lsmmap_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-lsmmap.lst: pre-lsmmap.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@
+else
+def-lsmmap.lst: pre-lsmmap.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@
+endif
+endif
+
+und-lsmmap.lst: pre-lsmmap.o
+	echo 'lsmmap' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+lsmmap_mod-commands_lsmmap.o: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -MD -c -o $@ $<
+-include lsmmap_mod-commands_lsmmap.d
+
+clean-module-lsmmap_mod-commands_lsmmap-extra.1:
+	rm -f cmd-lsmmap_mod-commands_lsmmap.lst fs-lsmmap_mod-commands_lsmmap.lst partmap-lsmmap_mod-commands_lsmmap.lst handler-lsmmap_mod-commands_lsmmap.lst parttool-lsmmap_mod-commands_lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap_mod-commands_lsmmap-extra.1
+
+COMMANDFILES += cmd-lsmmap_mod-commands_lsmmap.lst
+FSFILES += fs-lsmmap_mod-commands_lsmmap.lst
+PARTTOOLFILES += parttool-lsmmap_mod-commands_lsmmap.lst
+PARTMAPFILES += partmap-lsmmap_mod-commands_lsmmap.lst
+HANDLERFILES += handler-lsmmap_mod-commands_lsmmap.lst
+
+cmd-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+fs-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+parttool-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+partmap-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+handler-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
+grub-mkdevicemap: $(grub_mkdevicemap_DEPENDENCIES) $(grub_mkdevicemap_OBJECTS)
+	$(CC) -o $@ $(grub_mkdevicemap_OBJECTS) $(LDFLAGS) $(grub_mkdevicemap_LDFLAGS)
+
+grub-emu: $(grub_emu_DEPENDENCIES) $(grub_emu_OBJECTS)
+	$(CC) -o $@ $(grub_emu_OBJECTS) $(LDFLAGS) $(grub_emu_LDFLAGS)
+
diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk
new file mode 100644
index 0000000..4b640de
--- /dev/null
+++ b/conf/i386-ieee1275.rmk
@@ -0,0 +1,209 @@
+# -*- makefile -*-
+
+COMMON_ASFLAGS	= -m32 -nostdinc -fno-builtin
+COMMON_CFLAGS	= -ffreestanding -mrtd -mregparm=3
+COMMON_LDFLAGS	= -nostdlib
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Images.
+pkglib_PROGRAMS = kernel.img
+
+# For kernel.img.
+kernel_img_SOURCES = kern/i386/ieee1275/startup.S \
+	kern/i386/misc.S \
+	kern/i386/ieee1275/init.c \
+	kern/ieee1275/init.c \
+	kern/ieee1275/mmap.c \
+	kern/ieee1275/cmain.c kern/ieee1275/openfw.c \
+	kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
+	kern/env.c \
+	kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+	kern/generic/millisleep.c \
+	kern/ieee1275/ieee1275.c \
+	term/ieee1275/ofconsole.c \
+	disk/ieee1275/ofdisk.c \
+	symlist.c
+kernel_img_HEADERS = cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \
+	list.h handler.h command.h
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
+
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# Utilities.
+sbin_UTILITIES = grub-mkdevicemap
+ifeq ($(enable_grub_emu), yes)
+sbin_UTILITIES += grub-emu
+endif
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/devicemap.c util/misc.c
+
+# For grub-emu.
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c	\
+	commands/configfile.c commands/echo.c commands/help.c		\
+	commands/handler.c commands/ls.c commands/test.c 		\
+	commands/search.c commands/blocklist.c commands/hexdump.c	\
+	lib/hexdump.c commands/halt.c commands/reboot.c			\
+	lib/envblk.c commands/loadenv.c					\
+	commands/gptsync.c commands/probe.c  commands/xnu_uuid.c	\
+	commands/i386/cpuid.c	\
+	commands/password.c commands/keystatus.c			\
+	disk/host.c disk/loopback.c					\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c	\
+	fs/befs_be.c fs/tar.c				\
+	\
+	fs/fshelp.c							\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/list.c kern/handler.c				\
+	kern/command.c kern/corecmd.c commands/extcmd.c	kern/file.c 	\
+	kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c	\
+	kern/partition.c kern/reader.c kern/term.c			\
+	kern/rescue_reader.c kern/rescue_parser.c 			\
+	lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.c	\
+	normal/handler.c normal/auth.c normal/autofs.c			\
+	normal/completion.c normal/main.c normal/menu_text.c		\
+	normal/menu.c normal/menu_entry.c normal/menu_viewer.c		\
+	normal/color.c							\
+	script/sh/main.c script/sh/execute.c script/sh/function.c	\
+	script/sh/lexer.c script/sh/script.c grub_script.tab.c		\
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c partmap/gpt.c					\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	grub_emu_init.c
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/ieee1275/grub-install.in
+
+# Modules.
+pkglib_MODULES = halt.mod reboot.mod suspend.mod		\
+	multiboot.mod aout.mod serial.mod linux.mod		\
+	nand.mod memdisk.mod pci.mod lspci.mod datetime.mod	\
+	date.mod datehook.mod lsmmap.mod mmap.mod
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For multiboot.mod.
+multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \
+			loader/i386/multiboot_helper.S \
+			 loader/multiboot2.c \
+			 loader/multiboot_loader.c
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For aout.mod.
+aout_mod_SOURCES = loader/aout.c
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For suspend.mod
+suspend_mod_SOURCES = commands/ieee1275/suspend.c
+suspend_mod_CFLAGS = $(COMMON_CFLAGS)
+suspend_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod
+reboot_mod_SOURCES = commands/reboot.c
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For serial.mod.
+serial_mod_SOURCES = term/i386/pc/serial.c
+serial_mod_CFLAGS = $(COMMON_CFLAGS)
+serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/i386/ieee1275/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For nand.mod.
+nand_mod_SOURCES = disk/ieee1275/nand.c
+nand_mod_CFLAGS = $(COMMON_CFLAGS)
+nand_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memdisk.mod.
+memdisk_mod_SOURCES = disk/memdisk.c
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pci.mod
+pci_mod_SOURCES = bus/pci.c
+pci_mod_CFLAGS = $(COMMON_CFLAGS)
+pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lspci.mod
+lspci_mod_SOURCES = commands/lspci.c
+lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/i386/datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For date.mod
+date_mod_SOURCES = commands/date.c
+date_mod_CFLAGS = $(COMMON_CFLAGS)
+date_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datehook.mod
+datehook_mod_SOURCES = hook/datehook.c
+datehook_mod_CFLAGS = $(COMMON_CFLAGS)
+datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
diff --git a/conf/i386-pc-cygwin-img-ld.sc b/conf/i386-pc-cygwin-img-ld.sc
new file mode 100644
index 0000000..a41cac7
--- /dev/null
+++ b/conf/i386-pc-cygwin-img-ld.sc
@@ -0,0 +1,53 @@
+/* Linker script to create grub .img files on Cygwin.  */
+
+SECTIONS
+{
+  .text :
+  {
+    start = . ;
+    *(.text)
+    etext = . ;
+  }
+  .data :
+  {
+    __data_start__ = . ;
+    *(.data)
+    __data_end__ = . ;
+  }
+  .rdata :
+  {
+    __rdata_start__ = . ;
+    *(.rdata)
+    __rdata_end__ = . ;
+  }
+  .pdata :
+  {
+    *(.pdata)
+    edata = . ;
+  }
+  .bss :
+  {
+    __bss_start__ = . ;
+    *(.bss)
+    __common_start__ = . ;
+    *(COMMON)
+    __bss_end__ = . ;
+  }
+  .edata :
+  {
+    *(.edata)
+    end = . ;
+  }
+  .stab :
+  {
+    *(.stab)
+  }
+  .stabstr :
+  {
+    *(.stabstr)
+  }
+}
+
+ASSERT("__rdata_end__"=="edata", ".pdata not empty")
+ASSERT("__bss_end__"  =="end"  , ".edata not empty")
+
diff --git a/conf/i386-pc.mk b/conf/i386-pc.mk
new file mode 100644
index 0000000..b5c4c84
--- /dev/null
+++ b/conf/i386-pc.mk
@@ -0,0 +1,6016 @@
+# -*- makefile -*-
+# Generated by genmk.rb, please don't edit!
+
+GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200
+
+COMMON_ASFLAGS = -nostdinc -fno-builtin -m32
+COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32
+COMMON_LDFLAGS = -m32 -nostdlib
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Images.
+pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \
+	pxeboot.img
+
+# For boot.img.
+boot_img_SOURCES = boot/i386/pc/boot.S
+
+clean-image-boot.img.1:
+	rm -f boot.img boot.exec boot_img-boot_i386_pc_boot.o
+
+CLEAN_IMAGE_TARGETS += clean-image-boot.img.1
+
+mostlyclean-image-boot.img.1:
+	rm -f boot_img-boot_i386_pc_boot.d
+
+MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-boot.img.1
+
+ifneq ($(TARGET_APPLE_CC),1)
+boot.img: boot.exec
+	$(OBJCOPY) -O $(boot_img_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
+else
+ifneq (boot.exec,kernel.exec)
+boot.img: boot.exec ./grub-macho2img
+	./grub-macho2img $< $@
+else
+boot.img: boot.exec ./grub-macho2img
+	./grub-macho2img --bss $< $@
+endif
+endif
+
+boot.exec: boot_img-boot_i386_pc_boot.o
+	$(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(boot_img_LDFLAGS)
+
+boot_img-boot_i386_pc_boot.o: boot/i386/pc/boot.S $(boot/i386/pc/boot.S_DEPENDENCIES)
+	$(TARGET_CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(boot_img_ASFLAGS) -MD -c -o $@ $<
+-include boot_img-boot_i386_pc_boot.d
+
+boot_img_ASFLAGS = $(COMMON_ASFLAGS)
+boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00
+boot_img_FORMAT = binary
+
+# For pxeboot.img
+pxeboot_img_SOURCES = boot/i386/pc/pxeboot.S
+
+clean-image-pxeboot.img.1:
+	rm -f pxeboot.img pxeboot.exec pxeboot_img-boot_i386_pc_pxeboot.o
+
+CLEAN_IMAGE_TARGETS += clean-image-pxeboot.img.1
+
+mostlyclean-image-pxeboot.img.1:
+	rm -f pxeboot_img-boot_i386_pc_pxeboot.d
+
+MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-pxeboot.img.1
+
+ifneq ($(TARGET_APPLE_CC),1)
+pxeboot.img: pxeboot.exec
+	$(OBJCOPY) -O $(pxeboot_img_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
+else
+ifneq (pxeboot.exec,kernel.exec)
+pxeboot.img: pxeboot.exec ./grub-macho2img
+	./grub-macho2img $< $@
+else
+pxeboot.img: pxeboot.exec ./grub-macho2img
+	./grub-macho2img --bss $< $@
+endif
+endif
+
+pxeboot.exec: pxeboot_img-boot_i386_pc_pxeboot.o
+	$(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(pxeboot_img_LDFLAGS)
+
+pxeboot_img-boot_i386_pc_pxeboot.o: boot/i386/pc/pxeboot.S $(boot/i386/pc/pxeboot.S_DEPENDENCIES)
+	$(TARGET_CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(pxeboot_img_ASFLAGS) -MD -c -o $@ $<
+-include pxeboot_img-boot_i386_pc_pxeboot.d
+
+pxeboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+pxeboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00
+pxeboot_img_FORMAT = binary
+
+# For diskboot.img.
+diskboot_img_SOURCES = boot/i386/pc/diskboot.S
+
+clean-image-diskboot.img.1:
+	rm -f diskboot.img diskboot.exec diskboot_img-boot_i386_pc_diskboot.o
+
+CLEAN_IMAGE_TARGETS += clean-image-diskboot.img.1
+
+mostlyclean-image-diskboot.img.1:
+	rm -f diskboot_img-boot_i386_pc_diskboot.d
+
+MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-diskboot.img.1
+
+ifneq ($(TARGET_APPLE_CC),1)
+diskboot.img: diskboot.exec
+	$(OBJCOPY) -O $(diskboot_img_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
+else
+ifneq (diskboot.exec,kernel.exec)
+diskboot.img: diskboot.exec ./grub-macho2img
+	./grub-macho2img $< $@
+else
+diskboot.img: diskboot.exec ./grub-macho2img
+	./grub-macho2img --bss $< $@
+endif
+endif
+
+diskboot.exec: diskboot_img-boot_i386_pc_diskboot.o
+	$(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(diskboot_img_LDFLAGS)
+
+diskboot_img-boot_i386_pc_diskboot.o: boot/i386/pc/diskboot.S $(boot/i386/pc/diskboot.S_DEPENDENCIES)
+	$(TARGET_CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(diskboot_img_ASFLAGS) -MD -c -o $@ $<
+-include diskboot_img-boot_i386_pc_diskboot.d
+
+diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)8000
+diskboot_img_FORMAT = binary
+
+# For lnxboot.img.
+lnxboot_img_SOURCES = boot/i386/pc/lnxboot.S
+
+clean-image-lnxboot.img.1:
+	rm -f lnxboot.img lnxboot.exec lnxboot_img-boot_i386_pc_lnxboot.o
+
+CLEAN_IMAGE_TARGETS += clean-image-lnxboot.img.1
+
+mostlyclean-image-lnxboot.img.1:
+	rm -f lnxboot_img-boot_i386_pc_lnxboot.d
+
+MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-lnxboot.img.1
+
+ifneq ($(TARGET_APPLE_CC),1)
+lnxboot.img: lnxboot.exec
+	$(OBJCOPY) -O $(lnxboot_img_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
+else
+ifneq (lnxboot.exec,kernel.exec)
+lnxboot.img: lnxboot.exec ./grub-macho2img
+	./grub-macho2img $< $@
+else
+lnxboot.img: lnxboot.exec ./grub-macho2img
+	./grub-macho2img --bss $< $@
+endif
+endif
+
+lnxboot.exec: lnxboot_img-boot_i386_pc_lnxboot.o
+	$(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(lnxboot_img_LDFLAGS)
+
+lnxboot_img-boot_i386_pc_lnxboot.o: boot/i386/pc/lnxboot.S $(boot/i386/pc/lnxboot.S_DEPENDENCIES)
+	$(TARGET_CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(lnxboot_img_ASFLAGS) -MD -c -o $@ $<
+-include lnxboot_img-boot_i386_pc_lnxboot.d
+
+lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)6000
+lnxboot_img_FORMAT = binary
+
+# For cdboot.img.
+cdboot_img_SOURCES = boot/i386/pc/cdboot.S
+
+clean-image-cdboot.img.1:
+	rm -f cdboot.img cdboot.exec cdboot_img-boot_i386_pc_cdboot.o
+
+CLEAN_IMAGE_TARGETS += clean-image-cdboot.img.1
+
+mostlyclean-image-cdboot.img.1:
+	rm -f cdboot_img-boot_i386_pc_cdboot.d
+
+MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-cdboot.img.1
+
+ifneq ($(TARGET_APPLE_CC),1)
+cdboot.img: cdboot.exec
+	$(OBJCOPY) -O $(cdboot_img_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
+else
+ifneq (cdboot.exec,kernel.exec)
+cdboot.img: cdboot.exec ./grub-macho2img
+	./grub-macho2img $< $@
+else
+cdboot.img: cdboot.exec ./grub-macho2img
+	./grub-macho2img --bss $< $@
+endif
+endif
+
+cdboot.exec: cdboot_img-boot_i386_pc_cdboot.o
+	$(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(cdboot_img_LDFLAGS)
+
+cdboot_img-boot_i386_pc_cdboot.o: boot/i386/pc/cdboot.S $(boot/i386/pc/cdboot.S_DEPENDENCIES)
+	$(TARGET_CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(cdboot_img_ASFLAGS) -MD -c -o $@ $<
+-include cdboot_img-boot_i386_pc_cdboot.d
+
+cdboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00
+cdboot_img_FORMAT = binary
+
+# For kernel.img.
+kernel_img_SOURCES = kern/i386/pc/startup.S \
+	kern/i386/misc.S \
+	kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+	kern/$(target_cpu)/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \
+	kern/parser.c kern/partition.c \
+	kern/i386/tsc.c kern/i386/pit.c \
+	kern/generic/rtc_get_time_ms.c \
+	kern/generic/millisleep.c \
+	kern/env.c \
+	term/i386/pc/console.c term/i386/vga_common.c \
+	symlist.c
+
+clean-image-kernel.img.1:
+	rm -f kernel.img kernel.exec kernel_img-kern_i386_pc_startup.o kernel_img-kern_i386_misc.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern_time.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_i386_pc_init.o kernel_img-kern_i386_pc_mmap.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_i386_tsc.o kernel_img-kern_i386_pit.o kernel_img-kern_generic_rtc_get_time_ms.o kernel_img-kern_generic_millisleep.o kernel_img-kern_env.o kernel_img-term_i386_pc_console.o kernel_img-term_i386_vga_common.o kernel_img-symlist.o
+
+CLEAN_IMAGE_TARGETS += clean-image-kernel.img.1
+
+mostlyclean-image-kernel.img.1:
+	rm -f kernel_img-kern_i386_pc_startup.d kernel_img-kern_i386_misc.d kernel_img-kern_main.d kernel_img-kern_device.d kernel_img-kern_disk.d kernel_img-kern_dl.d kernel_img-kern_file.d kernel_img-kern_fs.d kernel_img-kern_err.d kernel_img-kern_misc.d kernel_img-kern_mm.d kernel_img-kern_reader.d kernel_img-kern_term.d kernel_img-kern_rescue_parser.d kernel_img-kern_rescue_reader.d kernel_img-kern_time.d kernel_img-kern_list.d kernel_img-kern_handler.d kernel_img-kern_command.d kernel_img-kern_corecmd.d kernel_img-kern___target_cpu__dl.d kernel_img-kern_i386_pc_init.d kernel_img-kern_i386_pc_mmap.d kernel_img-kern_parser.d kernel_img-kern_partition.d kernel_img-kern_i386_tsc.d kernel_img-kern_i386_pit.d kernel_img-kern_generic_rtc_get_time_ms.d kernel_img-kern_generic_millisleep.d kernel_img-kern_env.d kernel_img-term_i386_pc_console.d kernel_img-term_i386_vga_common.d kernel_img-symlist.d
+
+MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-kernel.img.1
+
+ifneq ($(TARGET_APPLE_CC),1)
+kernel.img: kernel.exec
+	$(OBJCOPY) -O $(kernel_img_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
+else
+ifneq (kernel.exec,kernel.exec)
+kernel.img: kernel.exec ./grub-macho2img
+	./grub-macho2img $< $@
+else
+kernel.img: kernel.exec ./grub-macho2img
+	./grub-macho2img --bss $< $@
+endif
+endif
+
+kernel.exec: kernel_img-kern_i386_pc_startup.o kernel_img-kern_i386_misc.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern_time.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_i386_pc_init.o kernel_img-kern_i386_pc_mmap.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_i386_tsc.o kernel_img-kern_i386_pit.o kernel_img-kern_generic_rtc_get_time_ms.o kernel_img-kern_generic_millisleep.o kernel_img-kern_env.o kernel_img-term_i386_pc_console.o kernel_img-term_i386_vga_common.o kernel_img-symlist.o
+	$(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(kernel_img_LDFLAGS)
+
+kernel_img-kern_i386_pc_startup.o: kern/i386/pc/startup.S $(kern/i386/pc/startup.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/pc -I$(srcdir)/kern/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_pc_startup.d
+
+kernel_img-kern_i386_misc.o: kern/i386/misc.S $(kern/i386/misc.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_misc.d
+
+kernel_img-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_main.d
+
+kernel_img-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_device.d
+
+kernel_img-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_disk.d
+
+kernel_img-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_dl.d
+
+kernel_img-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_file.d
+
+kernel_img-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_fs.d
+
+kernel_img-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_err.d
+
+kernel_img-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_misc.d
+
+kernel_img-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_mm.d
+
+kernel_img-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_reader.d
+
+kernel_img-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_term.d
+
+kernel_img-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_rescue_parser.d
+
+kernel_img-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_rescue_reader.d
+
+kernel_img-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_time.d
+
+kernel_img-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_list.d
+
+kernel_img-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_handler.d
+
+kernel_img-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_command.d
+
+kernel_img-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_corecmd.d
+
+kernel_img-kern___target_cpu__dl.o: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern___target_cpu__dl.d
+
+kernel_img-kern_i386_pc_init.o: kern/i386/pc/init.c $(kern/i386/pc/init.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/pc -I$(srcdir)/kern/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_pc_init.d
+
+kernel_img-kern_i386_pc_mmap.o: kern/i386/pc/mmap.c $(kern/i386/pc/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/pc -I$(srcdir)/kern/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_pc_mmap.d
+
+kernel_img-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_parser.d
+
+kernel_img-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_partition.d
+
+kernel_img-kern_i386_tsc.o: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_tsc.d
+
+kernel_img-kern_i386_pit.o: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_i386_pit.d
+
+kernel_img-kern_generic_rtc_get_time_ms.o: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_generic_rtc_get_time_ms.d
+
+kernel_img-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_generic_millisleep.d
+
+kernel_img-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_env.d
+
+kernel_img-term_i386_pc_console.o: term/i386/pc/console.c $(term/i386/pc/console.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-term_i386_pc_console.d
+
+kernel_img-term_i386_vga_common.o: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-term_i386_vga_common.d
+
+kernel_img-symlist.o: symlist.c $(symlist.c_DEPENDENCIES)
+	$(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-symlist.d
+
+kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
+	machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
+	machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h
+kernel_img_CFLAGS = $(COMMON_CFLAGS)  $(TARGET_IMG_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
+kernel_img_FORMAT = binary
+
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# Utilities.
+bin_UTILITIES = grub-mkimage
+sbin_UTILITIES = grub-setup grub-mkdevicemap
+ifeq ($(enable_grub_emu), yes)
+sbin_UTILITIES += grub-emu
+endif
+
+# For grub-mkimage.
+grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \
+	util/resolve.c lib/LzmaEnc.c lib/LzFind.c
+
+clean-utility-grub-mkimage.1:
+	rm -f grub-mkimage$(EXEEXT) grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o grub_mkimage-lib_LzmaEnc.o grub_mkimage-lib_LzFind.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkimage.1
+
+mostlyclean-utility-grub-mkimage.1:
+	rm -f grub_mkimage-util_i386_pc_grub_mkimage.d grub_mkimage-util_misc.d grub_mkimage-util_resolve.d grub_mkimage-lib_LzmaEnc.d grub_mkimage-lib_LzFind.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkimage.1
+
+grub_mkimage_OBJECTS += grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o grub_mkimage-lib_LzmaEnc.o grub_mkimage-lib_LzFind.o
+
+grub_mkimage-util_i386_pc_grub_mkimage.o: util/i386/pc/grub-mkimage.c $(util/i386/pc/grub-mkimage.c_DEPENDENCIES)
+	$(CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_i386_pc_grub_mkimage.d
+
+grub_mkimage-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_misc.d
+
+grub_mkimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_resolve.d
+
+grub_mkimage-lib_LzmaEnc.o: lib/LzmaEnc.c $(lib/LzmaEnc.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-lib_LzmaEnc.d
+
+grub_mkimage-lib_LzFind.o: lib/LzFind.c $(lib/LzFind.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-lib_LzFind.d
+
+grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
+util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile
+
+# For grub-setup.
+util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h
+grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c	\
+	util/misc.c util/getroot.c kern/device.c kern/disk.c	\
+	kern/err.c kern/misc.c kern/parser.c kern/partition.c	\
+	kern/file.c kern/fs.c kern/env.c fs/fshelp.c		\
+	\
+	fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c	\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c		\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c	\
+	fs/befs.c fs/befs_be.c fs/tar.c			\
+	\
+	partmap/msdos.c partmap/gpt.c				\
+	\
+	disk/raid.c disk/mdraid_linux.c disk/lvm.c		\
+	util/raid.c util/lvm.c					\
+	grub_setup_init.c
+
+clean-utility-grub-setup.1:
+	rm -f grub-setup$(EXEEXT) grub_setup-util_i386_pc_grub_setup.o grub_setup-util_hostdisk.o grub_setup-util_misc.o grub_setup-util_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o grub_setup-fs_affs.o grub_setup-fs_cpio.o grub_setup-fs_ext2.o grub_setup-fs_fat.o grub_setup-fs_hfs.o grub_setup-fs_hfsplus.o grub_setup-fs_iso9660.o grub_setup-fs_udf.o grub_setup-fs_jfs.o grub_setup-fs_minix.o grub_setup-fs_ntfs.o grub_setup-fs_ntfscomp.o grub_setup-fs_reiserfs.o grub_setup-fs_sfs.o grub_setup-fs_ufs.o grub_setup-fs_ufs2.o grub_setup-fs_xfs.o grub_setup-fs_afs.o grub_setup-fs_afs_be.o grub_setup-fs_befs.o grub_setup-fs_befs_be.o grub_setup-fs_tar.o grub_setup-partmap_msdos.o grub_setup-partmap_gpt.o grub_setup-disk_raid.o grub_setup-disk_mdraid_linux.o grub_setup-disk_lvm.o grub_setup-util_raid.o grub_setup-util_lvm.o grub_setup-grub_setup_init.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-setup.1
+
+mostlyclean-utility-grub-setup.1:
+	rm -f grub_setup-util_i386_pc_grub_setup.d grub_setup-util_hostdisk.d grub_setup-util_misc.d grub_setup-util_getroot.d grub_setup-kern_device.d grub_setup-kern_disk.d grub_setup-kern_err.d grub_setup-kern_misc.d grub_setup-kern_parser.d grub_setup-kern_partition.d grub_setup-kern_file.d grub_setup-kern_fs.d grub_setup-kern_env.d grub_setup-fs_fshelp.d grub_setup-fs_affs.d grub_setup-fs_cpio.d grub_setup-fs_ext2.d grub_setup-fs_fat.d grub_setup-fs_hfs.d grub_setup-fs_hfsplus.d grub_setup-fs_iso9660.d grub_setup-fs_udf.d grub_setup-fs_jfs.d grub_setup-fs_minix.d grub_setup-fs_ntfs.d grub_setup-fs_ntfscomp.d grub_setup-fs_reiserfs.d grub_setup-fs_sfs.d grub_setup-fs_ufs.d grub_setup-fs_ufs2.d grub_setup-fs_xfs.d grub_setup-fs_afs.d grub_setup-fs_afs_be.d grub_setup-fs_befs.d grub_setup-fs_befs_be.d grub_setup-fs_tar.d grub_setup-partmap_msdos.d grub_setup-partmap_gpt.d grub_setup-disk_raid.d grub_setup-disk_mdraid_linux.d grub_setup-disk_lvm.d grub_setup-util_raid.d grub_setup-util_lvm.d grub_setup-grub_setup_init.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-setup.1
+
+grub_setup_OBJECTS += grub_setup-util_i386_pc_grub_setup.o grub_setup-util_hostdisk.o grub_setup-util_misc.o grub_setup-util_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o grub_setup-fs_affs.o grub_setup-fs_cpio.o grub_setup-fs_ext2.o grub_setup-fs_fat.o grub_setup-fs_hfs.o grub_setup-fs_hfsplus.o grub_setup-fs_iso9660.o grub_setup-fs_udf.o grub_setup-fs_jfs.o grub_setup-fs_minix.o grub_setup-fs_ntfs.o grub_setup-fs_ntfscomp.o grub_setup-fs_reiserfs.o grub_setup-fs_sfs.o grub_setup-fs_ufs.o grub_setup-fs_ufs2.o grub_setup-fs_xfs.o grub_setup-fs_afs.o grub_setup-fs_afs_be.o grub_setup-fs_befs.o grub_setup-fs_befs_be.o grub_setup-fs_tar.o grub_setup-partmap_msdos.o grub_setup-partmap_gpt.o grub_setup-disk_raid.o grub_setup-disk_mdraid_linux.o grub_setup-disk_lvm.o grub_setup-util_raid.o grub_setup-util_lvm.o grub_setup-grub_setup_init.o
+
+grub_setup-util_i386_pc_grub_setup.o: util/i386/pc/grub-setup.c $(util/i386/pc/grub-setup.c_DEPENDENCIES)
+	$(CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_i386_pc_grub_setup.d
+
+grub_setup-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_hostdisk.d
+
+grub_setup-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_misc.d
+
+grub_setup-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_getroot.d
+
+grub_setup-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_device.d
+
+grub_setup-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_disk.d
+
+grub_setup-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_err.d
+
+grub_setup-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_misc.d
+
+grub_setup-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_parser.d
+
+grub_setup-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_partition.d
+
+grub_setup-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_file.d
+
+grub_setup-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_fs.d
+
+grub_setup-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_env.d
+
+grub_setup-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_fshelp.d
+
+grub_setup-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_affs.d
+
+grub_setup-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_cpio.d
+
+grub_setup-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_ext2.d
+
+grub_setup-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_fat.d
+
+grub_setup-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_hfs.d
+
+grub_setup-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_hfsplus.d
+
+grub_setup-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_iso9660.d
+
+grub_setup-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_udf.d
+
+grub_setup-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_jfs.d
+
+grub_setup-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_minix.d
+
+grub_setup-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_ntfs.d
+
+grub_setup-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_ntfscomp.d
+
+grub_setup-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_reiserfs.d
+
+grub_setup-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_sfs.d
+
+grub_setup-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_ufs.d
+
+grub_setup-fs_ufs2.o: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_ufs2.d
+
+grub_setup-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_xfs.d
+
+grub_setup-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_afs.d
+
+grub_setup-fs_afs_be.o: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_afs_be.d
+
+grub_setup-fs_befs.o: fs/befs.c $(fs/befs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_befs.d
+
+grub_setup-fs_befs_be.o: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_befs_be.d
+
+grub_setup-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_tar.d
+
+grub_setup-partmap_msdos.o: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-partmap_msdos.d
+
+grub_setup-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-partmap_gpt.d
+
+grub_setup-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-disk_raid.d
+
+grub_setup-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-disk_mdraid_linux.d
+
+grub_setup-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-disk_lvm.d
+
+grub_setup-util_raid.o: util/raid.c $(util/raid.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_raid.d
+
+grub_setup-util_lvm.o: util/lvm.c $(util/lvm.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_lvm.d
+
+grub_setup-grub_setup_init.o: grub_setup_init.c $(grub_setup_init.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-grub_setup_init.d
+
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/devicemap.c util/misc.c
+
+clean-utility-grub-mkdevicemap.1:
+	rm -f grub-mkdevicemap$(EXEEXT) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_devicemap.o grub_mkdevicemap-util_misc.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkdevicemap.1
+
+mostlyclean-utility-grub-mkdevicemap.1:
+	rm -f grub_mkdevicemap-util_grub_mkdevicemap.d grub_mkdevicemap-util_deviceiter.d grub_mkdevicemap-util_devicemap.d grub_mkdevicemap-util_misc.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkdevicemap.1
+
+grub_mkdevicemap_OBJECTS += grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_devicemap.o grub_mkdevicemap-util_misc.o
+
+grub_mkdevicemap-util_grub_mkdevicemap.o: util/grub-mkdevicemap.c $(util/grub-mkdevicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_grub_mkdevicemap.d
+
+grub_mkdevicemap-util_deviceiter.o: util/deviceiter.c $(util/deviceiter.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_deviceiter.d
+
+grub_mkdevicemap-util_devicemap.o: util/devicemap.c $(util/devicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_devicemap.d
+
+grub_mkdevicemap-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_misc.d
+
+
+# For grub-emu.
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c	\
+	commands/configfile.c commands/echo.c commands/help.c		\
+	commands/handler.c commands/ls.c commands/test.c 		\
+	commands/search.c commands/blocklist.c commands/hexdump.c	\
+	lib/hexdump.c commands/i386/pc/halt.c commands/reboot.c		\
+	lib/envblk.c commands/loadenv.c					\
+	commands/gptsync.c commands/probe.c commands/xnu_uuid.c		\
+	commands/i386/cpuid.c	\
+	commands/password.c commands/keystatus.c			\
+	disk/host.c disk/loopback.c disk/scsi.c				\
+	fs/fshelp.c 	\
+	\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/list.c kern/handler.c				\
+	kern/command.c kern/corecmd.c commands/extcmd.c	kern/file.c	\
+	kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c	\
+	kern/partition.c kern/reader.c kern/term.c			\
+	kern/rescue_reader.c kern/rescue_parser.c			\
+	lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.c	\
+	normal/handler.c normal/auth.c normal/autofs.c				\
+	normal/completion.c normal/main.c normal/color.c		\
+	normal/menu.c normal/menu_entry.c normal/menu_viewer.c		\
+	normal/menu_text.c						\
+	script/sh/main.c script/sh/execute.c script/sh/function.c	\
+	script/sh/lexer.c script/sh/script.c grub_script.tab.c		\
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c partmap/gpt.c					\
+	\
+	fs/affs.c fs/cpio.c  fs/fat.c fs/ext2.c fs/hfs.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c		\
+	fs/befs.c fs/befs_be.c fs/tar.c				\
+	\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	commands/parttool.c parttool/msdospart.c				\
+	grub_emu_init.c
+
+clean-utility-grub-emu.1:
+	rm -f grub-emu$(EXEEXT) grub_emu-commands_minicmd.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_handler.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_i386_pc_halt.o grub_emu-commands_reboot.o grub_emu-lib_envblk.o grub_emu-commands_loadenv.o grub_emu-commands_gptsync.o grub_emu-commands_probe.o grub_emu-commands_xnu_uuid.o grub_emu-commands_i386_cpuid.o grub_emu-commands_password.o grub_emu-commands_keystatus.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-disk_scsi.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_list.o grub_emu-kern_handler.o grub_emu-kern_command.o grub_emu-kern_corecmd.o grub_emu-commands_extcmd.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-commands_boot.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_reader.o grub_emu-kern_term.o grub_emu-kern_rescue_reader.o grub_emu-kern_rescue_parser.o grub_emu-lib_arg.o grub_emu-normal_cmdline.o grub_emu-normal_datetime.o grub_emu-normal_misc.o grub_emu-normal_handler.o grub_emu-normal_auth.o grub_emu-normal_autofs.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_color.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_menu_text.o grub_emu-script_sh_main.o grub_emu-script_sh_execute.o grub_emu-script_sh_function.o grub_emu-script_sh_lexer.o grub_emu-script_sh_script.o grub_emu-grub_script_tab.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_msdos.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_ufs2.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_afs_be.o grub_emu-fs_befs.o grub_emu-fs_befs_be.o grub_emu-fs_tar.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-commands_parttool.o grub_emu-parttool_msdospart.o grub_emu-grub_emu_init.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-emu.1
+
+mostlyclean-utility-grub-emu.1:
+	rm -f grub_emu-commands_minicmd.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_echo.d grub_emu-commands_help.d grub_emu-commands_handler.d grub_emu-commands_ls.d grub_emu-commands_test.d grub_emu-commands_search.d grub_emu-commands_blocklist.d grub_emu-commands_hexdump.d grub_emu-lib_hexdump.d grub_emu-commands_i386_pc_halt.d grub_emu-commands_reboot.d grub_emu-lib_envblk.d grub_emu-commands_loadenv.d grub_emu-commands_gptsync.d grub_emu-commands_probe.d grub_emu-commands_xnu_uuid.d grub_emu-commands_i386_cpuid.d grub_emu-commands_password.d grub_emu-commands_keystatus.d grub_emu-disk_host.d grub_emu-disk_loopback.d grub_emu-disk_scsi.d grub_emu-fs_fshelp.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_elf.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-kern_list.d grub_emu-kern_handler.d grub_emu-kern_command.d grub_emu-kern_corecmd.d grub_emu-commands_extcmd.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-commands_boot.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-kern_partition.d grub_emu-kern_reader.d grub_emu-kern_term.d grub_emu-kern_rescue_reader.d grub_emu-kern_rescue_parser.d grub_emu-lib_arg.d grub_emu-normal_cmdline.d grub_emu-normal_datetime.d grub_emu-normal_misc.d grub_emu-normal_handler.d grub_emu-normal_auth.d grub_emu-normal_autofs.d grub_emu-normal_completion.d grub_emu-normal_main.d grub_emu-normal_color.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d grub_emu-normal_menu_viewer.d grub_emu-normal_menu_text.d grub_emu-script_sh_main.d grub_emu-script_sh_execute.d grub_emu-script_sh_function.d grub_emu-script_sh_lexer.d grub_emu-script_sh_script.d grub_emu-grub_script_tab.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_msdos.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-partmap_gpt.d grub_emu-fs_affs.d grub_emu-fs_cpio.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_hfs.d grub_emu-fs_hfsplus.d grub_emu-fs_iso9660.d grub_emu-fs_udf.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ntfs.d grub_emu-fs_ntfscomp.d grub_emu-fs_reiserfs.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_ufs2.d grub_emu-fs_xfs.d grub_emu-fs_afs.d grub_emu-fs_afs_be.d grub_emu-fs_befs.d grub_emu-fs_befs_be.d grub_emu-fs_tar.d grub_emu-util_console.d grub_emu-util_hostfs.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_hostdisk.d grub_emu-util_getroot.d grub_emu-disk_raid.d grub_emu-disk_raid5_recover.d grub_emu-disk_raid6_recover.d grub_emu-disk_mdraid_linux.d grub_emu-disk_dmraid_nvidia.d grub_emu-disk_lvm.d grub_emu-commands_parttool.d grub_emu-parttool_msdospart.d grub_emu-grub_emu_init.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-emu.1
+
+grub_emu_OBJECTS += grub_emu-commands_minicmd.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_handler.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_i386_pc_halt.o grub_emu-commands_reboot.o grub_emu-lib_envblk.o grub_emu-commands_loadenv.o grub_emu-commands_gptsync.o grub_emu-commands_probe.o grub_emu-commands_xnu_uuid.o grub_emu-commands_i386_cpuid.o grub_emu-commands_password.o grub_emu-commands_keystatus.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-disk_scsi.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_list.o grub_emu-kern_handler.o grub_emu-kern_command.o grub_emu-kern_corecmd.o grub_emu-commands_extcmd.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-commands_boot.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_reader.o grub_emu-kern_term.o grub_emu-kern_rescue_reader.o grub_emu-kern_rescue_parser.o grub_emu-lib_arg.o grub_emu-normal_cmdline.o grub_emu-normal_datetime.o grub_emu-normal_misc.o grub_emu-normal_handler.o grub_emu-normal_auth.o grub_emu-normal_autofs.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_color.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_menu_text.o grub_emu-script_sh_main.o grub_emu-script_sh_execute.o grub_emu-script_sh_function.o grub_emu-script_sh_lexer.o grub_emu-script_sh_script.o grub_emu-grub_script_tab.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_msdos.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_ufs2.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_afs_be.o grub_emu-fs_befs.o grub_emu-fs_befs_be.o grub_emu-fs_tar.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-commands_parttool.o grub_emu-parttool_msdospart.o grub_emu-grub_emu_init.o
+
+grub_emu-commands_minicmd.o: commands/minicmd.c $(commands/minicmd.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_minicmd.d
+
+grub_emu-commands_cat.o: commands/cat.c $(commands/cat.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_cat.d
+
+grub_emu-commands_cmp.o: commands/cmp.c $(commands/cmp.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_cmp.d
+
+grub_emu-commands_configfile.o: commands/configfile.c $(commands/configfile.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_configfile.d
+
+grub_emu-commands_echo.o: commands/echo.c $(commands/echo.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_echo.d
+
+grub_emu-commands_help.o: commands/help.c $(commands/help.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_help.d
+
+grub_emu-commands_handler.o: commands/handler.c $(commands/handler.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_handler.d
+
+grub_emu-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_ls.d
+
+grub_emu-commands_test.o: commands/test.c $(commands/test.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_test.d
+
+grub_emu-commands_search.o: commands/search.c $(commands/search.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_search.d
+
+grub_emu-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_blocklist.d
+
+grub_emu-commands_hexdump.o: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_hexdump.d
+
+grub_emu-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_hexdump.d
+
+grub_emu-commands_i386_pc_halt.o: commands/i386/pc/halt.c $(commands/i386/pc/halt.c_DEPENDENCIES)
+	$(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_i386_pc_halt.d
+
+grub_emu-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_reboot.d
+
+grub_emu-lib_envblk.o: lib/envblk.c $(lib/envblk.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_envblk.d
+
+grub_emu-commands_loadenv.o: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_loadenv.d
+
+grub_emu-commands_gptsync.o: commands/gptsync.c $(commands/gptsync.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_gptsync.d
+
+grub_emu-commands_probe.o: commands/probe.c $(commands/probe.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_probe.d
+
+grub_emu-commands_xnu_uuid.o: commands/xnu_uuid.c $(commands/xnu_uuid.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_xnu_uuid.d
+
+grub_emu-commands_i386_cpuid.o: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES)
+	$(CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_i386_cpuid.d
+
+grub_emu-commands_password.o: commands/password.c $(commands/password.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_password.d
+
+grub_emu-commands_keystatus.o: commands/keystatus.c $(commands/keystatus.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_keystatus.d
+
+grub_emu-disk_host.o: disk/host.c $(disk/host.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_host.d
+
+grub_emu-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_loopback.d
+
+grub_emu-disk_scsi.o: disk/scsi.c $(disk/scsi.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_scsi.d
+
+grub_emu-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_fshelp.d
+
+grub_emu-io_gzio.o: io/gzio.c $(io/gzio.c_DEPENDENCIES)
+	$(CC) -Iio -I$(srcdir)/io $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-io_gzio.d
+
+grub_emu-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_device.d
+
+grub_emu-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_disk.d
+
+grub_emu-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_dl.d
+
+grub_emu-kern_elf.o: kern/elf.c $(kern/elf.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_elf.d
+
+grub_emu-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_env.d
+
+grub_emu-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_err.d
+
+grub_emu-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_list.d
+
+grub_emu-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_handler.d
+
+grub_emu-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_command.d
+
+grub_emu-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_corecmd.d
+
+grub_emu-commands_extcmd.o: commands/extcmd.c $(commands/extcmd.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_extcmd.d
+
+grub_emu-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_file.d
+
+grub_emu-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_fs.d
+
+grub_emu-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_boot.d
+
+grub_emu-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_main.d
+
+grub_emu-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_misc.d
+
+grub_emu-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_parser.d
+
+grub_emu-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_partition.d
+
+grub_emu-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_reader.d
+
+grub_emu-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_term.d
+
+grub_emu-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_rescue_reader.d
+
+grub_emu-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_rescue_parser.d
+
+grub_emu-lib_arg.o: lib/arg.c $(lib/arg.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_arg.d
+
+grub_emu-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_cmdline.d
+
+grub_emu-normal_datetime.o: normal/datetime.c $(normal/datetime.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_datetime.d
+
+grub_emu-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_misc.d
+
+grub_emu-normal_handler.o: normal/handler.c $(normal/handler.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_handler.d
+
+grub_emu-normal_auth.o: normal/auth.c $(normal/auth.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_auth.d
+
+grub_emu-normal_autofs.o: normal/autofs.c $(normal/autofs.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_autofs.d
+
+grub_emu-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_completion.d
+
+grub_emu-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_main.d
+
+grub_emu-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_color.d
+
+grub_emu-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu.d
+
+grub_emu-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_entry.d
+
+grub_emu-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_viewer.d
+
+grub_emu-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_text.d
+
+grub_emu-script_sh_main.o: script/sh/main.c $(script/sh/main.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_main.d
+
+grub_emu-script_sh_execute.o: script/sh/execute.c $(script/sh/execute.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_execute.d
+
+grub_emu-script_sh_function.o: script/sh/function.c $(script/sh/function.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_function.d
+
+grub_emu-script_sh_lexer.o: script/sh/lexer.c $(script/sh/lexer.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_lexer.d
+
+grub_emu-script_sh_script.o: script/sh/script.c $(script/sh/script.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_script.d
+
+grub_emu-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-grub_script_tab.d
+
+grub_emu-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_amiga.d
+
+grub_emu-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_apple.d
+
+grub_emu-partmap_msdos.o: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_msdos.d
+
+grub_emu-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_sun.d
+
+grub_emu-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_acorn.d
+
+grub_emu-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_gpt.d
+
+grub_emu-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_affs.d
+
+grub_emu-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_cpio.d
+
+grub_emu-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_fat.d
+
+grub_emu-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ext2.d
+
+grub_emu-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_hfs.d
+
+grub_emu-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_hfsplus.d
+
+grub_emu-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_iso9660.d
+
+grub_emu-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_udf.d
+
+grub_emu-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_jfs.d
+
+grub_emu-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_minix.d
+
+grub_emu-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ntfs.d
+
+grub_emu-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ntfscomp.d
+
+grub_emu-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_reiserfs.d
+
+grub_emu-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_sfs.d
+
+grub_emu-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ufs.d
+
+grub_emu-fs_ufs2.o: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ufs2.d
+
+grub_emu-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_xfs.d
+
+grub_emu-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_afs.d
+
+grub_emu-fs_afs_be.o: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_afs_be.d
+
+grub_emu-fs_befs.o: fs/befs.c $(fs/befs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_befs.d
+
+grub_emu-fs_befs_be.o: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_befs_be.d
+
+grub_emu-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_tar.d
+
+grub_emu-util_console.o: util/console.c $(util/console.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_console.d
+
+grub_emu-util_hostfs.o: util/hostfs.c $(util/hostfs.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_hostfs.d
+
+grub_emu-util_grub_emu.o: util/grub-emu.c $(util/grub-emu.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_grub_emu.d
+
+grub_emu-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_misc.d
+
+grub_emu-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_hostdisk.d
+
+grub_emu-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_getroot.d
+
+grub_emu-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid.d
+
+grub_emu-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid5_recover.d
+
+grub_emu-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid6_recover.d
+
+grub_emu-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_mdraid_linux.d
+
+grub_emu-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_dmraid_nvidia.d
+
+grub_emu-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_lvm.d
+
+grub_emu-commands_parttool.o: commands/parttool.c $(commands/parttool.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_parttool.d
+
+grub_emu-parttool_msdospart.o: parttool/msdospart.c $(parttool/msdospart.c_DEPENDENCIES)
+	$(CC) -Iparttool -I$(srcdir)/parttool $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-parttool_msdospart.d
+
+grub_emu-grub_emu_init.o: grub_emu_init.c $(grub_emu_init.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-grub_emu_init.d
+
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+ifeq ($(enable_grub_emu_usb), yes)
+grub_emu_SOURCES += disk/usbms.c util/usb.c bus/usb/usb.c	\
+		commands/usbtest.c
+
+clean-utility-grub-emu.2:
+	rm -f grub-emu$(EXEEXT) grub_emu-disk_usbms.o grub_emu-util_usb.o grub_emu-bus_usb_usb.o grub_emu-commands_usbtest.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-emu.2
+
+mostlyclean-utility-grub-emu.2:
+	rm -f grub_emu-disk_usbms.d grub_emu-util_usb.d grub_emu-bus_usb_usb.d grub_emu-commands_usbtest.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-emu.2
+
+grub_emu_OBJECTS += grub_emu-disk_usbms.o grub_emu-util_usb.o grub_emu-bus_usb_usb.o grub_emu-commands_usbtest.o
+
+grub_emu-disk_usbms.o: disk/usbms.c $(disk/usbms.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_usbms.d
+
+grub_emu-util_usb.o: util/usb.c $(util/usb.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_usb.d
+
+grub_emu-bus_usb_usb.o: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES)
+	$(CC) -Ibus/usb -I$(srcdir)/bus/usb $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-bus_usb_usb.d
+
+grub_emu-commands_usbtest.o: commands/usbtest.c $(commands/usbtest.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_usbtest.d
+
+grub_emu_LDFLAGS += $(LIBCURSES) $(LIBUSB)
+endif
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+bin_SCRIPTS = grub-mkrescue
+
+# For grub-install.
+grub_install_SOURCES = util/i386/pc/grub-install.in
+CLEANFILES += grub-install
+
+grub-install: util/i386/pc/grub-install.in $(util/i386/pc/grub-install.in_DEPENDENCIES) config.status
+	./config.status --file=grub-install:util/i386/pc/grub-install.in
+	chmod +x $@
+
+
+# For grub-mkrescue.
+grub_mkrescue_SOURCES = util/i386/pc/grub-mkrescue.in
+CLEANFILES += grub-mkrescue
+
+grub-mkrescue: util/i386/pc/grub-mkrescue.in $(util/i386/pc/grub-mkrescue.in_DEPENDENCIES) config.status
+	./config.status --file=grub-mkrescue:util/i386/pc/grub-mkrescue.in
+	chmod +x $@
+
+
+pkglib_MODULES = biosdisk.mod chain.mod \
+	multiboot.mod reboot.mod halt.mod	\
+	vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod	\
+	ata.mod vga.mod memdisk.mod pci.mod lspci.mod	\
+	aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
+	datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \
+	usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \
+	efiemu.mod mmap.mod acpi.mod drivemap.mod
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+
+clean-module-boot.mod.1:
+	rm -f boot.mod mod-boot.o mod-boot.c pre-boot.o boot_mod-commands_boot.o boot_mod-lib_i386_pc_biosnum.o und-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod.1
+
+ifneq ($(boot_mod_EXPORTS),no)
+clean-module-boot.mod-symbol.1:
+	rm -f def-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod-symbol.1
+DEFSYMFILES += def-boot.lst
+endif
+mostlyclean-module-boot.mod.1:
+	rm -f boot_mod-commands_boot.d boot_mod-lib_i386_pc_biosnum.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-boot.mod.1
+UNDSYMFILES += und-boot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-boot.o mod-boot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-boot.o mod-boot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-boot.o: $(boot_mod_DEPENDENCIES) boot_mod-commands_boot.o boot_mod-lib_i386_pc_biosnum.o
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ boot_mod-commands_boot.o boot_mod-lib_i386_pc_biosnum.o
+
+mod-boot.o: mod-boot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -c -o $@ $<
+
+mod-boot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'boot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(boot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-boot.lst: pre-boot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+else
+def-boot.lst: pre-boot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+endif
+endif
+
+und-boot.lst: pre-boot.o
+	echo 'boot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+boot_mod-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $<
+-include boot_mod-commands_boot.d
+
+clean-module-boot_mod-commands_boot-extra.1:
+	rm -f cmd-boot_mod-commands_boot.lst fs-boot_mod-commands_boot.lst partmap-boot_mod-commands_boot.lst handler-boot_mod-commands_boot.lst parttool-boot_mod-commands_boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot_mod-commands_boot-extra.1
+
+COMMANDFILES += cmd-boot_mod-commands_boot.lst
+FSFILES += fs-boot_mod-commands_boot.lst
+PARTTOOLFILES += parttool-boot_mod-commands_boot.lst
+PARTMAPFILES += partmap-boot_mod-commands_boot.lst
+HANDLERFILES += handler-boot_mod-commands_boot.lst
+
+cmd-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1)
+
+fs-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1)
+
+parttool-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh boot > $@ || (rm -f $@; exit 1)
+
+partmap-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1)
+
+handler-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh boot > $@ || (rm -f $@; exit 1)
+
+boot_mod-lib_i386_pc_biosnum.o: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $<
+-include boot_mod-lib_i386_pc_biosnum.d
+
+clean-module-boot_mod-lib_i386_pc_biosnum-extra.1:
+	rm -f cmd-boot_mod-lib_i386_pc_biosnum.lst fs-boot_mod-lib_i386_pc_biosnum.lst partmap-boot_mod-lib_i386_pc_biosnum.lst handler-boot_mod-lib_i386_pc_biosnum.lst parttool-boot_mod-lib_i386_pc_biosnum.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot_mod-lib_i386_pc_biosnum-extra.1
+
+COMMANDFILES += cmd-boot_mod-lib_i386_pc_biosnum.lst
+FSFILES += fs-boot_mod-lib_i386_pc_biosnum.lst
+PARTTOOLFILES += parttool-boot_mod-lib_i386_pc_biosnum.lst
+PARTMAPFILES += partmap-boot_mod-lib_i386_pc_biosnum.lst
+HANDLERFILES += handler-boot_mod-lib_i386_pc_biosnum.lst
+
+cmd-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1)
+
+fs-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1)
+
+parttool-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh boot > $@ || (rm -f $@; exit 1)
+
+partmap-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1)
+
+handler-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh boot > $@ || (rm -f $@; exit 1)
+
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For drivemap.mod.
+drivemap_mod_SOURCES = commands/i386/pc/drivemap.c \
+                       commands/i386/pc/drivemap_int13h.S
+
+clean-module-drivemap.mod.1:
+	rm -f drivemap.mod mod-drivemap.o mod-drivemap.c pre-drivemap.o drivemap_mod-commands_i386_pc_drivemap.o drivemap_mod-commands_i386_pc_drivemap_int13h.o und-drivemap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-drivemap.mod.1
+
+ifneq ($(drivemap_mod_EXPORTS),no)
+clean-module-drivemap.mod-symbol.1:
+	rm -f def-drivemap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-drivemap.mod-symbol.1
+DEFSYMFILES += def-drivemap.lst
+endif
+mostlyclean-module-drivemap.mod.1:
+	rm -f drivemap_mod-commands_i386_pc_drivemap.d drivemap_mod-commands_i386_pc_drivemap_int13h.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-drivemap.mod.1
+UNDSYMFILES += und-drivemap.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+drivemap.mod: pre-drivemap.o mod-drivemap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(drivemap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-drivemap.o mod-drivemap.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+drivemap.mod: pre-drivemap.o mod-drivemap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(drivemap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-drivemap.o mod-drivemap.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-drivemap.o: $(drivemap_mod_DEPENDENCIES) drivemap_mod-commands_i386_pc_drivemap.o drivemap_mod-commands_i386_pc_drivemap_int13h.o
+	-rm -f $@
+	$(TARGET_CC) $(drivemap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ drivemap_mod-commands_i386_pc_drivemap.o drivemap_mod-commands_i386_pc_drivemap_int13h.o
+
+mod-drivemap.o: mod-drivemap.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(drivemap_mod_CFLAGS) -c -o $@ $<
+
+mod-drivemap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'drivemap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(drivemap_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-drivemap.lst: pre-drivemap.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 drivemap/' > $@
+else
+def-drivemap.lst: pre-drivemap.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 drivemap/' > $@
+endif
+endif
+
+und-drivemap.lst: pre-drivemap.o
+	echo 'drivemap' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+drivemap_mod-commands_i386_pc_drivemap.o: commands/i386/pc/drivemap.c $(commands/i386/pc/drivemap.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(drivemap_mod_CFLAGS) -MD -c -o $@ $<
+-include drivemap_mod-commands_i386_pc_drivemap.d
+
+clean-module-drivemap_mod-commands_i386_pc_drivemap-extra.1:
+	rm -f cmd-drivemap_mod-commands_i386_pc_drivemap.lst fs-drivemap_mod-commands_i386_pc_drivemap.lst partmap-drivemap_mod-commands_i386_pc_drivemap.lst handler-drivemap_mod-commands_i386_pc_drivemap.lst parttool-drivemap_mod-commands_i386_pc_drivemap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-drivemap_mod-commands_i386_pc_drivemap-extra.1
+
+COMMANDFILES += cmd-drivemap_mod-commands_i386_pc_drivemap.lst
+FSFILES += fs-drivemap_mod-commands_i386_pc_drivemap.lst
+PARTTOOLFILES += parttool-drivemap_mod-commands_i386_pc_drivemap.lst
+PARTMAPFILES += partmap-drivemap_mod-commands_i386_pc_drivemap.lst
+HANDLERFILES += handler-drivemap_mod-commands_i386_pc_drivemap.lst
+
+cmd-drivemap_mod-commands_i386_pc_drivemap.lst: commands/i386/pc/drivemap.c $(commands/i386/pc/drivemap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(drivemap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh drivemap > $@ || (rm -f $@; exit 1)
+
+fs-drivemap_mod-commands_i386_pc_drivemap.lst: commands/i386/pc/drivemap.c $(commands/i386/pc/drivemap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(drivemap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh drivemap > $@ || (rm -f $@; exit 1)
+
+parttool-drivemap_mod-commands_i386_pc_drivemap.lst: commands/i386/pc/drivemap.c $(commands/i386/pc/drivemap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(drivemap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh drivemap > $@ || (rm -f $@; exit 1)
+
+partmap-drivemap_mod-commands_i386_pc_drivemap.lst: commands/i386/pc/drivemap.c $(commands/i386/pc/drivemap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(drivemap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh drivemap > $@ || (rm -f $@; exit 1)
+
+handler-drivemap_mod-commands_i386_pc_drivemap.lst: commands/i386/pc/drivemap.c $(commands/i386/pc/drivemap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(drivemap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh drivemap > $@ || (rm -f $@; exit 1)
+
+drivemap_mod-commands_i386_pc_drivemap_int13h.o: commands/i386/pc/drivemap_int13h.S $(commands/i386/pc/drivemap_int13h.S_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(drivemap_mod_ASFLAGS) -MD -c -o $@ $<
+-include drivemap_mod-commands_i386_pc_drivemap_int13h.d
+
+clean-module-drivemap_mod-commands_i386_pc_drivemap_int13h-extra.1:
+	rm -f cmd-drivemap_mod-commands_i386_pc_drivemap_int13h.lst fs-drivemap_mod-commands_i386_pc_drivemap_int13h.lst partmap-drivemap_mod-commands_i386_pc_drivemap_int13h.lst handler-drivemap_mod-commands_i386_pc_drivemap_int13h.lst parttool-drivemap_mod-commands_i386_pc_drivemap_int13h.lst
+
+CLEAN_MODULE_TARGETS += clean-module-drivemap_mod-commands_i386_pc_drivemap_int13h-extra.1
+
+COMMANDFILES += cmd-drivemap_mod-commands_i386_pc_drivemap_int13h.lst
+FSFILES += fs-drivemap_mod-commands_i386_pc_drivemap_int13h.lst
+PARTTOOLFILES += parttool-drivemap_mod-commands_i386_pc_drivemap_int13h.lst
+PARTMAPFILES += partmap-drivemap_mod-commands_i386_pc_drivemap_int13h.lst
+HANDLERFILES += handler-drivemap_mod-commands_i386_pc_drivemap_int13h.lst
+
+cmd-drivemap_mod-commands_i386_pc_drivemap_int13h.lst: commands/i386/pc/drivemap_int13h.S $(commands/i386/pc/drivemap_int13h.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(drivemap_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh drivemap > $@ || (rm -f $@; exit 1)
+
+fs-drivemap_mod-commands_i386_pc_drivemap_int13h.lst: commands/i386/pc/drivemap_int13h.S $(commands/i386/pc/drivemap_int13h.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(drivemap_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh drivemap > $@ || (rm -f $@; exit 1)
+
+parttool-drivemap_mod-commands_i386_pc_drivemap_int13h.lst: commands/i386/pc/drivemap_int13h.S $(commands/i386/pc/drivemap_int13h.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(drivemap_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh drivemap > $@ || (rm -f $@; exit 1)
+
+partmap-drivemap_mod-commands_i386_pc_drivemap_int13h.lst: commands/i386/pc/drivemap_int13h.S $(commands/i386/pc/drivemap_int13h.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(drivemap_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh drivemap > $@ || (rm -f $@; exit 1)
+
+handler-drivemap_mod-commands_i386_pc_drivemap_int13h.lst: commands/i386/pc/drivemap_int13h.S $(commands/i386/pc/drivemap_int13h.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(drivemap_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh drivemap > $@ || (rm -f $@; exit 1)
+
+drivemap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+drivemap_mod_CFLAGS = $(COMMON_CFLAGS)
+drivemap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For efiemu.mod.
+efiemu_mod_SOURCES = efiemu/main.c efiemu/i386/loadcore32.c \
+		     efiemu/i386/loadcore64.c efiemu/i386/pc/cfgtables.c \
+		     efiemu/mm.c efiemu/loadcore_common.c efiemu/symbols.c \
+		     efiemu/loadcore32.c efiemu/loadcore64.c \
+		     efiemu/prepare32.c efiemu/prepare64.c efiemu/pnvram.c \
+		     efiemu/i386/coredetect.c
+
+clean-module-efiemu.mod.1:
+	rm -f efiemu.mod mod-efiemu.o mod-efiemu.c pre-efiemu.o efiemu_mod-efiemu_main.o efiemu_mod-efiemu_i386_loadcore32.o efiemu_mod-efiemu_i386_loadcore64.o efiemu_mod-efiemu_i386_pc_cfgtables.o efiemu_mod-efiemu_mm.o efiemu_mod-efiemu_loadcore_common.o efiemu_mod-efiemu_symbols.o efiemu_mod-efiemu_loadcore32.o efiemu_mod-efiemu_loadcore64.o efiemu_mod-efiemu_prepare32.o efiemu_mod-efiemu_prepare64.o efiemu_mod-efiemu_pnvram.o efiemu_mod-efiemu_i386_coredetect.o und-efiemu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu.mod.1
+
+ifneq ($(efiemu_mod_EXPORTS),no)
+clean-module-efiemu.mod-symbol.1:
+	rm -f def-efiemu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu.mod-symbol.1
+DEFSYMFILES += def-efiemu.lst
+endif
+mostlyclean-module-efiemu.mod.1:
+	rm -f efiemu_mod-efiemu_main.d efiemu_mod-efiemu_i386_loadcore32.d efiemu_mod-efiemu_i386_loadcore64.d efiemu_mod-efiemu_i386_pc_cfgtables.d efiemu_mod-efiemu_mm.d efiemu_mod-efiemu_loadcore_common.d efiemu_mod-efiemu_symbols.d efiemu_mod-efiemu_loadcore32.d efiemu_mod-efiemu_loadcore64.d efiemu_mod-efiemu_prepare32.d efiemu_mod-efiemu_prepare64.d efiemu_mod-efiemu_pnvram.d efiemu_mod-efiemu_i386_coredetect.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-efiemu.mod.1
+UNDSYMFILES += und-efiemu.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+efiemu.mod: pre-efiemu.o mod-efiemu.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(efiemu_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-efiemu.o mod-efiemu.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+efiemu.mod: pre-efiemu.o mod-efiemu.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(efiemu_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-efiemu.o mod-efiemu.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-efiemu.o: $(efiemu_mod_DEPENDENCIES) efiemu_mod-efiemu_main.o efiemu_mod-efiemu_i386_loadcore32.o efiemu_mod-efiemu_i386_loadcore64.o efiemu_mod-efiemu_i386_pc_cfgtables.o efiemu_mod-efiemu_mm.o efiemu_mod-efiemu_loadcore_common.o efiemu_mod-efiemu_symbols.o efiemu_mod-efiemu_loadcore32.o efiemu_mod-efiemu_loadcore64.o efiemu_mod-efiemu_prepare32.o efiemu_mod-efiemu_prepare64.o efiemu_mod-efiemu_pnvram.o efiemu_mod-efiemu_i386_coredetect.o
+	-rm -f $@
+	$(TARGET_CC) $(efiemu_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ efiemu_mod-efiemu_main.o efiemu_mod-efiemu_i386_loadcore32.o efiemu_mod-efiemu_i386_loadcore64.o efiemu_mod-efiemu_i386_pc_cfgtables.o efiemu_mod-efiemu_mm.o efiemu_mod-efiemu_loadcore_common.o efiemu_mod-efiemu_symbols.o efiemu_mod-efiemu_loadcore32.o efiemu_mod-efiemu_loadcore64.o efiemu_mod-efiemu_prepare32.o efiemu_mod-efiemu_prepare64.o efiemu_mod-efiemu_pnvram.o efiemu_mod-efiemu_i386_coredetect.o
+
+mod-efiemu.o: mod-efiemu.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -c -o $@ $<
+
+mod-efiemu.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'efiemu' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(efiemu_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-efiemu.lst: pre-efiemu.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 efiemu/' > $@
+else
+def-efiemu.lst: pre-efiemu.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 efiemu/' > $@
+endif
+endif
+
+und-efiemu.lst: pre-efiemu.o
+	echo 'efiemu' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+efiemu_mod-efiemu_main.o: efiemu/main.c $(efiemu/main.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_main.d
+
+clean-module-efiemu_mod-efiemu_main-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_main.lst fs-efiemu_mod-efiemu_main.lst partmap-efiemu_mod-efiemu_main.lst handler-efiemu_mod-efiemu_main.lst parttool-efiemu_mod-efiemu_main.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_main-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_main.lst
+FSFILES += fs-efiemu_mod-efiemu_main.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_main.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_main.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_main.lst
+
+cmd-efiemu_mod-efiemu_main.lst: efiemu/main.c $(efiemu/main.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_main.lst: efiemu/main.c $(efiemu/main.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_main.lst: efiemu/main.c $(efiemu/main.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_main.lst: efiemu/main.c $(efiemu/main.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_main.lst: efiemu/main.c $(efiemu/main.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod-efiemu_i386_loadcore32.o: efiemu/i386/loadcore32.c $(efiemu/i386/loadcore32.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_i386_loadcore32.d
+
+clean-module-efiemu_mod-efiemu_i386_loadcore32-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_i386_loadcore32.lst fs-efiemu_mod-efiemu_i386_loadcore32.lst partmap-efiemu_mod-efiemu_i386_loadcore32.lst handler-efiemu_mod-efiemu_i386_loadcore32.lst parttool-efiemu_mod-efiemu_i386_loadcore32.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_i386_loadcore32-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_i386_loadcore32.lst
+FSFILES += fs-efiemu_mod-efiemu_i386_loadcore32.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_i386_loadcore32.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_i386_loadcore32.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_i386_loadcore32.lst
+
+cmd-efiemu_mod-efiemu_i386_loadcore32.lst: efiemu/i386/loadcore32.c $(efiemu/i386/loadcore32.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_i386_loadcore32.lst: efiemu/i386/loadcore32.c $(efiemu/i386/loadcore32.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_i386_loadcore32.lst: efiemu/i386/loadcore32.c $(efiemu/i386/loadcore32.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_i386_loadcore32.lst: efiemu/i386/loadcore32.c $(efiemu/i386/loadcore32.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_i386_loadcore32.lst: efiemu/i386/loadcore32.c $(efiemu/i386/loadcore32.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod-efiemu_i386_loadcore64.o: efiemu/i386/loadcore64.c $(efiemu/i386/loadcore64.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_i386_loadcore64.d
+
+clean-module-efiemu_mod-efiemu_i386_loadcore64-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_i386_loadcore64.lst fs-efiemu_mod-efiemu_i386_loadcore64.lst partmap-efiemu_mod-efiemu_i386_loadcore64.lst handler-efiemu_mod-efiemu_i386_loadcore64.lst parttool-efiemu_mod-efiemu_i386_loadcore64.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_i386_loadcore64-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_i386_loadcore64.lst
+FSFILES += fs-efiemu_mod-efiemu_i386_loadcore64.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_i386_loadcore64.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_i386_loadcore64.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_i386_loadcore64.lst
+
+cmd-efiemu_mod-efiemu_i386_loadcore64.lst: efiemu/i386/loadcore64.c $(efiemu/i386/loadcore64.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_i386_loadcore64.lst: efiemu/i386/loadcore64.c $(efiemu/i386/loadcore64.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_i386_loadcore64.lst: efiemu/i386/loadcore64.c $(efiemu/i386/loadcore64.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_i386_loadcore64.lst: efiemu/i386/loadcore64.c $(efiemu/i386/loadcore64.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_i386_loadcore64.lst: efiemu/i386/loadcore64.c $(efiemu/i386/loadcore64.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod-efiemu_i386_pc_cfgtables.o: efiemu/i386/pc/cfgtables.c $(efiemu/i386/pc/cfgtables.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu/i386/pc -I$(srcdir)/efiemu/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_i386_pc_cfgtables.d
+
+clean-module-efiemu_mod-efiemu_i386_pc_cfgtables-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_i386_pc_cfgtables.lst fs-efiemu_mod-efiemu_i386_pc_cfgtables.lst partmap-efiemu_mod-efiemu_i386_pc_cfgtables.lst handler-efiemu_mod-efiemu_i386_pc_cfgtables.lst parttool-efiemu_mod-efiemu_i386_pc_cfgtables.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_i386_pc_cfgtables-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_i386_pc_cfgtables.lst
+FSFILES += fs-efiemu_mod-efiemu_i386_pc_cfgtables.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_i386_pc_cfgtables.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_i386_pc_cfgtables.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_i386_pc_cfgtables.lst
+
+cmd-efiemu_mod-efiemu_i386_pc_cfgtables.lst: efiemu/i386/pc/cfgtables.c $(efiemu/i386/pc/cfgtables.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386/pc -I$(srcdir)/efiemu/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_i386_pc_cfgtables.lst: efiemu/i386/pc/cfgtables.c $(efiemu/i386/pc/cfgtables.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386/pc -I$(srcdir)/efiemu/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_i386_pc_cfgtables.lst: efiemu/i386/pc/cfgtables.c $(efiemu/i386/pc/cfgtables.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386/pc -I$(srcdir)/efiemu/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_i386_pc_cfgtables.lst: efiemu/i386/pc/cfgtables.c $(efiemu/i386/pc/cfgtables.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386/pc -I$(srcdir)/efiemu/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_i386_pc_cfgtables.lst: efiemu/i386/pc/cfgtables.c $(efiemu/i386/pc/cfgtables.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386/pc -I$(srcdir)/efiemu/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod-efiemu_mm.o: efiemu/mm.c $(efiemu/mm.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_mm.d
+
+clean-module-efiemu_mod-efiemu_mm-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_mm.lst fs-efiemu_mod-efiemu_mm.lst partmap-efiemu_mod-efiemu_mm.lst handler-efiemu_mod-efiemu_mm.lst parttool-efiemu_mod-efiemu_mm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_mm-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_mm.lst
+FSFILES += fs-efiemu_mod-efiemu_mm.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_mm.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_mm.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_mm.lst
+
+cmd-efiemu_mod-efiemu_mm.lst: efiemu/mm.c $(efiemu/mm.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_mm.lst: efiemu/mm.c $(efiemu/mm.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_mm.lst: efiemu/mm.c $(efiemu/mm.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_mm.lst: efiemu/mm.c $(efiemu/mm.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_mm.lst: efiemu/mm.c $(efiemu/mm.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod-efiemu_loadcore_common.o: efiemu/loadcore_common.c $(efiemu/loadcore_common.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_loadcore_common.d
+
+clean-module-efiemu_mod-efiemu_loadcore_common-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_loadcore_common.lst fs-efiemu_mod-efiemu_loadcore_common.lst partmap-efiemu_mod-efiemu_loadcore_common.lst handler-efiemu_mod-efiemu_loadcore_common.lst parttool-efiemu_mod-efiemu_loadcore_common.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_loadcore_common-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_loadcore_common.lst
+FSFILES += fs-efiemu_mod-efiemu_loadcore_common.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_loadcore_common.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_loadcore_common.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_loadcore_common.lst
+
+cmd-efiemu_mod-efiemu_loadcore_common.lst: efiemu/loadcore_common.c $(efiemu/loadcore_common.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_loadcore_common.lst: efiemu/loadcore_common.c $(efiemu/loadcore_common.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_loadcore_common.lst: efiemu/loadcore_common.c $(efiemu/loadcore_common.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_loadcore_common.lst: efiemu/loadcore_common.c $(efiemu/loadcore_common.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_loadcore_common.lst: efiemu/loadcore_common.c $(efiemu/loadcore_common.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod-efiemu_symbols.o: efiemu/symbols.c $(efiemu/symbols.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_symbols.d
+
+clean-module-efiemu_mod-efiemu_symbols-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_symbols.lst fs-efiemu_mod-efiemu_symbols.lst partmap-efiemu_mod-efiemu_symbols.lst handler-efiemu_mod-efiemu_symbols.lst parttool-efiemu_mod-efiemu_symbols.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_symbols-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_symbols.lst
+FSFILES += fs-efiemu_mod-efiemu_symbols.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_symbols.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_symbols.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_symbols.lst
+
+cmd-efiemu_mod-efiemu_symbols.lst: efiemu/symbols.c $(efiemu/symbols.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_symbols.lst: efiemu/symbols.c $(efiemu/symbols.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_symbols.lst: efiemu/symbols.c $(efiemu/symbols.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_symbols.lst: efiemu/symbols.c $(efiemu/symbols.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_symbols.lst: efiemu/symbols.c $(efiemu/symbols.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod-efiemu_loadcore32.o: efiemu/loadcore32.c $(efiemu/loadcore32.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_loadcore32.d
+
+clean-module-efiemu_mod-efiemu_loadcore32-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_loadcore32.lst fs-efiemu_mod-efiemu_loadcore32.lst partmap-efiemu_mod-efiemu_loadcore32.lst handler-efiemu_mod-efiemu_loadcore32.lst parttool-efiemu_mod-efiemu_loadcore32.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_loadcore32-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_loadcore32.lst
+FSFILES += fs-efiemu_mod-efiemu_loadcore32.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_loadcore32.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_loadcore32.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_loadcore32.lst
+
+cmd-efiemu_mod-efiemu_loadcore32.lst: efiemu/loadcore32.c $(efiemu/loadcore32.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_loadcore32.lst: efiemu/loadcore32.c $(efiemu/loadcore32.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_loadcore32.lst: efiemu/loadcore32.c $(efiemu/loadcore32.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_loadcore32.lst: efiemu/loadcore32.c $(efiemu/loadcore32.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_loadcore32.lst: efiemu/loadcore32.c $(efiemu/loadcore32.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod-efiemu_loadcore64.o: efiemu/loadcore64.c $(efiemu/loadcore64.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_loadcore64.d
+
+clean-module-efiemu_mod-efiemu_loadcore64-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_loadcore64.lst fs-efiemu_mod-efiemu_loadcore64.lst partmap-efiemu_mod-efiemu_loadcore64.lst handler-efiemu_mod-efiemu_loadcore64.lst parttool-efiemu_mod-efiemu_loadcore64.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_loadcore64-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_loadcore64.lst
+FSFILES += fs-efiemu_mod-efiemu_loadcore64.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_loadcore64.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_loadcore64.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_loadcore64.lst
+
+cmd-efiemu_mod-efiemu_loadcore64.lst: efiemu/loadcore64.c $(efiemu/loadcore64.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_loadcore64.lst: efiemu/loadcore64.c $(efiemu/loadcore64.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_loadcore64.lst: efiemu/loadcore64.c $(efiemu/loadcore64.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_loadcore64.lst: efiemu/loadcore64.c $(efiemu/loadcore64.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_loadcore64.lst: efiemu/loadcore64.c $(efiemu/loadcore64.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod-efiemu_prepare32.o: efiemu/prepare32.c $(efiemu/prepare32.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_prepare32.d
+
+clean-module-efiemu_mod-efiemu_prepare32-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_prepare32.lst fs-efiemu_mod-efiemu_prepare32.lst partmap-efiemu_mod-efiemu_prepare32.lst handler-efiemu_mod-efiemu_prepare32.lst parttool-efiemu_mod-efiemu_prepare32.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_prepare32-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_prepare32.lst
+FSFILES += fs-efiemu_mod-efiemu_prepare32.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_prepare32.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_prepare32.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_prepare32.lst
+
+cmd-efiemu_mod-efiemu_prepare32.lst: efiemu/prepare32.c $(efiemu/prepare32.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_prepare32.lst: efiemu/prepare32.c $(efiemu/prepare32.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_prepare32.lst: efiemu/prepare32.c $(efiemu/prepare32.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_prepare32.lst: efiemu/prepare32.c $(efiemu/prepare32.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_prepare32.lst: efiemu/prepare32.c $(efiemu/prepare32.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod-efiemu_prepare64.o: efiemu/prepare64.c $(efiemu/prepare64.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_prepare64.d
+
+clean-module-efiemu_mod-efiemu_prepare64-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_prepare64.lst fs-efiemu_mod-efiemu_prepare64.lst partmap-efiemu_mod-efiemu_prepare64.lst handler-efiemu_mod-efiemu_prepare64.lst parttool-efiemu_mod-efiemu_prepare64.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_prepare64-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_prepare64.lst
+FSFILES += fs-efiemu_mod-efiemu_prepare64.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_prepare64.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_prepare64.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_prepare64.lst
+
+cmd-efiemu_mod-efiemu_prepare64.lst: efiemu/prepare64.c $(efiemu/prepare64.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_prepare64.lst: efiemu/prepare64.c $(efiemu/prepare64.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_prepare64.lst: efiemu/prepare64.c $(efiemu/prepare64.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_prepare64.lst: efiemu/prepare64.c $(efiemu/prepare64.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_prepare64.lst: efiemu/prepare64.c $(efiemu/prepare64.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod-efiemu_pnvram.o: efiemu/pnvram.c $(efiemu/pnvram.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_pnvram.d
+
+clean-module-efiemu_mod-efiemu_pnvram-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_pnvram.lst fs-efiemu_mod-efiemu_pnvram.lst partmap-efiemu_mod-efiemu_pnvram.lst handler-efiemu_mod-efiemu_pnvram.lst parttool-efiemu_mod-efiemu_pnvram.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_pnvram-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_pnvram.lst
+FSFILES += fs-efiemu_mod-efiemu_pnvram.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_pnvram.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_pnvram.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_pnvram.lst
+
+cmd-efiemu_mod-efiemu_pnvram.lst: efiemu/pnvram.c $(efiemu/pnvram.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_pnvram.lst: efiemu/pnvram.c $(efiemu/pnvram.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_pnvram.lst: efiemu/pnvram.c $(efiemu/pnvram.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_pnvram.lst: efiemu/pnvram.c $(efiemu/pnvram.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_pnvram.lst: efiemu/pnvram.c $(efiemu/pnvram.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu -I$(srcdir)/efiemu $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod-efiemu_i386_coredetect.o: efiemu/i386/coredetect.c $(efiemu/i386/coredetect.c_DEPENDENCIES)
+	$(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -MD -c -o $@ $<
+-include efiemu_mod-efiemu_i386_coredetect.d
+
+clean-module-efiemu_mod-efiemu_i386_coredetect-extra.1:
+	rm -f cmd-efiemu_mod-efiemu_i386_coredetect.lst fs-efiemu_mod-efiemu_i386_coredetect.lst partmap-efiemu_mod-efiemu_i386_coredetect.lst handler-efiemu_mod-efiemu_i386_coredetect.lst parttool-efiemu_mod-efiemu_i386_coredetect.lst
+
+CLEAN_MODULE_TARGETS += clean-module-efiemu_mod-efiemu_i386_coredetect-extra.1
+
+COMMANDFILES += cmd-efiemu_mod-efiemu_i386_coredetect.lst
+FSFILES += fs-efiemu_mod-efiemu_i386_coredetect.lst
+PARTTOOLFILES += parttool-efiemu_mod-efiemu_i386_coredetect.lst
+PARTMAPFILES += partmap-efiemu_mod-efiemu_i386_coredetect.lst
+HANDLERFILES += handler-efiemu_mod-efiemu_i386_coredetect.lst
+
+cmd-efiemu_mod-efiemu_i386_coredetect.lst: efiemu/i386/coredetect.c $(efiemu/i386/coredetect.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+fs-efiemu_mod-efiemu_i386_coredetect.lst: efiemu/i386/coredetect.c $(efiemu/i386/coredetect.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+parttool-efiemu_mod-efiemu_i386_coredetect.lst: efiemu/i386/coredetect.c $(efiemu/i386/coredetect.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+partmap-efiemu_mod-efiemu_i386_coredetect.lst: efiemu/i386/coredetect.c $(efiemu/i386/coredetect.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+handler-efiemu_mod-efiemu_i386_coredetect.lst: efiemu/i386/coredetect.c $(efiemu/i386/coredetect.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iefiemu/i386 -I$(srcdir)/efiemu/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(efiemu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh efiemu > $@ || (rm -f $@; exit 1)
+
+efiemu_mod_CFLAGS = $(COMMON_CFLAGS)
+efiemu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For acpi.mod.
+acpi_mod_SOURCES = commands/acpi.c commands/i386/pc/acpi.c
+
+clean-module-acpi.mod.1:
+	rm -f acpi.mod mod-acpi.o mod-acpi.c pre-acpi.o acpi_mod-commands_acpi.o acpi_mod-commands_i386_pc_acpi.o und-acpi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-acpi.mod.1
+
+ifneq ($(acpi_mod_EXPORTS),no)
+clean-module-acpi.mod-symbol.1:
+	rm -f def-acpi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-acpi.mod-symbol.1
+DEFSYMFILES += def-acpi.lst
+endif
+mostlyclean-module-acpi.mod.1:
+	rm -f acpi_mod-commands_acpi.d acpi_mod-commands_i386_pc_acpi.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-acpi.mod.1
+UNDSYMFILES += und-acpi.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+acpi.mod: pre-acpi.o mod-acpi.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(acpi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-acpi.o mod-acpi.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+acpi.mod: pre-acpi.o mod-acpi.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(acpi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-acpi.o mod-acpi.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-acpi.o: $(acpi_mod_DEPENDENCIES) acpi_mod-commands_acpi.o acpi_mod-commands_i386_pc_acpi.o
+	-rm -f $@
+	$(TARGET_CC) $(acpi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ acpi_mod-commands_acpi.o acpi_mod-commands_i386_pc_acpi.o
+
+mod-acpi.o: mod-acpi.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -c -o $@ $<
+
+mod-acpi.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'acpi' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(acpi_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-acpi.lst: pre-acpi.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 acpi/' > $@
+else
+def-acpi.lst: pre-acpi.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 acpi/' > $@
+endif
+endif
+
+und-acpi.lst: pre-acpi.o
+	echo 'acpi' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+acpi_mod-commands_acpi.o: commands/acpi.c $(commands/acpi.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -MD -c -o $@ $<
+-include acpi_mod-commands_acpi.d
+
+clean-module-acpi_mod-commands_acpi-extra.1:
+	rm -f cmd-acpi_mod-commands_acpi.lst fs-acpi_mod-commands_acpi.lst partmap-acpi_mod-commands_acpi.lst handler-acpi_mod-commands_acpi.lst parttool-acpi_mod-commands_acpi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-acpi_mod-commands_acpi-extra.1
+
+COMMANDFILES += cmd-acpi_mod-commands_acpi.lst
+FSFILES += fs-acpi_mod-commands_acpi.lst
+PARTTOOLFILES += parttool-acpi_mod-commands_acpi.lst
+PARTMAPFILES += partmap-acpi_mod-commands_acpi.lst
+HANDLERFILES += handler-acpi_mod-commands_acpi.lst
+
+cmd-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh acpi > $@ || (rm -f $@; exit 1)
+
+fs-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh acpi > $@ || (rm -f $@; exit 1)
+
+parttool-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh acpi > $@ || (rm -f $@; exit 1)
+
+partmap-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh acpi > $@ || (rm -f $@; exit 1)
+
+handler-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh acpi > $@ || (rm -f $@; exit 1)
+
+acpi_mod-commands_i386_pc_acpi.o: commands/i386/pc/acpi.c $(commands/i386/pc/acpi.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -MD -c -o $@ $<
+-include acpi_mod-commands_i386_pc_acpi.d
+
+clean-module-acpi_mod-commands_i386_pc_acpi-extra.1:
+	rm -f cmd-acpi_mod-commands_i386_pc_acpi.lst fs-acpi_mod-commands_i386_pc_acpi.lst partmap-acpi_mod-commands_i386_pc_acpi.lst handler-acpi_mod-commands_i386_pc_acpi.lst parttool-acpi_mod-commands_i386_pc_acpi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-acpi_mod-commands_i386_pc_acpi-extra.1
+
+COMMANDFILES += cmd-acpi_mod-commands_i386_pc_acpi.lst
+FSFILES += fs-acpi_mod-commands_i386_pc_acpi.lst
+PARTTOOLFILES += parttool-acpi_mod-commands_i386_pc_acpi.lst
+PARTMAPFILES += partmap-acpi_mod-commands_i386_pc_acpi.lst
+HANDLERFILES += handler-acpi_mod-commands_i386_pc_acpi.lst
+
+cmd-acpi_mod-commands_i386_pc_acpi.lst: commands/i386/pc/acpi.c $(commands/i386/pc/acpi.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh acpi > $@ || (rm -f $@; exit 1)
+
+fs-acpi_mod-commands_i386_pc_acpi.lst: commands/i386/pc/acpi.c $(commands/i386/pc/acpi.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh acpi > $@ || (rm -f $@; exit 1)
+
+parttool-acpi_mod-commands_i386_pc_acpi.lst: commands/i386/pc/acpi.c $(commands/i386/pc/acpi.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh acpi > $@ || (rm -f $@; exit 1)
+
+partmap-acpi_mod-commands_i386_pc_acpi.lst: commands/i386/pc/acpi.c $(commands/i386/pc/acpi.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh acpi > $@ || (rm -f $@; exit 1)
+
+handler-acpi_mod-commands_i386_pc_acpi.lst: commands/i386/pc/acpi.c $(commands/i386/pc/acpi.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh acpi > $@ || (rm -f $@; exit 1)
+
+acpi_mod_CFLAGS = $(COMMON_CFLAGS)
+acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
+		   mmap/i386/pc/mmap.c mmap/i386/pc/mmap_helper.S
+
+clean-module-mmap.mod.1:
+	rm -f mmap.mod mod-mmap.o mod-mmap.c pre-mmap.o mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o mmap_mod-mmap_i386_pc_mmap.o mmap_mod-mmap_i386_pc_mmap_helper.o und-mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap.mod.1
+
+ifneq ($(mmap_mod_EXPORTS),no)
+clean-module-mmap.mod-symbol.1:
+	rm -f def-mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap.mod-symbol.1
+DEFSYMFILES += def-mmap.lst
+endif
+mostlyclean-module-mmap.mod.1:
+	rm -f mmap_mod-mmap_mmap.d mmap_mod-mmap_i386_uppermem.d mmap_mod-mmap_i386_mmap.d mmap_mod-mmap_i386_pc_mmap.d mmap_mod-mmap_i386_pc_mmap_helper.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-mmap.mod.1
+UNDSYMFILES += und-mmap.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+mmap.mod: pre-mmap.o mod-mmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-mmap.o mod-mmap.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+mmap.mod: pre-mmap.o mod-mmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-mmap.o mod-mmap.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-mmap.o: $(mmap_mod_DEPENDENCIES) mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o mmap_mod-mmap_i386_pc_mmap.o mmap_mod-mmap_i386_pc_mmap_helper.o
+	-rm -f $@
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o mmap_mod-mmap_i386_pc_mmap.o mmap_mod-mmap_i386_pc_mmap_helper.o
+
+mod-mmap.o: mod-mmap.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -c -o $@ $<
+
+mod-mmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'mmap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(mmap_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-mmap.lst: pre-mmap.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 mmap/' > $@
+else
+def-mmap.lst: pre-mmap.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 mmap/' > $@
+endif
+endif
+
+und-mmap.lst: pre-mmap.o
+	echo 'mmap' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+mmap_mod-mmap_mmap.o: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_mmap.d
+
+clean-module-mmap_mod-mmap_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_mmap.lst fs-mmap_mod-mmap_mmap.lst partmap-mmap_mod-mmap_mmap.lst handler-mmap_mod-mmap_mmap.lst parttool-mmap_mod-mmap_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_mmap.lst
+FSFILES += fs-mmap_mod-mmap_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_mmap.lst
+
+cmd-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_i386_uppermem.o: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_i386_uppermem.d
+
+clean-module-mmap_mod-mmap_i386_uppermem-extra.1:
+	rm -f cmd-mmap_mod-mmap_i386_uppermem.lst fs-mmap_mod-mmap_i386_uppermem.lst partmap-mmap_mod-mmap_i386_uppermem.lst handler-mmap_mod-mmap_i386_uppermem.lst parttool-mmap_mod-mmap_i386_uppermem.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_i386_uppermem-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_i386_uppermem.lst
+FSFILES += fs-mmap_mod-mmap_i386_uppermem.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_i386_uppermem.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_i386_uppermem.lst
+HANDLERFILES += handler-mmap_mod-mmap_i386_uppermem.lst
+
+cmd-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_i386_mmap.o: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_i386_mmap.d
+
+clean-module-mmap_mod-mmap_i386_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_i386_mmap.lst fs-mmap_mod-mmap_i386_mmap.lst partmap-mmap_mod-mmap_i386_mmap.lst handler-mmap_mod-mmap_i386_mmap.lst parttool-mmap_mod-mmap_i386_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_i386_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_i386_mmap.lst
+FSFILES += fs-mmap_mod-mmap_i386_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_i386_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_i386_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_i386_mmap.lst
+
+cmd-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_i386_pc_mmap.o: mmap/i386/pc/mmap.c $(mmap/i386/pc/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/i386/pc -I$(srcdir)/mmap/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_i386_pc_mmap.d
+
+clean-module-mmap_mod-mmap_i386_pc_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_i386_pc_mmap.lst fs-mmap_mod-mmap_i386_pc_mmap.lst partmap-mmap_mod-mmap_i386_pc_mmap.lst handler-mmap_mod-mmap_i386_pc_mmap.lst parttool-mmap_mod-mmap_i386_pc_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_i386_pc_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_i386_pc_mmap.lst
+FSFILES += fs-mmap_mod-mmap_i386_pc_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_i386_pc_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_i386_pc_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_i386_pc_mmap.lst
+
+cmd-mmap_mod-mmap_i386_pc_mmap.lst: mmap/i386/pc/mmap.c $(mmap/i386/pc/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386/pc -I$(srcdir)/mmap/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_i386_pc_mmap.lst: mmap/i386/pc/mmap.c $(mmap/i386/pc/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386/pc -I$(srcdir)/mmap/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_i386_pc_mmap.lst: mmap/i386/pc/mmap.c $(mmap/i386/pc/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386/pc -I$(srcdir)/mmap/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_i386_pc_mmap.lst: mmap/i386/pc/mmap.c $(mmap/i386/pc/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386/pc -I$(srcdir)/mmap/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_i386_pc_mmap.lst: mmap/i386/pc/mmap.c $(mmap/i386/pc/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386/pc -I$(srcdir)/mmap/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_i386_pc_mmap_helper.o: mmap/i386/pc/mmap_helper.S $(mmap/i386/pc/mmap_helper.S_DEPENDENCIES)
+	$(TARGET_CC) -Immap/i386/pc -I$(srcdir)/mmap/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(mmap_mod_ASFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_i386_pc_mmap_helper.d
+
+clean-module-mmap_mod-mmap_i386_pc_mmap_helper-extra.1:
+	rm -f cmd-mmap_mod-mmap_i386_pc_mmap_helper.lst fs-mmap_mod-mmap_i386_pc_mmap_helper.lst partmap-mmap_mod-mmap_i386_pc_mmap_helper.lst handler-mmap_mod-mmap_i386_pc_mmap_helper.lst parttool-mmap_mod-mmap_i386_pc_mmap_helper.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_i386_pc_mmap_helper-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_i386_pc_mmap_helper.lst
+FSFILES += fs-mmap_mod-mmap_i386_pc_mmap_helper.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_i386_pc_mmap_helper.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_i386_pc_mmap_helper.lst
+HANDLERFILES += handler-mmap_mod-mmap_i386_pc_mmap_helper.lst
+
+cmd-mmap_mod-mmap_i386_pc_mmap_helper.lst: mmap/i386/pc/mmap_helper.S $(mmap/i386/pc/mmap_helper.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386/pc -I$(srcdir)/mmap/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(mmap_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_i386_pc_mmap_helper.lst: mmap/i386/pc/mmap_helper.S $(mmap/i386/pc/mmap_helper.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386/pc -I$(srcdir)/mmap/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(mmap_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_i386_pc_mmap_helper.lst: mmap/i386/pc/mmap_helper.S $(mmap/i386/pc/mmap_helper.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386/pc -I$(srcdir)/mmap/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(mmap_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_i386_pc_mmap_helper.lst: mmap/i386/pc/mmap_helper.S $(mmap/i386/pc/mmap_helper.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386/pc -I$(srcdir)/mmap/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(mmap_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_i386_pc_mmap_helper.lst: mmap/i386/pc/mmap_helper.S $(mmap/i386/pc/mmap_helper.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386/pc -I$(srcdir)/mmap/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(mmap_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For biosdisk.mod.
+biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
+
+clean-module-biosdisk.mod.1:
+	rm -f biosdisk.mod mod-biosdisk.o mod-biosdisk.c pre-biosdisk.o biosdisk_mod-disk_i386_pc_biosdisk.o und-biosdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-biosdisk.mod.1
+
+ifneq ($(biosdisk_mod_EXPORTS),no)
+clean-module-biosdisk.mod-symbol.1:
+	rm -f def-biosdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-biosdisk.mod-symbol.1
+DEFSYMFILES += def-biosdisk.lst
+endif
+mostlyclean-module-biosdisk.mod.1:
+	rm -f biosdisk_mod-disk_i386_pc_biosdisk.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-biosdisk.mod.1
+UNDSYMFILES += und-biosdisk.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+biosdisk.mod: pre-biosdisk.o mod-biosdisk.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(biosdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-biosdisk.o mod-biosdisk.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+biosdisk.mod: pre-biosdisk.o mod-biosdisk.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(biosdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-biosdisk.o mod-biosdisk.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-biosdisk.o: $(biosdisk_mod_DEPENDENCIES) biosdisk_mod-disk_i386_pc_biosdisk.o
+	-rm -f $@
+	$(TARGET_CC) $(biosdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ biosdisk_mod-disk_i386_pc_biosdisk.o
+
+mod-biosdisk.o: mod-biosdisk.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(biosdisk_mod_CFLAGS) -c -o $@ $<
+
+mod-biosdisk.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'biosdisk' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(biosdisk_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-biosdisk.lst: pre-biosdisk.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 biosdisk/' > $@
+else
+def-biosdisk.lst: pre-biosdisk.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 biosdisk/' > $@
+endif
+endif
+
+und-biosdisk.lst: pre-biosdisk.o
+	echo 'biosdisk' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+biosdisk_mod-disk_i386_pc_biosdisk.o: disk/i386/pc/biosdisk.c $(disk/i386/pc/biosdisk.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(biosdisk_mod_CFLAGS) -MD -c -o $@ $<
+-include biosdisk_mod-disk_i386_pc_biosdisk.d
+
+clean-module-biosdisk_mod-disk_i386_pc_biosdisk-extra.1:
+	rm -f cmd-biosdisk_mod-disk_i386_pc_biosdisk.lst fs-biosdisk_mod-disk_i386_pc_biosdisk.lst partmap-biosdisk_mod-disk_i386_pc_biosdisk.lst handler-biosdisk_mod-disk_i386_pc_biosdisk.lst parttool-biosdisk_mod-disk_i386_pc_biosdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-biosdisk_mod-disk_i386_pc_biosdisk-extra.1
+
+COMMANDFILES += cmd-biosdisk_mod-disk_i386_pc_biosdisk.lst
+FSFILES += fs-biosdisk_mod-disk_i386_pc_biosdisk.lst
+PARTTOOLFILES += parttool-biosdisk_mod-disk_i386_pc_biosdisk.lst
+PARTMAPFILES += partmap-biosdisk_mod-disk_i386_pc_biosdisk.lst
+HANDLERFILES += handler-biosdisk_mod-disk_i386_pc_biosdisk.lst
+
+cmd-biosdisk_mod-disk_i386_pc_biosdisk.lst: disk/i386/pc/biosdisk.c $(disk/i386/pc/biosdisk.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(biosdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh biosdisk > $@ || (rm -f $@; exit 1)
+
+fs-biosdisk_mod-disk_i386_pc_biosdisk.lst: disk/i386/pc/biosdisk.c $(disk/i386/pc/biosdisk.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(biosdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh biosdisk > $@ || (rm -f $@; exit 1)
+
+parttool-biosdisk_mod-disk_i386_pc_biosdisk.lst: disk/i386/pc/biosdisk.c $(disk/i386/pc/biosdisk.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(biosdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh biosdisk > $@ || (rm -f $@; exit 1)
+
+partmap-biosdisk_mod-disk_i386_pc_biosdisk.lst: disk/i386/pc/biosdisk.c $(disk/i386/pc/biosdisk.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(biosdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh biosdisk > $@ || (rm -f $@; exit 1)
+
+handler-biosdisk_mod-disk_i386_pc_biosdisk.lst: disk/i386/pc/biosdisk.c $(disk/i386/pc/biosdisk.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(biosdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh biosdisk > $@ || (rm -f $@; exit 1)
+
+biosdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+biosdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For chain.mod.
+chain_mod_SOURCES = loader/i386/pc/chainloader.c
+
+clean-module-chain.mod.1:
+	rm -f chain.mod mod-chain.o mod-chain.c pre-chain.o chain_mod-loader_i386_pc_chainloader.o und-chain.lst
+
+CLEAN_MODULE_TARGETS += clean-module-chain.mod.1
+
+ifneq ($(chain_mod_EXPORTS),no)
+clean-module-chain.mod-symbol.1:
+	rm -f def-chain.lst
+
+CLEAN_MODULE_TARGETS += clean-module-chain.mod-symbol.1
+DEFSYMFILES += def-chain.lst
+endif
+mostlyclean-module-chain.mod.1:
+	rm -f chain_mod-loader_i386_pc_chainloader.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-chain.mod.1
+UNDSYMFILES += und-chain.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+chain.mod: pre-chain.o mod-chain.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-chain.o mod-chain.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+chain.mod: pre-chain.o mod-chain.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-chain.o mod-chain.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-chain.o: $(chain_mod_DEPENDENCIES) chain_mod-loader_i386_pc_chainloader.o
+	-rm -f $@
+	$(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ chain_mod-loader_i386_pc_chainloader.o
+
+mod-chain.o: mod-chain.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -c -o $@ $<
+
+mod-chain.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'chain' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(chain_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-chain.lst: pre-chain.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 chain/' > $@
+else
+def-chain.lst: pre-chain.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 chain/' > $@
+endif
+endif
+
+und-chain.lst: pre-chain.o
+	echo 'chain' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+chain_mod-loader_i386_pc_chainloader.o: loader/i386/pc/chainloader.c $(loader/i386/pc/chainloader.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -MD -c -o $@ $<
+-include chain_mod-loader_i386_pc_chainloader.d
+
+clean-module-chain_mod-loader_i386_pc_chainloader-extra.1:
+	rm -f cmd-chain_mod-loader_i386_pc_chainloader.lst fs-chain_mod-loader_i386_pc_chainloader.lst partmap-chain_mod-loader_i386_pc_chainloader.lst handler-chain_mod-loader_i386_pc_chainloader.lst parttool-chain_mod-loader_i386_pc_chainloader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-chain_mod-loader_i386_pc_chainloader-extra.1
+
+COMMANDFILES += cmd-chain_mod-loader_i386_pc_chainloader.lst
+FSFILES += fs-chain_mod-loader_i386_pc_chainloader.lst
+PARTTOOLFILES += parttool-chain_mod-loader_i386_pc_chainloader.lst
+PARTMAPFILES += partmap-chain_mod-loader_i386_pc_chainloader.lst
+HANDLERFILES += handler-chain_mod-loader_i386_pc_chainloader.lst
+
+cmd-chain_mod-loader_i386_pc_chainloader.lst: loader/i386/pc/chainloader.c $(loader/i386/pc/chainloader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh chain > $@ || (rm -f $@; exit 1)
+
+fs-chain_mod-loader_i386_pc_chainloader.lst: loader/i386/pc/chainloader.c $(loader/i386/pc/chainloader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh chain > $@ || (rm -f $@; exit 1)
+
+parttool-chain_mod-loader_i386_pc_chainloader.lst: loader/i386/pc/chainloader.c $(loader/i386/pc/chainloader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh chain > $@ || (rm -f $@; exit 1)
+
+partmap-chain_mod-loader_i386_pc_chainloader.lst: loader/i386/pc/chainloader.c $(loader/i386/pc/chainloader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh chain > $@ || (rm -f $@; exit 1)
+
+handler-chain_mod-loader_i386_pc_chainloader.lst: loader/i386/pc/chainloader.c $(loader/i386/pc/chainloader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh chain > $@ || (rm -f $@; exit 1)
+
+chain_mod_CFLAGS = $(COMMON_CFLAGS)
+chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += linux16.mod
+linux16_mod_SOURCES = loader/i386/pc/linux.c
+
+clean-module-linux16.mod.1:
+	rm -f linux16.mod mod-linux16.o mod-linux16.c pre-linux16.o linux16_mod-loader_i386_pc_linux.o und-linux16.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux16.mod.1
+
+ifneq ($(linux16_mod_EXPORTS),no)
+clean-module-linux16.mod-symbol.1:
+	rm -f def-linux16.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux16.mod-symbol.1
+DEFSYMFILES += def-linux16.lst
+endif
+mostlyclean-module-linux16.mod.1:
+	rm -f linux16_mod-loader_i386_pc_linux.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-linux16.mod.1
+UNDSYMFILES += und-linux16.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+linux16.mod: pre-linux16.o mod-linux16.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(linux16_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-linux16.o mod-linux16.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+linux16.mod: pre-linux16.o mod-linux16.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(linux16_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-linux16.o mod-linux16.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-linux16.o: $(linux16_mod_DEPENDENCIES) linux16_mod-loader_i386_pc_linux.o
+	-rm -f $@
+	$(TARGET_CC) $(linux16_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux16_mod-loader_i386_pc_linux.o
+
+mod-linux16.o: mod-linux16.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux16_mod_CFLAGS) -c -o $@ $<
+
+mod-linux16.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'linux16' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(linux16_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-linux16.lst: pre-linux16.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux16/' > $@
+else
+def-linux16.lst: pre-linux16.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 linux16/' > $@
+endif
+endif
+
+und-linux16.lst: pre-linux16.o
+	echo 'linux16' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+linux16_mod-loader_i386_pc_linux.o: loader/i386/pc/linux.c $(loader/i386/pc/linux.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux16_mod_CFLAGS) -MD -c -o $@ $<
+-include linux16_mod-loader_i386_pc_linux.d
+
+clean-module-linux16_mod-loader_i386_pc_linux-extra.1:
+	rm -f cmd-linux16_mod-loader_i386_pc_linux.lst fs-linux16_mod-loader_i386_pc_linux.lst partmap-linux16_mod-loader_i386_pc_linux.lst handler-linux16_mod-loader_i386_pc_linux.lst parttool-linux16_mod-loader_i386_pc_linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux16_mod-loader_i386_pc_linux-extra.1
+
+COMMANDFILES += cmd-linux16_mod-loader_i386_pc_linux.lst
+FSFILES += fs-linux16_mod-loader_i386_pc_linux.lst
+PARTTOOLFILES += parttool-linux16_mod-loader_i386_pc_linux.lst
+PARTMAPFILES += partmap-linux16_mod-loader_i386_pc_linux.lst
+HANDLERFILES += handler-linux16_mod-loader_i386_pc_linux.lst
+
+cmd-linux16_mod-loader_i386_pc_linux.lst: loader/i386/pc/linux.c $(loader/i386/pc/linux.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux16_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh linux16 > $@ || (rm -f $@; exit 1)
+
+fs-linux16_mod-loader_i386_pc_linux.lst: loader/i386/pc/linux.c $(loader/i386/pc/linux.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux16_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh linux16 > $@ || (rm -f $@; exit 1)
+
+parttool-linux16_mod-loader_i386_pc_linux.lst: loader/i386/pc/linux.c $(loader/i386/pc/linux.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux16_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh linux16 > $@ || (rm -f $@; exit 1)
+
+partmap-linux16_mod-loader_i386_pc_linux.lst: loader/i386/pc/linux.c $(loader/i386/pc/linux.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux16_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh linux16 > $@ || (rm -f $@; exit 1)
+
+handler-linux16_mod-loader_i386_pc_linux.lst: loader/i386/pc/linux.c $(loader/i386/pc/linux.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux16_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh linux16 > $@ || (rm -f $@; exit 1)
+
+linux16_mod_CFLAGS = $(COMMON_CFLAGS)
+linux16_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += linux.mod
+linux_mod_SOURCES = loader/i386/linux.c
+
+clean-module-linux.mod.1:
+	rm -f linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_i386_linux.o und-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod.1
+
+ifneq ($(linux_mod_EXPORTS),no)
+clean-module-linux.mod-symbol.1:
+	rm -f def-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod-symbol.1
+DEFSYMFILES += def-linux.lst
+endif
+mostlyclean-module-linux.mod.1:
+	rm -f linux_mod-loader_i386_linux.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-linux.mod.1
+UNDSYMFILES += und-linux.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-linux.o mod-linux.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_i386_linux.o
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_i386_linux.o
+
+mod-linux.o: mod-linux.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $<
+
+mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(linux_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-linux.lst: pre-linux.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+else
+def-linux.lst: pre-linux.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+endif
+endif
+
+und-linux.lst: pre-linux.o
+	echo 'linux' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+linux_mod-loader_i386_linux.o: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $<
+-include linux_mod-loader_i386_linux.d
+
+clean-module-linux_mod-loader_i386_linux-extra.1:
+	rm -f cmd-linux_mod-loader_i386_linux.lst fs-linux_mod-loader_i386_linux.lst partmap-linux_mod-loader_i386_linux.lst handler-linux_mod-loader_i386_linux.lst parttool-linux_mod-loader_i386_linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux_mod-loader_i386_linux-extra.1
+
+COMMANDFILES += cmd-linux_mod-loader_i386_linux.lst
+FSFILES += fs-linux_mod-loader_i386_linux.lst
+PARTTOOLFILES += parttool-linux_mod-loader_i386_linux.lst
+PARTMAPFILES += partmap-linux_mod-loader_i386_linux.lst
+HANDLERFILES += handler-linux_mod-loader_i386_linux.lst
+
+cmd-linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1)
+
+fs-linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1)
+
+parttool-linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh linux > $@ || (rm -f $@; exit 1)
+
+partmap-linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1)
+
+handler-linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh linux > $@ || (rm -f $@; exit 1)
+
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += xnu.mod
+xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c\
+	 loader/macho.c loader/xnu.c loader/i386/xnu_helper.S
+
+clean-module-xnu.mod.1:
+	rm -f xnu.mod mod-xnu.o mod-xnu.c pre-xnu.o xnu_mod-loader_xnu_resume.o xnu_mod-loader_i386_xnu.o xnu_mod-loader_i386_pc_xnu.o xnu_mod-loader_macho.o xnu_mod-loader_xnu.o xnu_mod-loader_i386_xnu_helper.o und-xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu.mod.1
+
+ifneq ($(xnu_mod_EXPORTS),no)
+clean-module-xnu.mod-symbol.1:
+	rm -f def-xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu.mod-symbol.1
+DEFSYMFILES += def-xnu.lst
+endif
+mostlyclean-module-xnu.mod.1:
+	rm -f xnu_mod-loader_xnu_resume.d xnu_mod-loader_i386_xnu.d xnu_mod-loader_i386_pc_xnu.d xnu_mod-loader_macho.d xnu_mod-loader_xnu.d xnu_mod-loader_i386_xnu_helper.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-xnu.mod.1
+UNDSYMFILES += und-xnu.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+xnu.mod: pre-xnu.o mod-xnu.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(xnu_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-xnu.o mod-xnu.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+xnu.mod: pre-xnu.o mod-xnu.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(xnu_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-xnu.o mod-xnu.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-xnu.o: $(xnu_mod_DEPENDENCIES) xnu_mod-loader_xnu_resume.o xnu_mod-loader_i386_xnu.o xnu_mod-loader_i386_pc_xnu.o xnu_mod-loader_macho.o xnu_mod-loader_xnu.o xnu_mod-loader_i386_xnu_helper.o
+	-rm -f $@
+	$(TARGET_CC) $(xnu_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ xnu_mod-loader_xnu_resume.o xnu_mod-loader_i386_xnu.o xnu_mod-loader_i386_pc_xnu.o xnu_mod-loader_macho.o xnu_mod-loader_xnu.o xnu_mod-loader_i386_xnu_helper.o
+
+mod-xnu.o: mod-xnu.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -c -o $@ $<
+
+mod-xnu.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'xnu' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(xnu_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-xnu.lst: pre-xnu.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 xnu/' > $@
+else
+def-xnu.lst: pre-xnu.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 xnu/' > $@
+endif
+endif
+
+und-xnu.lst: pre-xnu.o
+	echo 'xnu' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+xnu_mod-loader_xnu_resume.o: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_xnu_resume.d
+
+clean-module-xnu_mod-loader_xnu_resume-extra.1:
+	rm -f cmd-xnu_mod-loader_xnu_resume.lst fs-xnu_mod-loader_xnu_resume.lst partmap-xnu_mod-loader_xnu_resume.lst handler-xnu_mod-loader_xnu_resume.lst parttool-xnu_mod-loader_xnu_resume.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_xnu_resume-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_xnu_resume.lst
+FSFILES += fs-xnu_mod-loader_xnu_resume.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_xnu_resume.lst
+PARTMAPFILES += partmap-xnu_mod-loader_xnu_resume.lst
+HANDLERFILES += handler-xnu_mod-loader_xnu_resume.lst
+
+cmd-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_i386_xnu.o: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_i386_xnu.d
+
+clean-module-xnu_mod-loader_i386_xnu-extra.1:
+	rm -f cmd-xnu_mod-loader_i386_xnu.lst fs-xnu_mod-loader_i386_xnu.lst partmap-xnu_mod-loader_i386_xnu.lst handler-xnu_mod-loader_i386_xnu.lst parttool-xnu_mod-loader_i386_xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_i386_xnu-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_i386_xnu.lst
+FSFILES += fs-xnu_mod-loader_i386_xnu.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_i386_xnu.lst
+PARTMAPFILES += partmap-xnu_mod-loader_i386_xnu.lst
+HANDLERFILES += handler-xnu_mod-loader_i386_xnu.lst
+
+cmd-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_i386_pc_xnu.o: loader/i386/pc/xnu.c $(loader/i386/pc/xnu.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_i386_pc_xnu.d
+
+clean-module-xnu_mod-loader_i386_pc_xnu-extra.1:
+	rm -f cmd-xnu_mod-loader_i386_pc_xnu.lst fs-xnu_mod-loader_i386_pc_xnu.lst partmap-xnu_mod-loader_i386_pc_xnu.lst handler-xnu_mod-loader_i386_pc_xnu.lst parttool-xnu_mod-loader_i386_pc_xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_i386_pc_xnu-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_i386_pc_xnu.lst
+FSFILES += fs-xnu_mod-loader_i386_pc_xnu.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_i386_pc_xnu.lst
+PARTMAPFILES += partmap-xnu_mod-loader_i386_pc_xnu.lst
+HANDLERFILES += handler-xnu_mod-loader_i386_pc_xnu.lst
+
+cmd-xnu_mod-loader_i386_pc_xnu.lst: loader/i386/pc/xnu.c $(loader/i386/pc/xnu.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_i386_pc_xnu.lst: loader/i386/pc/xnu.c $(loader/i386/pc/xnu.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_i386_pc_xnu.lst: loader/i386/pc/xnu.c $(loader/i386/pc/xnu.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_i386_pc_xnu.lst: loader/i386/pc/xnu.c $(loader/i386/pc/xnu.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_i386_pc_xnu.lst: loader/i386/pc/xnu.c $(loader/i386/pc/xnu.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_macho.o: loader/macho.c $(loader/macho.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_macho.d
+
+clean-module-xnu_mod-loader_macho-extra.1:
+	rm -f cmd-xnu_mod-loader_macho.lst fs-xnu_mod-loader_macho.lst partmap-xnu_mod-loader_macho.lst handler-xnu_mod-loader_macho.lst parttool-xnu_mod-loader_macho.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_macho-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_macho.lst
+FSFILES += fs-xnu_mod-loader_macho.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_macho.lst
+PARTMAPFILES += partmap-xnu_mod-loader_macho.lst
+HANDLERFILES += handler-xnu_mod-loader_macho.lst
+
+cmd-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_xnu.o: loader/xnu.c $(loader/xnu.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_xnu.d
+
+clean-module-xnu_mod-loader_xnu-extra.1:
+	rm -f cmd-xnu_mod-loader_xnu.lst fs-xnu_mod-loader_xnu.lst partmap-xnu_mod-loader_xnu.lst handler-xnu_mod-loader_xnu.lst parttool-xnu_mod-loader_xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_xnu-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_xnu.lst
+FSFILES += fs-xnu_mod-loader_xnu.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_xnu.lst
+PARTMAPFILES += partmap-xnu_mod-loader_xnu.lst
+HANDLERFILES += handler-xnu_mod-loader_xnu.lst
+
+cmd-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_i386_xnu_helper.o: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_i386_xnu_helper.d
+
+clean-module-xnu_mod-loader_i386_xnu_helper-extra.1:
+	rm -f cmd-xnu_mod-loader_i386_xnu_helper.lst fs-xnu_mod-loader_i386_xnu_helper.lst partmap-xnu_mod-loader_i386_xnu_helper.lst handler-xnu_mod-loader_i386_xnu_helper.lst parttool-xnu_mod-loader_i386_xnu_helper.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_i386_xnu_helper-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_i386_xnu_helper.lst
+FSFILES += fs-xnu_mod-loader_i386_xnu_helper.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_i386_xnu_helper.lst
+PARTMAPFILES += partmap-xnu_mod-loader_i386_xnu_helper.lst
+HANDLERFILES += handler-xnu_mod-loader_i386_xnu_helper.lst
+
+cmd-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod_CFLAGS = $(COMMON_CFLAGS)
+xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For reboot.mod.
+reboot_mod_SOURCES = commands/reboot.c
+
+clean-module-reboot.mod.1:
+	rm -f reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o und-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod.1
+
+ifneq ($(reboot_mod_EXPORTS),no)
+clean-module-reboot.mod-symbol.1:
+	rm -f def-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod-symbol.1
+DEFSYMFILES += def-reboot.lst
+endif
+mostlyclean-module-reboot.mod.1:
+	rm -f reboot_mod-commands_reboot.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-reboot.mod.1
+UNDSYMFILES += und-reboot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-reboot.o mod-reboot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o
+
+mod-reboot.o: mod-reboot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $<
+
+mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(reboot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-reboot.lst: pre-reboot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+else
+def-reboot.lst: pre-reboot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+endif
+endif
+
+und-reboot.lst: pre-reboot.o
+	echo 'reboot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $<
+-include reboot_mod-commands_reboot.d
+
+clean-module-reboot_mod-commands_reboot-extra.1:
+	rm -f cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst handler-reboot_mod-commands_reboot.lst parttool-reboot_mod-commands_reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot_mod-commands_reboot-extra.1
+
+COMMANDFILES += cmd-reboot_mod-commands_reboot.lst
+FSFILES += fs-reboot_mod-commands_reboot.lst
+PARTTOOLFILES += parttool-reboot_mod-commands_reboot.lst
+PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst
+HANDLERFILES += handler-reboot_mod-commands_reboot.lst
+
+cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1)
+
+parttool-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh reboot > $@ || (rm -f $@; exit 1)
+
+partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1)
+
+handler-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/i386/pc/halt.c
+
+clean-module-halt.mod.1:
+	rm -f halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_i386_pc_halt.o und-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod.1
+
+ifneq ($(halt_mod_EXPORTS),no)
+clean-module-halt.mod-symbol.1:
+	rm -f def-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod-symbol.1
+DEFSYMFILES += def-halt.lst
+endif
+mostlyclean-module-halt.mod.1:
+	rm -f halt_mod-commands_i386_pc_halt.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-halt.mod.1
+UNDSYMFILES += und-halt.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-halt.o mod-halt.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_i386_pc_halt.o
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_i386_pc_halt.o
+
+mod-halt.o: mod-halt.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $<
+
+mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(halt_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-halt.lst: pre-halt.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+else
+def-halt.lst: pre-halt.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+endif
+endif
+
+und-halt.lst: pre-halt.o
+	echo 'halt' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+halt_mod-commands_i386_pc_halt.o: commands/i386/pc/halt.c $(commands/i386/pc/halt.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $<
+-include halt_mod-commands_i386_pc_halt.d
+
+clean-module-halt_mod-commands_i386_pc_halt-extra.1:
+	rm -f cmd-halt_mod-commands_i386_pc_halt.lst fs-halt_mod-commands_i386_pc_halt.lst partmap-halt_mod-commands_i386_pc_halt.lst handler-halt_mod-commands_i386_pc_halt.lst parttool-halt_mod-commands_i386_pc_halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt_mod-commands_i386_pc_halt-extra.1
+
+COMMANDFILES += cmd-halt_mod-commands_i386_pc_halt.lst
+FSFILES += fs-halt_mod-commands_i386_pc_halt.lst
+PARTTOOLFILES += parttool-halt_mod-commands_i386_pc_halt.lst
+PARTMAPFILES += partmap-halt_mod-commands_i386_pc_halt.lst
+HANDLERFILES += handler-halt_mod-commands_i386_pc_halt.lst
+
+cmd-halt_mod-commands_i386_pc_halt.lst: commands/i386/pc/halt.c $(commands/i386/pc/halt.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1)
+
+fs-halt_mod-commands_i386_pc_halt.lst: commands/i386/pc/halt.c $(commands/i386/pc/halt.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1)
+
+parttool-halt_mod-commands_i386_pc_halt.lst: commands/i386/pc/halt.c $(commands/i386/pc/halt.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh halt > $@ || (rm -f $@; exit 1)
+
+partmap-halt_mod-commands_i386_pc_halt.lst: commands/i386/pc/halt.c $(commands/i386/pc/halt.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1)
+
+handler-halt_mod-commands_i386_pc_halt.lst: commands/i386/pc/halt.c $(commands/i386/pc/halt.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh halt > $@ || (rm -f $@; exit 1)
+
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For serial.mod.
+serial_mod_SOURCES = term/i386/pc/serial.c
+
+clean-module-serial.mod.1:
+	rm -f serial.mod mod-serial.o mod-serial.c pre-serial.o serial_mod-term_i386_pc_serial.o und-serial.lst
+
+CLEAN_MODULE_TARGETS += clean-module-serial.mod.1
+
+ifneq ($(serial_mod_EXPORTS),no)
+clean-module-serial.mod-symbol.1:
+	rm -f def-serial.lst
+
+CLEAN_MODULE_TARGETS += clean-module-serial.mod-symbol.1
+DEFSYMFILES += def-serial.lst
+endif
+mostlyclean-module-serial.mod.1:
+	rm -f serial_mod-term_i386_pc_serial.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-serial.mod.1
+UNDSYMFILES += und-serial.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+serial.mod: pre-serial.o mod-serial.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-serial.o mod-serial.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+serial.mod: pre-serial.o mod-serial.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-serial.o mod-serial.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-serial.o: $(serial_mod_DEPENDENCIES) serial_mod-term_i386_pc_serial.o
+	-rm -f $@
+	$(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ serial_mod-term_i386_pc_serial.o
+
+mod-serial.o: mod-serial.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -c -o $@ $<
+
+mod-serial.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'serial' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(serial_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-serial.lst: pre-serial.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 serial/' > $@
+else
+def-serial.lst: pre-serial.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 serial/' > $@
+endif
+endif
+
+und-serial.lst: pre-serial.o
+	echo 'serial' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+serial_mod-term_i386_pc_serial.o: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -MD -c -o $@ $<
+-include serial_mod-term_i386_pc_serial.d
+
+clean-module-serial_mod-term_i386_pc_serial-extra.1:
+	rm -f cmd-serial_mod-term_i386_pc_serial.lst fs-serial_mod-term_i386_pc_serial.lst partmap-serial_mod-term_i386_pc_serial.lst handler-serial_mod-term_i386_pc_serial.lst parttool-serial_mod-term_i386_pc_serial.lst
+
+CLEAN_MODULE_TARGETS += clean-module-serial_mod-term_i386_pc_serial-extra.1
+
+COMMANDFILES += cmd-serial_mod-term_i386_pc_serial.lst
+FSFILES += fs-serial_mod-term_i386_pc_serial.lst
+PARTTOOLFILES += parttool-serial_mod-term_i386_pc_serial.lst
+PARTMAPFILES += partmap-serial_mod-term_i386_pc_serial.lst
+HANDLERFILES += handler-serial_mod-term_i386_pc_serial.lst
+
+cmd-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh serial > $@ || (rm -f $@; exit 1)
+
+fs-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh serial > $@ || (rm -f $@; exit 1)
+
+parttool-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh serial > $@ || (rm -f $@; exit 1)
+
+partmap-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh serial > $@ || (rm -f $@; exit 1)
+
+handler-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh serial > $@ || (rm -f $@; exit 1)
+
+serial_mod_CFLAGS = $(COMMON_CFLAGS)
+serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For multiboot.mod.
+multiboot_mod_SOURCES = loader/i386/multiboot.c \
+			loader/i386/multiboot_helper.S \
+                        loader/i386/pc/multiboot2.c \
+                        loader/multiboot2.c \
+                        loader/multiboot_loader.c
+
+clean-module-multiboot.mod.1:
+	rm -f multiboot.mod mod-multiboot.o mod-multiboot.c pre-multiboot.o multiboot_mod-loader_i386_multiboot.o multiboot_mod-loader_i386_multiboot_helper.o multiboot_mod-loader_i386_pc_multiboot2.o multiboot_mod-loader_multiboot2.o multiboot_mod-loader_multiboot_loader.o und-multiboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot.mod.1
+
+ifneq ($(multiboot_mod_EXPORTS),no)
+clean-module-multiboot.mod-symbol.1:
+	rm -f def-multiboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot.mod-symbol.1
+DEFSYMFILES += def-multiboot.lst
+endif
+mostlyclean-module-multiboot.mod.1:
+	rm -f multiboot_mod-loader_i386_multiboot.d multiboot_mod-loader_i386_multiboot_helper.d multiboot_mod-loader_i386_pc_multiboot2.d multiboot_mod-loader_multiboot2.d multiboot_mod-loader_multiboot_loader.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-multiboot.mod.1
+UNDSYMFILES += und-multiboot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+multiboot.mod: pre-multiboot.o mod-multiboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-multiboot.o mod-multiboot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+multiboot.mod: pre-multiboot.o mod-multiboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-multiboot.o mod-multiboot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-multiboot.o: $(multiboot_mod_DEPENDENCIES) multiboot_mod-loader_i386_multiboot.o multiboot_mod-loader_i386_multiboot_helper.o multiboot_mod-loader_i386_pc_multiboot2.o multiboot_mod-loader_multiboot2.o multiboot_mod-loader_multiboot_loader.o
+	-rm -f $@
+	$(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ multiboot_mod-loader_i386_multiboot.o multiboot_mod-loader_i386_multiboot_helper.o multiboot_mod-loader_i386_pc_multiboot2.o multiboot_mod-loader_multiboot2.o multiboot_mod-loader_multiboot_loader.o
+
+mod-multiboot.o: mod-multiboot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -c -o $@ $<
+
+mod-multiboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'multiboot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(multiboot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-multiboot.lst: pre-multiboot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@
+else
+def-multiboot.lst: pre-multiboot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@
+endif
+endif
+
+und-multiboot.lst: pre-multiboot.o
+	echo 'multiboot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+multiboot_mod-loader_i386_multiboot.o: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_i386_multiboot.d
+
+clean-module-multiboot_mod-loader_i386_multiboot-extra.1:
+	rm -f cmd-multiboot_mod-loader_i386_multiboot.lst fs-multiboot_mod-loader_i386_multiboot.lst partmap-multiboot_mod-loader_i386_multiboot.lst handler-multiboot_mod-loader_i386_multiboot.lst parttool-multiboot_mod-loader_i386_multiboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_i386_multiboot-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_i386_multiboot.lst
+FSFILES += fs-multiboot_mod-loader_i386_multiboot.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_i386_multiboot.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_i386_multiboot.lst
+HANDLERFILES += handler-multiboot_mod-loader_i386_multiboot.lst
+
+cmd-multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_i386_multiboot.lst: loader/i386/multiboot.c $(loader/i386/multiboot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_i386_multiboot_helper.o: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_i386_multiboot_helper.d
+
+clean-module-multiboot_mod-loader_i386_multiboot_helper-extra.1:
+	rm -f cmd-multiboot_mod-loader_i386_multiboot_helper.lst fs-multiboot_mod-loader_i386_multiboot_helper.lst partmap-multiboot_mod-loader_i386_multiboot_helper.lst handler-multiboot_mod-loader_i386_multiboot_helper.lst parttool-multiboot_mod-loader_i386_multiboot_helper.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_i386_multiboot_helper-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_i386_multiboot_helper.lst
+FSFILES += fs-multiboot_mod-loader_i386_multiboot_helper.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_i386_multiboot_helper.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_i386_multiboot_helper.lst
+HANDLERFILES += handler-multiboot_mod-loader_i386_multiboot_helper.lst
+
+cmd-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_i386_multiboot_helper.lst: loader/i386/multiboot_helper.S $(loader/i386/multiboot_helper.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(multiboot_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_i386_pc_multiboot2.o: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_i386_pc_multiboot2.d
+
+clean-module-multiboot_mod-loader_i386_pc_multiboot2-extra.1:
+	rm -f cmd-multiboot_mod-loader_i386_pc_multiboot2.lst fs-multiboot_mod-loader_i386_pc_multiboot2.lst partmap-multiboot_mod-loader_i386_pc_multiboot2.lst handler-multiboot_mod-loader_i386_pc_multiboot2.lst parttool-multiboot_mod-loader_i386_pc_multiboot2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_i386_pc_multiboot2-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_i386_pc_multiboot2.lst
+FSFILES += fs-multiboot_mod-loader_i386_pc_multiboot2.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_i386_pc_multiboot2.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_i386_pc_multiboot2.lst
+HANDLERFILES += handler-multiboot_mod-loader_i386_pc_multiboot2.lst
+
+cmd-multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_multiboot2.o: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_multiboot2.d
+
+clean-module-multiboot_mod-loader_multiboot2-extra.1:
+	rm -f cmd-multiboot_mod-loader_multiboot2.lst fs-multiboot_mod-loader_multiboot2.lst partmap-multiboot_mod-loader_multiboot2.lst handler-multiboot_mod-loader_multiboot2.lst parttool-multiboot_mod-loader_multiboot2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_multiboot2-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_multiboot2.lst
+FSFILES += fs-multiboot_mod-loader_multiboot2.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_multiboot2.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_multiboot2.lst
+HANDLERFILES += handler-multiboot_mod-loader_multiboot2.lst
+
+cmd-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_multiboot_loader.o: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_multiboot_loader.d
+
+clean-module-multiboot_mod-loader_multiboot_loader-extra.1:
+	rm -f cmd-multiboot_mod-loader_multiboot_loader.lst fs-multiboot_mod-loader_multiboot_loader.lst partmap-multiboot_mod-loader_multiboot_loader.lst handler-multiboot_mod-loader_multiboot_loader.lst parttool-multiboot_mod-loader_multiboot_loader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_multiboot_loader-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_multiboot_loader.lst
+FSFILES += fs-multiboot_mod-loader_multiboot_loader.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_multiboot_loader.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_multiboot_loader.lst
+HANDLERFILES += handler-multiboot_mod-loader_multiboot_loader.lst
+
+cmd-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For vbe.mod.
+vbe_mod_SOURCES = video/i386/pc/vbe.c
+
+clean-module-vbe.mod.1:
+	rm -f vbe.mod mod-vbe.o mod-vbe.c pre-vbe.o vbe_mod-video_i386_pc_vbe.o und-vbe.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vbe.mod.1
+
+ifneq ($(vbe_mod_EXPORTS),no)
+clean-module-vbe.mod-symbol.1:
+	rm -f def-vbe.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vbe.mod-symbol.1
+DEFSYMFILES += def-vbe.lst
+endif
+mostlyclean-module-vbe.mod.1:
+	rm -f vbe_mod-video_i386_pc_vbe.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-vbe.mod.1
+UNDSYMFILES += und-vbe.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+vbe.mod: pre-vbe.o mod-vbe.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(vbe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-vbe.o mod-vbe.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+vbe.mod: pre-vbe.o mod-vbe.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(vbe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-vbe.o mod-vbe.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-vbe.o: $(vbe_mod_DEPENDENCIES) vbe_mod-video_i386_pc_vbe.o
+	-rm -f $@
+	$(TARGET_CC) $(vbe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ vbe_mod-video_i386_pc_vbe.o
+
+mod-vbe.o: mod-vbe.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -c -o $@ $<
+
+mod-vbe.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'vbe' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(vbe_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-vbe.lst: pre-vbe.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vbe/' > $@
+else
+def-vbe.lst: pre-vbe.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 vbe/' > $@
+endif
+endif
+
+und-vbe.lst: pre-vbe.o
+	echo 'vbe' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+vbe_mod-video_i386_pc_vbe.o: video/i386/pc/vbe.c $(video/i386/pc/vbe.c_DEPENDENCIES)
+	$(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -MD -c -o $@ $<
+-include vbe_mod-video_i386_pc_vbe.d
+
+clean-module-vbe_mod-video_i386_pc_vbe-extra.1:
+	rm -f cmd-vbe_mod-video_i386_pc_vbe.lst fs-vbe_mod-video_i386_pc_vbe.lst partmap-vbe_mod-video_i386_pc_vbe.lst handler-vbe_mod-video_i386_pc_vbe.lst parttool-vbe_mod-video_i386_pc_vbe.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vbe_mod-video_i386_pc_vbe-extra.1
+
+COMMANDFILES += cmd-vbe_mod-video_i386_pc_vbe.lst
+FSFILES += fs-vbe_mod-video_i386_pc_vbe.lst
+PARTTOOLFILES += parttool-vbe_mod-video_i386_pc_vbe.lst
+PARTMAPFILES += partmap-vbe_mod-video_i386_pc_vbe.lst
+HANDLERFILES += handler-vbe_mod-video_i386_pc_vbe.lst
+
+cmd-vbe_mod-video_i386_pc_vbe.lst: video/i386/pc/vbe.c $(video/i386/pc/vbe.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh vbe > $@ || (rm -f $@; exit 1)
+
+fs-vbe_mod-video_i386_pc_vbe.lst: video/i386/pc/vbe.c $(video/i386/pc/vbe.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh vbe > $@ || (rm -f $@; exit 1)
+
+parttool-vbe_mod-video_i386_pc_vbe.lst: video/i386/pc/vbe.c $(video/i386/pc/vbe.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh vbe > $@ || (rm -f $@; exit 1)
+
+partmap-vbe_mod-video_i386_pc_vbe.lst: video/i386/pc/vbe.c $(video/i386/pc/vbe.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh vbe > $@ || (rm -f $@; exit 1)
+
+handler-vbe_mod-video_i386_pc_vbe.lst: video/i386/pc/vbe.c $(video/i386/pc/vbe.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh vbe > $@ || (rm -f $@; exit 1)
+
+vbe_mod_CFLAGS = $(COMMON_CFLAGS)
+vbe_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For vbeinfo.mod.
+vbeinfo_mod_SOURCES = commands/i386/pc/vbeinfo.c
+
+clean-module-vbeinfo.mod.1:
+	rm -f vbeinfo.mod mod-vbeinfo.o mod-vbeinfo.c pre-vbeinfo.o vbeinfo_mod-commands_i386_pc_vbeinfo.o und-vbeinfo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vbeinfo.mod.1
+
+ifneq ($(vbeinfo_mod_EXPORTS),no)
+clean-module-vbeinfo.mod-symbol.1:
+	rm -f def-vbeinfo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vbeinfo.mod-symbol.1
+DEFSYMFILES += def-vbeinfo.lst
+endif
+mostlyclean-module-vbeinfo.mod.1:
+	rm -f vbeinfo_mod-commands_i386_pc_vbeinfo.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-vbeinfo.mod.1
+UNDSYMFILES += und-vbeinfo.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+vbeinfo.mod: pre-vbeinfo.o mod-vbeinfo.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(vbeinfo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-vbeinfo.o mod-vbeinfo.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+vbeinfo.mod: pre-vbeinfo.o mod-vbeinfo.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(vbeinfo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-vbeinfo.o mod-vbeinfo.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-vbeinfo.o: $(vbeinfo_mod_DEPENDENCIES) vbeinfo_mod-commands_i386_pc_vbeinfo.o
+	-rm -f $@
+	$(TARGET_CC) $(vbeinfo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ vbeinfo_mod-commands_i386_pc_vbeinfo.o
+
+mod-vbeinfo.o: mod-vbeinfo.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbeinfo_mod_CFLAGS) -c -o $@ $<
+
+mod-vbeinfo.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'vbeinfo' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(vbeinfo_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-vbeinfo.lst: pre-vbeinfo.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vbeinfo/' > $@
+else
+def-vbeinfo.lst: pre-vbeinfo.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 vbeinfo/' > $@
+endif
+endif
+
+und-vbeinfo.lst: pre-vbeinfo.o
+	echo 'vbeinfo' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+vbeinfo_mod-commands_i386_pc_vbeinfo.o: commands/i386/pc/vbeinfo.c $(commands/i386/pc/vbeinfo.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbeinfo_mod_CFLAGS) -MD -c -o $@ $<
+-include vbeinfo_mod-commands_i386_pc_vbeinfo.d
+
+clean-module-vbeinfo_mod-commands_i386_pc_vbeinfo-extra.1:
+	rm -f cmd-vbeinfo_mod-commands_i386_pc_vbeinfo.lst fs-vbeinfo_mod-commands_i386_pc_vbeinfo.lst partmap-vbeinfo_mod-commands_i386_pc_vbeinfo.lst handler-vbeinfo_mod-commands_i386_pc_vbeinfo.lst parttool-vbeinfo_mod-commands_i386_pc_vbeinfo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vbeinfo_mod-commands_i386_pc_vbeinfo-extra.1
+
+COMMANDFILES += cmd-vbeinfo_mod-commands_i386_pc_vbeinfo.lst
+FSFILES += fs-vbeinfo_mod-commands_i386_pc_vbeinfo.lst
+PARTTOOLFILES += parttool-vbeinfo_mod-commands_i386_pc_vbeinfo.lst
+PARTMAPFILES += partmap-vbeinfo_mod-commands_i386_pc_vbeinfo.lst
+HANDLERFILES += handler-vbeinfo_mod-commands_i386_pc_vbeinfo.lst
+
+cmd-vbeinfo_mod-commands_i386_pc_vbeinfo.lst: commands/i386/pc/vbeinfo.c $(commands/i386/pc/vbeinfo.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbeinfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh vbeinfo > $@ || (rm -f $@; exit 1)
+
+fs-vbeinfo_mod-commands_i386_pc_vbeinfo.lst: commands/i386/pc/vbeinfo.c $(commands/i386/pc/vbeinfo.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbeinfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh vbeinfo > $@ || (rm -f $@; exit 1)
+
+parttool-vbeinfo_mod-commands_i386_pc_vbeinfo.lst: commands/i386/pc/vbeinfo.c $(commands/i386/pc/vbeinfo.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbeinfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh vbeinfo > $@ || (rm -f $@; exit 1)
+
+partmap-vbeinfo_mod-commands_i386_pc_vbeinfo.lst: commands/i386/pc/vbeinfo.c $(commands/i386/pc/vbeinfo.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbeinfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh vbeinfo > $@ || (rm -f $@; exit 1)
+
+handler-vbeinfo_mod-commands_i386_pc_vbeinfo.lst: commands/i386/pc/vbeinfo.c $(commands/i386/pc/vbeinfo.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbeinfo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh vbeinfo > $@ || (rm -f $@; exit 1)
+
+vbeinfo_mod_CFLAGS = $(COMMON_CFLAGS)
+vbeinfo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For vbetest.mod.
+vbetest_mod_SOURCES = commands/i386/pc/vbetest.c
+
+clean-module-vbetest.mod.1:
+	rm -f vbetest.mod mod-vbetest.o mod-vbetest.c pre-vbetest.o vbetest_mod-commands_i386_pc_vbetest.o und-vbetest.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vbetest.mod.1
+
+ifneq ($(vbetest_mod_EXPORTS),no)
+clean-module-vbetest.mod-symbol.1:
+	rm -f def-vbetest.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vbetest.mod-symbol.1
+DEFSYMFILES += def-vbetest.lst
+endif
+mostlyclean-module-vbetest.mod.1:
+	rm -f vbetest_mod-commands_i386_pc_vbetest.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-vbetest.mod.1
+UNDSYMFILES += und-vbetest.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+vbetest.mod: pre-vbetest.o mod-vbetest.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(vbetest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-vbetest.o mod-vbetest.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+vbetest.mod: pre-vbetest.o mod-vbetest.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(vbetest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-vbetest.o mod-vbetest.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-vbetest.o: $(vbetest_mod_DEPENDENCIES) vbetest_mod-commands_i386_pc_vbetest.o
+	-rm -f $@
+	$(TARGET_CC) $(vbetest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ vbetest_mod-commands_i386_pc_vbetest.o
+
+mod-vbetest.o: mod-vbetest.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbetest_mod_CFLAGS) -c -o $@ $<
+
+mod-vbetest.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'vbetest' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(vbetest_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-vbetest.lst: pre-vbetest.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vbetest/' > $@
+else
+def-vbetest.lst: pre-vbetest.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 vbetest/' > $@
+endif
+endif
+
+und-vbetest.lst: pre-vbetest.o
+	echo 'vbetest' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+vbetest_mod-commands_i386_pc_vbetest.o: commands/i386/pc/vbetest.c $(commands/i386/pc/vbetest.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbetest_mod_CFLAGS) -MD -c -o $@ $<
+-include vbetest_mod-commands_i386_pc_vbetest.d
+
+clean-module-vbetest_mod-commands_i386_pc_vbetest-extra.1:
+	rm -f cmd-vbetest_mod-commands_i386_pc_vbetest.lst fs-vbetest_mod-commands_i386_pc_vbetest.lst partmap-vbetest_mod-commands_i386_pc_vbetest.lst handler-vbetest_mod-commands_i386_pc_vbetest.lst parttool-vbetest_mod-commands_i386_pc_vbetest.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vbetest_mod-commands_i386_pc_vbetest-extra.1
+
+COMMANDFILES += cmd-vbetest_mod-commands_i386_pc_vbetest.lst
+FSFILES += fs-vbetest_mod-commands_i386_pc_vbetest.lst
+PARTTOOLFILES += parttool-vbetest_mod-commands_i386_pc_vbetest.lst
+PARTMAPFILES += partmap-vbetest_mod-commands_i386_pc_vbetest.lst
+HANDLERFILES += handler-vbetest_mod-commands_i386_pc_vbetest.lst
+
+cmd-vbetest_mod-commands_i386_pc_vbetest.lst: commands/i386/pc/vbetest.c $(commands/i386/pc/vbetest.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbetest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh vbetest > $@ || (rm -f $@; exit 1)
+
+fs-vbetest_mod-commands_i386_pc_vbetest.lst: commands/i386/pc/vbetest.c $(commands/i386/pc/vbetest.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbetest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh vbetest > $@ || (rm -f $@; exit 1)
+
+parttool-vbetest_mod-commands_i386_pc_vbetest.lst: commands/i386/pc/vbetest.c $(commands/i386/pc/vbetest.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbetest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh vbetest > $@ || (rm -f $@; exit 1)
+
+partmap-vbetest_mod-commands_i386_pc_vbetest.lst: commands/i386/pc/vbetest.c $(commands/i386/pc/vbetest.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbetest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh vbetest > $@ || (rm -f $@; exit 1)
+
+handler-vbetest_mod-commands_i386_pc_vbetest.lst: commands/i386/pc/vbetest.c $(commands/i386/pc/vbetest.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vbetest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh vbetest > $@ || (rm -f $@; exit 1)
+
+vbetest_mod_CFLAGS = $(COMMON_CFLAGS)
+vbetest_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For play.mod.
+play_mod_SOURCES = commands/i386/pc/play.c
+
+clean-module-play.mod.1:
+	rm -f play.mod mod-play.o mod-play.c pre-play.o play_mod-commands_i386_pc_play.o und-play.lst
+
+CLEAN_MODULE_TARGETS += clean-module-play.mod.1
+
+ifneq ($(play_mod_EXPORTS),no)
+clean-module-play.mod-symbol.1:
+	rm -f def-play.lst
+
+CLEAN_MODULE_TARGETS += clean-module-play.mod-symbol.1
+DEFSYMFILES += def-play.lst
+endif
+mostlyclean-module-play.mod.1:
+	rm -f play_mod-commands_i386_pc_play.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-play.mod.1
+UNDSYMFILES += und-play.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+play.mod: pre-play.o mod-play.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(play_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-play.o mod-play.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+play.mod: pre-play.o mod-play.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(play_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-play.o mod-play.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-play.o: $(play_mod_DEPENDENCIES) play_mod-commands_i386_pc_play.o
+	-rm -f $@
+	$(TARGET_CC) $(play_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ play_mod-commands_i386_pc_play.o
+
+mod-play.o: mod-play.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(play_mod_CFLAGS) -c -o $@ $<
+
+mod-play.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'play' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(play_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-play.lst: pre-play.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 play/' > $@
+else
+def-play.lst: pre-play.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 play/' > $@
+endif
+endif
+
+und-play.lst: pre-play.o
+	echo 'play' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+play_mod-commands_i386_pc_play.o: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(play_mod_CFLAGS) -MD -c -o $@ $<
+-include play_mod-commands_i386_pc_play.d
+
+clean-module-play_mod-commands_i386_pc_play-extra.1:
+	rm -f cmd-play_mod-commands_i386_pc_play.lst fs-play_mod-commands_i386_pc_play.lst partmap-play_mod-commands_i386_pc_play.lst handler-play_mod-commands_i386_pc_play.lst parttool-play_mod-commands_i386_pc_play.lst
+
+CLEAN_MODULE_TARGETS += clean-module-play_mod-commands_i386_pc_play-extra.1
+
+COMMANDFILES += cmd-play_mod-commands_i386_pc_play.lst
+FSFILES += fs-play_mod-commands_i386_pc_play.lst
+PARTTOOLFILES += parttool-play_mod-commands_i386_pc_play.lst
+PARTMAPFILES += partmap-play_mod-commands_i386_pc_play.lst
+HANDLERFILES += handler-play_mod-commands_i386_pc_play.lst
+
+cmd-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh play > $@ || (rm -f $@; exit 1)
+
+fs-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh play > $@ || (rm -f $@; exit 1)
+
+parttool-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh play > $@ || (rm -f $@; exit 1)
+
+partmap-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh play > $@ || (rm -f $@; exit 1)
+
+handler-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh play > $@ || (rm -f $@; exit 1)
+
+play_mod_CFLAGS = $(COMMON_CFLAGS)
+play_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ata.mod.
+ata_mod_SOURCES = disk/ata.c
+
+clean-module-ata.mod.1:
+	rm -f ata.mod mod-ata.o mod-ata.c pre-ata.o ata_mod-disk_ata.o und-ata.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ata.mod.1
+
+ifneq ($(ata_mod_EXPORTS),no)
+clean-module-ata.mod-symbol.1:
+	rm -f def-ata.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ata.mod-symbol.1
+DEFSYMFILES += def-ata.lst
+endif
+mostlyclean-module-ata.mod.1:
+	rm -f ata_mod-disk_ata.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-ata.mod.1
+UNDSYMFILES += und-ata.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+ata.mod: pre-ata.o mod-ata.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(ata_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-ata.o mod-ata.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+ata.mod: pre-ata.o mod-ata.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(ata_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-ata.o mod-ata.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-ata.o: $(ata_mod_DEPENDENCIES) ata_mod-disk_ata.o
+	-rm -f $@
+	$(TARGET_CC) $(ata_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ata_mod-disk_ata.o
+
+mod-ata.o: mod-ata.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -c -o $@ $<
+
+mod-ata.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'ata' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(ata_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-ata.lst: pre-ata.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ata/' > $@
+else
+def-ata.lst: pre-ata.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 ata/' > $@
+endif
+endif
+
+und-ata.lst: pre-ata.o
+	echo 'ata' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+ata_mod-disk_ata.o: disk/ata.c $(disk/ata.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -MD -c -o $@ $<
+-include ata_mod-disk_ata.d
+
+clean-module-ata_mod-disk_ata-extra.1:
+	rm -f cmd-ata_mod-disk_ata.lst fs-ata_mod-disk_ata.lst partmap-ata_mod-disk_ata.lst handler-ata_mod-disk_ata.lst parttool-ata_mod-disk_ata.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ata_mod-disk_ata-extra.1
+
+COMMANDFILES += cmd-ata_mod-disk_ata.lst
+FSFILES += fs-ata_mod-disk_ata.lst
+PARTTOOLFILES += parttool-ata_mod-disk_ata.lst
+PARTMAPFILES += partmap-ata_mod-disk_ata.lst
+HANDLERFILES += handler-ata_mod-disk_ata.lst
+
+cmd-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh ata > $@ || (rm -f $@; exit 1)
+
+fs-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh ata > $@ || (rm -f $@; exit 1)
+
+parttool-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh ata > $@ || (rm -f $@; exit 1)
+
+partmap-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh ata > $@ || (rm -f $@; exit 1)
+
+handler-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh ata > $@ || (rm -f $@; exit 1)
+
+ata_mod_CFLAGS = $(COMMON_CFLAGS)
+ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For vga.mod.
+vga_mod_SOURCES = term/i386/pc/vga.c
+
+clean-module-vga.mod.1:
+	rm -f vga.mod mod-vga.o mod-vga.c pre-vga.o vga_mod-term_i386_pc_vga.o und-vga.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vga.mod.1
+
+ifneq ($(vga_mod_EXPORTS),no)
+clean-module-vga.mod-symbol.1:
+	rm -f def-vga.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vga.mod-symbol.1
+DEFSYMFILES += def-vga.lst
+endif
+mostlyclean-module-vga.mod.1:
+	rm -f vga_mod-term_i386_pc_vga.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-vga.mod.1
+UNDSYMFILES += und-vga.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+vga.mod: pre-vga.o mod-vga.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(vga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-vga.o mod-vga.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+vga.mod: pre-vga.o mod-vga.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(vga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-vga.o mod-vga.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-vga.o: $(vga_mod_DEPENDENCIES) vga_mod-term_i386_pc_vga.o
+	-rm -f $@
+	$(TARGET_CC) $(vga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ vga_mod-term_i386_pc_vga.o
+
+mod-vga.o: mod-vga.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_mod_CFLAGS) -c -o $@ $<
+
+mod-vga.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'vga' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(vga_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-vga.lst: pre-vga.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vga/' > $@
+else
+def-vga.lst: pre-vga.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 vga/' > $@
+endif
+endif
+
+und-vga.lst: pre-vga.o
+	echo 'vga' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+vga_mod-term_i386_pc_vga.o: term/i386/pc/vga.c $(term/i386/pc/vga.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_mod_CFLAGS) -MD -c -o $@ $<
+-include vga_mod-term_i386_pc_vga.d
+
+clean-module-vga_mod-term_i386_pc_vga-extra.1:
+	rm -f cmd-vga_mod-term_i386_pc_vga.lst fs-vga_mod-term_i386_pc_vga.lst partmap-vga_mod-term_i386_pc_vga.lst handler-vga_mod-term_i386_pc_vga.lst parttool-vga_mod-term_i386_pc_vga.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vga_mod-term_i386_pc_vga-extra.1
+
+COMMANDFILES += cmd-vga_mod-term_i386_pc_vga.lst
+FSFILES += fs-vga_mod-term_i386_pc_vga.lst
+PARTTOOLFILES += parttool-vga_mod-term_i386_pc_vga.lst
+PARTMAPFILES += partmap-vga_mod-term_i386_pc_vga.lst
+HANDLERFILES += handler-vga_mod-term_i386_pc_vga.lst
+
+cmd-vga_mod-term_i386_pc_vga.lst: term/i386/pc/vga.c $(term/i386/pc/vga.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh vga > $@ || (rm -f $@; exit 1)
+
+fs-vga_mod-term_i386_pc_vga.lst: term/i386/pc/vga.c $(term/i386/pc/vga.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh vga > $@ || (rm -f $@; exit 1)
+
+parttool-vga_mod-term_i386_pc_vga.lst: term/i386/pc/vga.c $(term/i386/pc/vga.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh vga > $@ || (rm -f $@; exit 1)
+
+partmap-vga_mod-term_i386_pc_vga.lst: term/i386/pc/vga.c $(term/i386/pc/vga.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh vga > $@ || (rm -f $@; exit 1)
+
+handler-vga_mod-term_i386_pc_vga.lst: term/i386/pc/vga.c $(term/i386/pc/vga.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh vga > $@ || (rm -f $@; exit 1)
+
+vga_mod_CFLAGS = $(COMMON_CFLAGS)
+vga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memdisk.mod.
+memdisk_mod_SOURCES = disk/memdisk.c
+
+clean-module-memdisk.mod.1:
+	rm -f memdisk.mod mod-memdisk.o mod-memdisk.c pre-memdisk.o memdisk_mod-disk_memdisk.o und-memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk.mod.1
+
+ifneq ($(memdisk_mod_EXPORTS),no)
+clean-module-memdisk.mod-symbol.1:
+	rm -f def-memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk.mod-symbol.1
+DEFSYMFILES += def-memdisk.lst
+endif
+mostlyclean-module-memdisk.mod.1:
+	rm -f memdisk_mod-disk_memdisk.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-memdisk.mod.1
+UNDSYMFILES += und-memdisk.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-memdisk.o mod-memdisk.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-memdisk.o mod-memdisk.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-memdisk.o: $(memdisk_mod_DEPENDENCIES) memdisk_mod-disk_memdisk.o
+	-rm -f $@
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memdisk_mod-disk_memdisk.o
+
+mod-memdisk.o: mod-memdisk.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -c -o $@ $<
+
+mod-memdisk.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'memdisk' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(memdisk_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-memdisk.lst: pre-memdisk.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@
+else
+def-memdisk.lst: pre-memdisk.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@
+endif
+endif
+
+und-memdisk.lst: pre-memdisk.o
+	echo 'memdisk' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+memdisk_mod-disk_memdisk.o: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -MD -c -o $@ $<
+-include memdisk_mod-disk_memdisk.d
+
+clean-module-memdisk_mod-disk_memdisk-extra.1:
+	rm -f cmd-memdisk_mod-disk_memdisk.lst fs-memdisk_mod-disk_memdisk.lst partmap-memdisk_mod-disk_memdisk.lst handler-memdisk_mod-disk_memdisk.lst parttool-memdisk_mod-disk_memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk_mod-disk_memdisk-extra.1
+
+COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst
+FSFILES += fs-memdisk_mod-disk_memdisk.lst
+PARTTOOLFILES += parttool-memdisk_mod-disk_memdisk.lst
+PARTMAPFILES += partmap-memdisk_mod-disk_memdisk.lst
+HANDLERFILES += handler-memdisk_mod-disk_memdisk.lst
+
+cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+fs-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+parttool-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+partmap-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+handler-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pci.mod
+pci_mod_SOURCES = bus/pci.c
+
+clean-module-pci.mod.1:
+	rm -f pci.mod mod-pci.o mod-pci.c pre-pci.o pci_mod-bus_pci.o und-pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci.mod.1
+
+ifneq ($(pci_mod_EXPORTS),no)
+clean-module-pci.mod-symbol.1:
+	rm -f def-pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci.mod-symbol.1
+DEFSYMFILES += def-pci.lst
+endif
+mostlyclean-module-pci.mod.1:
+	rm -f pci_mod-bus_pci.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-pci.mod.1
+UNDSYMFILES += und-pci.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-pci.o mod-pci.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-pci.o mod-pci.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-pci.o: $(pci_mod_DEPENDENCIES) pci_mod-bus_pci.o
+	-rm -f $@
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pci_mod-bus_pci.o
+
+mod-pci.o: mod-pci.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -c -o $@ $<
+
+mod-pci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'pci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(pci_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-pci.lst: pre-pci.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pci/' > $@
+else
+def-pci.lst: pre-pci.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 pci/' > $@
+endif
+endif
+
+und-pci.lst: pre-pci.o
+	echo 'pci' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+pci_mod-bus_pci.o: bus/pci.c $(bus/pci.c_DEPENDENCIES)
+	$(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -MD -c -o $@ $<
+-include pci_mod-bus_pci.d
+
+clean-module-pci_mod-bus_pci-extra.1:
+	rm -f cmd-pci_mod-bus_pci.lst fs-pci_mod-bus_pci.lst partmap-pci_mod-bus_pci.lst handler-pci_mod-bus_pci.lst parttool-pci_mod-bus_pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci_mod-bus_pci-extra.1
+
+COMMANDFILES += cmd-pci_mod-bus_pci.lst
+FSFILES += fs-pci_mod-bus_pci.lst
+PARTTOOLFILES += parttool-pci_mod-bus_pci.lst
+PARTMAPFILES += partmap-pci_mod-bus_pci.lst
+HANDLERFILES += handler-pci_mod-bus_pci.lst
+
+cmd-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh pci > $@ || (rm -f $@; exit 1)
+
+fs-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh pci > $@ || (rm -f $@; exit 1)
+
+parttool-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh pci > $@ || (rm -f $@; exit 1)
+
+partmap-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh pci > $@ || (rm -f $@; exit 1)
+
+handler-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh pci > $@ || (rm -f $@; exit 1)
+
+pci_mod_CFLAGS = $(COMMON_CFLAGS)
+pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lspci.mod
+lspci_mod_SOURCES = commands/lspci.c
+
+clean-module-lspci.mod.1:
+	rm -f lspci.mod mod-lspci.o mod-lspci.c pre-lspci.o lspci_mod-commands_lspci.o und-lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci.mod.1
+
+ifneq ($(lspci_mod_EXPORTS),no)
+clean-module-lspci.mod-symbol.1:
+	rm -f def-lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci.mod-symbol.1
+DEFSYMFILES += def-lspci.lst
+endif
+mostlyclean-module-lspci.mod.1:
+	rm -f lspci_mod-commands_lspci.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-lspci.mod.1
+UNDSYMFILES += und-lspci.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-lspci.o mod-lspci.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-lspci.o mod-lspci.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-lspci.o: $(lspci_mod_DEPENDENCIES) lspci_mod-commands_lspci.o
+	-rm -f $@
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lspci_mod-commands_lspci.o
+
+mod-lspci.o: mod-lspci.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -c -o $@ $<
+
+mod-lspci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'lspci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(lspci_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-lspci.lst: pre-lspci.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lspci/' > $@
+else
+def-lspci.lst: pre-lspci.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 lspci/' > $@
+endif
+endif
+
+und-lspci.lst: pre-lspci.o
+	echo 'lspci' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+lspci_mod-commands_lspci.o: commands/lspci.c $(commands/lspci.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -MD -c -o $@ $<
+-include lspci_mod-commands_lspci.d
+
+clean-module-lspci_mod-commands_lspci-extra.1:
+	rm -f cmd-lspci_mod-commands_lspci.lst fs-lspci_mod-commands_lspci.lst partmap-lspci_mod-commands_lspci.lst handler-lspci_mod-commands_lspci.lst parttool-lspci_mod-commands_lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci_mod-commands_lspci-extra.1
+
+COMMANDFILES += cmd-lspci_mod-commands_lspci.lst
+FSFILES += fs-lspci_mod-commands_lspci.lst
+PARTTOOLFILES += parttool-lspci_mod-commands_lspci.lst
+PARTMAPFILES += partmap-lspci_mod-commands_lspci.lst
+HANDLERFILES += handler-lspci_mod-commands_lspci.lst
+
+cmd-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh lspci > $@ || (rm -f $@; exit 1)
+
+fs-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh lspci > $@ || (rm -f $@; exit 1)
+
+parttool-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh lspci > $@ || (rm -f $@; exit 1)
+
+partmap-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh lspci > $@ || (rm -f $@; exit 1)
+
+handler-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh lspci > $@ || (rm -f $@; exit 1)
+
+lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For aout.mod
+aout_mod_SOURCES = loader/aout.c
+
+clean-module-aout.mod.1:
+	rm -f aout.mod mod-aout.o mod-aout.c pre-aout.o aout_mod-loader_aout.o und-aout.lst
+
+CLEAN_MODULE_TARGETS += clean-module-aout.mod.1
+
+ifneq ($(aout_mod_EXPORTS),no)
+clean-module-aout.mod-symbol.1:
+	rm -f def-aout.lst
+
+CLEAN_MODULE_TARGETS += clean-module-aout.mod-symbol.1
+DEFSYMFILES += def-aout.lst
+endif
+mostlyclean-module-aout.mod.1:
+	rm -f aout_mod-loader_aout.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-aout.mod.1
+UNDSYMFILES += und-aout.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+aout.mod: pre-aout.o mod-aout.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-aout.o mod-aout.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+aout.mod: pre-aout.o mod-aout.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-aout.o mod-aout.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-aout.o: $(aout_mod_DEPENDENCIES) aout_mod-loader_aout.o
+	-rm -f $@
+	$(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ aout_mod-loader_aout.o
+
+mod-aout.o: mod-aout.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -c -o $@ $<
+
+mod-aout.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'aout' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(aout_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-aout.lst: pre-aout.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 aout/' > $@
+else
+def-aout.lst: pre-aout.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 aout/' > $@
+endif
+endif
+
+und-aout.lst: pre-aout.o
+	echo 'aout' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+aout_mod-loader_aout.o: loader/aout.c $(loader/aout.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -MD -c -o $@ $<
+-include aout_mod-loader_aout.d
+
+clean-module-aout_mod-loader_aout-extra.1:
+	rm -f cmd-aout_mod-loader_aout.lst fs-aout_mod-loader_aout.lst partmap-aout_mod-loader_aout.lst handler-aout_mod-loader_aout.lst parttool-aout_mod-loader_aout.lst
+
+CLEAN_MODULE_TARGETS += clean-module-aout_mod-loader_aout-extra.1
+
+COMMANDFILES += cmd-aout_mod-loader_aout.lst
+FSFILES += fs-aout_mod-loader_aout.lst
+PARTTOOLFILES += parttool-aout_mod-loader_aout.lst
+PARTMAPFILES += partmap-aout_mod-loader_aout.lst
+HANDLERFILES += handler-aout_mod-loader_aout.lst
+
+cmd-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh aout > $@ || (rm -f $@; exit 1)
+
+fs-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh aout > $@ || (rm -f $@; exit 1)
+
+parttool-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh aout > $@ || (rm -f $@; exit 1)
+
+partmap-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh aout > $@ || (rm -f $@; exit 1)
+
+handler-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh aout > $@ || (rm -f $@; exit 1)
+
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bsd.mod
+bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
+
+clean-module-bsd.mod.1:
+	rm -f bsd.mod mod-bsd.o mod-bsd.c pre-bsd.o bsd_mod-loader_i386_bsd.o bsd_mod-loader_i386_bsd32.o bsd_mod-loader_i386_bsd64.o bsd_mod-loader_i386_bsd_helper.o bsd_mod-loader_i386_bsd_trampoline.o und-bsd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd.mod.1
+
+ifneq ($(bsd_mod_EXPORTS),no)
+clean-module-bsd.mod-symbol.1:
+	rm -f def-bsd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd.mod-symbol.1
+DEFSYMFILES += def-bsd.lst
+endif
+mostlyclean-module-bsd.mod.1:
+	rm -f bsd_mod-loader_i386_bsd.d bsd_mod-loader_i386_bsd32.d bsd_mod-loader_i386_bsd64.d bsd_mod-loader_i386_bsd_helper.d bsd_mod-loader_i386_bsd_trampoline.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-bsd.mod.1
+UNDSYMFILES += und-bsd.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+bsd.mod: pre-bsd.o mod-bsd.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(bsd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-bsd.o mod-bsd.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+bsd.mod: pre-bsd.o mod-bsd.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(bsd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-bsd.o mod-bsd.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-bsd.o: $(bsd_mod_DEPENDENCIES) bsd_mod-loader_i386_bsd.o bsd_mod-loader_i386_bsd32.o bsd_mod-loader_i386_bsd64.o bsd_mod-loader_i386_bsd_helper.o bsd_mod-loader_i386_bsd_trampoline.o
+	-rm -f $@
+	$(TARGET_CC) $(bsd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ bsd_mod-loader_i386_bsd.o bsd_mod-loader_i386_bsd32.o bsd_mod-loader_i386_bsd64.o bsd_mod-loader_i386_bsd_helper.o bsd_mod-loader_i386_bsd_trampoline.o
+
+mod-bsd.o: mod-bsd.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -c -o $@ $<
+
+mod-bsd.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'bsd' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(bsd_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-bsd.lst: pre-bsd.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 bsd/' > $@
+else
+def-bsd.lst: pre-bsd.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 bsd/' > $@
+endif
+endif
+
+und-bsd.lst: pre-bsd.o
+	echo 'bsd' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+bsd_mod-loader_i386_bsd.o: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -MD -c -o $@ $<
+-include bsd_mod-loader_i386_bsd.d
+
+clean-module-bsd_mod-loader_i386_bsd-extra.1:
+	rm -f cmd-bsd_mod-loader_i386_bsd.lst fs-bsd_mod-loader_i386_bsd.lst partmap-bsd_mod-loader_i386_bsd.lst handler-bsd_mod-loader_i386_bsd.lst parttool-bsd_mod-loader_i386_bsd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd_mod-loader_i386_bsd-extra.1
+
+COMMANDFILES += cmd-bsd_mod-loader_i386_bsd.lst
+FSFILES += fs-bsd_mod-loader_i386_bsd.lst
+PARTTOOLFILES += parttool-bsd_mod-loader_i386_bsd.lst
+PARTMAPFILES += partmap-bsd_mod-loader_i386_bsd.lst
+HANDLERFILES += handler-bsd_mod-loader_i386_bsd.lst
+
+cmd-bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+fs-bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh bsd > $@ || (rm -f $@; exit 1)
+
+parttool-bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh bsd > $@ || (rm -f $@; exit 1)
+
+partmap-bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh bsd > $@ || (rm -f $@; exit 1)
+
+handler-bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+bsd_mod-loader_i386_bsd32.o: loader/i386/bsd32.c $(loader/i386/bsd32.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -MD -c -o $@ $<
+-include bsd_mod-loader_i386_bsd32.d
+
+clean-module-bsd_mod-loader_i386_bsd32-extra.1:
+	rm -f cmd-bsd_mod-loader_i386_bsd32.lst fs-bsd_mod-loader_i386_bsd32.lst partmap-bsd_mod-loader_i386_bsd32.lst handler-bsd_mod-loader_i386_bsd32.lst parttool-bsd_mod-loader_i386_bsd32.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd_mod-loader_i386_bsd32-extra.1
+
+COMMANDFILES += cmd-bsd_mod-loader_i386_bsd32.lst
+FSFILES += fs-bsd_mod-loader_i386_bsd32.lst
+PARTTOOLFILES += parttool-bsd_mod-loader_i386_bsd32.lst
+PARTMAPFILES += partmap-bsd_mod-loader_i386_bsd32.lst
+HANDLERFILES += handler-bsd_mod-loader_i386_bsd32.lst
+
+cmd-bsd_mod-loader_i386_bsd32.lst: loader/i386/bsd32.c $(loader/i386/bsd32.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+fs-bsd_mod-loader_i386_bsd32.lst: loader/i386/bsd32.c $(loader/i386/bsd32.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh bsd > $@ || (rm -f $@; exit 1)
+
+parttool-bsd_mod-loader_i386_bsd32.lst: loader/i386/bsd32.c $(loader/i386/bsd32.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh bsd > $@ || (rm -f $@; exit 1)
+
+partmap-bsd_mod-loader_i386_bsd32.lst: loader/i386/bsd32.c $(loader/i386/bsd32.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh bsd > $@ || (rm -f $@; exit 1)
+
+handler-bsd_mod-loader_i386_bsd32.lst: loader/i386/bsd32.c $(loader/i386/bsd32.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+bsd_mod-loader_i386_bsd64.o: loader/i386/bsd64.c $(loader/i386/bsd64.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -MD -c -o $@ $<
+-include bsd_mod-loader_i386_bsd64.d
+
+clean-module-bsd_mod-loader_i386_bsd64-extra.1:
+	rm -f cmd-bsd_mod-loader_i386_bsd64.lst fs-bsd_mod-loader_i386_bsd64.lst partmap-bsd_mod-loader_i386_bsd64.lst handler-bsd_mod-loader_i386_bsd64.lst parttool-bsd_mod-loader_i386_bsd64.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd_mod-loader_i386_bsd64-extra.1
+
+COMMANDFILES += cmd-bsd_mod-loader_i386_bsd64.lst
+FSFILES += fs-bsd_mod-loader_i386_bsd64.lst
+PARTTOOLFILES += parttool-bsd_mod-loader_i386_bsd64.lst
+PARTMAPFILES += partmap-bsd_mod-loader_i386_bsd64.lst
+HANDLERFILES += handler-bsd_mod-loader_i386_bsd64.lst
+
+cmd-bsd_mod-loader_i386_bsd64.lst: loader/i386/bsd64.c $(loader/i386/bsd64.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+fs-bsd_mod-loader_i386_bsd64.lst: loader/i386/bsd64.c $(loader/i386/bsd64.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh bsd > $@ || (rm -f $@; exit 1)
+
+parttool-bsd_mod-loader_i386_bsd64.lst: loader/i386/bsd64.c $(loader/i386/bsd64.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh bsd > $@ || (rm -f $@; exit 1)
+
+partmap-bsd_mod-loader_i386_bsd64.lst: loader/i386/bsd64.c $(loader/i386/bsd64.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh bsd > $@ || (rm -f $@; exit 1)
+
+handler-bsd_mod-loader_i386_bsd64.lst: loader/i386/bsd64.c $(loader/i386/bsd64.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+bsd_mod-loader_i386_bsd_helper.o: loader/i386/bsd_helper.S $(loader/i386/bsd_helper.S_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -MD -c -o $@ $<
+-include bsd_mod-loader_i386_bsd_helper.d
+
+clean-module-bsd_mod-loader_i386_bsd_helper-extra.1:
+	rm -f cmd-bsd_mod-loader_i386_bsd_helper.lst fs-bsd_mod-loader_i386_bsd_helper.lst partmap-bsd_mod-loader_i386_bsd_helper.lst handler-bsd_mod-loader_i386_bsd_helper.lst parttool-bsd_mod-loader_i386_bsd_helper.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd_mod-loader_i386_bsd_helper-extra.1
+
+COMMANDFILES += cmd-bsd_mod-loader_i386_bsd_helper.lst
+FSFILES += fs-bsd_mod-loader_i386_bsd_helper.lst
+PARTTOOLFILES += parttool-bsd_mod-loader_i386_bsd_helper.lst
+PARTMAPFILES += partmap-bsd_mod-loader_i386_bsd_helper.lst
+HANDLERFILES += handler-bsd_mod-loader_i386_bsd_helper.lst
+
+cmd-bsd_mod-loader_i386_bsd_helper.lst: loader/i386/bsd_helper.S $(loader/i386/bsd_helper.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+fs-bsd_mod-loader_i386_bsd_helper.lst: loader/i386/bsd_helper.S $(loader/i386/bsd_helper.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh bsd > $@ || (rm -f $@; exit 1)
+
+parttool-bsd_mod-loader_i386_bsd_helper.lst: loader/i386/bsd_helper.S $(loader/i386/bsd_helper.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh bsd > $@ || (rm -f $@; exit 1)
+
+partmap-bsd_mod-loader_i386_bsd_helper.lst: loader/i386/bsd_helper.S $(loader/i386/bsd_helper.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh bsd > $@ || (rm -f $@; exit 1)
+
+handler-bsd_mod-loader_i386_bsd_helper.lst: loader/i386/bsd_helper.S $(loader/i386/bsd_helper.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+bsd_mod-loader_i386_bsd_trampoline.o: loader/i386/bsd_trampoline.S $(loader/i386/bsd_trampoline.S_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -MD -c -o $@ $<
+-include bsd_mod-loader_i386_bsd_trampoline.d
+
+clean-module-bsd_mod-loader_i386_bsd_trampoline-extra.1:
+	rm -f cmd-bsd_mod-loader_i386_bsd_trampoline.lst fs-bsd_mod-loader_i386_bsd_trampoline.lst partmap-bsd_mod-loader_i386_bsd_trampoline.lst handler-bsd_mod-loader_i386_bsd_trampoline.lst parttool-bsd_mod-loader_i386_bsd_trampoline.lst
+
+CLEAN_MODULE_TARGETS += clean-module-bsd_mod-loader_i386_bsd_trampoline-extra.1
+
+COMMANDFILES += cmd-bsd_mod-loader_i386_bsd_trampoline.lst
+FSFILES += fs-bsd_mod-loader_i386_bsd_trampoline.lst
+PARTTOOLFILES += parttool-bsd_mod-loader_i386_bsd_trampoline.lst
+PARTMAPFILES += partmap-bsd_mod-loader_i386_bsd_trampoline.lst
+HANDLERFILES += handler-bsd_mod-loader_i386_bsd_trampoline.lst
+
+cmd-bsd_mod-loader_i386_bsd_trampoline.lst: loader/i386/bsd_trampoline.S $(loader/i386/bsd_trampoline.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+fs-bsd_mod-loader_i386_bsd_trampoline.lst: loader/i386/bsd_trampoline.S $(loader/i386/bsd_trampoline.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh bsd > $@ || (rm -f $@; exit 1)
+
+parttool-bsd_mod-loader_i386_bsd_trampoline.lst: loader/i386/bsd_trampoline.S $(loader/i386/bsd_trampoline.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh bsd > $@ || (rm -f $@; exit 1)
+
+partmap-bsd_mod-loader_i386_bsd_trampoline.lst: loader/i386/bsd_trampoline.S $(loader/i386/bsd_trampoline.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh bsd > $@ || (rm -f $@; exit 1)
+
+handler-bsd_mod-loader_i386_bsd_trampoline.lst: loader/i386/bsd_trampoline.S $(loader/i386/bsd_trampoline.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(bsd_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh bsd > $@ || (rm -f $@; exit 1)
+
+bsd_mod_CFLAGS = $(COMMON_CFLAGS)
+bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For usb.mod
+usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
+
+clean-module-usb.mod.1:
+	rm -f usb.mod mod-usb.o mod-usb.c pre-usb.o usb_mod-bus_usb_usb.o usb_mod-bus_usb_usbtrans.o usb_mod-bus_usb_usbhub.o und-usb.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usb.mod.1
+
+ifneq ($(usb_mod_EXPORTS),no)
+clean-module-usb.mod-symbol.1:
+	rm -f def-usb.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usb.mod-symbol.1
+DEFSYMFILES += def-usb.lst
+endif
+mostlyclean-module-usb.mod.1:
+	rm -f usb_mod-bus_usb_usb.d usb_mod-bus_usb_usbtrans.d usb_mod-bus_usb_usbhub.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-usb.mod.1
+UNDSYMFILES += und-usb.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+usb.mod: pre-usb.o mod-usb.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(usb_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-usb.o mod-usb.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+usb.mod: pre-usb.o mod-usb.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(usb_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-usb.o mod-usb.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-usb.o: $(usb_mod_DEPENDENCIES) usb_mod-bus_usb_usb.o usb_mod-bus_usb_usbtrans.o usb_mod-bus_usb_usbhub.o
+	-rm -f $@
+	$(TARGET_CC) $(usb_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ usb_mod-bus_usb_usb.o usb_mod-bus_usb_usbtrans.o usb_mod-bus_usb_usbhub.o
+
+mod-usb.o: mod-usb.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -c -o $@ $<
+
+mod-usb.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'usb' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(usb_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-usb.lst: pre-usb.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 usb/' > $@
+else
+def-usb.lst: pre-usb.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 usb/' > $@
+endif
+endif
+
+und-usb.lst: pre-usb.o
+	echo 'usb' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+usb_mod-bus_usb_usb.o: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES)
+	$(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -MD -c -o $@ $<
+-include usb_mod-bus_usb_usb.d
+
+clean-module-usb_mod-bus_usb_usb-extra.1:
+	rm -f cmd-usb_mod-bus_usb_usb.lst fs-usb_mod-bus_usb_usb.lst partmap-usb_mod-bus_usb_usb.lst handler-usb_mod-bus_usb_usb.lst parttool-usb_mod-bus_usb_usb.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usb_mod-bus_usb_usb-extra.1
+
+COMMANDFILES += cmd-usb_mod-bus_usb_usb.lst
+FSFILES += fs-usb_mod-bus_usb_usb.lst
+PARTTOOLFILES += parttool-usb_mod-bus_usb_usb.lst
+PARTMAPFILES += partmap-usb_mod-bus_usb_usb.lst
+HANDLERFILES += handler-usb_mod-bus_usb_usb.lst
+
+cmd-usb_mod-bus_usb_usb.lst: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh usb > $@ || (rm -f $@; exit 1)
+
+fs-usb_mod-bus_usb_usb.lst: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh usb > $@ || (rm -f $@; exit 1)
+
+parttool-usb_mod-bus_usb_usb.lst: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh usb > $@ || (rm -f $@; exit 1)
+
+partmap-usb_mod-bus_usb_usb.lst: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh usb > $@ || (rm -f $@; exit 1)
+
+handler-usb_mod-bus_usb_usb.lst: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh usb > $@ || (rm -f $@; exit 1)
+
+usb_mod-bus_usb_usbtrans.o: bus/usb/usbtrans.c $(bus/usb/usbtrans.c_DEPENDENCIES)
+	$(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -MD -c -o $@ $<
+-include usb_mod-bus_usb_usbtrans.d
+
+clean-module-usb_mod-bus_usb_usbtrans-extra.1:
+	rm -f cmd-usb_mod-bus_usb_usbtrans.lst fs-usb_mod-bus_usb_usbtrans.lst partmap-usb_mod-bus_usb_usbtrans.lst handler-usb_mod-bus_usb_usbtrans.lst parttool-usb_mod-bus_usb_usbtrans.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usb_mod-bus_usb_usbtrans-extra.1
+
+COMMANDFILES += cmd-usb_mod-bus_usb_usbtrans.lst
+FSFILES += fs-usb_mod-bus_usb_usbtrans.lst
+PARTTOOLFILES += parttool-usb_mod-bus_usb_usbtrans.lst
+PARTMAPFILES += partmap-usb_mod-bus_usb_usbtrans.lst
+HANDLERFILES += handler-usb_mod-bus_usb_usbtrans.lst
+
+cmd-usb_mod-bus_usb_usbtrans.lst: bus/usb/usbtrans.c $(bus/usb/usbtrans.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh usb > $@ || (rm -f $@; exit 1)
+
+fs-usb_mod-bus_usb_usbtrans.lst: bus/usb/usbtrans.c $(bus/usb/usbtrans.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh usb > $@ || (rm -f $@; exit 1)
+
+parttool-usb_mod-bus_usb_usbtrans.lst: bus/usb/usbtrans.c $(bus/usb/usbtrans.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh usb > $@ || (rm -f $@; exit 1)
+
+partmap-usb_mod-bus_usb_usbtrans.lst: bus/usb/usbtrans.c $(bus/usb/usbtrans.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh usb > $@ || (rm -f $@; exit 1)
+
+handler-usb_mod-bus_usb_usbtrans.lst: bus/usb/usbtrans.c $(bus/usb/usbtrans.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh usb > $@ || (rm -f $@; exit 1)
+
+usb_mod-bus_usb_usbhub.o: bus/usb/usbhub.c $(bus/usb/usbhub.c_DEPENDENCIES)
+	$(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -MD -c -o $@ $<
+-include usb_mod-bus_usb_usbhub.d
+
+clean-module-usb_mod-bus_usb_usbhub-extra.1:
+	rm -f cmd-usb_mod-bus_usb_usbhub.lst fs-usb_mod-bus_usb_usbhub.lst partmap-usb_mod-bus_usb_usbhub.lst handler-usb_mod-bus_usb_usbhub.lst parttool-usb_mod-bus_usb_usbhub.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usb_mod-bus_usb_usbhub-extra.1
+
+COMMANDFILES += cmd-usb_mod-bus_usb_usbhub.lst
+FSFILES += fs-usb_mod-bus_usb_usbhub.lst
+PARTTOOLFILES += parttool-usb_mod-bus_usb_usbhub.lst
+PARTMAPFILES += partmap-usb_mod-bus_usb_usbhub.lst
+HANDLERFILES += handler-usb_mod-bus_usb_usbhub.lst
+
+cmd-usb_mod-bus_usb_usbhub.lst: bus/usb/usbhub.c $(bus/usb/usbhub.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh usb > $@ || (rm -f $@; exit 1)
+
+fs-usb_mod-bus_usb_usbhub.lst: bus/usb/usbhub.c $(bus/usb/usbhub.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh usb > $@ || (rm -f $@; exit 1)
+
+parttool-usb_mod-bus_usb_usbhub.lst: bus/usb/usbhub.c $(bus/usb/usbhub.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh usb > $@ || (rm -f $@; exit 1)
+
+partmap-usb_mod-bus_usb_usbhub.lst: bus/usb/usbhub.c $(bus/usb/usbhub.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh usb > $@ || (rm -f $@; exit 1)
+
+handler-usb_mod-bus_usb_usbhub.lst: bus/usb/usbhub.c $(bus/usb/usbhub.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh usb > $@ || (rm -f $@; exit 1)
+
+usb_mod_CFLAGS = $(COMMON_CFLAGS)
+usb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usbtest.mod
+usbtest_mod_SOURCES = commands/usbtest.c
+
+clean-module-usbtest.mod.1:
+	rm -f usbtest.mod mod-usbtest.o mod-usbtest.c pre-usbtest.o usbtest_mod-commands_usbtest.o und-usbtest.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usbtest.mod.1
+
+ifneq ($(usbtest_mod_EXPORTS),no)
+clean-module-usbtest.mod-symbol.1:
+	rm -f def-usbtest.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usbtest.mod-symbol.1
+DEFSYMFILES += def-usbtest.lst
+endif
+mostlyclean-module-usbtest.mod.1:
+	rm -f usbtest_mod-commands_usbtest.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-usbtest.mod.1
+UNDSYMFILES += und-usbtest.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+usbtest.mod: pre-usbtest.o mod-usbtest.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(usbtest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-usbtest.o mod-usbtest.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+usbtest.mod: pre-usbtest.o mod-usbtest.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(usbtest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-usbtest.o mod-usbtest.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-usbtest.o: $(usbtest_mod_DEPENDENCIES) usbtest_mod-commands_usbtest.o
+	-rm -f $@
+	$(TARGET_CC) $(usbtest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ usbtest_mod-commands_usbtest.o
+
+mod-usbtest.o: mod-usbtest.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -c -o $@ $<
+
+mod-usbtest.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'usbtest' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(usbtest_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-usbtest.lst: pre-usbtest.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 usbtest/' > $@
+else
+def-usbtest.lst: pre-usbtest.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 usbtest/' > $@
+endif
+endif
+
+und-usbtest.lst: pre-usbtest.o
+	echo 'usbtest' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+usbtest_mod-commands_usbtest.o: commands/usbtest.c $(commands/usbtest.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -MD -c -o $@ $<
+-include usbtest_mod-commands_usbtest.d
+
+clean-module-usbtest_mod-commands_usbtest-extra.1:
+	rm -f cmd-usbtest_mod-commands_usbtest.lst fs-usbtest_mod-commands_usbtest.lst partmap-usbtest_mod-commands_usbtest.lst handler-usbtest_mod-commands_usbtest.lst parttool-usbtest_mod-commands_usbtest.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usbtest_mod-commands_usbtest-extra.1
+
+COMMANDFILES += cmd-usbtest_mod-commands_usbtest.lst
+FSFILES += fs-usbtest_mod-commands_usbtest.lst
+PARTTOOLFILES += parttool-usbtest_mod-commands_usbtest.lst
+PARTMAPFILES += partmap-usbtest_mod-commands_usbtest.lst
+HANDLERFILES += handler-usbtest_mod-commands_usbtest.lst
+
+cmd-usbtest_mod-commands_usbtest.lst: commands/usbtest.c $(commands/usbtest.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh usbtest > $@ || (rm -f $@; exit 1)
+
+fs-usbtest_mod-commands_usbtest.lst: commands/usbtest.c $(commands/usbtest.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh usbtest > $@ || (rm -f $@; exit 1)
+
+parttool-usbtest_mod-commands_usbtest.lst: commands/usbtest.c $(commands/usbtest.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh usbtest > $@ || (rm -f $@; exit 1)
+
+partmap-usbtest_mod-commands_usbtest.lst: commands/usbtest.c $(commands/usbtest.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh usbtest > $@ || (rm -f $@; exit 1)
+
+handler-usbtest_mod-commands_usbtest.lst: commands/usbtest.c $(commands/usbtest.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh usbtest > $@ || (rm -f $@; exit 1)
+
+usbtest_mod_CFLAGS = $(COMMON_CFLAGS)
+usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For uhci.mod
+uhci_mod_SOURCES = bus/usb/uhci.c
+
+clean-module-uhci.mod.1:
+	rm -f uhci.mod mod-uhci.o mod-uhci.c pre-uhci.o uhci_mod-bus_usb_uhci.o und-uhci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-uhci.mod.1
+
+ifneq ($(uhci_mod_EXPORTS),no)
+clean-module-uhci.mod-symbol.1:
+	rm -f def-uhci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-uhci.mod-symbol.1
+DEFSYMFILES += def-uhci.lst
+endif
+mostlyclean-module-uhci.mod.1:
+	rm -f uhci_mod-bus_usb_uhci.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-uhci.mod.1
+UNDSYMFILES += und-uhci.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+uhci.mod: pre-uhci.o mod-uhci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(uhci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-uhci.o mod-uhci.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+uhci.mod: pre-uhci.o mod-uhci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(uhci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-uhci.o mod-uhci.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-uhci.o: $(uhci_mod_DEPENDENCIES) uhci_mod-bus_usb_uhci.o
+	-rm -f $@
+	$(TARGET_CC) $(uhci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ uhci_mod-bus_usb_uhci.o
+
+mod-uhci.o: mod-uhci.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -c -o $@ $<
+
+mod-uhci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'uhci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(uhci_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-uhci.lst: pre-uhci.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 uhci/' > $@
+else
+def-uhci.lst: pre-uhci.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 uhci/' > $@
+endif
+endif
+
+und-uhci.lst: pre-uhci.o
+	echo 'uhci' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+uhci_mod-bus_usb_uhci.o: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES)
+	$(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -MD -c -o $@ $<
+-include uhci_mod-bus_usb_uhci.d
+
+clean-module-uhci_mod-bus_usb_uhci-extra.1:
+	rm -f cmd-uhci_mod-bus_usb_uhci.lst fs-uhci_mod-bus_usb_uhci.lst partmap-uhci_mod-bus_usb_uhci.lst handler-uhci_mod-bus_usb_uhci.lst parttool-uhci_mod-bus_usb_uhci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-uhci_mod-bus_usb_uhci-extra.1
+
+COMMANDFILES += cmd-uhci_mod-bus_usb_uhci.lst
+FSFILES += fs-uhci_mod-bus_usb_uhci.lst
+PARTTOOLFILES += parttool-uhci_mod-bus_usb_uhci.lst
+PARTMAPFILES += partmap-uhci_mod-bus_usb_uhci.lst
+HANDLERFILES += handler-uhci_mod-bus_usb_uhci.lst
+
+cmd-uhci_mod-bus_usb_uhci.lst: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh uhci > $@ || (rm -f $@; exit 1)
+
+fs-uhci_mod-bus_usb_uhci.lst: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh uhci > $@ || (rm -f $@; exit 1)
+
+parttool-uhci_mod-bus_usb_uhci.lst: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh uhci > $@ || (rm -f $@; exit 1)
+
+partmap-uhci_mod-bus_usb_uhci.lst: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh uhci > $@ || (rm -f $@; exit 1)
+
+handler-uhci_mod-bus_usb_uhci.lst: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh uhci > $@ || (rm -f $@; exit 1)
+
+uhci_mod_CFLAGS = $(COMMON_CFLAGS)
+uhci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ohci.mod
+ohci_mod_SOURCES = bus/usb/ohci.c
+
+clean-module-ohci.mod.1:
+	rm -f ohci.mod mod-ohci.o mod-ohci.c pre-ohci.o ohci_mod-bus_usb_ohci.o und-ohci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ohci.mod.1
+
+ifneq ($(ohci_mod_EXPORTS),no)
+clean-module-ohci.mod-symbol.1:
+	rm -f def-ohci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ohci.mod-symbol.1
+DEFSYMFILES += def-ohci.lst
+endif
+mostlyclean-module-ohci.mod.1:
+	rm -f ohci_mod-bus_usb_ohci.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-ohci.mod.1
+UNDSYMFILES += und-ohci.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+ohci.mod: pre-ohci.o mod-ohci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(ohci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-ohci.o mod-ohci.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+ohci.mod: pre-ohci.o mod-ohci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(ohci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-ohci.o mod-ohci.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-ohci.o: $(ohci_mod_DEPENDENCIES) ohci_mod-bus_usb_ohci.o
+	-rm -f $@
+	$(TARGET_CC) $(ohci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ohci_mod-bus_usb_ohci.o
+
+mod-ohci.o: mod-ohci.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -c -o $@ $<
+
+mod-ohci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'ohci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(ohci_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-ohci.lst: pre-ohci.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ohci/' > $@
+else
+def-ohci.lst: pre-ohci.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 ohci/' > $@
+endif
+endif
+
+und-ohci.lst: pre-ohci.o
+	echo 'ohci' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+ohci_mod-bus_usb_ohci.o: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES)
+	$(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -MD -c -o $@ $<
+-include ohci_mod-bus_usb_ohci.d
+
+clean-module-ohci_mod-bus_usb_ohci-extra.1:
+	rm -f cmd-ohci_mod-bus_usb_ohci.lst fs-ohci_mod-bus_usb_ohci.lst partmap-ohci_mod-bus_usb_ohci.lst handler-ohci_mod-bus_usb_ohci.lst parttool-ohci_mod-bus_usb_ohci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ohci_mod-bus_usb_ohci-extra.1
+
+COMMANDFILES += cmd-ohci_mod-bus_usb_ohci.lst
+FSFILES += fs-ohci_mod-bus_usb_ohci.lst
+PARTTOOLFILES += parttool-ohci_mod-bus_usb_ohci.lst
+PARTMAPFILES += partmap-ohci_mod-bus_usb_ohci.lst
+HANDLERFILES += handler-ohci_mod-bus_usb_ohci.lst
+
+cmd-ohci_mod-bus_usb_ohci.lst: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh ohci > $@ || (rm -f $@; exit 1)
+
+fs-ohci_mod-bus_usb_ohci.lst: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh ohci > $@ || (rm -f $@; exit 1)
+
+parttool-ohci_mod-bus_usb_ohci.lst: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh ohci > $@ || (rm -f $@; exit 1)
+
+partmap-ohci_mod-bus_usb_ohci.lst: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh ohci > $@ || (rm -f $@; exit 1)
+
+handler-ohci_mod-bus_usb_ohci.lst: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh ohci > $@ || (rm -f $@; exit 1)
+
+ohci_mod_CFLAGS = $(COMMON_CFLAGS)
+ohci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usbms.mod
+usbms_mod_SOURCES = disk/usbms.c
+
+clean-module-usbms.mod.1:
+	rm -f usbms.mod mod-usbms.o mod-usbms.c pre-usbms.o usbms_mod-disk_usbms.o und-usbms.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usbms.mod.1
+
+ifneq ($(usbms_mod_EXPORTS),no)
+clean-module-usbms.mod-symbol.1:
+	rm -f def-usbms.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usbms.mod-symbol.1
+DEFSYMFILES += def-usbms.lst
+endif
+mostlyclean-module-usbms.mod.1:
+	rm -f usbms_mod-disk_usbms.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-usbms.mod.1
+UNDSYMFILES += und-usbms.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+usbms.mod: pre-usbms.o mod-usbms.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(usbms_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-usbms.o mod-usbms.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+usbms.mod: pre-usbms.o mod-usbms.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(usbms_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-usbms.o mod-usbms.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-usbms.o: $(usbms_mod_DEPENDENCIES) usbms_mod-disk_usbms.o
+	-rm -f $@
+	$(TARGET_CC) $(usbms_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ usbms_mod-disk_usbms.o
+
+mod-usbms.o: mod-usbms.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -c -o $@ $<
+
+mod-usbms.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'usbms' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(usbms_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-usbms.lst: pre-usbms.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 usbms/' > $@
+else
+def-usbms.lst: pre-usbms.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 usbms/' > $@
+endif
+endif
+
+und-usbms.lst: pre-usbms.o
+	echo 'usbms' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+usbms_mod-disk_usbms.o: disk/usbms.c $(disk/usbms.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -MD -c -o $@ $<
+-include usbms_mod-disk_usbms.d
+
+clean-module-usbms_mod-disk_usbms-extra.1:
+	rm -f cmd-usbms_mod-disk_usbms.lst fs-usbms_mod-disk_usbms.lst partmap-usbms_mod-disk_usbms.lst handler-usbms_mod-disk_usbms.lst parttool-usbms_mod-disk_usbms.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usbms_mod-disk_usbms-extra.1
+
+COMMANDFILES += cmd-usbms_mod-disk_usbms.lst
+FSFILES += fs-usbms_mod-disk_usbms.lst
+PARTTOOLFILES += parttool-usbms_mod-disk_usbms.lst
+PARTMAPFILES += partmap-usbms_mod-disk_usbms.lst
+HANDLERFILES += handler-usbms_mod-disk_usbms.lst
+
+cmd-usbms_mod-disk_usbms.lst: disk/usbms.c $(disk/usbms.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh usbms > $@ || (rm -f $@; exit 1)
+
+fs-usbms_mod-disk_usbms.lst: disk/usbms.c $(disk/usbms.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh usbms > $@ || (rm -f $@; exit 1)
+
+parttool-usbms_mod-disk_usbms.lst: disk/usbms.c $(disk/usbms.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh usbms > $@ || (rm -f $@; exit 1)
+
+partmap-usbms_mod-disk_usbms.lst: disk/usbms.c $(disk/usbms.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh usbms > $@ || (rm -f $@; exit 1)
+
+handler-usbms_mod-disk_usbms.lst: disk/usbms.c $(disk/usbms.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh usbms > $@ || (rm -f $@; exit 1)
+
+usbms_mod_CFLAGS = $(COMMON_CFLAGS)
+usbms_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usb_keyboard.mod
+usb_keyboard_mod_SOURCES = term/usb_keyboard.c
+
+clean-module-usb_keyboard.mod.1:
+	rm -f usb_keyboard.mod mod-usb_keyboard.o mod-usb_keyboard.c pre-usb_keyboard.o usb_keyboard_mod-term_usb_keyboard.o und-usb_keyboard.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usb_keyboard.mod.1
+
+ifneq ($(usb_keyboard_mod_EXPORTS),no)
+clean-module-usb_keyboard.mod-symbol.1:
+	rm -f def-usb_keyboard.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usb_keyboard.mod-symbol.1
+DEFSYMFILES += def-usb_keyboard.lst
+endif
+mostlyclean-module-usb_keyboard.mod.1:
+	rm -f usb_keyboard_mod-term_usb_keyboard.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-usb_keyboard.mod.1
+UNDSYMFILES += und-usb_keyboard.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+usb_keyboard.mod: pre-usb_keyboard.o mod-usb_keyboard.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(usb_keyboard_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-usb_keyboard.o mod-usb_keyboard.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+usb_keyboard.mod: pre-usb_keyboard.o mod-usb_keyboard.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(usb_keyboard_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-usb_keyboard.o mod-usb_keyboard.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-usb_keyboard.o: $(usb_keyboard_mod_DEPENDENCIES) usb_keyboard_mod-term_usb_keyboard.o
+	-rm -f $@
+	$(TARGET_CC) $(usb_keyboard_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ usb_keyboard_mod-term_usb_keyboard.o
+
+mod-usb_keyboard.o: mod-usb_keyboard.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -c -o $@ $<
+
+mod-usb_keyboard.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'usb_keyboard' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(usb_keyboard_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-usb_keyboard.lst: pre-usb_keyboard.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 usb_keyboard/' > $@
+else
+def-usb_keyboard.lst: pre-usb_keyboard.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 usb_keyboard/' > $@
+endif
+endif
+
+und-usb_keyboard.lst: pre-usb_keyboard.o
+	echo 'usb_keyboard' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+usb_keyboard_mod-term_usb_keyboard.o: term/usb_keyboard.c $(term/usb_keyboard.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -MD -c -o $@ $<
+-include usb_keyboard_mod-term_usb_keyboard.d
+
+clean-module-usb_keyboard_mod-term_usb_keyboard-extra.1:
+	rm -f cmd-usb_keyboard_mod-term_usb_keyboard.lst fs-usb_keyboard_mod-term_usb_keyboard.lst partmap-usb_keyboard_mod-term_usb_keyboard.lst handler-usb_keyboard_mod-term_usb_keyboard.lst parttool-usb_keyboard_mod-term_usb_keyboard.lst
+
+CLEAN_MODULE_TARGETS += clean-module-usb_keyboard_mod-term_usb_keyboard-extra.1
+
+COMMANDFILES += cmd-usb_keyboard_mod-term_usb_keyboard.lst
+FSFILES += fs-usb_keyboard_mod-term_usb_keyboard.lst
+PARTTOOLFILES += parttool-usb_keyboard_mod-term_usb_keyboard.lst
+PARTMAPFILES += partmap-usb_keyboard_mod-term_usb_keyboard.lst
+HANDLERFILES += handler-usb_keyboard_mod-term_usb_keyboard.lst
+
+cmd-usb_keyboard_mod-term_usb_keyboard.lst: term/usb_keyboard.c $(term/usb_keyboard.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh usb_keyboard > $@ || (rm -f $@; exit 1)
+
+fs-usb_keyboard_mod-term_usb_keyboard.lst: term/usb_keyboard.c $(term/usb_keyboard.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh usb_keyboard > $@ || (rm -f $@; exit 1)
+
+parttool-usb_keyboard_mod-term_usb_keyboard.lst: term/usb_keyboard.c $(term/usb_keyboard.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh usb_keyboard > $@ || (rm -f $@; exit 1)
+
+partmap-usb_keyboard_mod-term_usb_keyboard.lst: term/usb_keyboard.c $(term/usb_keyboard.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh usb_keyboard > $@ || (rm -f $@; exit 1)
+
+handler-usb_keyboard_mod-term_usb_keyboard.lst: term/usb_keyboard.c $(term/usb_keyboard.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh usb_keyboard > $@ || (rm -f $@; exit 1)
+
+usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
+usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pxe.mod
+pxe_mod_SOURCES = fs/i386/pc/pxe.c
+
+clean-module-pxe.mod.1:
+	rm -f pxe.mod mod-pxe.o mod-pxe.c pre-pxe.o pxe_mod-fs_i386_pc_pxe.o und-pxe.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pxe.mod.1
+
+ifneq ($(pxe_mod_EXPORTS),no)
+clean-module-pxe.mod-symbol.1:
+	rm -f def-pxe.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pxe.mod-symbol.1
+DEFSYMFILES += def-pxe.lst
+endif
+mostlyclean-module-pxe.mod.1:
+	rm -f pxe_mod-fs_i386_pc_pxe.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-pxe.mod.1
+UNDSYMFILES += und-pxe.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+pxe.mod: pre-pxe.o mod-pxe.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(pxe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-pxe.o mod-pxe.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+pxe.mod: pre-pxe.o mod-pxe.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(pxe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-pxe.o mod-pxe.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-pxe.o: $(pxe_mod_DEPENDENCIES) pxe_mod-fs_i386_pc_pxe.o
+	-rm -f $@
+	$(TARGET_CC) $(pxe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pxe_mod-fs_i386_pc_pxe.o
+
+mod-pxe.o: mod-pxe.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pxe_mod_CFLAGS) -c -o $@ $<
+
+mod-pxe.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'pxe' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(pxe_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-pxe.lst: pre-pxe.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pxe/' > $@
+else
+def-pxe.lst: pre-pxe.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 pxe/' > $@
+endif
+endif
+
+und-pxe.lst: pre-pxe.o
+	echo 'pxe' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+pxe_mod-fs_i386_pc_pxe.o: fs/i386/pc/pxe.c $(fs/i386/pc/pxe.c_DEPENDENCIES)
+	$(TARGET_CC) -Ifs/i386/pc -I$(srcdir)/fs/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pxe_mod_CFLAGS) -MD -c -o $@ $<
+-include pxe_mod-fs_i386_pc_pxe.d
+
+clean-module-pxe_mod-fs_i386_pc_pxe-extra.1:
+	rm -f cmd-pxe_mod-fs_i386_pc_pxe.lst fs-pxe_mod-fs_i386_pc_pxe.lst partmap-pxe_mod-fs_i386_pc_pxe.lst handler-pxe_mod-fs_i386_pc_pxe.lst parttool-pxe_mod-fs_i386_pc_pxe.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pxe_mod-fs_i386_pc_pxe-extra.1
+
+COMMANDFILES += cmd-pxe_mod-fs_i386_pc_pxe.lst
+FSFILES += fs-pxe_mod-fs_i386_pc_pxe.lst
+PARTTOOLFILES += parttool-pxe_mod-fs_i386_pc_pxe.lst
+PARTMAPFILES += partmap-pxe_mod-fs_i386_pc_pxe.lst
+HANDLERFILES += handler-pxe_mod-fs_i386_pc_pxe.lst
+
+cmd-pxe_mod-fs_i386_pc_pxe.lst: fs/i386/pc/pxe.c $(fs/i386/pc/pxe.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs/i386/pc -I$(srcdir)/fs/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pxe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh pxe > $@ || (rm -f $@; exit 1)
+
+fs-pxe_mod-fs_i386_pc_pxe.lst: fs/i386/pc/pxe.c $(fs/i386/pc/pxe.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ifs/i386/pc -I$(srcdir)/fs/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pxe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh pxe > $@ || (rm -f $@; exit 1)
+
+parttool-pxe_mod-fs_i386_pc_pxe.lst: fs/i386/pc/pxe.c $(fs/i386/pc/pxe.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ifs/i386/pc -I$(srcdir)/fs/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pxe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh pxe > $@ || (rm -f $@; exit 1)
+
+partmap-pxe_mod-fs_i386_pc_pxe.lst: fs/i386/pc/pxe.c $(fs/i386/pc/pxe.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ifs/i386/pc -I$(srcdir)/fs/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pxe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh pxe > $@ || (rm -f $@; exit 1)
+
+handler-pxe_mod-fs_i386_pc_pxe.lst: fs/i386/pc/pxe.c $(fs/i386/pc/pxe.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ifs/i386/pc -I$(srcdir)/fs/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pxe_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh pxe > $@ || (rm -f $@; exit 1)
+
+pxe_mod_CFLAGS = $(COMMON_CFLAGS)
+pxe_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pxecmd.mod
+pxecmd_mod_SOURCES = commands/i386/pc/pxecmd.c
+
+clean-module-pxecmd.mod.1:
+	rm -f pxecmd.mod mod-pxecmd.o mod-pxecmd.c pre-pxecmd.o pxecmd_mod-commands_i386_pc_pxecmd.o und-pxecmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pxecmd.mod.1
+
+ifneq ($(pxecmd_mod_EXPORTS),no)
+clean-module-pxecmd.mod-symbol.1:
+	rm -f def-pxecmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pxecmd.mod-symbol.1
+DEFSYMFILES += def-pxecmd.lst
+endif
+mostlyclean-module-pxecmd.mod.1:
+	rm -f pxecmd_mod-commands_i386_pc_pxecmd.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-pxecmd.mod.1
+UNDSYMFILES += und-pxecmd.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+pxecmd.mod: pre-pxecmd.o mod-pxecmd.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(pxecmd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-pxecmd.o mod-pxecmd.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+pxecmd.mod: pre-pxecmd.o mod-pxecmd.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(pxecmd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-pxecmd.o mod-pxecmd.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-pxecmd.o: $(pxecmd_mod_DEPENDENCIES) pxecmd_mod-commands_i386_pc_pxecmd.o
+	-rm -f $@
+	$(TARGET_CC) $(pxecmd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pxecmd_mod-commands_i386_pc_pxecmd.o
+
+mod-pxecmd.o: mod-pxecmd.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pxecmd_mod_CFLAGS) -c -o $@ $<
+
+mod-pxecmd.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'pxecmd' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(pxecmd_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-pxecmd.lst: pre-pxecmd.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pxecmd/' > $@
+else
+def-pxecmd.lst: pre-pxecmd.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 pxecmd/' > $@
+endif
+endif
+
+und-pxecmd.lst: pre-pxecmd.o
+	echo 'pxecmd' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+pxecmd_mod-commands_i386_pc_pxecmd.o: commands/i386/pc/pxecmd.c $(commands/i386/pc/pxecmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pxecmd_mod_CFLAGS) -MD -c -o $@ $<
+-include pxecmd_mod-commands_i386_pc_pxecmd.d
+
+clean-module-pxecmd_mod-commands_i386_pc_pxecmd-extra.1:
+	rm -f cmd-pxecmd_mod-commands_i386_pc_pxecmd.lst fs-pxecmd_mod-commands_i386_pc_pxecmd.lst partmap-pxecmd_mod-commands_i386_pc_pxecmd.lst handler-pxecmd_mod-commands_i386_pc_pxecmd.lst parttool-pxecmd_mod-commands_i386_pc_pxecmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pxecmd_mod-commands_i386_pc_pxecmd-extra.1
+
+COMMANDFILES += cmd-pxecmd_mod-commands_i386_pc_pxecmd.lst
+FSFILES += fs-pxecmd_mod-commands_i386_pc_pxecmd.lst
+PARTTOOLFILES += parttool-pxecmd_mod-commands_i386_pc_pxecmd.lst
+PARTMAPFILES += partmap-pxecmd_mod-commands_i386_pc_pxecmd.lst
+HANDLERFILES += handler-pxecmd_mod-commands_i386_pc_pxecmd.lst
+
+cmd-pxecmd_mod-commands_i386_pc_pxecmd.lst: commands/i386/pc/pxecmd.c $(commands/i386/pc/pxecmd.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pxecmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh pxecmd > $@ || (rm -f $@; exit 1)
+
+fs-pxecmd_mod-commands_i386_pc_pxecmd.lst: commands/i386/pc/pxecmd.c $(commands/i386/pc/pxecmd.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pxecmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh pxecmd > $@ || (rm -f $@; exit 1)
+
+parttool-pxecmd_mod-commands_i386_pc_pxecmd.lst: commands/i386/pc/pxecmd.c $(commands/i386/pc/pxecmd.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pxecmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh pxecmd > $@ || (rm -f $@; exit 1)
+
+partmap-pxecmd_mod-commands_i386_pc_pxecmd.lst: commands/i386/pc/pxecmd.c $(commands/i386/pc/pxecmd.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pxecmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh pxecmd > $@ || (rm -f $@; exit 1)
+
+handler-pxecmd_mod-commands_i386_pc_pxecmd.lst: commands/i386/pc/pxecmd.c $(commands/i386/pc/pxecmd.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pxecmd_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh pxecmd > $@ || (rm -f $@; exit 1)
+
+pxecmd_mod_CFLAGS = $(COMMON_CFLAGS)
+pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/i386/datetime.c
+
+clean-module-datetime.mod.1:
+	rm -f datetime.mod mod-datetime.o mod-datetime.c pre-datetime.o datetime_mod-lib_i386_datetime.o und-datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime.mod.1
+
+ifneq ($(datetime_mod_EXPORTS),no)
+clean-module-datetime.mod-symbol.1:
+	rm -f def-datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime.mod-symbol.1
+DEFSYMFILES += def-datetime.lst
+endif
+mostlyclean-module-datetime.mod.1:
+	rm -f datetime_mod-lib_i386_datetime.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-datetime.mod.1
+UNDSYMFILES += und-datetime.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-datetime.o mod-datetime.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-datetime.o mod-datetime.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-datetime.o: $(datetime_mod_DEPENDENCIES) datetime_mod-lib_i386_datetime.o
+	-rm -f $@
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datetime_mod-lib_i386_datetime.o
+
+mod-datetime.o: mod-datetime.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -c -o $@ $<
+
+mod-datetime.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'datetime' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(datetime_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-datetime.lst: pre-datetime.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datetime/' > $@
+else
+def-datetime.lst: pre-datetime.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 datetime/' > $@
+endif
+endif
+
+und-datetime.lst: pre-datetime.o
+	echo 'datetime' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+datetime_mod-lib_i386_datetime.o: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $<
+-include datetime_mod-lib_i386_datetime.d
+
+clean-module-datetime_mod-lib_i386_datetime-extra.1:
+	rm -f cmd-datetime_mod-lib_i386_datetime.lst fs-datetime_mod-lib_i386_datetime.lst partmap-datetime_mod-lib_i386_datetime.lst handler-datetime_mod-lib_i386_datetime.lst parttool-datetime_mod-lib_i386_datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime_mod-lib_i386_datetime-extra.1
+
+COMMANDFILES += cmd-datetime_mod-lib_i386_datetime.lst
+FSFILES += fs-datetime_mod-lib_i386_datetime.lst
+PARTTOOLFILES += parttool-datetime_mod-lib_i386_datetime.lst
+PARTMAPFILES += partmap-datetime_mod-lib_i386_datetime.lst
+HANDLERFILES += handler-datetime_mod-lib_i386_datetime.lst
+
+cmd-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1)
+
+fs-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1)
+
+parttool-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh datetime > $@ || (rm -f $@; exit 1)
+
+partmap-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1)
+
+handler-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh datetime > $@ || (rm -f $@; exit 1)
+
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For date.mod
+date_mod_SOURCES = commands/date.c
+
+clean-module-date.mod.1:
+	rm -f date.mod mod-date.o mod-date.c pre-date.o date_mod-commands_date.o und-date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date.mod.1
+
+ifneq ($(date_mod_EXPORTS),no)
+clean-module-date.mod-symbol.1:
+	rm -f def-date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date.mod-symbol.1
+DEFSYMFILES += def-date.lst
+endif
+mostlyclean-module-date.mod.1:
+	rm -f date_mod-commands_date.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-date.mod.1
+UNDSYMFILES += und-date.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-date.o mod-date.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-date.o mod-date.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-date.o: $(date_mod_DEPENDENCIES) date_mod-commands_date.o
+	-rm -f $@
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ date_mod-commands_date.o
+
+mod-date.o: mod-date.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -c -o $@ $<
+
+mod-date.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'date' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(date_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-date.lst: pre-date.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 date/' > $@
+else
+def-date.lst: pre-date.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 date/' > $@
+endif
+endif
+
+und-date.lst: pre-date.o
+	echo 'date' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+date_mod-commands_date.o: commands/date.c $(commands/date.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -MD -c -o $@ $<
+-include date_mod-commands_date.d
+
+clean-module-date_mod-commands_date-extra.1:
+	rm -f cmd-date_mod-commands_date.lst fs-date_mod-commands_date.lst partmap-date_mod-commands_date.lst handler-date_mod-commands_date.lst parttool-date_mod-commands_date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date_mod-commands_date-extra.1
+
+COMMANDFILES += cmd-date_mod-commands_date.lst
+FSFILES += fs-date_mod-commands_date.lst
+PARTTOOLFILES += parttool-date_mod-commands_date.lst
+PARTMAPFILES += partmap-date_mod-commands_date.lst
+HANDLERFILES += handler-date_mod-commands_date.lst
+
+cmd-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh date > $@ || (rm -f $@; exit 1)
+
+fs-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh date > $@ || (rm -f $@; exit 1)
+
+parttool-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh date > $@ || (rm -f $@; exit 1)
+
+partmap-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh date > $@ || (rm -f $@; exit 1)
+
+handler-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh date > $@ || (rm -f $@; exit 1)
+
+date_mod_CFLAGS = $(COMMON_CFLAGS)
+date_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datehook.mod
+datehook_mod_SOURCES = hook/datehook.c
+
+clean-module-datehook.mod.1:
+	rm -f datehook.mod mod-datehook.o mod-datehook.c pre-datehook.o datehook_mod-hook_datehook.o und-datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook.mod.1
+
+ifneq ($(datehook_mod_EXPORTS),no)
+clean-module-datehook.mod-symbol.1:
+	rm -f def-datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook.mod-symbol.1
+DEFSYMFILES += def-datehook.lst
+endif
+mostlyclean-module-datehook.mod.1:
+	rm -f datehook_mod-hook_datehook.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-datehook.mod.1
+UNDSYMFILES += und-datehook.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-datehook.o mod-datehook.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-datehook.o mod-datehook.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-datehook.o: $(datehook_mod_DEPENDENCIES) datehook_mod-hook_datehook.o
+	-rm -f $@
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datehook_mod-hook_datehook.o
+
+mod-datehook.o: mod-datehook.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -c -o $@ $<
+
+mod-datehook.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'datehook' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(datehook_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-datehook.lst: pre-datehook.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datehook/' > $@
+else
+def-datehook.lst: pre-datehook.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 datehook/' > $@
+endif
+endif
+
+und-datehook.lst: pre-datehook.o
+	echo 'datehook' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+datehook_mod-hook_datehook.o: hook/datehook.c $(hook/datehook.c_DEPENDENCIES)
+	$(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -MD -c -o $@ $<
+-include datehook_mod-hook_datehook.d
+
+clean-module-datehook_mod-hook_datehook-extra.1:
+	rm -f cmd-datehook_mod-hook_datehook.lst fs-datehook_mod-hook_datehook.lst partmap-datehook_mod-hook_datehook.lst handler-datehook_mod-hook_datehook.lst parttool-datehook_mod-hook_datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook_mod-hook_datehook-extra.1
+
+COMMANDFILES += cmd-datehook_mod-hook_datehook.lst
+FSFILES += fs-datehook_mod-hook_datehook.lst
+PARTTOOLFILES += parttool-datehook_mod-hook_datehook.lst
+PARTMAPFILES += partmap-datehook_mod-hook_datehook.lst
+HANDLERFILES += handler-datehook_mod-hook_datehook.lst
+
+cmd-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh datehook > $@ || (rm -f $@; exit 1)
+
+fs-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh datehook > $@ || (rm -f $@; exit 1)
+
+parttool-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh datehook > $@ || (rm -f $@; exit 1)
+
+partmap-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh datehook > $@ || (rm -f $@; exit 1)
+
+handler-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh datehook > $@ || (rm -f $@; exit 1)
+
+datehook_mod_CFLAGS = $(COMMON_CFLAGS)
+datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+
+clean-module-lsmmap.mod.1:
+	rm -f lsmmap.mod mod-lsmmap.o mod-lsmmap.c pre-lsmmap.o lsmmap_mod-commands_lsmmap.o und-lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap.mod.1
+
+ifneq ($(lsmmap_mod_EXPORTS),no)
+clean-module-lsmmap.mod-symbol.1:
+	rm -f def-lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap.mod-symbol.1
+DEFSYMFILES += def-lsmmap.lst
+endif
+mostlyclean-module-lsmmap.mod.1:
+	rm -f lsmmap_mod-commands_lsmmap.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-lsmmap.mod.1
+UNDSYMFILES += und-lsmmap.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-lsmmap.o mod-lsmmap.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-lsmmap.o mod-lsmmap.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-lsmmap.o: $(lsmmap_mod_DEPENDENCIES) lsmmap_mod-commands_lsmmap.o
+	-rm -f $@
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lsmmap_mod-commands_lsmmap.o
+
+mod-lsmmap.o: mod-lsmmap.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -c -o $@ $<
+
+mod-lsmmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'lsmmap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(lsmmap_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-lsmmap.lst: pre-lsmmap.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@
+else
+def-lsmmap.lst: pre-lsmmap.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@
+endif
+endif
+
+und-lsmmap.lst: pre-lsmmap.o
+	echo 'lsmmap' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+lsmmap_mod-commands_lsmmap.o: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -MD -c -o $@ $<
+-include lsmmap_mod-commands_lsmmap.d
+
+clean-module-lsmmap_mod-commands_lsmmap-extra.1:
+	rm -f cmd-lsmmap_mod-commands_lsmmap.lst fs-lsmmap_mod-commands_lsmmap.lst partmap-lsmmap_mod-commands_lsmmap.lst handler-lsmmap_mod-commands_lsmmap.lst parttool-lsmmap_mod-commands_lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap_mod-commands_lsmmap-extra.1
+
+COMMANDFILES += cmd-lsmmap_mod-commands_lsmmap.lst
+FSFILES += fs-lsmmap_mod-commands_lsmmap.lst
+PARTTOOLFILES += parttool-lsmmap_mod-commands_lsmmap.lst
+PARTMAPFILES += partmap-lsmmap_mod-commands_lsmmap.lst
+HANDLERFILES += handler-lsmmap_mod-commands_lsmmap.lst
+
+cmd-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+fs-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+parttool-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+partmap-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+handler-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ata_pthru.mod.
+ata_pthru_mod_SOURCES = disk/ata_pthru.c
+
+clean-module-ata_pthru.mod.1:
+	rm -f ata_pthru.mod mod-ata_pthru.o mod-ata_pthru.c pre-ata_pthru.o ata_pthru_mod-disk_ata_pthru.o und-ata_pthru.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ata_pthru.mod.1
+
+ifneq ($(ata_pthru_mod_EXPORTS),no)
+clean-module-ata_pthru.mod-symbol.1:
+	rm -f def-ata_pthru.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ata_pthru.mod-symbol.1
+DEFSYMFILES += def-ata_pthru.lst
+endif
+mostlyclean-module-ata_pthru.mod.1:
+	rm -f ata_pthru_mod-disk_ata_pthru.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-ata_pthru.mod.1
+UNDSYMFILES += und-ata_pthru.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+ata_pthru.mod: pre-ata_pthru.o mod-ata_pthru.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(ata_pthru_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-ata_pthru.o mod-ata_pthru.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+ata_pthru.mod: pre-ata_pthru.o mod-ata_pthru.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(ata_pthru_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-ata_pthru.o mod-ata_pthru.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-ata_pthru.o: $(ata_pthru_mod_DEPENDENCIES) ata_pthru_mod-disk_ata_pthru.o
+	-rm -f $@
+	$(TARGET_CC) $(ata_pthru_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ata_pthru_mod-disk_ata_pthru.o
+
+mod-ata_pthru.o: mod-ata_pthru.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_pthru_mod_CFLAGS) -c -o $@ $<
+
+mod-ata_pthru.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'ata_pthru' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(ata_pthru_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-ata_pthru.lst: pre-ata_pthru.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ata_pthru/' > $@
+else
+def-ata_pthru.lst: pre-ata_pthru.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 ata_pthru/' > $@
+endif
+endif
+
+und-ata_pthru.lst: pre-ata_pthru.o
+	echo 'ata_pthru' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+ata_pthru_mod-disk_ata_pthru.o: disk/ata_pthru.c $(disk/ata_pthru.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_pthru_mod_CFLAGS) -MD -c -o $@ $<
+-include ata_pthru_mod-disk_ata_pthru.d
+
+clean-module-ata_pthru_mod-disk_ata_pthru-extra.1:
+	rm -f cmd-ata_pthru_mod-disk_ata_pthru.lst fs-ata_pthru_mod-disk_ata_pthru.lst partmap-ata_pthru_mod-disk_ata_pthru.lst handler-ata_pthru_mod-disk_ata_pthru.lst parttool-ata_pthru_mod-disk_ata_pthru.lst
+
+CLEAN_MODULE_TARGETS += clean-module-ata_pthru_mod-disk_ata_pthru-extra.1
+
+COMMANDFILES += cmd-ata_pthru_mod-disk_ata_pthru.lst
+FSFILES += fs-ata_pthru_mod-disk_ata_pthru.lst
+PARTTOOLFILES += parttool-ata_pthru_mod-disk_ata_pthru.lst
+PARTMAPFILES += partmap-ata_pthru_mod-disk_ata_pthru.lst
+HANDLERFILES += handler-ata_pthru_mod-disk_ata_pthru.lst
+
+cmd-ata_pthru_mod-disk_ata_pthru.lst: disk/ata_pthru.c $(disk/ata_pthru.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_pthru_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh ata_pthru > $@ || (rm -f $@; exit 1)
+
+fs-ata_pthru_mod-disk_ata_pthru.lst: disk/ata_pthru.c $(disk/ata_pthru.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_pthru_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh ata_pthru > $@ || (rm -f $@; exit 1)
+
+parttool-ata_pthru_mod-disk_ata_pthru.lst: disk/ata_pthru.c $(disk/ata_pthru.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_pthru_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh ata_pthru > $@ || (rm -f $@; exit 1)
+
+partmap-ata_pthru_mod-disk_ata_pthru.lst: disk/ata_pthru.c $(disk/ata_pthru.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_pthru_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh ata_pthru > $@ || (rm -f $@; exit 1)
+
+handler-ata_pthru_mod-disk_ata_pthru.lst: disk/ata_pthru.c $(disk/ata_pthru.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(ata_pthru_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh ata_pthru > $@ || (rm -f $@; exit 1)
+
+ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS)
+ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hdparm.mod.
+hdparm_mod_SOURCES = commands/hdparm.c lib/hexdump.c
+
+clean-module-hdparm.mod.1:
+	rm -f hdparm.mod mod-hdparm.o mod-hdparm.c pre-hdparm.o hdparm_mod-commands_hdparm.o hdparm_mod-lib_hexdump.o und-hdparm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hdparm.mod.1
+
+ifneq ($(hdparm_mod_EXPORTS),no)
+clean-module-hdparm.mod-symbol.1:
+	rm -f def-hdparm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hdparm.mod-symbol.1
+DEFSYMFILES += def-hdparm.lst
+endif
+mostlyclean-module-hdparm.mod.1:
+	rm -f hdparm_mod-commands_hdparm.d hdparm_mod-lib_hexdump.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-hdparm.mod.1
+UNDSYMFILES += und-hdparm.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+hdparm.mod: pre-hdparm.o mod-hdparm.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(hdparm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-hdparm.o mod-hdparm.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+hdparm.mod: pre-hdparm.o mod-hdparm.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(hdparm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-hdparm.o mod-hdparm.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-hdparm.o: $(hdparm_mod_DEPENDENCIES) hdparm_mod-commands_hdparm.o hdparm_mod-lib_hexdump.o
+	-rm -f $@
+	$(TARGET_CC) $(hdparm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ hdparm_mod-commands_hdparm.o hdparm_mod-lib_hexdump.o
+
+mod-hdparm.o: mod-hdparm.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -c -o $@ $<
+
+mod-hdparm.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'hdparm' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(hdparm_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-hdparm.lst: pre-hdparm.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 hdparm/' > $@
+else
+def-hdparm.lst: pre-hdparm.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 hdparm/' > $@
+endif
+endif
+
+und-hdparm.lst: pre-hdparm.o
+	echo 'hdparm' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+hdparm_mod-commands_hdparm.o: commands/hdparm.c $(commands/hdparm.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -MD -c -o $@ $<
+-include hdparm_mod-commands_hdparm.d
+
+clean-module-hdparm_mod-commands_hdparm-extra.1:
+	rm -f cmd-hdparm_mod-commands_hdparm.lst fs-hdparm_mod-commands_hdparm.lst partmap-hdparm_mod-commands_hdparm.lst handler-hdparm_mod-commands_hdparm.lst parttool-hdparm_mod-commands_hdparm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hdparm_mod-commands_hdparm-extra.1
+
+COMMANDFILES += cmd-hdparm_mod-commands_hdparm.lst
+FSFILES += fs-hdparm_mod-commands_hdparm.lst
+PARTTOOLFILES += parttool-hdparm_mod-commands_hdparm.lst
+PARTMAPFILES += partmap-hdparm_mod-commands_hdparm.lst
+HANDLERFILES += handler-hdparm_mod-commands_hdparm.lst
+
+cmd-hdparm_mod-commands_hdparm.lst: commands/hdparm.c $(commands/hdparm.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh hdparm > $@ || (rm -f $@; exit 1)
+
+fs-hdparm_mod-commands_hdparm.lst: commands/hdparm.c $(commands/hdparm.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh hdparm > $@ || (rm -f $@; exit 1)
+
+parttool-hdparm_mod-commands_hdparm.lst: commands/hdparm.c $(commands/hdparm.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh hdparm > $@ || (rm -f $@; exit 1)
+
+partmap-hdparm_mod-commands_hdparm.lst: commands/hdparm.c $(commands/hdparm.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh hdparm > $@ || (rm -f $@; exit 1)
+
+handler-hdparm_mod-commands_hdparm.lst: commands/hdparm.c $(commands/hdparm.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh hdparm > $@ || (rm -f $@; exit 1)
+
+hdparm_mod-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -MD -c -o $@ $<
+-include hdparm_mod-lib_hexdump.d
+
+clean-module-hdparm_mod-lib_hexdump-extra.1:
+	rm -f cmd-hdparm_mod-lib_hexdump.lst fs-hdparm_mod-lib_hexdump.lst partmap-hdparm_mod-lib_hexdump.lst handler-hdparm_mod-lib_hexdump.lst parttool-hdparm_mod-lib_hexdump.lst
+
+CLEAN_MODULE_TARGETS += clean-module-hdparm_mod-lib_hexdump-extra.1
+
+COMMANDFILES += cmd-hdparm_mod-lib_hexdump.lst
+FSFILES += fs-hdparm_mod-lib_hexdump.lst
+PARTTOOLFILES += parttool-hdparm_mod-lib_hexdump.lst
+PARTMAPFILES += partmap-hdparm_mod-lib_hexdump.lst
+HANDLERFILES += handler-hdparm_mod-lib_hexdump.lst
+
+cmd-hdparm_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh hdparm > $@ || (rm -f $@; exit 1)
+
+fs-hdparm_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh hdparm > $@ || (rm -f $@; exit 1)
+
+parttool-hdparm_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh hdparm > $@ || (rm -f $@; exit 1)
+
+partmap-hdparm_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh hdparm > $@ || (rm -f $@; exit 1)
+
+handler-hdparm_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh hdparm > $@ || (rm -f $@; exit 1)
+
+hdparm_mod_CFLAGS = $(COMMON_CFLAGS)
+hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+ifeq ($(enable_efiemu), yes)
+
+efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
+	-rm -f $@
+ifeq ($(TARGET_APPLE_CC), 1)
+	-rm -f $@.bin
+	$(TARGET_CC) -c -m32 -DELF32 -DAPPLE_CC -o $@.bin -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+	$(OBJCONV) -felf32 -nu -nd $@.bin $@
+	-rm -f $@.bin
+else
+	$(TARGET_CC) -c -m32 -DELF32 -o $@ -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+	if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+endif
+
+efiemu64_c.o: efiemu/runtime/efiemu.c
+ifeq ($(TARGET_APPLE_CC), 1)
+	$(TARGET_CC) -c -m64 -DAPPLE_CC=1 -DELF64 -o $@ -Wall -Werror $< -nostdlib -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+else
+	$(TARGET_CC) -c -m64 -DELF64 -o $@ -Wall -Werror $< -nostdlib  -mcmodel=large -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+endif
+
+efiemu64_s.o: efiemu/runtime/efiemu.S
+	-rm -f $@
+ifeq ($(TARGET_APPLE_CC), 1)
+	$(TARGET_CC) -c -m64 -DAPPLE_CC=1 -DELF64 -o $@ -Wall -Werror $< -nostdlib -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+else
+	$(TARGET_CC) -c -m64 -DELF64 -o $@ -Wall -Werror $< -nostdlib  -mcmodel=large -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+endif
+
+efiemu64.o: efiemu64_c.o efiemu64_s.o  $(TARGET_OBJ2ELF)
+	-rm -f $@
+ifeq ($(TARGET_APPLE_CC), 1)
+	-rm -f $@.bin
+	$(TARGET_CC) -m64 -o $@.bin -Wl,-r $^ -nostdlib
+	$(OBJCONV) -felf64 -nu -nd $@.bin $@
+	-rm -f $@.bin
+else
+	$(TARGET_CC) -m64 -o $@ -Wl,-r $^ -nostdlib
+	if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+endif
+
+CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o
+pkglib_DATA += efiemu32.o efiemu64.o
+
+endif
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
+grub-mkimage: $(grub_mkimage_DEPENDENCIES) $(grub_mkimage_OBJECTS)
+	$(CC) -o $@ $(grub_mkimage_OBJECTS) $(LDFLAGS) $(grub_mkimage_LDFLAGS)
+
+grub-setup: $(grub_setup_DEPENDENCIES) $(grub_setup_OBJECTS)
+	$(CC) -o $@ $(grub_setup_OBJECTS) $(LDFLAGS) $(grub_setup_LDFLAGS)
+
+grub-mkdevicemap: $(grub_mkdevicemap_DEPENDENCIES) $(grub_mkdevicemap_OBJECTS)
+	$(CC) -o $@ $(grub_mkdevicemap_OBJECTS) $(LDFLAGS) $(grub_mkdevicemap_LDFLAGS)
+
+grub-emu: $(grub_emu_DEPENDENCIES) $(grub_emu_OBJECTS)
+	$(CC) -o $@ $(grub_emu_OBJECTS) $(LDFLAGS) $(grub_emu_LDFLAGS)
+
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
new file mode 100644
index 0000000..bf8fbfb
--- /dev/null
+++ b/conf/i386-pc.rmk
@@ -0,0 +1,450 @@
+# -*- makefile -*-
+
+GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200
+
+COMMON_ASFLAGS = -nostdinc -fno-builtin -m32
+COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32
+COMMON_LDFLAGS = -m32 -nostdlib
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Images.
+pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \
+	pxeboot.img
+
+# For boot.img.
+boot_img_SOURCES = boot/i386/pc/boot.S
+boot_img_ASFLAGS = $(COMMON_ASFLAGS)
+boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00
+boot_img_FORMAT = binary
+
+# For pxeboot.img
+pxeboot_img_SOURCES = boot/i386/pc/pxeboot.S
+pxeboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+pxeboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00
+pxeboot_img_FORMAT = binary
+
+# For diskboot.img.
+diskboot_img_SOURCES = boot/i386/pc/diskboot.S
+diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)8000
+diskboot_img_FORMAT = binary
+
+# For lnxboot.img.
+lnxboot_img_SOURCES = boot/i386/pc/lnxboot.S
+lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)6000
+lnxboot_img_FORMAT = binary
+
+# For cdboot.img.
+cdboot_img_SOURCES = boot/i386/pc/cdboot.S
+cdboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00
+cdboot_img_FORMAT = binary
+
+# For kernel.img.
+kernel_img_SOURCES = kern/i386/pc/startup.S \
+	kern/i386/misc.S \
+	kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+	kern/$(target_cpu)/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \
+	kern/parser.c kern/partition.c \
+	kern/i386/tsc.c kern/i386/pit.c \
+	kern/generic/rtc_get_time_ms.c \
+	kern/generic/millisleep.c \
+	kern/env.c \
+	term/i386/pc/console.c term/i386/vga_common.c \
+	symlist.c
+kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
+	machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
+	machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h
+kernel_img_CFLAGS = $(COMMON_CFLAGS)  $(TARGET_IMG_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
+kernel_img_FORMAT = binary
+
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# Utilities.
+bin_UTILITIES = grub-mkimage
+sbin_UTILITIES = grub-setup grub-mkdevicemap
+ifeq ($(enable_grub_emu), yes)
+sbin_UTILITIES += grub-emu
+endif
+
+# For grub-mkimage.
+grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \
+	util/resolve.c lib/LzmaEnc.c lib/LzFind.c
+grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
+util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile
+
+# For grub-setup.
+util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h
+grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c	\
+	util/misc.c util/getroot.c kern/device.c kern/disk.c	\
+	kern/err.c kern/misc.c kern/parser.c kern/partition.c	\
+	kern/file.c kern/fs.c kern/env.c fs/fshelp.c		\
+	\
+	fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c	\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c		\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c	\
+	fs/befs.c fs/befs_be.c fs/tar.c			\
+	\
+	partmap/msdos.c partmap/gpt.c				\
+	\
+	disk/raid.c disk/mdraid_linux.c disk/lvm.c		\
+	util/raid.c util/lvm.c					\
+	grub_setup_init.c
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/devicemap.c util/misc.c
+
+# For grub-emu.
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c	\
+	commands/configfile.c commands/echo.c commands/help.c		\
+	commands/handler.c commands/ls.c commands/test.c 		\
+	commands/search.c commands/blocklist.c commands/hexdump.c	\
+	lib/hexdump.c commands/i386/pc/halt.c commands/reboot.c		\
+	lib/envblk.c commands/loadenv.c					\
+	commands/gptsync.c commands/probe.c commands/xnu_uuid.c		\
+	commands/i386/cpuid.c	\
+	commands/password.c commands/keystatus.c			\
+	disk/host.c disk/loopback.c disk/scsi.c				\
+	fs/fshelp.c 	\
+	\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/list.c kern/handler.c				\
+	kern/command.c kern/corecmd.c commands/extcmd.c	kern/file.c	\
+	kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c	\
+	kern/partition.c kern/reader.c kern/term.c			\
+	kern/rescue_reader.c kern/rescue_parser.c			\
+	lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.c	\
+	normal/handler.c normal/auth.c normal/autofs.c				\
+	normal/completion.c normal/main.c normal/color.c		\
+	normal/menu.c normal/menu_entry.c normal/menu_viewer.c		\
+	normal/menu_text.c						\
+	script/sh/main.c script/sh/execute.c script/sh/function.c	\
+	script/sh/lexer.c script/sh/script.c grub_script.tab.c		\
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c partmap/gpt.c					\
+	\
+	fs/affs.c fs/cpio.c  fs/fat.c fs/ext2.c fs/hfs.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c		\
+	fs/befs.c fs/befs_be.c fs/tar.c				\
+	\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	commands/parttool.c parttool/msdospart.c				\
+	grub_emu_init.c
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+ifeq ($(enable_grub_emu_usb), yes)
+grub_emu_SOURCES += disk/usbms.c util/usb.c bus/usb/usb.c	\
+		commands/usbtest.c
+grub_emu_LDFLAGS += $(LIBCURSES) $(LIBUSB)
+endif
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+bin_SCRIPTS = grub-mkrescue
+
+# For grub-install.
+grub_install_SOURCES = util/i386/pc/grub-install.in
+
+# For grub-mkrescue.
+grub_mkrescue_SOURCES = util/i386/pc/grub-mkrescue.in
+
+pkglib_MODULES = biosdisk.mod chain.mod \
+	multiboot.mod reboot.mod halt.mod	\
+	vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod	\
+	ata.mod vga.mod memdisk.mod pci.mod lspci.mod	\
+	aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
+	datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \
+	usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \
+	efiemu.mod mmap.mod acpi.mod drivemap.mod
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For drivemap.mod.
+drivemap_mod_SOURCES = commands/i386/pc/drivemap.c \
+                       commands/i386/pc/drivemap_int13h.S
+drivemap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+drivemap_mod_CFLAGS = $(COMMON_CFLAGS)
+drivemap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For efiemu.mod.
+efiemu_mod_SOURCES = efiemu/main.c efiemu/i386/loadcore32.c \
+		     efiemu/i386/loadcore64.c efiemu/i386/pc/cfgtables.c \
+		     efiemu/mm.c efiemu/loadcore_common.c efiemu/symbols.c \
+		     efiemu/loadcore32.c efiemu/loadcore64.c \
+		     efiemu/prepare32.c efiemu/prepare64.c efiemu/pnvram.c \
+		     efiemu/i386/coredetect.c
+efiemu_mod_CFLAGS = $(COMMON_CFLAGS)
+efiemu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For acpi.mod.
+acpi_mod_SOURCES = commands/acpi.c commands/i386/pc/acpi.c
+acpi_mod_CFLAGS = $(COMMON_CFLAGS)
+acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
+		   mmap/i386/pc/mmap.c mmap/i386/pc/mmap_helper.S
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For biosdisk.mod.
+biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
+biosdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+biosdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For chain.mod.
+chain_mod_SOURCES = loader/i386/pc/chainloader.c
+chain_mod_CFLAGS = $(COMMON_CFLAGS)
+chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += linux16.mod
+linux16_mod_SOURCES = loader/i386/pc/linux.c
+linux16_mod_CFLAGS = $(COMMON_CFLAGS)
+linux16_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += linux.mod
+linux_mod_SOURCES = loader/i386/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += xnu.mod
+xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c\
+	 loader/macho.c loader/xnu.c loader/i386/xnu_helper.S
+xnu_mod_CFLAGS = $(COMMON_CFLAGS)
+xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For reboot.mod.
+reboot_mod_SOURCES = commands/reboot.c
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/i386/pc/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For serial.mod.
+serial_mod_SOURCES = term/i386/pc/serial.c
+serial_mod_CFLAGS = $(COMMON_CFLAGS)
+serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For multiboot.mod.
+multiboot_mod_SOURCES = loader/i386/multiboot.c \
+			loader/i386/multiboot_helper.S \
+                        loader/i386/pc/multiboot2.c \
+                        loader/multiboot2.c \
+                        loader/multiboot_loader.c
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For vbe.mod.
+vbe_mod_SOURCES = video/i386/pc/vbe.c
+vbe_mod_CFLAGS = $(COMMON_CFLAGS)
+vbe_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For vbeinfo.mod.
+vbeinfo_mod_SOURCES = commands/i386/pc/vbeinfo.c
+vbeinfo_mod_CFLAGS = $(COMMON_CFLAGS)
+vbeinfo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For vbetest.mod.
+vbetest_mod_SOURCES = commands/i386/pc/vbetest.c
+vbetest_mod_CFLAGS = $(COMMON_CFLAGS)
+vbetest_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For play.mod.
+play_mod_SOURCES = commands/i386/pc/play.c
+play_mod_CFLAGS = $(COMMON_CFLAGS)
+play_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ata.mod.
+ata_mod_SOURCES = disk/ata.c
+ata_mod_CFLAGS = $(COMMON_CFLAGS)
+ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For vga.mod.
+vga_mod_SOURCES = term/i386/pc/vga.c
+vga_mod_CFLAGS = $(COMMON_CFLAGS)
+vga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memdisk.mod.
+memdisk_mod_SOURCES = disk/memdisk.c
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pci.mod
+pci_mod_SOURCES = bus/pci.c
+pci_mod_CFLAGS = $(COMMON_CFLAGS)
+pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lspci.mod
+lspci_mod_SOURCES = commands/lspci.c
+lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For aout.mod
+aout_mod_SOURCES = loader/aout.c
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bsd.mod
+bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
+bsd_mod_CFLAGS = $(COMMON_CFLAGS)
+bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For usb.mod
+usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
+usb_mod_CFLAGS = $(COMMON_CFLAGS)
+usb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usbtest.mod
+usbtest_mod_SOURCES = commands/usbtest.c
+usbtest_mod_CFLAGS = $(COMMON_CFLAGS)
+usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For uhci.mod
+uhci_mod_SOURCES = bus/usb/uhci.c
+uhci_mod_CFLAGS = $(COMMON_CFLAGS)
+uhci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ohci.mod
+ohci_mod_SOURCES = bus/usb/ohci.c
+ohci_mod_CFLAGS = $(COMMON_CFLAGS)
+ohci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usbms.mod
+usbms_mod_SOURCES = disk/usbms.c
+usbms_mod_CFLAGS = $(COMMON_CFLAGS)
+usbms_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usb_keyboard.mod
+usb_keyboard_mod_SOURCES = term/usb_keyboard.c
+usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
+usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pxe.mod
+pxe_mod_SOURCES = fs/i386/pc/pxe.c
+pxe_mod_CFLAGS = $(COMMON_CFLAGS)
+pxe_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pxecmd.mod
+pxecmd_mod_SOURCES = commands/i386/pc/pxecmd.c
+pxecmd_mod_CFLAGS = $(COMMON_CFLAGS)
+pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/i386/datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For date.mod
+date_mod_SOURCES = commands/date.c
+date_mod_CFLAGS = $(COMMON_CFLAGS)
+date_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datehook.mod
+datehook_mod_SOURCES = hook/datehook.c
+datehook_mod_CFLAGS = $(COMMON_CFLAGS)
+datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ata_pthru.mod.
+ata_pthru_mod_SOURCES = disk/ata_pthru.c
+ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS)
+ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hdparm.mod.
+hdparm_mod_SOURCES = commands/hdparm.c lib/hexdump.c
+hdparm_mod_CFLAGS = $(COMMON_CFLAGS)
+hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+ifeq ($(enable_efiemu), yes)
+
+efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
+	-rm -f $@
+ifeq ($(TARGET_APPLE_CC), 1)
+	-rm -f $@.bin
+	$(TARGET_CC) -c -m32 -DELF32 -DAPPLE_CC -o $@.bin -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+	$(OBJCONV) -felf32 -nu -nd $@.bin $@
+	-rm -f $@.bin
+else
+	$(TARGET_CC) -c -m32 -DELF32 -o $@ -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+	if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+endif
+
+efiemu64_c.o: efiemu/runtime/efiemu.c
+ifeq ($(TARGET_APPLE_CC), 1)
+	$(TARGET_CC) -c -m64 -DAPPLE_CC=1 -DELF64 -o $@ -Wall -Werror $< -nostdlib -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+else
+	$(TARGET_CC) -c -m64 -DELF64 -o $@ -Wall -Werror $< -nostdlib  -mcmodel=large -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+endif
+
+efiemu64_s.o: efiemu/runtime/efiemu.S
+	-rm -f $@
+ifeq ($(TARGET_APPLE_CC), 1)
+	$(TARGET_CC) -c -m64 -DAPPLE_CC=1 -DELF64 -o $@ -Wall -Werror $< -nostdlib -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+else
+	$(TARGET_CC) -c -m64 -DELF64 -o $@ -Wall -Werror $< -nostdlib  -mcmodel=large -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+endif
+
+efiemu64.o: efiemu64_c.o efiemu64_s.o  $(TARGET_OBJ2ELF)
+	-rm -f $@
+ifeq ($(TARGET_APPLE_CC), 1)
+	-rm -f $@.bin
+	$(TARGET_CC) -m64 -o $@.bin -Wl,-r $^ -nostdlib
+	$(OBJCONV) -felf64 -nu -nd $@.bin $@
+	-rm -f $@.bin
+else
+	$(TARGET_CC) -m64 -o $@ -Wl,-r $^ -nostdlib
+	if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+endif
+
+CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o
+pkglib_DATA += efiemu32.o efiemu64.o
+
+endif
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
diff --git a/conf/i386-qemu.mk b/conf/i386-qemu.mk
new file mode 100644
index 0000000..1510367
--- /dev/null
+++ b/conf/i386-qemu.mk
@@ -0,0 +1,3 @@
+# -*- makefile -*-
+# Generated by genmk.rb, please don't edit!
+include $(srcdir)/conf/i386-coreboot.mk
diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk
new file mode 100644
index 0000000..573a5d0
--- /dev/null
+++ b/conf/i386-qemu.rmk
@@ -0,0 +1,2 @@
+# -*- makefile -*-
+include $(srcdir)/conf/i386-coreboot.mk
diff --git a/conf/i386.mk b/conf/i386.mk
new file mode 100644
index 0000000..2d18fae
--- /dev/null
+++ b/conf/i386.mk
@@ -0,0 +1,311 @@
+# -*- makefile -*-
+# Generated by genmk.rb, please don't edit!
+
+pkglib_MODULES += cpuid.mod
+cpuid_mod_SOURCES = commands/i386/cpuid.c
+
+clean-module-cpuid.mod.1:
+	rm -f cpuid.mod mod-cpuid.o mod-cpuid.c pre-cpuid.o cpuid_mod-commands_i386_cpuid.o und-cpuid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-cpuid.mod.1
+
+ifneq ($(cpuid_mod_EXPORTS),no)
+clean-module-cpuid.mod-symbol.1:
+	rm -f def-cpuid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-cpuid.mod-symbol.1
+DEFSYMFILES += def-cpuid.lst
+endif
+mostlyclean-module-cpuid.mod.1:
+	rm -f cpuid_mod-commands_i386_cpuid.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-cpuid.mod.1
+UNDSYMFILES += und-cpuid.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+cpuid.mod: pre-cpuid.o mod-cpuid.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(cpuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-cpuid.o mod-cpuid.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+cpuid.mod: pre-cpuid.o mod-cpuid.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(cpuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-cpuid.o mod-cpuid.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-cpuid.o: $(cpuid_mod_DEPENDENCIES) cpuid_mod-commands_i386_cpuid.o
+	-rm -f $@
+	$(TARGET_CC) $(cpuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ cpuid_mod-commands_i386_cpuid.o
+
+mod-cpuid.o: mod-cpuid.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cpuid_mod_CFLAGS) -c -o $@ $<
+
+mod-cpuid.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'cpuid' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(cpuid_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-cpuid.lst: pre-cpuid.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 cpuid/' > $@
+else
+def-cpuid.lst: pre-cpuid.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 cpuid/' > $@
+endif
+endif
+
+und-cpuid.lst: pre-cpuid.o
+	echo 'cpuid' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+cpuid_mod-commands_i386_cpuid.o: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cpuid_mod_CFLAGS) -MD -c -o $@ $<
+-include cpuid_mod-commands_i386_cpuid.d
+
+clean-module-cpuid_mod-commands_i386_cpuid-extra.1:
+	rm -f cmd-cpuid_mod-commands_i386_cpuid.lst fs-cpuid_mod-commands_i386_cpuid.lst partmap-cpuid_mod-commands_i386_cpuid.lst handler-cpuid_mod-commands_i386_cpuid.lst parttool-cpuid_mod-commands_i386_cpuid.lst
+
+CLEAN_MODULE_TARGETS += clean-module-cpuid_mod-commands_i386_cpuid-extra.1
+
+COMMANDFILES += cmd-cpuid_mod-commands_i386_cpuid.lst
+FSFILES += fs-cpuid_mod-commands_i386_cpuid.lst
+PARTTOOLFILES += parttool-cpuid_mod-commands_i386_cpuid.lst
+PARTMAPFILES += partmap-cpuid_mod-commands_i386_cpuid.lst
+HANDLERFILES += handler-cpuid_mod-commands_i386_cpuid.lst
+
+cmd-cpuid_mod-commands_i386_cpuid.lst: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cpuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh cpuid > $@ || (rm -f $@; exit 1)
+
+fs-cpuid_mod-commands_i386_cpuid.lst: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cpuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh cpuid > $@ || (rm -f $@; exit 1)
+
+parttool-cpuid_mod-commands_i386_cpuid.lst: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cpuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh cpuid > $@ || (rm -f $@; exit 1)
+
+partmap-cpuid_mod-commands_i386_cpuid.lst: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cpuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh cpuid > $@ || (rm -f $@; exit 1)
+
+handler-cpuid_mod-commands_i386_cpuid.lst: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(cpuid_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh cpuid > $@ || (rm -f $@; exit 1)
+
+cpuid_mod_CFLAGS = $(COMMON_CFLAGS)
+cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += at_keyboard.mod
+at_keyboard_mod_SOURCES = term/i386/pc/at_keyboard.c
+
+clean-module-at_keyboard.mod.1:
+	rm -f at_keyboard.mod mod-at_keyboard.o mod-at_keyboard.c pre-at_keyboard.o at_keyboard_mod-term_i386_pc_at_keyboard.o und-at_keyboard.lst
+
+CLEAN_MODULE_TARGETS += clean-module-at_keyboard.mod.1
+
+ifneq ($(at_keyboard_mod_EXPORTS),no)
+clean-module-at_keyboard.mod-symbol.1:
+	rm -f def-at_keyboard.lst
+
+CLEAN_MODULE_TARGETS += clean-module-at_keyboard.mod-symbol.1
+DEFSYMFILES += def-at_keyboard.lst
+endif
+mostlyclean-module-at_keyboard.mod.1:
+	rm -f at_keyboard_mod-term_i386_pc_at_keyboard.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-at_keyboard.mod.1
+UNDSYMFILES += und-at_keyboard.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+at_keyboard.mod: pre-at_keyboard.o mod-at_keyboard.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(at_keyboard_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-at_keyboard.o mod-at_keyboard.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+at_keyboard.mod: pre-at_keyboard.o mod-at_keyboard.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(at_keyboard_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-at_keyboard.o mod-at_keyboard.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-at_keyboard.o: $(at_keyboard_mod_DEPENDENCIES) at_keyboard_mod-term_i386_pc_at_keyboard.o
+	-rm -f $@
+	$(TARGET_CC) $(at_keyboard_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ at_keyboard_mod-term_i386_pc_at_keyboard.o
+
+mod-at_keyboard.o: mod-at_keyboard.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(at_keyboard_mod_CFLAGS) -c -o $@ $<
+
+mod-at_keyboard.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'at_keyboard' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(at_keyboard_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-at_keyboard.lst: pre-at_keyboard.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 at_keyboard/' > $@
+else
+def-at_keyboard.lst: pre-at_keyboard.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 at_keyboard/' > $@
+endif
+endif
+
+und-at_keyboard.lst: pre-at_keyboard.o
+	echo 'at_keyboard' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+at_keyboard_mod-term_i386_pc_at_keyboard.o: term/i386/pc/at_keyboard.c $(term/i386/pc/at_keyboard.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(at_keyboard_mod_CFLAGS) -MD -c -o $@ $<
+-include at_keyboard_mod-term_i386_pc_at_keyboard.d
+
+clean-module-at_keyboard_mod-term_i386_pc_at_keyboard-extra.1:
+	rm -f cmd-at_keyboard_mod-term_i386_pc_at_keyboard.lst fs-at_keyboard_mod-term_i386_pc_at_keyboard.lst partmap-at_keyboard_mod-term_i386_pc_at_keyboard.lst handler-at_keyboard_mod-term_i386_pc_at_keyboard.lst parttool-at_keyboard_mod-term_i386_pc_at_keyboard.lst
+
+CLEAN_MODULE_TARGETS += clean-module-at_keyboard_mod-term_i386_pc_at_keyboard-extra.1
+
+COMMANDFILES += cmd-at_keyboard_mod-term_i386_pc_at_keyboard.lst
+FSFILES += fs-at_keyboard_mod-term_i386_pc_at_keyboard.lst
+PARTTOOLFILES += parttool-at_keyboard_mod-term_i386_pc_at_keyboard.lst
+PARTMAPFILES += partmap-at_keyboard_mod-term_i386_pc_at_keyboard.lst
+HANDLERFILES += handler-at_keyboard_mod-term_i386_pc_at_keyboard.lst
+
+cmd-at_keyboard_mod-term_i386_pc_at_keyboard.lst: term/i386/pc/at_keyboard.c $(term/i386/pc/at_keyboard.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(at_keyboard_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh at_keyboard > $@ || (rm -f $@; exit 1)
+
+fs-at_keyboard_mod-term_i386_pc_at_keyboard.lst: term/i386/pc/at_keyboard.c $(term/i386/pc/at_keyboard.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(at_keyboard_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh at_keyboard > $@ || (rm -f $@; exit 1)
+
+parttool-at_keyboard_mod-term_i386_pc_at_keyboard.lst: term/i386/pc/at_keyboard.c $(term/i386/pc/at_keyboard.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(at_keyboard_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh at_keyboard > $@ || (rm -f $@; exit 1)
+
+partmap-at_keyboard_mod-term_i386_pc_at_keyboard.lst: term/i386/pc/at_keyboard.c $(term/i386/pc/at_keyboard.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(at_keyboard_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh at_keyboard > $@ || (rm -f $@; exit 1)
+
+handler-at_keyboard_mod-term_i386_pc_at_keyboard.lst: term/i386/pc/at_keyboard.c $(term/i386/pc/at_keyboard.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(at_keyboard_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh at_keyboard > $@ || (rm -f $@; exit 1)
+
+at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
+at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += vga_text.mod
+vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c
+
+clean-module-vga_text.mod.1:
+	rm -f vga_text.mod mod-vga_text.o mod-vga_text.c pre-vga_text.o vga_text_mod-term_i386_pc_vga_text.o vga_text_mod-term_i386_vga_common.o und-vga_text.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vga_text.mod.1
+
+ifneq ($(vga_text_mod_EXPORTS),no)
+clean-module-vga_text.mod-symbol.1:
+	rm -f def-vga_text.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vga_text.mod-symbol.1
+DEFSYMFILES += def-vga_text.lst
+endif
+mostlyclean-module-vga_text.mod.1:
+	rm -f vga_text_mod-term_i386_pc_vga_text.d vga_text_mod-term_i386_vga_common.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-vga_text.mod.1
+UNDSYMFILES += und-vga_text.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+vga_text.mod: pre-vga_text.o mod-vga_text.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(vga_text_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-vga_text.o mod-vga_text.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+vga_text.mod: pre-vga_text.o mod-vga_text.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(vga_text_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-vga_text.o mod-vga_text.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-vga_text.o: $(vga_text_mod_DEPENDENCIES) vga_text_mod-term_i386_pc_vga_text.o vga_text_mod-term_i386_vga_common.o
+	-rm -f $@
+	$(TARGET_CC) $(vga_text_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ vga_text_mod-term_i386_pc_vga_text.o vga_text_mod-term_i386_vga_common.o
+
+mod-vga_text.o: mod-vga_text.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -c -o $@ $<
+
+mod-vga_text.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'vga_text' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(vga_text_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-vga_text.lst: pre-vga_text.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vga_text/' > $@
+else
+def-vga_text.lst: pre-vga_text.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 vga_text/' > $@
+endif
+endif
+
+und-vga_text.lst: pre-vga_text.o
+	echo 'vga_text' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+vga_text_mod-term_i386_pc_vga_text.o: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -MD -c -o $@ $<
+-include vga_text_mod-term_i386_pc_vga_text.d
+
+clean-module-vga_text_mod-term_i386_pc_vga_text-extra.1:
+	rm -f cmd-vga_text_mod-term_i386_pc_vga_text.lst fs-vga_text_mod-term_i386_pc_vga_text.lst partmap-vga_text_mod-term_i386_pc_vga_text.lst handler-vga_text_mod-term_i386_pc_vga_text.lst parttool-vga_text_mod-term_i386_pc_vga_text.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vga_text_mod-term_i386_pc_vga_text-extra.1
+
+COMMANDFILES += cmd-vga_text_mod-term_i386_pc_vga_text.lst
+FSFILES += fs-vga_text_mod-term_i386_pc_vga_text.lst
+PARTTOOLFILES += parttool-vga_text_mod-term_i386_pc_vga_text.lst
+PARTMAPFILES += partmap-vga_text_mod-term_i386_pc_vga_text.lst
+HANDLERFILES += handler-vga_text_mod-term_i386_pc_vga_text.lst
+
+cmd-vga_text_mod-term_i386_pc_vga_text.lst: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh vga_text > $@ || (rm -f $@; exit 1)
+
+fs-vga_text_mod-term_i386_pc_vga_text.lst: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh vga_text > $@ || (rm -f $@; exit 1)
+
+parttool-vga_text_mod-term_i386_pc_vga_text.lst: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh vga_text > $@ || (rm -f $@; exit 1)
+
+partmap-vga_text_mod-term_i386_pc_vga_text.lst: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh vga_text > $@ || (rm -f $@; exit 1)
+
+handler-vga_text_mod-term_i386_pc_vga_text.lst: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh vga_text > $@ || (rm -f $@; exit 1)
+
+vga_text_mod-term_i386_vga_common.o: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -MD -c -o $@ $<
+-include vga_text_mod-term_i386_vga_common.d
+
+clean-module-vga_text_mod-term_i386_vga_common-extra.1:
+	rm -f cmd-vga_text_mod-term_i386_vga_common.lst fs-vga_text_mod-term_i386_vga_common.lst partmap-vga_text_mod-term_i386_vga_common.lst handler-vga_text_mod-term_i386_vga_common.lst parttool-vga_text_mod-term_i386_vga_common.lst
+
+CLEAN_MODULE_TARGETS += clean-module-vga_text_mod-term_i386_vga_common-extra.1
+
+COMMANDFILES += cmd-vga_text_mod-term_i386_vga_common.lst
+FSFILES += fs-vga_text_mod-term_i386_vga_common.lst
+PARTTOOLFILES += parttool-vga_text_mod-term_i386_vga_common.lst
+PARTMAPFILES += partmap-vga_text_mod-term_i386_vga_common.lst
+HANDLERFILES += handler-vga_text_mod-term_i386_vga_common.lst
+
+cmd-vga_text_mod-term_i386_vga_common.lst: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh vga_text > $@ || (rm -f $@; exit 1)
+
+fs-vga_text_mod-term_i386_vga_common.lst: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh vga_text > $@ || (rm -f $@; exit 1)
+
+parttool-vga_text_mod-term_i386_vga_common.lst: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh vga_text > $@ || (rm -f $@; exit 1)
+
+partmap-vga_text_mod-term_i386_vga_common.lst: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh vga_text > $@ || (rm -f $@; exit 1)
+
+handler-vga_text_mod-term_i386_vga_common.lst: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh vga_text > $@ || (rm -f $@; exit 1)
+
+vga_text_mod_CFLAGS = $(COMMON_CFLAGS)
+vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/i386.rmk b/conf/i386.rmk
new file mode 100644
index 0000000..93f84ce
--- /dev/null
+++ b/conf/i386.rmk
@@ -0,0 +1,16 @@
+# -*- makefile -*-
+
+pkglib_MODULES += cpuid.mod
+cpuid_mod_SOURCES = commands/i386/cpuid.c
+cpuid_mod_CFLAGS = $(COMMON_CFLAGS)
+cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += at_keyboard.mod
+at_keyboard_mod_SOURCES = term/i386/pc/at_keyboard.c
+at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
+at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += vga_text.mod
+vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c
+vga_text_mod_CFLAGS = $(COMMON_CFLAGS)
+vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/powerpc-ieee1275.mk b/conf/powerpc-ieee1275.mk
new file mode 100644
index 0000000..af5aa00
--- /dev/null
+++ b/conf/powerpc-ieee1275.mk
@@ -0,0 +1,1592 @@
+
+# Generated by genmk.rb, please don't edit!
+# -*- makefile -*-
+
+COMMON_ASFLAGS = -nostdinc -D__ASSEMBLY__
+COMMON_CFLAGS = -ffreestanding
+COMMON_LDFLAGS += -nostdlib
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Images.
+
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \
+	symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \
+	msdos_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h \
+	command.h
+
+symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# Programs
+pkglib_PROGRAMS = kernel.img
+
+# Utilities.
+sbin_UTILITIES = grub-mkdevicemap
+ifeq ($(enable_grub_emu), yes)
+sbin_UTILITIES += grub-emu
+endif
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/devicemap.c util/misc.c
+
+clean-utility-grub-mkdevicemap.1:
+	rm -f grub-mkdevicemap$(EXEEXT) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_devicemap.o grub_mkdevicemap-util_misc.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkdevicemap.1
+
+mostlyclean-utility-grub-mkdevicemap.1:
+	rm -f grub_mkdevicemap-util_grub_mkdevicemap.d grub_mkdevicemap-util_deviceiter.d grub_mkdevicemap-util_devicemap.d grub_mkdevicemap-util_misc.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkdevicemap.1
+
+grub_mkdevicemap_OBJECTS += grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_devicemap.o grub_mkdevicemap-util_misc.o
+
+grub_mkdevicemap-util_grub_mkdevicemap.o: util/grub-mkdevicemap.c $(util/grub-mkdevicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_grub_mkdevicemap.d
+
+grub_mkdevicemap-util_deviceiter.o: util/deviceiter.c $(util/deviceiter.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_deviceiter.d
+
+grub_mkdevicemap-util_devicemap.o: util/devicemap.c $(util/devicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_devicemap.d
+
+grub_mkdevicemap-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_misc.d
+
+
+# For grub-emu
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c 	\
+	commands/configfile.c commands/help.c				\
+	commands/search.c commands/handler.c commands/test.c 		\
+	commands/ls.c commands/blocklist.c commands/hexdump.c		\
+	lib/hexdump.c commands/halt.c commands/reboot.c 		\
+	lib/envblk.c commands/loadenv.c					\
+	commands/gptsync.c commands/probe.c commands/xnu_uuid.c		\
+	commands/password.c commands/keystatus.c			\
+	disk/loopback.c							\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c		\
+	fs/befs.c fs/befs_be.c fs/tar.c				\
+	\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/file.c kern/fs.c commands/boot.c kern/main.c	\
+	kern/misc.c kern/parser.c kern/partition.c kern/reader.c	\
+	kern/rescue_reader.c kern/rescue_parser.c			\
+	kern/term.c kern/list.c kern/handler.c fs/fshelp.c		\
+	kern/command.c kern/corecmd.c commands/extcmd.c			\
+	lib/arg.c normal/cmdline.c normal/datetime.c 			\
+	normal/completion.c normal/misc.c		 		\
+	normal/handler.c normal/auth.c normal/autofs.c normal/main.c	\
+	normal/menu.c 							\
+	normal/menu_text.c						\
+	normal/menu_entry.c normal/menu_viewer.c 	 		\
+	normal/color.c							\
+	script/sh/main.c script/sh/execute.c script/sh/function.c	\
+	script/sh/lexer.c script/sh/script.c				\
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c							\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	commands/parttool.c parttool/msdospart.c				\
+	grub_script.tab.c grub_emu_init.c
+
+clean-utility-grub-emu.1:
+	rm -f grub-emu$(EXEEXT) grub_emu-commands_minicmd.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_handler.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_halt.o grub_emu-commands_reboot.o grub_emu-lib_envblk.o grub_emu-commands_loadenv.o grub_emu-commands_gptsync.o grub_emu-commands_probe.o grub_emu-commands_xnu_uuid.o grub_emu-commands_password.o grub_emu-commands_keystatus.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_ufs2.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_afs_be.o grub_emu-fs_befs.o grub_emu-fs_befs_be.o grub_emu-fs_tar.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-commands_boot.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_reader.o grub_emu-kern_rescue_reader.o grub_emu-kern_rescue_parser.o grub_emu-kern_term.o grub_emu-kern_list.o grub_emu-kern_handler.o grub_emu-fs_fshelp.o grub_emu-kern_command.o grub_emu-kern_corecmd.o grub_emu-commands_extcmd.o grub_emu-lib_arg.o grub_emu-normal_cmdline.o grub_emu-normal_datetime.o grub_emu-normal_completion.o grub_emu-normal_misc.o grub_emu-normal_handler.o grub_emu-normal_auth.o grub_emu-normal_autofs.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_text.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_color.o grub_emu-script_sh_main.o grub_emu-script_sh_execute.o grub_emu-script_sh_function.o grub_emu-script_sh_lexer.o grub_emu-script_sh_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_msdos.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-commands_parttool.o grub_emu-parttool_msdospart.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-emu.1
+
+mostlyclean-utility-grub-emu.1:
+	rm -f grub_emu-commands_minicmd.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_help.d grub_emu-commands_search.d grub_emu-commands_handler.d grub_emu-commands_test.d grub_emu-commands_ls.d grub_emu-commands_blocklist.d grub_emu-commands_hexdump.d grub_emu-lib_hexdump.d grub_emu-commands_halt.d grub_emu-commands_reboot.d grub_emu-lib_envblk.d grub_emu-commands_loadenv.d grub_emu-commands_gptsync.d grub_emu-commands_probe.d grub_emu-commands_xnu_uuid.d grub_emu-commands_password.d grub_emu-commands_keystatus.d grub_emu-disk_loopback.d grub_emu-fs_affs.d grub_emu-fs_cpio.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_hfs.d grub_emu-fs_hfsplus.d grub_emu-fs_iso9660.d grub_emu-fs_udf.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ntfs.d grub_emu-fs_ntfscomp.d grub_emu-fs_reiserfs.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_ufs2.d grub_emu-fs_xfs.d grub_emu-fs_afs.d grub_emu-fs_afs_be.d grub_emu-fs_befs.d grub_emu-fs_befs_be.d grub_emu-fs_tar.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_elf.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-commands_boot.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-kern_partition.d grub_emu-kern_reader.d grub_emu-kern_rescue_reader.d grub_emu-kern_rescue_parser.d grub_emu-kern_term.d grub_emu-kern_list.d grub_emu-kern_handler.d grub_emu-fs_fshelp.d grub_emu-kern_command.d grub_emu-kern_corecmd.d grub_emu-commands_extcmd.d grub_emu-lib_arg.d grub_emu-normal_cmdline.d grub_emu-normal_datetime.d grub_emu-normal_completion.d grub_emu-normal_misc.d grub_emu-normal_handler.d grub_emu-normal_auth.d grub_emu-normal_autofs.d grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_menu_text.d grub_emu-normal_menu_entry.d grub_emu-normal_menu_viewer.d grub_emu-normal_color.d grub_emu-script_sh_main.d grub_emu-script_sh_execute.d grub_emu-script_sh_function.d grub_emu-script_sh_lexer.d grub_emu-script_sh_script.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_msdos.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-util_console.d grub_emu-util_hostfs.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_hostdisk.d grub_emu-util_getroot.d grub_emu-disk_raid.d grub_emu-disk_raid5_recover.d grub_emu-disk_raid6_recover.d grub_emu-disk_mdraid_linux.d grub_emu-disk_dmraid_nvidia.d grub_emu-disk_lvm.d grub_emu-commands_parttool.d grub_emu-parttool_msdospart.d grub_emu-grub_script_tab.d grub_emu-grub_emu_init.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-emu.1
+
+grub_emu_OBJECTS += grub_emu-commands_minicmd.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_handler.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_halt.o grub_emu-commands_reboot.o grub_emu-lib_envblk.o grub_emu-commands_loadenv.o grub_emu-commands_gptsync.o grub_emu-commands_probe.o grub_emu-commands_xnu_uuid.o grub_emu-commands_password.o grub_emu-commands_keystatus.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_ufs2.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_afs_be.o grub_emu-fs_befs.o grub_emu-fs_befs_be.o grub_emu-fs_tar.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-commands_boot.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_reader.o grub_emu-kern_rescue_reader.o grub_emu-kern_rescue_parser.o grub_emu-kern_term.o grub_emu-kern_list.o grub_emu-kern_handler.o grub_emu-fs_fshelp.o grub_emu-kern_command.o grub_emu-kern_corecmd.o grub_emu-commands_extcmd.o grub_emu-lib_arg.o grub_emu-normal_cmdline.o grub_emu-normal_datetime.o grub_emu-normal_completion.o grub_emu-normal_misc.o grub_emu-normal_handler.o grub_emu-normal_auth.o grub_emu-normal_autofs.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_text.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_color.o grub_emu-script_sh_main.o grub_emu-script_sh_execute.o grub_emu-script_sh_function.o grub_emu-script_sh_lexer.o grub_emu-script_sh_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_msdos.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-commands_parttool.o grub_emu-parttool_msdospart.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o
+
+grub_emu-commands_minicmd.o: commands/minicmd.c $(commands/minicmd.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_minicmd.d
+
+grub_emu-commands_cat.o: commands/cat.c $(commands/cat.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_cat.d
+
+grub_emu-commands_cmp.o: commands/cmp.c $(commands/cmp.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_cmp.d
+
+grub_emu-commands_configfile.o: commands/configfile.c $(commands/configfile.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_configfile.d
+
+grub_emu-commands_help.o: commands/help.c $(commands/help.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_help.d
+
+grub_emu-commands_search.o: commands/search.c $(commands/search.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_search.d
+
+grub_emu-commands_handler.o: commands/handler.c $(commands/handler.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_handler.d
+
+grub_emu-commands_test.o: commands/test.c $(commands/test.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_test.d
+
+grub_emu-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_ls.d
+
+grub_emu-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_blocklist.d
+
+grub_emu-commands_hexdump.o: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_hexdump.d
+
+grub_emu-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_hexdump.d
+
+grub_emu-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_halt.d
+
+grub_emu-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_reboot.d
+
+grub_emu-lib_envblk.o: lib/envblk.c $(lib/envblk.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_envblk.d
+
+grub_emu-commands_loadenv.o: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_loadenv.d
+
+grub_emu-commands_gptsync.o: commands/gptsync.c $(commands/gptsync.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_gptsync.d
+
+grub_emu-commands_probe.o: commands/probe.c $(commands/probe.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_probe.d
+
+grub_emu-commands_xnu_uuid.o: commands/xnu_uuid.c $(commands/xnu_uuid.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_xnu_uuid.d
+
+grub_emu-commands_password.o: commands/password.c $(commands/password.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_password.d
+
+grub_emu-commands_keystatus.o: commands/keystatus.c $(commands/keystatus.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_keystatus.d
+
+grub_emu-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_loopback.d
+
+grub_emu-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_affs.d
+
+grub_emu-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_cpio.d
+
+grub_emu-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_fat.d
+
+grub_emu-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ext2.d
+
+grub_emu-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_hfs.d
+
+grub_emu-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_hfsplus.d
+
+grub_emu-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_iso9660.d
+
+grub_emu-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_udf.d
+
+grub_emu-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_jfs.d
+
+grub_emu-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_minix.d
+
+grub_emu-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ntfs.d
+
+grub_emu-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ntfscomp.d
+
+grub_emu-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_reiserfs.d
+
+grub_emu-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_sfs.d
+
+grub_emu-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ufs.d
+
+grub_emu-fs_ufs2.o: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ufs2.d
+
+grub_emu-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_xfs.d
+
+grub_emu-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_afs.d
+
+grub_emu-fs_afs_be.o: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_afs_be.d
+
+grub_emu-fs_befs.o: fs/befs.c $(fs/befs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_befs.d
+
+grub_emu-fs_befs_be.o: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_befs_be.d
+
+grub_emu-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_tar.d
+
+grub_emu-io_gzio.o: io/gzio.c $(io/gzio.c_DEPENDENCIES)
+	$(CC) -Iio -I$(srcdir)/io $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-io_gzio.d
+
+grub_emu-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_device.d
+
+grub_emu-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_disk.d
+
+grub_emu-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_dl.d
+
+grub_emu-kern_elf.o: kern/elf.c $(kern/elf.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_elf.d
+
+grub_emu-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_env.d
+
+grub_emu-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_err.d
+
+grub_emu-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_file.d
+
+grub_emu-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_fs.d
+
+grub_emu-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_boot.d
+
+grub_emu-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_main.d
+
+grub_emu-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_misc.d
+
+grub_emu-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_parser.d
+
+grub_emu-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_partition.d
+
+grub_emu-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_reader.d
+
+grub_emu-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_rescue_reader.d
+
+grub_emu-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_rescue_parser.d
+
+grub_emu-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_term.d
+
+grub_emu-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_list.d
+
+grub_emu-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_handler.d
+
+grub_emu-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_fshelp.d
+
+grub_emu-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_command.d
+
+grub_emu-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_corecmd.d
+
+grub_emu-commands_extcmd.o: commands/extcmd.c $(commands/extcmd.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_extcmd.d
+
+grub_emu-lib_arg.o: lib/arg.c $(lib/arg.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_arg.d
+
+grub_emu-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_cmdline.d
+
+grub_emu-normal_datetime.o: normal/datetime.c $(normal/datetime.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_datetime.d
+
+grub_emu-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_completion.d
+
+grub_emu-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_misc.d
+
+grub_emu-normal_handler.o: normal/handler.c $(normal/handler.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_handler.d
+
+grub_emu-normal_auth.o: normal/auth.c $(normal/auth.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_auth.d
+
+grub_emu-normal_autofs.o: normal/autofs.c $(normal/autofs.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_autofs.d
+
+grub_emu-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_main.d
+
+grub_emu-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu.d
+
+grub_emu-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_text.d
+
+grub_emu-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_entry.d
+
+grub_emu-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_viewer.d
+
+grub_emu-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_color.d
+
+grub_emu-script_sh_main.o: script/sh/main.c $(script/sh/main.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_main.d
+
+grub_emu-script_sh_execute.o: script/sh/execute.c $(script/sh/execute.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_execute.d
+
+grub_emu-script_sh_function.o: script/sh/function.c $(script/sh/function.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_function.d
+
+grub_emu-script_sh_lexer.o: script/sh/lexer.c $(script/sh/lexer.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_lexer.d
+
+grub_emu-script_sh_script.o: script/sh/script.c $(script/sh/script.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_script.d
+
+grub_emu-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_amiga.d
+
+grub_emu-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_apple.d
+
+grub_emu-partmap_msdos.o: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_msdos.d
+
+grub_emu-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_sun.d
+
+grub_emu-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_acorn.d
+
+grub_emu-util_console.o: util/console.c $(util/console.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_console.d
+
+grub_emu-util_hostfs.o: util/hostfs.c $(util/hostfs.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_hostfs.d
+
+grub_emu-util_grub_emu.o: util/grub-emu.c $(util/grub-emu.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_grub_emu.d
+
+grub_emu-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_misc.d
+
+grub_emu-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_hostdisk.d
+
+grub_emu-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_getroot.d
+
+grub_emu-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid.d
+
+grub_emu-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid5_recover.d
+
+grub_emu-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid6_recover.d
+
+grub_emu-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_mdraid_linux.d
+
+grub_emu-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_dmraid_nvidia.d
+
+grub_emu-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_lvm.d
+
+grub_emu-commands_parttool.o: commands/parttool.c $(commands/parttool.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_parttool.d
+
+grub_emu-parttool_msdospart.o: parttool/msdospart.c $(parttool/msdospart.c_DEPENDENCIES)
+	$(CC) -Iparttool -I$(srcdir)/parttool $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-parttool_msdospart.d
+
+grub_emu-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-grub_script_tab.d
+
+grub_emu-grub_emu_init.o: grub_emu_init.c $(grub_emu_init.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-grub_emu_init.d
+
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
+	kern/ieee1275/ieee1275.c kern/main.c kern/device.c 		\
+	kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c 		\
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c 	\
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/list.c kern/handler.c kern/command.c kern/corecmd.c	\
+	kern/ieee1275/init.c 						\
+	kern/ieee1275/mmap.c						\
+	term/ieee1275/ofconsole.c 		\
+	kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c 		\
+	kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c 	\
+	kern/generic/millisleep.c kern/time.c                            \
+	symlist.c kern/$(target_cpu)/cache.S
+CLEANFILES += kernel.img kernel_img-kern_powerpc_ieee1275_startup.o kernel_img-kern_ieee1275_cmain.o kernel_img-kern_ieee1275_ieee1275.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_err.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern_ieee1275_init.o kernel_img-kern_ieee1275_mmap.o kernel_img-term_ieee1275_ofconsole.o kernel_img-kern_ieee1275_openfw.o kernel_img-disk_ieee1275_ofdisk.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_env.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_generic_millisleep.o kernel_img-kern_time.o kernel_img-symlist.o kernel_img-kern___target_cpu__cache.o
+MOSTLYCLEANFILES += kernel_img-kern_powerpc_ieee1275_startup.d kernel_img-kern_ieee1275_cmain.d kernel_img-kern_ieee1275_ieee1275.d kernel_img-kern_main.d kernel_img-kern_device.d kernel_img-kern_disk.d kernel_img-kern_dl.d kernel_img-kern_err.d kernel_img-kern_file.d kernel_img-kern_fs.d kernel_img-kern_misc.d kernel_img-kern_mm.d kernel_img-kern_reader.d kernel_img-kern_term.d kernel_img-kern_rescue_parser.d kernel_img-kern_rescue_reader.d kernel_img-kern_list.d kernel_img-kern_handler.d kernel_img-kern_command.d kernel_img-kern_corecmd.d kernel_img-kern_ieee1275_init.d kernel_img-kern_ieee1275_mmap.d kernel_img-term_ieee1275_ofconsole.d kernel_img-kern_ieee1275_openfw.d kernel_img-disk_ieee1275_ofdisk.d kernel_img-kern_parser.d kernel_img-kern_partition.d kernel_img-kern_env.d kernel_img-kern___target_cpu__dl.d kernel_img-kern_generic_millisleep.d kernel_img-kern_time.d kernel_img-symlist.d kernel_img-kern___target_cpu__cache.d
+
+kernel.img: $(kernel_img_DEPENDENCIES) kernel_img-kern_powerpc_ieee1275_startup.o kernel_img-kern_ieee1275_cmain.o kernel_img-kern_ieee1275_ieee1275.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_err.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern_ieee1275_init.o kernel_img-kern_ieee1275_mmap.o kernel_img-term_ieee1275_ofconsole.o kernel_img-kern_ieee1275_openfw.o kernel_img-disk_ieee1275_ofdisk.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_env.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_generic_millisleep.o kernel_img-kern_time.o kernel_img-symlist.o kernel_img-kern___target_cpu__cache.o
+	$(TARGET_CC) -o $@ kernel_img-kern_powerpc_ieee1275_startup.o kernel_img-kern_ieee1275_cmain.o kernel_img-kern_ieee1275_ieee1275.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_err.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern_ieee1275_init.o kernel_img-kern_ieee1275_mmap.o kernel_img-term_ieee1275_ofconsole.o kernel_img-kern_ieee1275_openfw.o kernel_img-disk_ieee1275_ofdisk.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_env.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_generic_millisleep.o kernel_img-kern_time.o kernel_img-symlist.o kernel_img-kern___target_cpu__cache.o $(TARGET_LDFLAGS) $(kernel_img_LDFLAGS)
+
+kernel_img-kern_powerpc_ieee1275_startup.o: kern/powerpc/ieee1275/startup.S $(kern/powerpc/ieee1275/startup.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/powerpc/ieee1275 -I$(srcdir)/kern/powerpc/ieee1275 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_powerpc_ieee1275_startup.d
+
+kernel_img-kern_ieee1275_cmain.o: kern/ieee1275/cmain.c $(kern/ieee1275/cmain.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_cmain.d
+
+kernel_img-kern_ieee1275_ieee1275.o: kern/ieee1275/ieee1275.c $(kern/ieee1275/ieee1275.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_ieee1275.d
+
+kernel_img-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_main.d
+
+kernel_img-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_device.d
+
+kernel_img-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_disk.d
+
+kernel_img-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_dl.d
+
+kernel_img-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_err.d
+
+kernel_img-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_file.d
+
+kernel_img-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_fs.d
+
+kernel_img-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_misc.d
+
+kernel_img-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_mm.d
+
+kernel_img-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_reader.d
+
+kernel_img-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_term.d
+
+kernel_img-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_rescue_parser.d
+
+kernel_img-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_rescue_reader.d
+
+kernel_img-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_list.d
+
+kernel_img-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_handler.d
+
+kernel_img-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_command.d
+
+kernel_img-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_corecmd.d
+
+kernel_img-kern_ieee1275_init.o: kern/ieee1275/init.c $(kern/ieee1275/init.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_init.d
+
+kernel_img-kern_ieee1275_mmap.o: kern/ieee1275/mmap.c $(kern/ieee1275/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_mmap.d
+
+kernel_img-term_ieee1275_ofconsole.o: term/ieee1275/ofconsole.c $(term/ieee1275/ofconsole.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/ieee1275 -I$(srcdir)/term/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-term_ieee1275_ofconsole.d
+
+kernel_img-kern_ieee1275_openfw.o: kern/ieee1275/openfw.c $(kern/ieee1275/openfw.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_openfw.d
+
+kernel_img-disk_ieee1275_ofdisk.o: disk/ieee1275/ofdisk.c $(disk/ieee1275/ofdisk.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-disk_ieee1275_ofdisk.d
+
+kernel_img-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_parser.d
+
+kernel_img-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_partition.d
+
+kernel_img-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_env.d
+
+kernel_img-kern___target_cpu__dl.o: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern___target_cpu__dl.d
+
+kernel_img-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_generic_millisleep.d
+
+kernel_img-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_time.d
+
+kernel_img-symlist.o: symlist.c $(symlist.c_DEPENDENCIES)
+	$(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-symlist.d
+
+kernel_img-kern___target_cpu__cache.o: kern/$(target_cpu)/cache.S $(kern/$(target_cpu)/cache.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern___target_cpu__cache.d
+
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \
+	-Wl,-N,-S,-Ttext,0x200000,-Bstatic
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+bin_SCRIPTS = grub-mkrescue
+
+# For grub-install.
+grub_install_SOURCES = util/ieee1275/grub-install.in
+CLEANFILES += grub-install
+
+grub-install: util/ieee1275/grub-install.in $(util/ieee1275/grub-install.in_DEPENDENCIES) config.status
+	./config.status --file=grub-install:util/ieee1275/grub-install.in
+	chmod +x $@
+
+
+# For grub-mkrescue.
+grub_mkrescue_SOURCES = util/powerpc/ieee1275/grub-mkrescue.in
+CLEANFILES += grub-mkrescue
+
+grub-mkrescue: util/powerpc/ieee1275/grub-mkrescue.in $(util/powerpc/ieee1275/grub-mkrescue.in_DEPENDENCIES) config.status
+	./config.status --file=grub-mkrescue:util/powerpc/ieee1275/grub-mkrescue.in
+	chmod +x $@
+
+
+# Modules.
+pkglib_MODULES = halt.mod \
+	linux.mod \
+	reboot.mod \
+	suspend.mod \
+        multiboot.mod \
+	memdisk.mod \
+	lsmmap.mod
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+
+clean-module-boot.mod.1:
+	rm -f boot.mod mod-boot.o mod-boot.c pre-boot.o boot_mod-commands_boot.o boot_mod-lib_i386_pc_biosnum.o und-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod.1
+
+ifneq ($(boot_mod_EXPORTS),no)
+clean-module-boot.mod-symbol.1:
+	rm -f def-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod-symbol.1
+DEFSYMFILES += def-boot.lst
+endif
+mostlyclean-module-boot.mod.1:
+	rm -f boot_mod-commands_boot.d boot_mod-lib_i386_pc_biosnum.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-boot.mod.1
+UNDSYMFILES += und-boot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-boot.o mod-boot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-boot.o mod-boot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-boot.o: $(boot_mod_DEPENDENCIES) boot_mod-commands_boot.o boot_mod-lib_i386_pc_biosnum.o
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ boot_mod-commands_boot.o boot_mod-lib_i386_pc_biosnum.o
+
+mod-boot.o: mod-boot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -c -o $@ $<
+
+mod-boot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'boot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(boot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-boot.lst: pre-boot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+else
+def-boot.lst: pre-boot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+endif
+endif
+
+und-boot.lst: pre-boot.o
+	echo 'boot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+boot_mod-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $<
+-include boot_mod-commands_boot.d
+
+clean-module-boot_mod-commands_boot-extra.1:
+	rm -f cmd-boot_mod-commands_boot.lst fs-boot_mod-commands_boot.lst partmap-boot_mod-commands_boot.lst handler-boot_mod-commands_boot.lst parttool-boot_mod-commands_boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot_mod-commands_boot-extra.1
+
+COMMANDFILES += cmd-boot_mod-commands_boot.lst
+FSFILES += fs-boot_mod-commands_boot.lst
+PARTTOOLFILES += parttool-boot_mod-commands_boot.lst
+PARTMAPFILES += partmap-boot_mod-commands_boot.lst
+HANDLERFILES += handler-boot_mod-commands_boot.lst
+
+cmd-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1)
+
+fs-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1)
+
+parttool-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh boot > $@ || (rm -f $@; exit 1)
+
+partmap-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1)
+
+handler-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh boot > $@ || (rm -f $@; exit 1)
+
+boot_mod-lib_i386_pc_biosnum.o: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $<
+-include boot_mod-lib_i386_pc_biosnum.d
+
+clean-module-boot_mod-lib_i386_pc_biosnum-extra.1:
+	rm -f cmd-boot_mod-lib_i386_pc_biosnum.lst fs-boot_mod-lib_i386_pc_biosnum.lst partmap-boot_mod-lib_i386_pc_biosnum.lst handler-boot_mod-lib_i386_pc_biosnum.lst parttool-boot_mod-lib_i386_pc_biosnum.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot_mod-lib_i386_pc_biosnum-extra.1
+
+COMMANDFILES += cmd-boot_mod-lib_i386_pc_biosnum.lst
+FSFILES += fs-boot_mod-lib_i386_pc_biosnum.lst
+PARTTOOLFILES += parttool-boot_mod-lib_i386_pc_biosnum.lst
+PARTMAPFILES += partmap-boot_mod-lib_i386_pc_biosnum.lst
+HANDLERFILES += handler-boot_mod-lib_i386_pc_biosnum.lst
+
+cmd-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1)
+
+fs-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1)
+
+parttool-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh boot > $@ || (rm -f $@; exit 1)
+
+partmap-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1)
+
+handler-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh boot > $@ || (rm -f $@; exit 1)
+
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
+
+clean-module-linux.mod.1:
+	rm -f linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_powerpc_ieee1275_linux.o und-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod.1
+
+ifneq ($(linux_mod_EXPORTS),no)
+clean-module-linux.mod-symbol.1:
+	rm -f def-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod-symbol.1
+DEFSYMFILES += def-linux.lst
+endif
+mostlyclean-module-linux.mod.1:
+	rm -f linux_mod-loader_powerpc_ieee1275_linux.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-linux.mod.1
+UNDSYMFILES += und-linux.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-linux.o mod-linux.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_powerpc_ieee1275_linux.o
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_powerpc_ieee1275_linux.o
+
+mod-linux.o: mod-linux.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $<
+
+mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(linux_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-linux.lst: pre-linux.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+else
+def-linux.lst: pre-linux.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+endif
+endif
+
+und-linux.lst: pre-linux.o
+	echo 'linux' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+linux_mod-loader_powerpc_ieee1275_linux.o: loader/powerpc/ieee1275/linux.c $(loader/powerpc/ieee1275/linux.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $<
+-include linux_mod-loader_powerpc_ieee1275_linux.d
+
+clean-module-linux_mod-loader_powerpc_ieee1275_linux-extra.1:
+	rm -f cmd-linux_mod-loader_powerpc_ieee1275_linux.lst fs-linux_mod-loader_powerpc_ieee1275_linux.lst partmap-linux_mod-loader_powerpc_ieee1275_linux.lst handler-linux_mod-loader_powerpc_ieee1275_linux.lst parttool-linux_mod-loader_powerpc_ieee1275_linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux_mod-loader_powerpc_ieee1275_linux-extra.1
+
+COMMANDFILES += cmd-linux_mod-loader_powerpc_ieee1275_linux.lst
+FSFILES += fs-linux_mod-loader_powerpc_ieee1275_linux.lst
+PARTTOOLFILES += parttool-linux_mod-loader_powerpc_ieee1275_linux.lst
+PARTMAPFILES += partmap-linux_mod-loader_powerpc_ieee1275_linux.lst
+HANDLERFILES += handler-linux_mod-loader_powerpc_ieee1275_linux.lst
+
+cmd-linux_mod-loader_powerpc_ieee1275_linux.lst: loader/powerpc/ieee1275/linux.c $(loader/powerpc/ieee1275/linux.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1)
+
+fs-linux_mod-loader_powerpc_ieee1275_linux.lst: loader/powerpc/ieee1275/linux.c $(loader/powerpc/ieee1275/linux.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1)
+
+parttool-linux_mod-loader_powerpc_ieee1275_linux.lst: loader/powerpc/ieee1275/linux.c $(loader/powerpc/ieee1275/linux.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh linux > $@ || (rm -f $@; exit 1)
+
+partmap-linux_mod-loader_powerpc_ieee1275_linux.lst: loader/powerpc/ieee1275/linux.c $(loader/powerpc/ieee1275/linux.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1)
+
+handler-linux_mod-loader_powerpc_ieee1275_linux.lst: loader/powerpc/ieee1275/linux.c $(loader/powerpc/ieee1275/linux.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh linux > $@ || (rm -f $@; exit 1)
+
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For suspend.mod
+suspend_mod_SOURCES = commands/ieee1275/suspend.c
+
+clean-module-suspend.mod.1:
+	rm -f suspend.mod mod-suspend.o mod-suspend.c pre-suspend.o suspend_mod-commands_ieee1275_suspend.o und-suspend.lst
+
+CLEAN_MODULE_TARGETS += clean-module-suspend.mod.1
+
+ifneq ($(suspend_mod_EXPORTS),no)
+clean-module-suspend.mod-symbol.1:
+	rm -f def-suspend.lst
+
+CLEAN_MODULE_TARGETS += clean-module-suspend.mod-symbol.1
+DEFSYMFILES += def-suspend.lst
+endif
+mostlyclean-module-suspend.mod.1:
+	rm -f suspend_mod-commands_ieee1275_suspend.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-suspend.mod.1
+UNDSYMFILES += und-suspend.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+suspend.mod: pre-suspend.o mod-suspend.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(suspend_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-suspend.o mod-suspend.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+suspend.mod: pre-suspend.o mod-suspend.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(suspend_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-suspend.o mod-suspend.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-suspend.o: $(suspend_mod_DEPENDENCIES) suspend_mod-commands_ieee1275_suspend.o
+	-rm -f $@
+	$(TARGET_CC) $(suspend_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ suspend_mod-commands_ieee1275_suspend.o
+
+mod-suspend.o: mod-suspend.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -c -o $@ $<
+
+mod-suspend.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'suspend' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(suspend_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-suspend.lst: pre-suspend.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 suspend/' > $@
+else
+def-suspend.lst: pre-suspend.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 suspend/' > $@
+endif
+endif
+
+und-suspend.lst: pre-suspend.o
+	echo 'suspend' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+suspend_mod-commands_ieee1275_suspend.o: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -MD -c -o $@ $<
+-include suspend_mod-commands_ieee1275_suspend.d
+
+clean-module-suspend_mod-commands_ieee1275_suspend-extra.1:
+	rm -f cmd-suspend_mod-commands_ieee1275_suspend.lst fs-suspend_mod-commands_ieee1275_suspend.lst partmap-suspend_mod-commands_ieee1275_suspend.lst handler-suspend_mod-commands_ieee1275_suspend.lst parttool-suspend_mod-commands_ieee1275_suspend.lst
+
+CLEAN_MODULE_TARGETS += clean-module-suspend_mod-commands_ieee1275_suspend-extra.1
+
+COMMANDFILES += cmd-suspend_mod-commands_ieee1275_suspend.lst
+FSFILES += fs-suspend_mod-commands_ieee1275_suspend.lst
+PARTTOOLFILES += parttool-suspend_mod-commands_ieee1275_suspend.lst
+PARTMAPFILES += partmap-suspend_mod-commands_ieee1275_suspend.lst
+HANDLERFILES += handler-suspend_mod-commands_ieee1275_suspend.lst
+
+cmd-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh suspend > $@ || (rm -f $@; exit 1)
+
+fs-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh suspend > $@ || (rm -f $@; exit 1)
+
+parttool-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh suspend > $@ || (rm -f $@; exit 1)
+
+partmap-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh suspend > $@ || (rm -f $@; exit 1)
+
+handler-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh suspend > $@ || (rm -f $@; exit 1)
+
+suspend_mod_CFLAGS = $(COMMON_CFLAGS)
+suspend_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod
+reboot_mod_SOURCES = commands/reboot.c
+
+clean-module-reboot.mod.1:
+	rm -f reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o und-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod.1
+
+ifneq ($(reboot_mod_EXPORTS),no)
+clean-module-reboot.mod-symbol.1:
+	rm -f def-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod-symbol.1
+DEFSYMFILES += def-reboot.lst
+endif
+mostlyclean-module-reboot.mod.1:
+	rm -f reboot_mod-commands_reboot.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-reboot.mod.1
+UNDSYMFILES += und-reboot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-reboot.o mod-reboot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o
+
+mod-reboot.o: mod-reboot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $<
+
+mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(reboot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-reboot.lst: pre-reboot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+else
+def-reboot.lst: pre-reboot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+endif
+endif
+
+und-reboot.lst: pre-reboot.o
+	echo 'reboot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $<
+-include reboot_mod-commands_reboot.d
+
+clean-module-reboot_mod-commands_reboot-extra.1:
+	rm -f cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst handler-reboot_mod-commands_reboot.lst parttool-reboot_mod-commands_reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot_mod-commands_reboot-extra.1
+
+COMMANDFILES += cmd-reboot_mod-commands_reboot.lst
+FSFILES += fs-reboot_mod-commands_reboot.lst
+PARTTOOLFILES += parttool-reboot_mod-commands_reboot.lst
+PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst
+HANDLERFILES += handler-reboot_mod-commands_reboot.lst
+
+cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1)
+
+parttool-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh reboot > $@ || (rm -f $@; exit 1)
+
+partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1)
+
+handler-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod
+halt_mod_SOURCES = commands/halt.c
+
+clean-module-halt.mod.1:
+	rm -f halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_halt.o und-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod.1
+
+ifneq ($(halt_mod_EXPORTS),no)
+clean-module-halt.mod-symbol.1:
+	rm -f def-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod-symbol.1
+DEFSYMFILES += def-halt.lst
+endif
+mostlyclean-module-halt.mod.1:
+	rm -f halt_mod-commands_halt.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-halt.mod.1
+UNDSYMFILES += und-halt.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-halt.o mod-halt.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_halt.o
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_halt.o
+
+mod-halt.o: mod-halt.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $<
+
+mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(halt_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-halt.lst: pre-halt.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+else
+def-halt.lst: pre-halt.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+endif
+endif
+
+und-halt.lst: pre-halt.o
+	echo 'halt' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+halt_mod-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $<
+-include halt_mod-commands_halt.d
+
+clean-module-halt_mod-commands_halt-extra.1:
+	rm -f cmd-halt_mod-commands_halt.lst fs-halt_mod-commands_halt.lst partmap-halt_mod-commands_halt.lst handler-halt_mod-commands_halt.lst parttool-halt_mod-commands_halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt_mod-commands_halt-extra.1
+
+COMMANDFILES += cmd-halt_mod-commands_halt.lst
+FSFILES += fs-halt_mod-commands_halt.lst
+PARTTOOLFILES += parttool-halt_mod-commands_halt.lst
+PARTMAPFILES += partmap-halt_mod-commands_halt.lst
+HANDLERFILES += handler-halt_mod-commands_halt.lst
+
+cmd-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1)
+
+fs-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1)
+
+parttool-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh halt > $@ || (rm -f $@; exit 1)
+
+partmap-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1)
+
+handler-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh halt > $@ || (rm -f $@; exit 1)
+
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For multiboot.mod
+multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \
+                         loader/multiboot2.c \
+                         loader/multiboot_loader.c
+
+clean-module-multiboot.mod.1:
+	rm -f multiboot.mod mod-multiboot.o mod-multiboot.c pre-multiboot.o multiboot_mod-loader_ieee1275_multiboot2.o multiboot_mod-loader_multiboot2.o multiboot_mod-loader_multiboot_loader.o und-multiboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot.mod.1
+
+ifneq ($(multiboot_mod_EXPORTS),no)
+clean-module-multiboot.mod-symbol.1:
+	rm -f def-multiboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot.mod-symbol.1
+DEFSYMFILES += def-multiboot.lst
+endif
+mostlyclean-module-multiboot.mod.1:
+	rm -f multiboot_mod-loader_ieee1275_multiboot2.d multiboot_mod-loader_multiboot2.d multiboot_mod-loader_multiboot_loader.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-multiboot.mod.1
+UNDSYMFILES += und-multiboot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+multiboot.mod: pre-multiboot.o mod-multiboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-multiboot.o mod-multiboot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+multiboot.mod: pre-multiboot.o mod-multiboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-multiboot.o mod-multiboot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-multiboot.o: $(multiboot_mod_DEPENDENCIES) multiboot_mod-loader_ieee1275_multiboot2.o multiboot_mod-loader_multiboot2.o multiboot_mod-loader_multiboot_loader.o
+	-rm -f $@
+	$(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ multiboot_mod-loader_ieee1275_multiboot2.o multiboot_mod-loader_multiboot2.o multiboot_mod-loader_multiboot_loader.o
+
+mod-multiboot.o: mod-multiboot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -c -o $@ $<
+
+mod-multiboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'multiboot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(multiboot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-multiboot.lst: pre-multiboot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@
+else
+def-multiboot.lst: pre-multiboot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@
+endif
+endif
+
+und-multiboot.lst: pre-multiboot.o
+	echo 'multiboot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+multiboot_mod-loader_ieee1275_multiboot2.o: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_ieee1275_multiboot2.d
+
+clean-module-multiboot_mod-loader_ieee1275_multiboot2-extra.1:
+	rm -f cmd-multiboot_mod-loader_ieee1275_multiboot2.lst fs-multiboot_mod-loader_ieee1275_multiboot2.lst partmap-multiboot_mod-loader_ieee1275_multiboot2.lst handler-multiboot_mod-loader_ieee1275_multiboot2.lst parttool-multiboot_mod-loader_ieee1275_multiboot2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_ieee1275_multiboot2-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_ieee1275_multiboot2.lst
+FSFILES += fs-multiboot_mod-loader_ieee1275_multiboot2.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_ieee1275_multiboot2.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_ieee1275_multiboot2.lst
+HANDLERFILES += handler-multiboot_mod-loader_ieee1275_multiboot2.lst
+
+cmd-multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_multiboot2.o: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_multiboot2.d
+
+clean-module-multiboot_mod-loader_multiboot2-extra.1:
+	rm -f cmd-multiboot_mod-loader_multiboot2.lst fs-multiboot_mod-loader_multiboot2.lst partmap-multiboot_mod-loader_multiboot2.lst handler-multiboot_mod-loader_multiboot2.lst parttool-multiboot_mod-loader_multiboot2.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_multiboot2-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_multiboot2.lst
+FSFILES += fs-multiboot_mod-loader_multiboot2.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_multiboot2.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_multiboot2.lst
+HANDLERFILES += handler-multiboot_mod-loader_multiboot2.lst
+
+cmd-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod-loader_multiboot_loader.o: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $<
+-include multiboot_mod-loader_multiboot_loader.d
+
+clean-module-multiboot_mod-loader_multiboot_loader-extra.1:
+	rm -f cmd-multiboot_mod-loader_multiboot_loader.lst fs-multiboot_mod-loader_multiboot_loader.lst partmap-multiboot_mod-loader_multiboot_loader.lst handler-multiboot_mod-loader_multiboot_loader.lst parttool-multiboot_mod-loader_multiboot_loader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-multiboot_mod-loader_multiboot_loader-extra.1
+
+COMMANDFILES += cmd-multiboot_mod-loader_multiboot_loader.lst
+FSFILES += fs-multiboot_mod-loader_multiboot_loader.lst
+PARTTOOLFILES += parttool-multiboot_mod-loader_multiboot_loader.lst
+PARTMAPFILES += partmap-multiboot_mod-loader_multiboot_loader.lst
+HANDLERFILES += handler-multiboot_mod-loader_multiboot_loader.lst
+
+cmd-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+fs-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+parttool-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+partmap-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+handler-multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh multiboot > $@ || (rm -f $@; exit 1)
+
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memdisk.mod.
+memdisk_mod_SOURCES = disk/memdisk.c
+
+clean-module-memdisk.mod.1:
+	rm -f memdisk.mod mod-memdisk.o mod-memdisk.c pre-memdisk.o memdisk_mod-disk_memdisk.o und-memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk.mod.1
+
+ifneq ($(memdisk_mod_EXPORTS),no)
+clean-module-memdisk.mod-symbol.1:
+	rm -f def-memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk.mod-symbol.1
+DEFSYMFILES += def-memdisk.lst
+endif
+mostlyclean-module-memdisk.mod.1:
+	rm -f memdisk_mod-disk_memdisk.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-memdisk.mod.1
+UNDSYMFILES += und-memdisk.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-memdisk.o mod-memdisk.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-memdisk.o mod-memdisk.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-memdisk.o: $(memdisk_mod_DEPENDENCIES) memdisk_mod-disk_memdisk.o
+	-rm -f $@
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memdisk_mod-disk_memdisk.o
+
+mod-memdisk.o: mod-memdisk.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -c -o $@ $<
+
+mod-memdisk.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'memdisk' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(memdisk_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-memdisk.lst: pre-memdisk.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@
+else
+def-memdisk.lst: pre-memdisk.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@
+endif
+endif
+
+und-memdisk.lst: pre-memdisk.o
+	echo 'memdisk' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+memdisk_mod-disk_memdisk.o: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -MD -c -o $@ $<
+-include memdisk_mod-disk_memdisk.d
+
+clean-module-memdisk_mod-disk_memdisk-extra.1:
+	rm -f cmd-memdisk_mod-disk_memdisk.lst fs-memdisk_mod-disk_memdisk.lst partmap-memdisk_mod-disk_memdisk.lst handler-memdisk_mod-disk_memdisk.lst parttool-memdisk_mod-disk_memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk_mod-disk_memdisk-extra.1
+
+COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst
+FSFILES += fs-memdisk_mod-disk_memdisk.lst
+PARTTOOLFILES += parttool-memdisk_mod-disk_memdisk.lst
+PARTMAPFILES += partmap-memdisk_mod-disk_memdisk.lst
+HANDLERFILES += handler-memdisk_mod-disk_memdisk.lst
+
+cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+fs-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+parttool-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+partmap-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+handler-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+
+clean-module-lsmmap.mod.1:
+	rm -f lsmmap.mod mod-lsmmap.o mod-lsmmap.c pre-lsmmap.o lsmmap_mod-commands_lsmmap.o und-lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap.mod.1
+
+ifneq ($(lsmmap_mod_EXPORTS),no)
+clean-module-lsmmap.mod-symbol.1:
+	rm -f def-lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap.mod-symbol.1
+DEFSYMFILES += def-lsmmap.lst
+endif
+mostlyclean-module-lsmmap.mod.1:
+	rm -f lsmmap_mod-commands_lsmmap.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-lsmmap.mod.1
+UNDSYMFILES += und-lsmmap.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-lsmmap.o mod-lsmmap.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-lsmmap.o mod-lsmmap.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-lsmmap.o: $(lsmmap_mod_DEPENDENCIES) lsmmap_mod-commands_lsmmap.o
+	-rm -f $@
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lsmmap_mod-commands_lsmmap.o
+
+mod-lsmmap.o: mod-lsmmap.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -c -o $@ $<
+
+mod-lsmmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'lsmmap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(lsmmap_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-lsmmap.lst: pre-lsmmap.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@
+else
+def-lsmmap.lst: pre-lsmmap.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@
+endif
+endif
+
+und-lsmmap.lst: pre-lsmmap.o
+	echo 'lsmmap' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+lsmmap_mod-commands_lsmmap.o: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -MD -c -o $@ $<
+-include lsmmap_mod-commands_lsmmap.d
+
+clean-module-lsmmap_mod-commands_lsmmap-extra.1:
+	rm -f cmd-lsmmap_mod-commands_lsmmap.lst fs-lsmmap_mod-commands_lsmmap.lst partmap-lsmmap_mod-commands_lsmmap.lst handler-lsmmap_mod-commands_lsmmap.lst parttool-lsmmap_mod-commands_lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap_mod-commands_lsmmap-extra.1
+
+COMMANDFILES += cmd-lsmmap_mod-commands_lsmmap.lst
+FSFILES += fs-lsmmap_mod-commands_lsmmap.lst
+PARTTOOLFILES += parttool-lsmmap_mod-commands_lsmmap.lst
+PARTMAPFILES += partmap-lsmmap_mod-commands_lsmmap.lst
+HANDLERFILES += handler-lsmmap_mod-commands_lsmmap.lst
+
+cmd-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+fs-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+parttool-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+partmap-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+handler-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/common.mk
+grub-mkdevicemap: $(grub_mkdevicemap_DEPENDENCIES) $(grub_mkdevicemap_OBJECTS)
+	$(CC) -o $@ $(grub_mkdevicemap_OBJECTS) $(LDFLAGS) $(grub_mkdevicemap_LDFLAGS)
+
+grub-emu: $(grub_emu_DEPENDENCIES) $(grub_emu_OBJECTS)
+	$(CC) -o $@ $(grub_emu_OBJECTS) $(LDFLAGS) $(grub_emu_LDFLAGS)
+
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
new file mode 100644
index 0000000..ee7f9ec
--- /dev/null
+++ b/conf/powerpc-ieee1275.rmk
@@ -0,0 +1,167 @@
+
+# -*- makefile -*-
+
+COMMON_ASFLAGS = -nostdinc -D__ASSEMBLY__
+COMMON_CFLAGS = -ffreestanding
+COMMON_LDFLAGS += -nostdlib
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Images.
+
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \
+	symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \
+	msdos_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h \
+	command.h
+
+symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# Programs
+pkglib_PROGRAMS = kernel.img
+
+# Utilities.
+sbin_UTILITIES = grub-mkdevicemap
+ifeq ($(enable_grub_emu), yes)
+sbin_UTILITIES += grub-emu
+endif
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/devicemap.c util/misc.c
+
+# For grub-emu
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c 	\
+	commands/configfile.c commands/help.c				\
+	commands/search.c commands/handler.c commands/test.c 		\
+	commands/ls.c commands/blocklist.c commands/hexdump.c		\
+	lib/hexdump.c commands/halt.c commands/reboot.c 		\
+	lib/envblk.c commands/loadenv.c					\
+	commands/gptsync.c commands/probe.c commands/xnu_uuid.c		\
+	commands/password.c commands/keystatus.c			\
+	disk/loopback.c							\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c		\
+	fs/befs.c fs/befs_be.c fs/tar.c				\
+	\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/file.c kern/fs.c commands/boot.c kern/main.c	\
+	kern/misc.c kern/parser.c kern/partition.c kern/reader.c	\
+	kern/rescue_reader.c kern/rescue_parser.c			\
+	kern/term.c kern/list.c kern/handler.c fs/fshelp.c		\
+	kern/command.c kern/corecmd.c commands/extcmd.c			\
+	lib/arg.c normal/cmdline.c normal/datetime.c 			\
+	normal/completion.c normal/misc.c		 		\
+	normal/handler.c normal/auth.c normal/autofs.c normal/main.c	\
+	normal/menu.c 							\
+	normal/menu_text.c						\
+	normal/menu_entry.c normal/menu_viewer.c 	 		\
+	normal/color.c							\
+	script/sh/main.c script/sh/execute.c script/sh/function.c	\
+	script/sh/lexer.c script/sh/script.c				\
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c							\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	commands/parttool.c parttool/msdospart.c				\
+	grub_script.tab.c grub_emu_init.c
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
+	kern/ieee1275/ieee1275.c kern/main.c kern/device.c 		\
+	kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c 		\
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c 	\
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/list.c kern/handler.c kern/command.c kern/corecmd.c	\
+	kern/ieee1275/init.c 						\
+	kern/ieee1275/mmap.c						\
+	term/ieee1275/ofconsole.c 		\
+	kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c 		\
+	kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c 	\
+	kern/generic/millisleep.c kern/time.c                            \
+	symlist.c kern/$(target_cpu)/cache.S
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \
+	-Wl,-N,-S,-Ttext,0x200000,-Bstatic
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+bin_SCRIPTS = grub-mkrescue
+
+# For grub-install.
+grub_install_SOURCES = util/ieee1275/grub-install.in
+
+# For grub-mkrescue.
+grub_mkrescue_SOURCES = util/powerpc/ieee1275/grub-mkrescue.in
+
+# Modules.
+pkglib_MODULES = halt.mod \
+	linux.mod \
+	reboot.mod \
+	suspend.mod \
+        multiboot.mod \
+	memdisk.mod \
+	lsmmap.mod
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For suspend.mod
+suspend_mod_SOURCES = commands/ieee1275/suspend.c
+suspend_mod_CFLAGS = $(COMMON_CFLAGS)
+suspend_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod
+reboot_mod_SOURCES = commands/reboot.c
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For multiboot.mod
+multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \
+                         loader/multiboot2.c \
+                         loader/multiboot_loader.c
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memdisk.mod.
+memdisk_mod_SOURCES = disk/memdisk.c
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/common.mk
diff --git a/conf/sparc64-ieee1275.mk b/conf/sparc64-ieee1275.mk
new file mode 100644
index 0000000..48e5ac6
--- /dev/null
+++ b/conf/sparc64-ieee1275.mk
@@ -0,0 +1,1723 @@
+
+# Generated by genmk.rb, please don't edit!
+# -*- makefile -*-
+
+COMMON_ASFLAGS = -nostdinc -m64
+COMMON_CFLAGS = -ffreestanding -m64 -mno-app-regs
+COMMON_LDFLAGS = -melf64_sparc -nostdlib -mno-relax
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Images.
+pkglib_IMAGES = boot.img diskboot.img kernel.img
+
+# For boot.img.
+boot_img_SOURCES = boot/sparc64/ieee1275/boot.S
+
+clean-image-boot.img.1:
+	rm -f boot.img boot.exec boot_img-boot_sparc64_ieee1275_boot.o
+
+CLEAN_IMAGE_TARGETS += clean-image-boot.img.1
+
+mostlyclean-image-boot.img.1:
+	rm -f boot_img-boot_sparc64_ieee1275_boot.d
+
+MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-boot.img.1
+
+ifneq ($(TARGET_APPLE_CC),1)
+boot.img: boot.exec
+	$(OBJCOPY) -O $(boot_img_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
+else
+ifneq (boot.exec,kernel.exec)
+boot.img: boot.exec ./grub-macho2img
+	./grub-macho2img $< $@
+else
+boot.img: boot.exec ./grub-macho2img
+	./grub-macho2img --bss $< $@
+endif
+endif
+
+boot.exec: boot_img-boot_sparc64_ieee1275_boot.o
+	$(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(boot_img_LDFLAGS)
+
+boot_img-boot_sparc64_ieee1275_boot.o: boot/sparc64/ieee1275/boot.S $(boot/sparc64/ieee1275/boot.S_DEPENDENCIES)
+	$(TARGET_CC) -Iboot/sparc64/ieee1275 -I$(srcdir)/boot/sparc64/ieee1275 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(boot_img_ASFLAGS) -MD -c -o $@ $<
+-include boot_img-boot_sparc64_ieee1275_boot.d
+
+boot_img_ASFLAGS = $(COMMON_ASFLAGS)
+boot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4000
+boot_img_FORMAT = a.out-sunos-big
+
+# For diskboot.img.
+diskboot_img_SOURCES = boot/sparc64/ieee1275/diskboot.S
+
+clean-image-diskboot.img.1:
+	rm -f diskboot.img diskboot.exec diskboot_img-boot_sparc64_ieee1275_diskboot.o
+
+CLEAN_IMAGE_TARGETS += clean-image-diskboot.img.1
+
+mostlyclean-image-diskboot.img.1:
+	rm -f diskboot_img-boot_sparc64_ieee1275_diskboot.d
+
+MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-diskboot.img.1
+
+ifneq ($(TARGET_APPLE_CC),1)
+diskboot.img: diskboot.exec
+	$(OBJCOPY) -O $(diskboot_img_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
+else
+ifneq (diskboot.exec,kernel.exec)
+diskboot.img: diskboot.exec ./grub-macho2img
+	./grub-macho2img $< $@
+else
+diskboot.img: diskboot.exec ./grub-macho2img
+	./grub-macho2img --bss $< $@
+endif
+endif
+
+diskboot.exec: diskboot_img-boot_sparc64_ieee1275_diskboot.o
+	$(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(diskboot_img_LDFLAGS)
+
+diskboot_img-boot_sparc64_ieee1275_diskboot.o: boot/sparc64/ieee1275/diskboot.S $(boot/sparc64/ieee1275/diskboot.S_DEPENDENCIES)
+	$(TARGET_CC) -Iboot/sparc64/ieee1275 -I$(srcdir)/boot/sparc64/ieee1275 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(diskboot_img_ASFLAGS) -MD -c -o $@ $<
+-include diskboot_img-boot_sparc64_ieee1275_diskboot.d
+
+diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4200
+diskboot_img_FORMAT = binary
+
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	list.h handler.h command.h \
+	sparc64/libgcc.h ieee1275/ieee1275.h machine/kernel.h \
+	sparc64/ieee1275/ieee1275.h
+kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c	\
+	kern/ieee1275/ieee1275.c kern/main.c kern/device.c		\
+	kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c		\
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c			\
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/list.c kern/handler.c kern/command.c kern/corecmd.c	\
+	kern/sparc64/ieee1275/ieee1275.c 				\
+	kern/sparc64/ieee1275/init.c 					\
+	kern/ieee1275/mmap.c						\
+	term/ieee1275/ofconsole.c 					\
+	kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c 			\
+	kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c	\
+	kern/generic/millisleep.c kern/time.c				\
+	symlist.c kern/$(target_cpu)/cache.S
+
+clean-image-kernel.img.1:
+	rm -f kernel.img kernel.exec kernel_img-kern_sparc64_ieee1275_crt0.o kernel_img-kern_ieee1275_cmain.o kernel_img-kern_ieee1275_ieee1275.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_err.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern_sparc64_ieee1275_ieee1275.o kernel_img-kern_sparc64_ieee1275_init.o kernel_img-kern_ieee1275_mmap.o kernel_img-term_ieee1275_ofconsole.o kernel_img-kern_ieee1275_openfw.o kernel_img-disk_ieee1275_ofdisk.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_env.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_generic_millisleep.o kernel_img-kern_time.o kernel_img-symlist.o kernel_img-kern___target_cpu__cache.o
+
+CLEAN_IMAGE_TARGETS += clean-image-kernel.img.1
+
+mostlyclean-image-kernel.img.1:
+	rm -f kernel_img-kern_sparc64_ieee1275_crt0.d kernel_img-kern_ieee1275_cmain.d kernel_img-kern_ieee1275_ieee1275.d kernel_img-kern_main.d kernel_img-kern_device.d kernel_img-kern_disk.d kernel_img-kern_dl.d kernel_img-kern_err.d kernel_img-kern_file.d kernel_img-kern_fs.d kernel_img-kern_misc.d kernel_img-kern_mm.d kernel_img-kern_reader.d kernel_img-kern_term.d kernel_img-kern_rescue_parser.d kernel_img-kern_rescue_reader.d kernel_img-kern_list.d kernel_img-kern_handler.d kernel_img-kern_command.d kernel_img-kern_corecmd.d kernel_img-kern_sparc64_ieee1275_ieee1275.d kernel_img-kern_sparc64_ieee1275_init.d kernel_img-kern_ieee1275_mmap.d kernel_img-term_ieee1275_ofconsole.d kernel_img-kern_ieee1275_openfw.d kernel_img-disk_ieee1275_ofdisk.d kernel_img-kern_parser.d kernel_img-kern_partition.d kernel_img-kern_env.d kernel_img-kern___target_cpu__dl.d kernel_img-kern_generic_millisleep.d kernel_img-kern_time.d kernel_img-symlist.d kernel_img-kern___target_cpu__cache.d
+
+MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-kernel.img.1
+
+ifneq ($(TARGET_APPLE_CC),1)
+kernel.img: kernel.exec
+	$(OBJCOPY) -O $(kernel_img_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
+else
+ifneq (kernel.exec,kernel.exec)
+kernel.img: kernel.exec ./grub-macho2img
+	./grub-macho2img $< $@
+else
+kernel.img: kernel.exec ./grub-macho2img
+	./grub-macho2img --bss $< $@
+endif
+endif
+
+kernel.exec: kernel_img-kern_sparc64_ieee1275_crt0.o kernel_img-kern_ieee1275_cmain.o kernel_img-kern_ieee1275_ieee1275.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_err.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_reader.o kernel_img-kern_term.o kernel_img-kern_rescue_parser.o kernel_img-kern_rescue_reader.o kernel_img-kern_list.o kernel_img-kern_handler.o kernel_img-kern_command.o kernel_img-kern_corecmd.o kernel_img-kern_sparc64_ieee1275_ieee1275.o kernel_img-kern_sparc64_ieee1275_init.o kernel_img-kern_ieee1275_mmap.o kernel_img-term_ieee1275_ofconsole.o kernel_img-kern_ieee1275_openfw.o kernel_img-disk_ieee1275_ofdisk.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_env.o kernel_img-kern___target_cpu__dl.o kernel_img-kern_generic_millisleep.o kernel_img-kern_time.o kernel_img-symlist.o kernel_img-kern___target_cpu__cache.o
+	$(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(kernel_img_LDFLAGS)
+
+kernel_img-kern_sparc64_ieee1275_crt0.o: kern/sparc64/ieee1275/crt0.S $(kern/sparc64/ieee1275/crt0.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/sparc64/ieee1275 -I$(srcdir)/kern/sparc64/ieee1275 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_sparc64_ieee1275_crt0.d
+
+kernel_img-kern_ieee1275_cmain.o: kern/ieee1275/cmain.c $(kern/ieee1275/cmain.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_cmain.d
+
+kernel_img-kern_ieee1275_ieee1275.o: kern/ieee1275/ieee1275.c $(kern/ieee1275/ieee1275.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_ieee1275.d
+
+kernel_img-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_main.d
+
+kernel_img-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_device.d
+
+kernel_img-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_disk.d
+
+kernel_img-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_dl.d
+
+kernel_img-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_err.d
+
+kernel_img-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_file.d
+
+kernel_img-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_fs.d
+
+kernel_img-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_misc.d
+
+kernel_img-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_mm.d
+
+kernel_img-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_reader.d
+
+kernel_img-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_term.d
+
+kernel_img-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_rescue_parser.d
+
+kernel_img-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_rescue_reader.d
+
+kernel_img-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_list.d
+
+kernel_img-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_handler.d
+
+kernel_img-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_command.d
+
+kernel_img-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_corecmd.d
+
+kernel_img-kern_sparc64_ieee1275_ieee1275.o: kern/sparc64/ieee1275/ieee1275.c $(kern/sparc64/ieee1275/ieee1275.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/sparc64/ieee1275 -I$(srcdir)/kern/sparc64/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_sparc64_ieee1275_ieee1275.d
+
+kernel_img-kern_sparc64_ieee1275_init.o: kern/sparc64/ieee1275/init.c $(kern/sparc64/ieee1275/init.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/sparc64/ieee1275 -I$(srcdir)/kern/sparc64/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_sparc64_ieee1275_init.d
+
+kernel_img-kern_ieee1275_mmap.o: kern/ieee1275/mmap.c $(kern/ieee1275/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_mmap.d
+
+kernel_img-term_ieee1275_ofconsole.o: term/ieee1275/ofconsole.c $(term/ieee1275/ofconsole.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/ieee1275 -I$(srcdir)/term/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-term_ieee1275_ofconsole.d
+
+kernel_img-kern_ieee1275_openfw.o: kern/ieee1275/openfw.c $(kern/ieee1275/openfw.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_ieee1275_openfw.d
+
+kernel_img-disk_ieee1275_ofdisk.o: disk/ieee1275/ofdisk.c $(disk/ieee1275/ofdisk.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-disk_ieee1275_ofdisk.d
+
+kernel_img-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_parser.d
+
+kernel_img-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_partition.d
+
+kernel_img-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_env.d
+
+kernel_img-kern___target_cpu__dl.o: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern___target_cpu__dl.d
+
+kernel_img-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_generic_millisleep.d
+
+kernel_img-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern_time.d
+
+kernel_img-symlist.o: symlist.c $(symlist.c_DEPENDENCIES)
+	$(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $<
+-include kernel_img-symlist.d
+
+kernel_img-kern___target_cpu__cache.o: kern/$(target_cpu)/cache.S $(kern/$(target_cpu)/cache.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $<
+-include kernel_img-kern___target_cpu__cache.d
+
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc -static-libgcc -lgcc
+kernel_img_FORMAT = binary
+
+symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# Utilities.
+bin_UTILITIES = grub-mkimage
+sbin_UTILITIES = grub-setup grub-mkdevicemap grub-ofpathname
+ifeq ($(enable_grub_emu), yes)
+sbin_UTILITIES += grub-emu
+endif
+
+# For grub-mkimage.
+grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \
+        util/resolve.c
+
+clean-utility-grub-mkimage.1:
+	rm -f grub-mkimage$(EXEEXT) grub_mkimage-util_sparc64_ieee1275_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkimage.1
+
+mostlyclean-utility-grub-mkimage.1:
+	rm -f grub_mkimage-util_sparc64_ieee1275_grub_mkimage.d grub_mkimage-util_misc.d grub_mkimage-util_resolve.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkimage.1
+
+grub_mkimage_OBJECTS += grub_mkimage-util_sparc64_ieee1275_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o
+
+grub_mkimage-util_sparc64_ieee1275_grub_mkimage.o: util/sparc64/ieee1275/grub-mkimage.c $(util/sparc64/ieee1275/grub-mkimage.c_DEPENDENCIES)
+	$(CC) -Iutil/sparc64/ieee1275 -I$(srcdir)/util/sparc64/ieee1275 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_sparc64_ieee1275_grub_mkimage.d
+
+grub_mkimage-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_misc.d
+
+grub_mkimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_resolve.d
+
+
+# For grub-setup.
+util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h
+grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c	\
+	util/misc.c util/getroot.c kern/device.c kern/disk.c	\
+	kern/err.c kern/misc.c kern/parser.c kern/partition.c	\
+	kern/file.c kern/fs.c kern/env.c fs/fshelp.c		\
+	\
+	fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c	\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c		\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c	\
+	fs/befs.c fs/befs_be.c fs/tar.c			\
+	\
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c		\
+	partmap/sun.c partmap/acorn.c				\
+	\
+	disk/raid.c disk/mdraid_linux.c disk/lvm.c		\
+	util/raid.c util/lvm.c					\
+	grub_setup_init.c
+
+clean-utility-grub-setup.1:
+	rm -f grub-setup$(EXEEXT) grub_setup-util_sparc64_ieee1275_grub_setup.o grub_setup-util_hostdisk.o grub_setup-util_misc.o grub_setup-util_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o grub_setup-fs_affs.o grub_setup-fs_cpio.o grub_setup-fs_ext2.o grub_setup-fs_fat.o grub_setup-fs_hfs.o grub_setup-fs_hfsplus.o grub_setup-fs_iso9660.o grub_setup-fs_udf.o grub_setup-fs_jfs.o grub_setup-fs_minix.o grub_setup-fs_ntfs.o grub_setup-fs_ntfscomp.o grub_setup-fs_reiserfs.o grub_setup-fs_sfs.o grub_setup-fs_ufs.o grub_setup-fs_ufs2.o grub_setup-fs_xfs.o grub_setup-fs_afs.o grub_setup-fs_afs_be.o grub_setup-fs_befs.o grub_setup-fs_befs_be.o grub_setup-fs_tar.o grub_setup-partmap_amiga.o grub_setup-partmap_apple.o grub_setup-partmap_msdos.o grub_setup-partmap_sun.o grub_setup-partmap_acorn.o grub_setup-disk_raid.o grub_setup-disk_mdraid_linux.o grub_setup-disk_lvm.o grub_setup-util_raid.o grub_setup-util_lvm.o grub_setup-grub_setup_init.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-setup.1
+
+mostlyclean-utility-grub-setup.1:
+	rm -f grub_setup-util_sparc64_ieee1275_grub_setup.d grub_setup-util_hostdisk.d grub_setup-util_misc.d grub_setup-util_getroot.d grub_setup-kern_device.d grub_setup-kern_disk.d grub_setup-kern_err.d grub_setup-kern_misc.d grub_setup-kern_parser.d grub_setup-kern_partition.d grub_setup-kern_file.d grub_setup-kern_fs.d grub_setup-kern_env.d grub_setup-fs_fshelp.d grub_setup-fs_affs.d grub_setup-fs_cpio.d grub_setup-fs_ext2.d grub_setup-fs_fat.d grub_setup-fs_hfs.d grub_setup-fs_hfsplus.d grub_setup-fs_iso9660.d grub_setup-fs_udf.d grub_setup-fs_jfs.d grub_setup-fs_minix.d grub_setup-fs_ntfs.d grub_setup-fs_ntfscomp.d grub_setup-fs_reiserfs.d grub_setup-fs_sfs.d grub_setup-fs_ufs.d grub_setup-fs_ufs2.d grub_setup-fs_xfs.d grub_setup-fs_afs.d grub_setup-fs_afs_be.d grub_setup-fs_befs.d grub_setup-fs_befs_be.d grub_setup-fs_tar.d grub_setup-partmap_amiga.d grub_setup-partmap_apple.d grub_setup-partmap_msdos.d grub_setup-partmap_sun.d grub_setup-partmap_acorn.d grub_setup-disk_raid.d grub_setup-disk_mdraid_linux.d grub_setup-disk_lvm.d grub_setup-util_raid.d grub_setup-util_lvm.d grub_setup-grub_setup_init.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-setup.1
+
+grub_setup_OBJECTS += grub_setup-util_sparc64_ieee1275_grub_setup.o grub_setup-util_hostdisk.o grub_setup-util_misc.o grub_setup-util_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o grub_setup-fs_affs.o grub_setup-fs_cpio.o grub_setup-fs_ext2.o grub_setup-fs_fat.o grub_setup-fs_hfs.o grub_setup-fs_hfsplus.o grub_setup-fs_iso9660.o grub_setup-fs_udf.o grub_setup-fs_jfs.o grub_setup-fs_minix.o grub_setup-fs_ntfs.o grub_setup-fs_ntfscomp.o grub_setup-fs_reiserfs.o grub_setup-fs_sfs.o grub_setup-fs_ufs.o grub_setup-fs_ufs2.o grub_setup-fs_xfs.o grub_setup-fs_afs.o grub_setup-fs_afs_be.o grub_setup-fs_befs.o grub_setup-fs_befs_be.o grub_setup-fs_tar.o grub_setup-partmap_amiga.o grub_setup-partmap_apple.o grub_setup-partmap_msdos.o grub_setup-partmap_sun.o grub_setup-partmap_acorn.o grub_setup-disk_raid.o grub_setup-disk_mdraid_linux.o grub_setup-disk_lvm.o grub_setup-util_raid.o grub_setup-util_lvm.o grub_setup-grub_setup_init.o
+
+grub_setup-util_sparc64_ieee1275_grub_setup.o: util/sparc64/ieee1275/grub-setup.c $(util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES)
+	$(CC) -Iutil/sparc64/ieee1275 -I$(srcdir)/util/sparc64/ieee1275 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_sparc64_ieee1275_grub_setup.d
+
+grub_setup-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_hostdisk.d
+
+grub_setup-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_misc.d
+
+grub_setup-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_getroot.d
+
+grub_setup-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_device.d
+
+grub_setup-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_disk.d
+
+grub_setup-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_err.d
+
+grub_setup-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_misc.d
+
+grub_setup-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_parser.d
+
+grub_setup-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_partition.d
+
+grub_setup-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_file.d
+
+grub_setup-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_fs.d
+
+grub_setup-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-kern_env.d
+
+grub_setup-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_fshelp.d
+
+grub_setup-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_affs.d
+
+grub_setup-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_cpio.d
+
+grub_setup-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_ext2.d
+
+grub_setup-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_fat.d
+
+grub_setup-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_hfs.d
+
+grub_setup-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_hfsplus.d
+
+grub_setup-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_iso9660.d
+
+grub_setup-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_udf.d
+
+grub_setup-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_jfs.d
+
+grub_setup-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_minix.d
+
+grub_setup-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_ntfs.d
+
+grub_setup-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_ntfscomp.d
+
+grub_setup-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_reiserfs.d
+
+grub_setup-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_sfs.d
+
+grub_setup-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_ufs.d
+
+grub_setup-fs_ufs2.o: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_ufs2.d
+
+grub_setup-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_xfs.d
+
+grub_setup-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_afs.d
+
+grub_setup-fs_afs_be.o: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_afs_be.d
+
+grub_setup-fs_befs.o: fs/befs.c $(fs/befs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_befs.d
+
+grub_setup-fs_befs_be.o: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_befs_be.d
+
+grub_setup-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-fs_tar.d
+
+grub_setup-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-partmap_amiga.d
+
+grub_setup-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-partmap_apple.d
+
+grub_setup-partmap_msdos.o: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-partmap_msdos.d
+
+grub_setup-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-partmap_sun.d
+
+grub_setup-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-partmap_acorn.d
+
+grub_setup-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-disk_raid.d
+
+grub_setup-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-disk_mdraid_linux.d
+
+grub_setup-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-disk_lvm.d
+
+grub_setup-util_raid.o: util/raid.c $(util/raid.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_raid.d
+
+grub_setup-util_lvm.o: util/lvm.c $(util/lvm.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_lvm.d
+
+grub_setup-grub_setup_init.o: grub_setup_init.c $(grub_setup_init.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-grub_setup_init.d
+
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/ieee1275/ofpath.c util/ieee1275/devicemap.c util/misc.c
+
+clean-utility-grub-mkdevicemap.1:
+	rm -f grub-mkdevicemap$(EXEEXT) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_ieee1275_ofpath.o grub_mkdevicemap-util_ieee1275_devicemap.o grub_mkdevicemap-util_misc.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkdevicemap.1
+
+mostlyclean-utility-grub-mkdevicemap.1:
+	rm -f grub_mkdevicemap-util_grub_mkdevicemap.d grub_mkdevicemap-util_deviceiter.d grub_mkdevicemap-util_ieee1275_ofpath.d grub_mkdevicemap-util_ieee1275_devicemap.d grub_mkdevicemap-util_misc.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkdevicemap.1
+
+grub_mkdevicemap_OBJECTS += grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_ieee1275_ofpath.o grub_mkdevicemap-util_ieee1275_devicemap.o grub_mkdevicemap-util_misc.o
+
+grub_mkdevicemap-util_grub_mkdevicemap.o: util/grub-mkdevicemap.c $(util/grub-mkdevicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_grub_mkdevicemap.d
+
+grub_mkdevicemap-util_deviceiter.o: util/deviceiter.c $(util/deviceiter.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_deviceiter.d
+
+grub_mkdevicemap-util_ieee1275_ofpath.o: util/ieee1275/ofpath.c $(util/ieee1275/ofpath.c_DEPENDENCIES)
+	$(CC) -Iutil/ieee1275 -I$(srcdir)/util/ieee1275 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_ieee1275_ofpath.d
+
+grub_mkdevicemap-util_ieee1275_devicemap.o: util/ieee1275/devicemap.c $(util/ieee1275/devicemap.c_DEPENDENCIES)
+	$(CC) -Iutil/ieee1275 -I$(srcdir)/util/ieee1275 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_ieee1275_devicemap.d
+
+grub_mkdevicemap-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_misc.d
+
+
+# For grub-ofpathname.
+grub_ofpathname_SOURCES = util/sparc64/ieee1275/grub-ofpathname.c \
+	util/ieee1275/ofpath.c util/misc.c
+
+clean-utility-grub-ofpathname.1:
+	rm -f grub-ofpathname$(EXEEXT) grub_ofpathname-util_sparc64_ieee1275_grub_ofpathname.o grub_ofpathname-util_ieee1275_ofpath.o grub_ofpathname-util_misc.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-ofpathname.1
+
+mostlyclean-utility-grub-ofpathname.1:
+	rm -f grub_ofpathname-util_sparc64_ieee1275_grub_ofpathname.d grub_ofpathname-util_ieee1275_ofpath.d grub_ofpathname-util_misc.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-ofpathname.1
+
+grub_ofpathname_OBJECTS += grub_ofpathname-util_sparc64_ieee1275_grub_ofpathname.o grub_ofpathname-util_ieee1275_ofpath.o grub_ofpathname-util_misc.o
+
+grub_ofpathname-util_sparc64_ieee1275_grub_ofpathname.o: util/sparc64/ieee1275/grub-ofpathname.c $(util/sparc64/ieee1275/grub-ofpathname.c_DEPENDENCIES)
+	$(CC) -Iutil/sparc64/ieee1275 -I$(srcdir)/util/sparc64/ieee1275 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_ofpathname_CFLAGS) -MD -c -o $@ $<
+-include grub_ofpathname-util_sparc64_ieee1275_grub_ofpathname.d
+
+grub_ofpathname-util_ieee1275_ofpath.o: util/ieee1275/ofpath.c $(util/ieee1275/ofpath.c_DEPENDENCIES)
+	$(CC) -Iutil/ieee1275 -I$(srcdir)/util/ieee1275 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_ofpathname_CFLAGS) -MD -c -o $@ $<
+-include grub_ofpathname-util_ieee1275_ofpath.d
+
+grub_ofpathname-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_ofpathname_CFLAGS) -MD -c -o $@ $<
+-include grub_ofpathname-util_misc.d
+
+
+# For grub-emu
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c 	\
+	commands/configfile.c commands/help.c				\
+	commands/search.c commands/handler.c commands/test.c 		\
+	commands/ls.c commands/blocklist.c commands/hexdump.c		\
+	lib/hexdump.c commands/halt.c commands/reboot.c 		\
+	lib/envblk.c commands/loadenv.c					\
+	commands/gptsync.c commands/probe.c commands/xnu_uuid.c		\
+	commands/password.c commands/keystatus.c			\
+	disk/loopback.c							\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c		\
+	fs/befs.c fs/befs_be.c fs/tar.c				\
+	\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/file.c kern/fs.c commands/boot.c kern/main.c	\
+	kern/misc.c kern/parser.c kern/partition.c kern/reader.c	\
+	kern/rescue_reader.c kern/rescue_parser.c			\
+	kern/term.c kern/list.c kern/handler.c fs/fshelp.c		\
+	kern/command.c kern/corecmd.c commands/extcmd.c			\
+	lib/arg.c normal/cmdline.c normal/datetime.c 			\
+	normal/completion.c normal/misc.c		 		\
+	normal/handler.c normal/auth.c normal/autofs.c normal/main.c	\
+	normal/menu.c 							\
+	normal/menu_text.c						\
+	normal/menu_entry.c normal/menu_viewer.c 	 		\
+	normal/color.c							\
+	script/sh/main.c script/sh/execute.c script/sh/function.c	\
+	script/sh/lexer.c script/sh/script.c				\
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c							\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	commands/parttool.c parttool/msdospart.c				\
+	grub_script.tab.c grub_emu_init.c
+
+clean-utility-grub-emu.1:
+	rm -f grub-emu$(EXEEXT) grub_emu-commands_minicmd.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_handler.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_halt.o grub_emu-commands_reboot.o grub_emu-lib_envblk.o grub_emu-commands_loadenv.o grub_emu-commands_gptsync.o grub_emu-commands_probe.o grub_emu-commands_xnu_uuid.o grub_emu-commands_password.o grub_emu-commands_keystatus.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_ufs2.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_afs_be.o grub_emu-fs_befs.o grub_emu-fs_befs_be.o grub_emu-fs_tar.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-commands_boot.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_reader.o grub_emu-kern_rescue_reader.o grub_emu-kern_rescue_parser.o grub_emu-kern_term.o grub_emu-kern_list.o grub_emu-kern_handler.o grub_emu-fs_fshelp.o grub_emu-kern_command.o grub_emu-kern_corecmd.o grub_emu-commands_extcmd.o grub_emu-lib_arg.o grub_emu-normal_cmdline.o grub_emu-normal_datetime.o grub_emu-normal_completion.o grub_emu-normal_misc.o grub_emu-normal_handler.o grub_emu-normal_auth.o grub_emu-normal_autofs.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_text.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_color.o grub_emu-script_sh_main.o grub_emu-script_sh_execute.o grub_emu-script_sh_function.o grub_emu-script_sh_lexer.o grub_emu-script_sh_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_msdos.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-commands_parttool.o grub_emu-parttool_msdospart.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-emu.1
+
+mostlyclean-utility-grub-emu.1:
+	rm -f grub_emu-commands_minicmd.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_help.d grub_emu-commands_search.d grub_emu-commands_handler.d grub_emu-commands_test.d grub_emu-commands_ls.d grub_emu-commands_blocklist.d grub_emu-commands_hexdump.d grub_emu-lib_hexdump.d grub_emu-commands_halt.d grub_emu-commands_reboot.d grub_emu-lib_envblk.d grub_emu-commands_loadenv.d grub_emu-commands_gptsync.d grub_emu-commands_probe.d grub_emu-commands_xnu_uuid.d grub_emu-commands_password.d grub_emu-commands_keystatus.d grub_emu-disk_loopback.d grub_emu-fs_affs.d grub_emu-fs_cpio.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_hfs.d grub_emu-fs_hfsplus.d grub_emu-fs_iso9660.d grub_emu-fs_udf.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ntfs.d grub_emu-fs_ntfscomp.d grub_emu-fs_reiserfs.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_ufs2.d grub_emu-fs_xfs.d grub_emu-fs_afs.d grub_emu-fs_afs_be.d grub_emu-fs_befs.d grub_emu-fs_befs_be.d grub_emu-fs_tar.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_elf.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-commands_boot.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-kern_partition.d grub_emu-kern_reader.d grub_emu-kern_rescue_reader.d grub_emu-kern_rescue_parser.d grub_emu-kern_term.d grub_emu-kern_list.d grub_emu-kern_handler.d grub_emu-fs_fshelp.d grub_emu-kern_command.d grub_emu-kern_corecmd.d grub_emu-commands_extcmd.d grub_emu-lib_arg.d grub_emu-normal_cmdline.d grub_emu-normal_datetime.d grub_emu-normal_completion.d grub_emu-normal_misc.d grub_emu-normal_handler.d grub_emu-normal_auth.d grub_emu-normal_autofs.d grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_menu_text.d grub_emu-normal_menu_entry.d grub_emu-normal_menu_viewer.d grub_emu-normal_color.d grub_emu-script_sh_main.d grub_emu-script_sh_execute.d grub_emu-script_sh_function.d grub_emu-script_sh_lexer.d grub_emu-script_sh_script.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_msdos.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-util_console.d grub_emu-util_hostfs.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_hostdisk.d grub_emu-util_getroot.d grub_emu-disk_raid.d grub_emu-disk_raid5_recover.d grub_emu-disk_raid6_recover.d grub_emu-disk_mdraid_linux.d grub_emu-disk_dmraid_nvidia.d grub_emu-disk_lvm.d grub_emu-commands_parttool.d grub_emu-parttool_msdospart.d grub_emu-grub_script_tab.d grub_emu-grub_emu_init.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-emu.1
+
+grub_emu_OBJECTS += grub_emu-commands_minicmd.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_handler.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_halt.o grub_emu-commands_reboot.o grub_emu-lib_envblk.o grub_emu-commands_loadenv.o grub_emu-commands_gptsync.o grub_emu-commands_probe.o grub_emu-commands_xnu_uuid.o grub_emu-commands_password.o grub_emu-commands_keystatus.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_ufs2.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_afs_be.o grub_emu-fs_befs.o grub_emu-fs_befs_be.o grub_emu-fs_tar.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-commands_boot.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_reader.o grub_emu-kern_rescue_reader.o grub_emu-kern_rescue_parser.o grub_emu-kern_term.o grub_emu-kern_list.o grub_emu-kern_handler.o grub_emu-fs_fshelp.o grub_emu-kern_command.o grub_emu-kern_corecmd.o grub_emu-commands_extcmd.o grub_emu-lib_arg.o grub_emu-normal_cmdline.o grub_emu-normal_datetime.o grub_emu-normal_completion.o grub_emu-normal_misc.o grub_emu-normal_handler.o grub_emu-normal_auth.o grub_emu-normal_autofs.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_text.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_color.o grub_emu-script_sh_main.o grub_emu-script_sh_execute.o grub_emu-script_sh_function.o grub_emu-script_sh_lexer.o grub_emu-script_sh_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_msdos.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-commands_parttool.o grub_emu-parttool_msdospart.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o
+
+grub_emu-commands_minicmd.o: commands/minicmd.c $(commands/minicmd.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_minicmd.d
+
+grub_emu-commands_cat.o: commands/cat.c $(commands/cat.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_cat.d
+
+grub_emu-commands_cmp.o: commands/cmp.c $(commands/cmp.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_cmp.d
+
+grub_emu-commands_configfile.o: commands/configfile.c $(commands/configfile.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_configfile.d
+
+grub_emu-commands_help.o: commands/help.c $(commands/help.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_help.d
+
+grub_emu-commands_search.o: commands/search.c $(commands/search.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_search.d
+
+grub_emu-commands_handler.o: commands/handler.c $(commands/handler.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_handler.d
+
+grub_emu-commands_test.o: commands/test.c $(commands/test.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_test.d
+
+grub_emu-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_ls.d
+
+grub_emu-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_blocklist.d
+
+grub_emu-commands_hexdump.o: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_hexdump.d
+
+grub_emu-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_hexdump.d
+
+grub_emu-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_halt.d
+
+grub_emu-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_reboot.d
+
+grub_emu-lib_envblk.o: lib/envblk.c $(lib/envblk.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_envblk.d
+
+grub_emu-commands_loadenv.o: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_loadenv.d
+
+grub_emu-commands_gptsync.o: commands/gptsync.c $(commands/gptsync.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_gptsync.d
+
+grub_emu-commands_probe.o: commands/probe.c $(commands/probe.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_probe.d
+
+grub_emu-commands_xnu_uuid.o: commands/xnu_uuid.c $(commands/xnu_uuid.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_xnu_uuid.d
+
+grub_emu-commands_password.o: commands/password.c $(commands/password.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_password.d
+
+grub_emu-commands_keystatus.o: commands/keystatus.c $(commands/keystatus.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_keystatus.d
+
+grub_emu-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_loopback.d
+
+grub_emu-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_affs.d
+
+grub_emu-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_cpio.d
+
+grub_emu-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_fat.d
+
+grub_emu-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ext2.d
+
+grub_emu-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_hfs.d
+
+grub_emu-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_hfsplus.d
+
+grub_emu-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_iso9660.d
+
+grub_emu-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_udf.d
+
+grub_emu-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_jfs.d
+
+grub_emu-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_minix.d
+
+grub_emu-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ntfs.d
+
+grub_emu-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ntfscomp.d
+
+grub_emu-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_reiserfs.d
+
+grub_emu-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_sfs.d
+
+grub_emu-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ufs.d
+
+grub_emu-fs_ufs2.o: fs/ufs2.c $(fs/ufs2.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_ufs2.d
+
+grub_emu-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_xfs.d
+
+grub_emu-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_afs.d
+
+grub_emu-fs_afs_be.o: fs/afs_be.c $(fs/afs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_afs_be.d
+
+grub_emu-fs_befs.o: fs/befs.c $(fs/befs.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_befs.d
+
+grub_emu-fs_befs_be.o: fs/befs_be.c $(fs/befs_be.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_befs_be.d
+
+grub_emu-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_tar.d
+
+grub_emu-io_gzio.o: io/gzio.c $(io/gzio.c_DEPENDENCIES)
+	$(CC) -Iio -I$(srcdir)/io $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-io_gzio.d
+
+grub_emu-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_device.d
+
+grub_emu-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_disk.d
+
+grub_emu-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_dl.d
+
+grub_emu-kern_elf.o: kern/elf.c $(kern/elf.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_elf.d
+
+grub_emu-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_env.d
+
+grub_emu-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_err.d
+
+grub_emu-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_file.d
+
+grub_emu-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_fs.d
+
+grub_emu-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_boot.d
+
+grub_emu-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_main.d
+
+grub_emu-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_misc.d
+
+grub_emu-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_parser.d
+
+grub_emu-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_partition.d
+
+grub_emu-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_reader.d
+
+grub_emu-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_rescue_reader.d
+
+grub_emu-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_rescue_parser.d
+
+grub_emu-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_term.d
+
+grub_emu-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_list.d
+
+grub_emu-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_handler.d
+
+grub_emu-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES)
+	$(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-fs_fshelp.d
+
+grub_emu-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_command.d
+
+grub_emu-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-kern_corecmd.d
+
+grub_emu-commands_extcmd.o: commands/extcmd.c $(commands/extcmd.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_extcmd.d
+
+grub_emu-lib_arg.o: lib/arg.c $(lib/arg.c_DEPENDENCIES)
+	$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-lib_arg.d
+
+grub_emu-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_cmdline.d
+
+grub_emu-normal_datetime.o: normal/datetime.c $(normal/datetime.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_datetime.d
+
+grub_emu-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_completion.d
+
+grub_emu-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_misc.d
+
+grub_emu-normal_handler.o: normal/handler.c $(normal/handler.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_handler.d
+
+grub_emu-normal_auth.o: normal/auth.c $(normal/auth.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_auth.d
+
+grub_emu-normal_autofs.o: normal/autofs.c $(normal/autofs.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_autofs.d
+
+grub_emu-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_main.d
+
+grub_emu-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu.d
+
+grub_emu-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_text.d
+
+grub_emu-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_entry.d
+
+grub_emu-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_menu_viewer.d
+
+grub_emu-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES)
+	$(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-normal_color.d
+
+grub_emu-script_sh_main.o: script/sh/main.c $(script/sh/main.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_main.d
+
+grub_emu-script_sh_execute.o: script/sh/execute.c $(script/sh/execute.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_execute.d
+
+grub_emu-script_sh_function.o: script/sh/function.c $(script/sh/function.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_function.d
+
+grub_emu-script_sh_lexer.o: script/sh/lexer.c $(script/sh/lexer.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_lexer.d
+
+grub_emu-script_sh_script.o: script/sh/script.c $(script/sh/script.c_DEPENDENCIES)
+	$(CC) -Iscript/sh -I$(srcdir)/script/sh $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-script_sh_script.d
+
+grub_emu-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_amiga.d
+
+grub_emu-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_apple.d
+
+grub_emu-partmap_msdos.o: partmap/msdos.c $(partmap/msdos.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_msdos.d
+
+grub_emu-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_sun.d
+
+grub_emu-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES)
+	$(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-partmap_acorn.d
+
+grub_emu-util_console.o: util/console.c $(util/console.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_console.d
+
+grub_emu-util_hostfs.o: util/hostfs.c $(util/hostfs.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_hostfs.d
+
+grub_emu-util_grub_emu.o: util/grub-emu.c $(util/grub-emu.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_grub_emu.d
+
+grub_emu-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_misc.d
+
+grub_emu-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_hostdisk.d
+
+grub_emu-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-util_getroot.d
+
+grub_emu-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid.d
+
+grub_emu-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid5_recover.d
+
+grub_emu-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid6_recover.d
+
+grub_emu-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_mdraid_linux.d
+
+grub_emu-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_dmraid_nvidia.d
+
+grub_emu-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES)
+	$(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_lvm.d
+
+grub_emu-commands_parttool.o: commands/parttool.c $(commands/parttool.c_DEPENDENCIES)
+	$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-commands_parttool.d
+
+grub_emu-parttool_msdospart.o: parttool/msdospart.c $(parttool/msdospart.c_DEPENDENCIES)
+	$(CC) -Iparttool -I$(srcdir)/parttool $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-parttool_msdospart.d
+
+grub_emu-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-grub_script_tab.d
+
+grub_emu-grub_emu_init.o: grub_emu_init.c $(grub_emu_init.c_DEPENDENCIES)
+	$(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-grub_emu_init.d
+
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/sparc64/ieee1275/grub-install.in
+CLEANFILES += grub-install
+
+grub-install: util/sparc64/ieee1275/grub-install.in $(util/sparc64/ieee1275/grub-install.in_DEPENDENCIES) config.status
+	./config.status --file=grub-install:util/sparc64/ieee1275/grub-install.in
+	chmod +x $@
+
+
+# Modules.
+pkglib_MODULES = halt.mod \
+	linux.mod \
+	reboot.mod \
+	memdisk.mod \
+	lsmmap.mod
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+
+clean-module-boot.mod.1:
+	rm -f boot.mod mod-boot.o mod-boot.c pre-boot.o boot_mod-commands_boot.o boot_mod-lib_i386_pc_biosnum.o und-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod.1
+
+ifneq ($(boot_mod_EXPORTS),no)
+clean-module-boot.mod-symbol.1:
+	rm -f def-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod-symbol.1
+DEFSYMFILES += def-boot.lst
+endif
+mostlyclean-module-boot.mod.1:
+	rm -f boot_mod-commands_boot.d boot_mod-lib_i386_pc_biosnum.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-boot.mod.1
+UNDSYMFILES += und-boot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-boot.o mod-boot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-boot.o mod-boot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-boot.o: $(boot_mod_DEPENDENCIES) boot_mod-commands_boot.o boot_mod-lib_i386_pc_biosnum.o
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ boot_mod-commands_boot.o boot_mod-lib_i386_pc_biosnum.o
+
+mod-boot.o: mod-boot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -c -o $@ $<
+
+mod-boot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'boot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(boot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-boot.lst: pre-boot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+else
+def-boot.lst: pre-boot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+endif
+endif
+
+und-boot.lst: pre-boot.o
+	echo 'boot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+boot_mod-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $<
+-include boot_mod-commands_boot.d
+
+clean-module-boot_mod-commands_boot-extra.1:
+	rm -f cmd-boot_mod-commands_boot.lst fs-boot_mod-commands_boot.lst partmap-boot_mod-commands_boot.lst handler-boot_mod-commands_boot.lst parttool-boot_mod-commands_boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot_mod-commands_boot-extra.1
+
+COMMANDFILES += cmd-boot_mod-commands_boot.lst
+FSFILES += fs-boot_mod-commands_boot.lst
+PARTTOOLFILES += parttool-boot_mod-commands_boot.lst
+PARTMAPFILES += partmap-boot_mod-commands_boot.lst
+HANDLERFILES += handler-boot_mod-commands_boot.lst
+
+cmd-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1)
+
+fs-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1)
+
+parttool-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh boot > $@ || (rm -f $@; exit 1)
+
+partmap-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1)
+
+handler-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh boot > $@ || (rm -f $@; exit 1)
+
+boot_mod-lib_i386_pc_biosnum.o: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $<
+-include boot_mod-lib_i386_pc_biosnum.d
+
+clean-module-boot_mod-lib_i386_pc_biosnum-extra.1:
+	rm -f cmd-boot_mod-lib_i386_pc_biosnum.lst fs-boot_mod-lib_i386_pc_biosnum.lst partmap-boot_mod-lib_i386_pc_biosnum.lst handler-boot_mod-lib_i386_pc_biosnum.lst parttool-boot_mod-lib_i386_pc_biosnum.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot_mod-lib_i386_pc_biosnum-extra.1
+
+COMMANDFILES += cmd-boot_mod-lib_i386_pc_biosnum.lst
+FSFILES += fs-boot_mod-lib_i386_pc_biosnum.lst
+PARTTOOLFILES += parttool-boot_mod-lib_i386_pc_biosnum.lst
+PARTMAPFILES += partmap-boot_mod-lib_i386_pc_biosnum.lst
+HANDLERFILES += handler-boot_mod-lib_i386_pc_biosnum.lst
+
+cmd-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1)
+
+fs-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1)
+
+parttool-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh boot > $@ || (rm -f $@; exit 1)
+
+partmap-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1)
+
+handler-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh boot > $@ || (rm -f $@; exit 1)
+
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/sparc64/ieee1275/linux.c
+
+clean-module-linux.mod.1:
+	rm -f linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_sparc64_ieee1275_linux.o und-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod.1
+
+ifneq ($(linux_mod_EXPORTS),no)
+clean-module-linux.mod-symbol.1:
+	rm -f def-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod-symbol.1
+DEFSYMFILES += def-linux.lst
+endif
+mostlyclean-module-linux.mod.1:
+	rm -f linux_mod-loader_sparc64_ieee1275_linux.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-linux.mod.1
+UNDSYMFILES += und-linux.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-linux.o mod-linux.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_sparc64_ieee1275_linux.o
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_sparc64_ieee1275_linux.o
+
+mod-linux.o: mod-linux.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $<
+
+mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(linux_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-linux.lst: pre-linux.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+else
+def-linux.lst: pre-linux.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+endif
+endif
+
+und-linux.lst: pre-linux.o
+	echo 'linux' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+linux_mod-loader_sparc64_ieee1275_linux.o: loader/sparc64/ieee1275/linux.c $(loader/sparc64/ieee1275/linux.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/sparc64/ieee1275 -I$(srcdir)/loader/sparc64/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $<
+-include linux_mod-loader_sparc64_ieee1275_linux.d
+
+clean-module-linux_mod-loader_sparc64_ieee1275_linux-extra.1:
+	rm -f cmd-linux_mod-loader_sparc64_ieee1275_linux.lst fs-linux_mod-loader_sparc64_ieee1275_linux.lst partmap-linux_mod-loader_sparc64_ieee1275_linux.lst handler-linux_mod-loader_sparc64_ieee1275_linux.lst parttool-linux_mod-loader_sparc64_ieee1275_linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux_mod-loader_sparc64_ieee1275_linux-extra.1
+
+COMMANDFILES += cmd-linux_mod-loader_sparc64_ieee1275_linux.lst
+FSFILES += fs-linux_mod-loader_sparc64_ieee1275_linux.lst
+PARTTOOLFILES += parttool-linux_mod-loader_sparc64_ieee1275_linux.lst
+PARTMAPFILES += partmap-linux_mod-loader_sparc64_ieee1275_linux.lst
+HANDLERFILES += handler-linux_mod-loader_sparc64_ieee1275_linux.lst
+
+cmd-linux_mod-loader_sparc64_ieee1275_linux.lst: loader/sparc64/ieee1275/linux.c $(loader/sparc64/ieee1275/linux.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/sparc64/ieee1275 -I$(srcdir)/loader/sparc64/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1)
+
+fs-linux_mod-loader_sparc64_ieee1275_linux.lst: loader/sparc64/ieee1275/linux.c $(loader/sparc64/ieee1275/linux.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/sparc64/ieee1275 -I$(srcdir)/loader/sparc64/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1)
+
+parttool-linux_mod-loader_sparc64_ieee1275_linux.lst: loader/sparc64/ieee1275/linux.c $(loader/sparc64/ieee1275/linux.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/sparc64/ieee1275 -I$(srcdir)/loader/sparc64/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh linux > $@ || (rm -f $@; exit 1)
+
+partmap-linux_mod-loader_sparc64_ieee1275_linux.lst: loader/sparc64/ieee1275/linux.c $(loader/sparc64/ieee1275/linux.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/sparc64/ieee1275 -I$(srcdir)/loader/sparc64/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1)
+
+handler-linux_mod-loader_sparc64_ieee1275_linux.lst: loader/sparc64/ieee1275/linux.c $(loader/sparc64/ieee1275/linux.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/sparc64/ieee1275 -I$(srcdir)/loader/sparc64/ieee1275 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh linux > $@ || (rm -f $@; exit 1)
+
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod.
+reboot_mod_SOURCES = commands/reboot.c
+
+clean-module-reboot.mod.1:
+	rm -f reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o und-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod.1
+
+ifneq ($(reboot_mod_EXPORTS),no)
+clean-module-reboot.mod-symbol.1:
+	rm -f def-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod-symbol.1
+DEFSYMFILES += def-reboot.lst
+endif
+mostlyclean-module-reboot.mod.1:
+	rm -f reboot_mod-commands_reboot.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-reboot.mod.1
+UNDSYMFILES += und-reboot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-reboot.o mod-reboot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o
+
+mod-reboot.o: mod-reboot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $<
+
+mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(reboot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-reboot.lst: pre-reboot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+else
+def-reboot.lst: pre-reboot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+endif
+endif
+
+und-reboot.lst: pre-reboot.o
+	echo 'reboot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $<
+-include reboot_mod-commands_reboot.d
+
+clean-module-reboot_mod-commands_reboot-extra.1:
+	rm -f cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst handler-reboot_mod-commands_reboot.lst parttool-reboot_mod-commands_reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot_mod-commands_reboot-extra.1
+
+COMMANDFILES += cmd-reboot_mod-commands_reboot.lst
+FSFILES += fs-reboot_mod-commands_reboot.lst
+PARTTOOLFILES += parttool-reboot_mod-commands_reboot.lst
+PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst
+HANDLERFILES += handler-reboot_mod-commands_reboot.lst
+
+cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1)
+
+parttool-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh reboot > $@ || (rm -f $@; exit 1)
+
+partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1)
+
+handler-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/halt.c
+
+clean-module-halt.mod.1:
+	rm -f halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_halt.o und-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod.1
+
+ifneq ($(halt_mod_EXPORTS),no)
+clean-module-halt.mod-symbol.1:
+	rm -f def-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod-symbol.1
+DEFSYMFILES += def-halt.lst
+endif
+mostlyclean-module-halt.mod.1:
+	rm -f halt_mod-commands_halt.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-halt.mod.1
+UNDSYMFILES += und-halt.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-halt.o mod-halt.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_halt.o
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_halt.o
+
+mod-halt.o: mod-halt.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $<
+
+mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(halt_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-halt.lst: pre-halt.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+else
+def-halt.lst: pre-halt.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+endif
+endif
+
+und-halt.lst: pre-halt.o
+	echo 'halt' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+halt_mod-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $<
+-include halt_mod-commands_halt.d
+
+clean-module-halt_mod-commands_halt-extra.1:
+	rm -f cmd-halt_mod-commands_halt.lst fs-halt_mod-commands_halt.lst partmap-halt_mod-commands_halt.lst handler-halt_mod-commands_halt.lst parttool-halt_mod-commands_halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt_mod-commands_halt-extra.1
+
+COMMANDFILES += cmd-halt_mod-commands_halt.lst
+FSFILES += fs-halt_mod-commands_halt.lst
+PARTTOOLFILES += parttool-halt_mod-commands_halt.lst
+PARTMAPFILES += partmap-halt_mod-commands_halt.lst
+HANDLERFILES += handler-halt_mod-commands_halt.lst
+
+cmd-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1)
+
+fs-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1)
+
+parttool-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh halt > $@ || (rm -f $@; exit 1)
+
+partmap-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1)
+
+handler-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh halt > $@ || (rm -f $@; exit 1)
+
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memdisk.mod.
+memdisk_mod_SOURCES = disk/memdisk.c
+
+clean-module-memdisk.mod.1:
+	rm -f memdisk.mod mod-memdisk.o mod-memdisk.c pre-memdisk.o memdisk_mod-disk_memdisk.o und-memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk.mod.1
+
+ifneq ($(memdisk_mod_EXPORTS),no)
+clean-module-memdisk.mod-symbol.1:
+	rm -f def-memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk.mod-symbol.1
+DEFSYMFILES += def-memdisk.lst
+endif
+mostlyclean-module-memdisk.mod.1:
+	rm -f memdisk_mod-disk_memdisk.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-memdisk.mod.1
+UNDSYMFILES += und-memdisk.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-memdisk.o mod-memdisk.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-memdisk.o mod-memdisk.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-memdisk.o: $(memdisk_mod_DEPENDENCIES) memdisk_mod-disk_memdisk.o
+	-rm -f $@
+	$(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memdisk_mod-disk_memdisk.o
+
+mod-memdisk.o: mod-memdisk.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -c -o $@ $<
+
+mod-memdisk.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'memdisk' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(memdisk_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-memdisk.lst: pre-memdisk.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@
+else
+def-memdisk.lst: pre-memdisk.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@
+endif
+endif
+
+und-memdisk.lst: pre-memdisk.o
+	echo 'memdisk' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+memdisk_mod-disk_memdisk.o: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -MD -c -o $@ $<
+-include memdisk_mod-disk_memdisk.d
+
+clean-module-memdisk_mod-disk_memdisk-extra.1:
+	rm -f cmd-memdisk_mod-disk_memdisk.lst fs-memdisk_mod-disk_memdisk.lst partmap-memdisk_mod-disk_memdisk.lst handler-memdisk_mod-disk_memdisk.lst parttool-memdisk_mod-disk_memdisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-memdisk_mod-disk_memdisk-extra.1
+
+COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst
+FSFILES += fs-memdisk_mod-disk_memdisk.lst
+PARTTOOLFILES += parttool-memdisk_mod-disk_memdisk.lst
+PARTMAPFILES += partmap-memdisk_mod-disk_memdisk.lst
+HANDLERFILES += handler-memdisk_mod-disk_memdisk.lst
+
+cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+fs-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+parttool-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+partmap-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+handler-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh memdisk > $@ || (rm -f $@; exit 1)
+
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+
+clean-module-lsmmap.mod.1:
+	rm -f lsmmap.mod mod-lsmmap.o mod-lsmmap.c pre-lsmmap.o lsmmap_mod-commands_lsmmap.o und-lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap.mod.1
+
+ifneq ($(lsmmap_mod_EXPORTS),no)
+clean-module-lsmmap.mod-symbol.1:
+	rm -f def-lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap.mod-symbol.1
+DEFSYMFILES += def-lsmmap.lst
+endif
+mostlyclean-module-lsmmap.mod.1:
+	rm -f lsmmap_mod-commands_lsmmap.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-lsmmap.mod.1
+UNDSYMFILES += und-lsmmap.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-lsmmap.o mod-lsmmap.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-lsmmap.o mod-lsmmap.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-lsmmap.o: $(lsmmap_mod_DEPENDENCIES) lsmmap_mod-commands_lsmmap.o
+	-rm -f $@
+	$(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lsmmap_mod-commands_lsmmap.o
+
+mod-lsmmap.o: mod-lsmmap.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -c -o $@ $<
+
+mod-lsmmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'lsmmap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(lsmmap_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-lsmmap.lst: pre-lsmmap.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@
+else
+def-lsmmap.lst: pre-lsmmap.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@
+endif
+endif
+
+und-lsmmap.lst: pre-lsmmap.o
+	echo 'lsmmap' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+lsmmap_mod-commands_lsmmap.o: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -MD -c -o $@ $<
+-include lsmmap_mod-commands_lsmmap.d
+
+clean-module-lsmmap_mod-commands_lsmmap-extra.1:
+	rm -f cmd-lsmmap_mod-commands_lsmmap.lst fs-lsmmap_mod-commands_lsmmap.lst partmap-lsmmap_mod-commands_lsmmap.lst handler-lsmmap_mod-commands_lsmmap.lst parttool-lsmmap_mod-commands_lsmmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lsmmap_mod-commands_lsmmap-extra.1
+
+COMMANDFILES += cmd-lsmmap_mod-commands_lsmmap.lst
+FSFILES += fs-lsmmap_mod-commands_lsmmap.lst
+PARTTOOLFILES += parttool-lsmmap_mod-commands_lsmmap.lst
+PARTMAPFILES += partmap-lsmmap_mod-commands_lsmmap.lst
+HANDLERFILES += handler-lsmmap_mod-commands_lsmmap.lst
+
+cmd-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+fs-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+parttool-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+partmap-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+handler-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh lsmmap > $@ || (rm -f $@; exit 1)
+
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/common.mk
+grub-mkimage: $(grub_mkimage_DEPENDENCIES) $(grub_mkimage_OBJECTS)
+	$(CC) -o $@ $(grub_mkimage_OBJECTS) $(LDFLAGS) $(grub_mkimage_LDFLAGS)
+
+grub-setup: $(grub_setup_DEPENDENCIES) $(grub_setup_OBJECTS)
+	$(CC) -o $@ $(grub_setup_OBJECTS) $(LDFLAGS) $(grub_setup_LDFLAGS)
+
+grub-mkdevicemap: $(grub_mkdevicemap_DEPENDENCIES) $(grub_mkdevicemap_OBJECTS)
+	$(CC) -o $@ $(grub_mkdevicemap_OBJECTS) $(LDFLAGS) $(grub_mkdevicemap_LDFLAGS)
+
+grub-ofpathname: $(grub_ofpathname_DEPENDENCIES) $(grub_ofpathname_OBJECTS)
+	$(CC) -o $@ $(grub_ofpathname_OBJECTS) $(LDFLAGS) $(grub_ofpathname_LDFLAGS)
+
+grub-emu: $(grub_emu_DEPENDENCIES) $(grub_emu_OBJECTS)
+	$(CC) -o $@ $(grub_emu_OBJECTS) $(LDFLAGS) $(grub_emu_LDFLAGS)
+
diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
new file mode 100644
index 0000000..62e951a
--- /dev/null
+++ b/conf/sparc64-ieee1275.rmk
@@ -0,0 +1,189 @@
+
+# -*- makefile -*-
+
+COMMON_ASFLAGS = -nostdinc -m64
+COMMON_CFLAGS = -ffreestanding -m64 -mno-app-regs
+COMMON_LDFLAGS = -melf64_sparc -nostdlib -mno-relax
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Images.
+pkglib_IMAGES = boot.img diskboot.img kernel.img
+
+# For boot.img.
+boot_img_SOURCES = boot/sparc64/ieee1275/boot.S
+boot_img_ASFLAGS = $(COMMON_ASFLAGS)
+boot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4000
+boot_img_FORMAT = a.out-sunos-big
+
+# For diskboot.img.
+diskboot_img_SOURCES = boot/sparc64/ieee1275/diskboot.S
+diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4200
+diskboot_img_FORMAT = binary
+
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	list.h handler.h command.h \
+	sparc64/libgcc.h ieee1275/ieee1275.h machine/kernel.h \
+	sparc64/ieee1275/ieee1275.h
+kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c	\
+	kern/ieee1275/ieee1275.c kern/main.c kern/device.c		\
+	kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c		\
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c			\
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/list.c kern/handler.c kern/command.c kern/corecmd.c	\
+	kern/sparc64/ieee1275/ieee1275.c 				\
+	kern/sparc64/ieee1275/init.c 					\
+	kern/ieee1275/mmap.c						\
+	term/ieee1275/ofconsole.c 					\
+	kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c 			\
+	kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c	\
+	kern/generic/millisleep.c kern/time.c				\
+	symlist.c kern/$(target_cpu)/cache.S
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc -static-libgcc -lgcc
+kernel_img_FORMAT = binary
+
+symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# Utilities.
+bin_UTILITIES = grub-mkimage
+sbin_UTILITIES = grub-setup grub-mkdevicemap grub-ofpathname
+ifeq ($(enable_grub_emu), yes)
+sbin_UTILITIES += grub-emu
+endif
+
+# For grub-mkimage.
+grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \
+        util/resolve.c
+
+# For grub-setup.
+util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h
+grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c	\
+	util/misc.c util/getroot.c kern/device.c kern/disk.c	\
+	kern/err.c kern/misc.c kern/parser.c kern/partition.c	\
+	kern/file.c kern/fs.c kern/env.c fs/fshelp.c		\
+	\
+	fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c	\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c		\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c	\
+	fs/befs.c fs/befs_be.c fs/tar.c			\
+	\
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c		\
+	partmap/sun.c partmap/acorn.c				\
+	\
+	disk/raid.c disk/mdraid_linux.c disk/lvm.c		\
+	util/raid.c util/lvm.c					\
+	grub_setup_init.c
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/ieee1275/ofpath.c util/ieee1275/devicemap.c util/misc.c
+
+# For grub-ofpathname.
+grub_ofpathname_SOURCES = util/sparc64/ieee1275/grub-ofpathname.c \
+	util/ieee1275/ofpath.c util/misc.c
+
+# For grub-emu
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c 	\
+	commands/configfile.c commands/help.c				\
+	commands/search.c commands/handler.c commands/test.c 		\
+	commands/ls.c commands/blocklist.c commands/hexdump.c		\
+	lib/hexdump.c commands/halt.c commands/reboot.c 		\
+	lib/envblk.c commands/loadenv.c					\
+	commands/gptsync.c commands/probe.c commands/xnu_uuid.c		\
+	commands/password.c commands/keystatus.c			\
+	disk/loopback.c							\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c		\
+	fs/befs.c fs/befs_be.c fs/tar.c				\
+	\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/file.c kern/fs.c commands/boot.c kern/main.c	\
+	kern/misc.c kern/parser.c kern/partition.c kern/reader.c	\
+	kern/rescue_reader.c kern/rescue_parser.c			\
+	kern/term.c kern/list.c kern/handler.c fs/fshelp.c		\
+	kern/command.c kern/corecmd.c commands/extcmd.c			\
+	lib/arg.c normal/cmdline.c normal/datetime.c 			\
+	normal/completion.c normal/misc.c		 		\
+	normal/handler.c normal/auth.c normal/autofs.c normal/main.c	\
+	normal/menu.c 							\
+	normal/menu_text.c						\
+	normal/menu_entry.c normal/menu_viewer.c 	 		\
+	normal/color.c							\
+	script/sh/main.c script/sh/execute.c script/sh/function.c	\
+	script/sh/lexer.c script/sh/script.c				\
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c							\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	commands/parttool.c parttool/msdospart.c				\
+	grub_script.tab.c grub_emu_init.c
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/sparc64/ieee1275/grub-install.in
+
+# Modules.
+pkglib_MODULES = halt.mod \
+	linux.mod \
+	reboot.mod \
+	memdisk.mod \
+	lsmmap.mod
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/sparc64/ieee1275/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod.
+reboot_mod_SOURCES = commands/reboot.c
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memdisk.mod.
+memdisk_mod_SOURCES = disk/memdisk.c
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/common.mk
diff --git a/conf/x86_64-efi.mk b/conf/x86_64-efi.mk
new file mode 100644
index 0000000..4b15c31
--- /dev/null
+++ b/conf/x86_64-efi.mk
@@ -0,0 +1,3119 @@
+# -*- makefile -*-
+# Generated by genmk.rb, please don't edit!
+
+COMMON_ASFLAGS = -nostdinc -fno-builtin -m64
+COMMON_CFLAGS = -fno-builtin -m64
+COMMON_LDFLAGS = -melf_x86_64 -nostdlib
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Utilities.
+bin_UTILITIES = grub-mkimage
+sbin_UTILITIES = grub-mkdevicemap
+#ifeq ($(enable_grub_emu), yes)
+#sbin_UTILITIES += grub-emu
+#endif
+
+# For grub-mkimage.
+grub_mkimage_SOURCES = util/i386/efi/grub-mkimage.c util/misc.c \
+	util/resolve.c
+
+clean-utility-grub-mkimage.1:
+	rm -f grub-mkimage$(EXEEXT) grub_mkimage-util_i386_efi_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkimage.1
+
+mostlyclean-utility-grub-mkimage.1:
+	rm -f grub_mkimage-util_i386_efi_grub_mkimage.d grub_mkimage-util_misc.d grub_mkimage-util_resolve.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkimage.1
+
+grub_mkimage_OBJECTS += grub_mkimage-util_i386_efi_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o
+
+grub_mkimage-util_i386_efi_grub_mkimage.o: util/i386/efi/grub-mkimage.c $(util/i386/efi/grub-mkimage.c_DEPENDENCIES)
+	$(CC) -Iutil/i386/efi -I$(srcdir)/util/i386/efi $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_i386_efi_grub_mkimage.d
+
+grub_mkimage-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_misc.d
+
+grub_mkimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
+-include grub_mkimage-util_resolve.d
+
+
+# For grub-setup.
+#grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c	\
+#	util/misc.c util/getroot.c kern/device.c kern/disk.c	\
+#	kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c	\
+#	fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c		\
+#	fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c	\
+#	kern/fs.c kern/env.c fs/fshelp.c
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/devicemap.c util/misc.c
+
+clean-utility-grub-mkdevicemap.1:
+	rm -f grub-mkdevicemap$(EXEEXT) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_devicemap.o grub_mkdevicemap-util_misc.o
+
+CLEAN_UTILITY_TARGETS += clean-utility-grub-mkdevicemap.1
+
+mostlyclean-utility-grub-mkdevicemap.1:
+	rm -f grub_mkdevicemap-util_grub_mkdevicemap.d grub_mkdevicemap-util_deviceiter.d grub_mkdevicemap-util_devicemap.d grub_mkdevicemap-util_misc.d
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-grub-mkdevicemap.1
+
+grub_mkdevicemap_OBJECTS += grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_deviceiter.o grub_mkdevicemap-util_devicemap.o grub_mkdevicemap-util_misc.o
+
+grub_mkdevicemap-util_grub_mkdevicemap.o: util/grub-mkdevicemap.c $(util/grub-mkdevicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_grub_mkdevicemap.d
+
+grub_mkdevicemap-util_deviceiter.o: util/deviceiter.c $(util/deviceiter.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_deviceiter.d
+
+grub_mkdevicemap-util_devicemap.o: util/devicemap.c $(util/devicemap.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_devicemap.d
+
+grub_mkdevicemap-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
+	$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $<
+-include grub_mkdevicemap-util_misc.d
+
+
+# For grub-emu.
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c 	\
+	commands/configfile.c commands/help.c				\
+	commands/handler.c commands/ls.c commands/test.c 		\
+	commands/search.c commands/hexdump.c lib/hexdump.c		\
+	commands/halt.c commands/reboot.c				\
+	commands/i386/cpuid.c						\
+	commands/password.c commands/keystatus.c			\
+	lib/envblk.c commands/loadenv.c					\
+	disk/loopback.c							\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c					\
+	\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/list.c kern/handler.c				\
+	kern/command.c kern/corecmd.c commands/extcmd.c kern/file.c 	\
+	kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c	\
+	kern/partition.c kern/readerescue.c kern/term.c			\
+	lib/arg.c normal/cmdline.c normal/misc.c normal/auth.c		\
+	normal/autofs.c	\
+	normal/completion.c normal/datetime.c normal/context.c 		\
+	normal/main.c		\
+	normal/menu.c normal/menu_entry.c normal/menu_viewer.c		\
+	normal/menu_text.c						\
+	normal/color.c							\
+	script/sh/main.c script/sh/execute.c script/sh/function.c	\
+	script/sh/lexer.c script/sh/script.c grub_script.tab.c		\
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c partmap/gpt.c					\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	commands/parttool.c parttool/msdospart.c				\
+	grub_emu_init.c
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/i386/efi/grub-install.in
+CLEANFILES += grub-install
+
+grub-install: util/i386/efi/grub-install.in $(util/i386/efi/grub-install.in_DEPENDENCIES) config.status
+	./config.status --file=grub-install:util/i386/efi/grub-install.in
+	chmod +x $@
+
+
+# Modules.
+pkglib_MODULES = kernel.mod chain.mod appleldr.mod \
+	halt.mod reboot.mod linux.mod pci.mod lspci.mod \
+	datetime.mod date.mod datehook.mod loadbios.mod \
+	fixvideo.mod mmap.mod acpi.mod
+
+# For kernel.mod.
+kernel_mod_EXPORTS = no
+kernel_mod_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \
+	kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
+	kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
+	kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+	kern/i386/tsc.c kern/i386/pit.c \
+	kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c \
+	term/efi/console.c disk/efi/efidisk.c
+
+clean-module-kernel.mod.1:
+	rm -f kernel.mod mod-kernel.o mod-kernel.c pre-kernel.o kernel_mod-kern_x86_64_efi_startup.o kernel_mod-kern_x86_64_efi_callwrap.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_reader.o kernel_mod-kern_term.o kernel_mod-kern_rescue_parser.o kernel_mod-kern_rescue_reader.o kernel_mod-kern___target_cpu__dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-kern_time.o kernel_mod-kern_list.o kernel_mod-kern_handler.o kernel_mod-kern_command.o kernel_mod-kern_corecmd.o kernel_mod-kern_i386_tsc.o kernel_mod-kern_i386_pit.o kernel_mod-kern_generic_millisleep.o kernel_mod-kern_generic_rtc_get_time_ms.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o und-kernel.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel.mod.1
+
+ifneq ($(kernel_mod_EXPORTS),no)
+clean-module-kernel.mod-symbol.1:
+	rm -f def-kernel.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel.mod-symbol.1
+DEFSYMFILES += def-kernel.lst
+endif
+mostlyclean-module-kernel.mod.1:
+	rm -f kernel_mod-kern_x86_64_efi_startup.d kernel_mod-kern_x86_64_efi_callwrap.d kernel_mod-kern_main.d kernel_mod-kern_device.d kernel_mod-kern_disk.d kernel_mod-kern_dl.d kernel_mod-kern_file.d kernel_mod-kern_fs.d kernel_mod-kern_err.d kernel_mod-kern_misc.d kernel_mod-kern_mm.d kernel_mod-kern_reader.d kernel_mod-kern_term.d kernel_mod-kern_rescue_parser.d kernel_mod-kern_rescue_reader.d kernel_mod-kern___target_cpu__dl.d kernel_mod-kern_i386_efi_init.d kernel_mod-kern_parser.d kernel_mod-kern_partition.d kernel_mod-kern_env.d kernel_mod-symlist.d kernel_mod-kern_efi_efi.d kernel_mod-kern_efi_init.d kernel_mod-kern_efi_mm.d kernel_mod-kern_time.d kernel_mod-kern_list.d kernel_mod-kern_handler.d kernel_mod-kern_command.d kernel_mod-kern_corecmd.d kernel_mod-kern_i386_tsc.d kernel_mod-kern_i386_pit.d kernel_mod-kern_generic_millisleep.d kernel_mod-kern_generic_rtc_get_time_ms.d kernel_mod-term_efi_console.d kernel_mod-disk_efi_efidisk.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-kernel.mod.1
+UNDSYMFILES += und-kernel.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+kernel.mod: pre-kernel.o mod-kernel.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(kernel_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-kernel.o mod-kernel.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+kernel.mod: pre-kernel.o mod-kernel.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(kernel_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-kernel.o mod-kernel.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-kernel.o: $(kernel_mod_DEPENDENCIES) kernel_mod-kern_x86_64_efi_startup.o kernel_mod-kern_x86_64_efi_callwrap.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_reader.o kernel_mod-kern_term.o kernel_mod-kern_rescue_parser.o kernel_mod-kern_rescue_reader.o kernel_mod-kern___target_cpu__dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-kern_time.o kernel_mod-kern_list.o kernel_mod-kern_handler.o kernel_mod-kern_command.o kernel_mod-kern_corecmd.o kernel_mod-kern_i386_tsc.o kernel_mod-kern_i386_pit.o kernel_mod-kern_generic_millisleep.o kernel_mod-kern_generic_rtc_get_time_ms.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o
+	-rm -f $@
+	$(TARGET_CC) $(kernel_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ kernel_mod-kern_x86_64_efi_startup.o kernel_mod-kern_x86_64_efi_callwrap.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_reader.o kernel_mod-kern_term.o kernel_mod-kern_rescue_parser.o kernel_mod-kern_rescue_reader.o kernel_mod-kern___target_cpu__dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-kern_time.o kernel_mod-kern_list.o kernel_mod-kern_handler.o kernel_mod-kern_command.o kernel_mod-kern_corecmd.o kernel_mod-kern_i386_tsc.o kernel_mod-kern_i386_pit.o kernel_mod-kern_generic_millisleep.o kernel_mod-kern_generic_rtc_get_time_ms.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o
+
+mod-kernel.o: mod-kernel.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -c -o $@ $<
+
+mod-kernel.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'kernel' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(kernel_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-kernel.lst: pre-kernel.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 kernel/' > $@
+else
+def-kernel.lst: pre-kernel.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 kernel/' > $@
+endif
+endif
+
+und-kernel.lst: pre-kernel.o
+	echo 'kernel' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+kernel_mod-kern_x86_64_efi_startup.o: kern/x86_64/efi/startup.S $(kern/x86_64/efi/startup.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_x86_64_efi_startup.d
+
+clean-module-kernel_mod-kern_x86_64_efi_startup-extra.1:
+	rm -f cmd-kernel_mod-kern_x86_64_efi_startup.lst fs-kernel_mod-kern_x86_64_efi_startup.lst partmap-kernel_mod-kern_x86_64_efi_startup.lst handler-kernel_mod-kern_x86_64_efi_startup.lst parttool-kernel_mod-kern_x86_64_efi_startup.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_x86_64_efi_startup-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_x86_64_efi_startup.lst
+FSFILES += fs-kernel_mod-kern_x86_64_efi_startup.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_x86_64_efi_startup.lst
+PARTMAPFILES += partmap-kernel_mod-kern_x86_64_efi_startup.lst
+HANDLERFILES += handler-kernel_mod-kern_x86_64_efi_startup.lst
+
+cmd-kernel_mod-kern_x86_64_efi_startup.lst: kern/x86_64/efi/startup.S $(kern/x86_64/efi/startup.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_x86_64_efi_startup.lst: kern/x86_64/efi/startup.S $(kern/x86_64/efi/startup.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_x86_64_efi_startup.lst: kern/x86_64/efi/startup.S $(kern/x86_64/efi/startup.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_x86_64_efi_startup.lst: kern/x86_64/efi/startup.S $(kern/x86_64/efi/startup.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_x86_64_efi_startup.lst: kern/x86_64/efi/startup.S $(kern/x86_64/efi/startup.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_x86_64_efi_callwrap.o: kern/x86_64/efi/callwrap.S $(kern/x86_64/efi/callwrap.S_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_x86_64_efi_callwrap.d
+
+clean-module-kernel_mod-kern_x86_64_efi_callwrap-extra.1:
+	rm -f cmd-kernel_mod-kern_x86_64_efi_callwrap.lst fs-kernel_mod-kern_x86_64_efi_callwrap.lst partmap-kernel_mod-kern_x86_64_efi_callwrap.lst handler-kernel_mod-kern_x86_64_efi_callwrap.lst parttool-kernel_mod-kern_x86_64_efi_callwrap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_x86_64_efi_callwrap-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_x86_64_efi_callwrap.lst
+FSFILES += fs-kernel_mod-kern_x86_64_efi_callwrap.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_x86_64_efi_callwrap.lst
+PARTMAPFILES += partmap-kernel_mod-kern_x86_64_efi_callwrap.lst
+HANDLERFILES += handler-kernel_mod-kern_x86_64_efi_callwrap.lst
+
+cmd-kernel_mod-kern_x86_64_efi_callwrap.lst: kern/x86_64/efi/callwrap.S $(kern/x86_64/efi/callwrap.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_x86_64_efi_callwrap.lst: kern/x86_64/efi/callwrap.S $(kern/x86_64/efi/callwrap.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_x86_64_efi_callwrap.lst: kern/x86_64/efi/callwrap.S $(kern/x86_64/efi/callwrap.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_x86_64_efi_callwrap.lst: kern/x86_64/efi/callwrap.S $(kern/x86_64/efi/callwrap.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_x86_64_efi_callwrap.lst: kern/x86_64/efi/callwrap.S $(kern/x86_64/efi/callwrap.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_main.d
+
+clean-module-kernel_mod-kern_main-extra.1:
+	rm -f cmd-kernel_mod-kern_main.lst fs-kernel_mod-kern_main.lst partmap-kernel_mod-kern_main.lst handler-kernel_mod-kern_main.lst parttool-kernel_mod-kern_main.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_main-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_main.lst
+FSFILES += fs-kernel_mod-kern_main.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_main.lst
+PARTMAPFILES += partmap-kernel_mod-kern_main.lst
+HANDLERFILES += handler-kernel_mod-kern_main.lst
+
+cmd-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_device.d
+
+clean-module-kernel_mod-kern_device-extra.1:
+	rm -f cmd-kernel_mod-kern_device.lst fs-kernel_mod-kern_device.lst partmap-kernel_mod-kern_device.lst handler-kernel_mod-kern_device.lst parttool-kernel_mod-kern_device.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_device-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_device.lst
+FSFILES += fs-kernel_mod-kern_device.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_device.lst
+PARTMAPFILES += partmap-kernel_mod-kern_device.lst
+HANDLERFILES += handler-kernel_mod-kern_device.lst
+
+cmd-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_disk.d
+
+clean-module-kernel_mod-kern_disk-extra.1:
+	rm -f cmd-kernel_mod-kern_disk.lst fs-kernel_mod-kern_disk.lst partmap-kernel_mod-kern_disk.lst handler-kernel_mod-kern_disk.lst parttool-kernel_mod-kern_disk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_disk-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_disk.lst
+FSFILES += fs-kernel_mod-kern_disk.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_disk.lst
+PARTMAPFILES += partmap-kernel_mod-kern_disk.lst
+HANDLERFILES += handler-kernel_mod-kern_disk.lst
+
+cmd-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_dl.d
+
+clean-module-kernel_mod-kern_dl-extra.1:
+	rm -f cmd-kernel_mod-kern_dl.lst fs-kernel_mod-kern_dl.lst partmap-kernel_mod-kern_dl.lst handler-kernel_mod-kern_dl.lst parttool-kernel_mod-kern_dl.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_dl-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_dl.lst
+FSFILES += fs-kernel_mod-kern_dl.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_dl.lst
+PARTMAPFILES += partmap-kernel_mod-kern_dl.lst
+HANDLERFILES += handler-kernel_mod-kern_dl.lst
+
+cmd-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_file.d
+
+clean-module-kernel_mod-kern_file-extra.1:
+	rm -f cmd-kernel_mod-kern_file.lst fs-kernel_mod-kern_file.lst partmap-kernel_mod-kern_file.lst handler-kernel_mod-kern_file.lst parttool-kernel_mod-kern_file.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_file-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_file.lst
+FSFILES += fs-kernel_mod-kern_file.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_file.lst
+PARTMAPFILES += partmap-kernel_mod-kern_file.lst
+HANDLERFILES += handler-kernel_mod-kern_file.lst
+
+cmd-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_fs.d
+
+clean-module-kernel_mod-kern_fs-extra.1:
+	rm -f cmd-kernel_mod-kern_fs.lst fs-kernel_mod-kern_fs.lst partmap-kernel_mod-kern_fs.lst handler-kernel_mod-kern_fs.lst parttool-kernel_mod-kern_fs.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_fs-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_fs.lst
+FSFILES += fs-kernel_mod-kern_fs.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_fs.lst
+PARTMAPFILES += partmap-kernel_mod-kern_fs.lst
+HANDLERFILES += handler-kernel_mod-kern_fs.lst
+
+cmd-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_err.d
+
+clean-module-kernel_mod-kern_err-extra.1:
+	rm -f cmd-kernel_mod-kern_err.lst fs-kernel_mod-kern_err.lst partmap-kernel_mod-kern_err.lst handler-kernel_mod-kern_err.lst parttool-kernel_mod-kern_err.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_err-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_err.lst
+FSFILES += fs-kernel_mod-kern_err.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_err.lst
+PARTMAPFILES += partmap-kernel_mod-kern_err.lst
+HANDLERFILES += handler-kernel_mod-kern_err.lst
+
+cmd-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_misc.d
+
+clean-module-kernel_mod-kern_misc-extra.1:
+	rm -f cmd-kernel_mod-kern_misc.lst fs-kernel_mod-kern_misc.lst partmap-kernel_mod-kern_misc.lst handler-kernel_mod-kern_misc.lst parttool-kernel_mod-kern_misc.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_misc-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_misc.lst
+FSFILES += fs-kernel_mod-kern_misc.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_misc.lst
+PARTMAPFILES += partmap-kernel_mod-kern_misc.lst
+HANDLERFILES += handler-kernel_mod-kern_misc.lst
+
+cmd-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_mm.d
+
+clean-module-kernel_mod-kern_mm-extra.1:
+	rm -f cmd-kernel_mod-kern_mm.lst fs-kernel_mod-kern_mm.lst partmap-kernel_mod-kern_mm.lst handler-kernel_mod-kern_mm.lst parttool-kernel_mod-kern_mm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_mm-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_mm.lst
+FSFILES += fs-kernel_mod-kern_mm.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_mm.lst
+PARTMAPFILES += partmap-kernel_mod-kern_mm.lst
+HANDLERFILES += handler-kernel_mod-kern_mm.lst
+
+cmd-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_reader.o: kern/reader.c $(kern/reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_reader.d
+
+clean-module-kernel_mod-kern_reader-extra.1:
+	rm -f cmd-kernel_mod-kern_reader.lst fs-kernel_mod-kern_reader.lst partmap-kernel_mod-kern_reader.lst handler-kernel_mod-kern_reader.lst parttool-kernel_mod-kern_reader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_reader-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_reader.lst
+FSFILES += fs-kernel_mod-kern_reader.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_reader.lst
+PARTMAPFILES += partmap-kernel_mod-kern_reader.lst
+HANDLERFILES += handler-kernel_mod-kern_reader.lst
+
+cmd-kernel_mod-kern_reader.lst: kern/reader.c $(kern/reader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_reader.lst: kern/reader.c $(kern/reader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_reader.lst: kern/reader.c $(kern/reader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_reader.lst: kern/reader.c $(kern/reader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_reader.lst: kern/reader.c $(kern/reader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_term.d
+
+clean-module-kernel_mod-kern_term-extra.1:
+	rm -f cmd-kernel_mod-kern_term.lst fs-kernel_mod-kern_term.lst partmap-kernel_mod-kern_term.lst handler-kernel_mod-kern_term.lst parttool-kernel_mod-kern_term.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_term-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_term.lst
+FSFILES += fs-kernel_mod-kern_term.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_term.lst
+PARTMAPFILES += partmap-kernel_mod-kern_term.lst
+HANDLERFILES += handler-kernel_mod-kern_term.lst
+
+cmd-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_rescue_parser.o: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_rescue_parser.d
+
+clean-module-kernel_mod-kern_rescue_parser-extra.1:
+	rm -f cmd-kernel_mod-kern_rescue_parser.lst fs-kernel_mod-kern_rescue_parser.lst partmap-kernel_mod-kern_rescue_parser.lst handler-kernel_mod-kern_rescue_parser.lst parttool-kernel_mod-kern_rescue_parser.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_rescue_parser-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_rescue_parser.lst
+FSFILES += fs-kernel_mod-kern_rescue_parser.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_rescue_parser.lst
+PARTMAPFILES += partmap-kernel_mod-kern_rescue_parser.lst
+HANDLERFILES += handler-kernel_mod-kern_rescue_parser.lst
+
+cmd-kernel_mod-kern_rescue_parser.lst: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_rescue_parser.lst: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_rescue_parser.lst: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_rescue_parser.lst: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_rescue_parser.lst: kern/rescue_parser.c $(kern/rescue_parser.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_rescue_reader.o: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_rescue_reader.d
+
+clean-module-kernel_mod-kern_rescue_reader-extra.1:
+	rm -f cmd-kernel_mod-kern_rescue_reader.lst fs-kernel_mod-kern_rescue_reader.lst partmap-kernel_mod-kern_rescue_reader.lst handler-kernel_mod-kern_rescue_reader.lst parttool-kernel_mod-kern_rescue_reader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_rescue_reader-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_rescue_reader.lst
+FSFILES += fs-kernel_mod-kern_rescue_reader.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_rescue_reader.lst
+PARTMAPFILES += partmap-kernel_mod-kern_rescue_reader.lst
+HANDLERFILES += handler-kernel_mod-kern_rescue_reader.lst
+
+cmd-kernel_mod-kern_rescue_reader.lst: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_rescue_reader.lst: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_rescue_reader.lst: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_rescue_reader.lst: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_rescue_reader.lst: kern/rescue_reader.c $(kern/rescue_reader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern___target_cpu__dl.o: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern___target_cpu__dl.d
+
+clean-module-kernel_mod-kern___target_cpu__dl-extra.1:
+	rm -f cmd-kernel_mod-kern___target_cpu__dl.lst fs-kernel_mod-kern___target_cpu__dl.lst partmap-kernel_mod-kern___target_cpu__dl.lst handler-kernel_mod-kern___target_cpu__dl.lst parttool-kernel_mod-kern___target_cpu__dl.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern___target_cpu__dl-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern___target_cpu__dl.lst
+FSFILES += fs-kernel_mod-kern___target_cpu__dl.lst
+PARTTOOLFILES += parttool-kernel_mod-kern___target_cpu__dl.lst
+PARTMAPFILES += partmap-kernel_mod-kern___target_cpu__dl.lst
+HANDLERFILES += handler-kernel_mod-kern___target_cpu__dl.lst
+
+cmd-kernel_mod-kern___target_cpu__dl.lst: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern___target_cpu__dl.lst: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern___target_cpu__dl.lst: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern___target_cpu__dl.lst: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern___target_cpu__dl.lst: kern/$(target_cpu)/dl.c $(kern/$(target_cpu)/dl.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/$(target_cpu) -I$(srcdir)/kern/$(target_cpu) $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_i386_efi_init.o: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_i386_efi_init.d
+
+clean-module-kernel_mod-kern_i386_efi_init-extra.1:
+	rm -f cmd-kernel_mod-kern_i386_efi_init.lst fs-kernel_mod-kern_i386_efi_init.lst partmap-kernel_mod-kern_i386_efi_init.lst handler-kernel_mod-kern_i386_efi_init.lst parttool-kernel_mod-kern_i386_efi_init.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_i386_efi_init-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_i386_efi_init.lst
+FSFILES += fs-kernel_mod-kern_i386_efi_init.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_i386_efi_init.lst
+PARTMAPFILES += partmap-kernel_mod-kern_i386_efi_init.lst
+HANDLERFILES += handler-kernel_mod-kern_i386_efi_init.lst
+
+cmd-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_parser.d
+
+clean-module-kernel_mod-kern_parser-extra.1:
+	rm -f cmd-kernel_mod-kern_parser.lst fs-kernel_mod-kern_parser.lst partmap-kernel_mod-kern_parser.lst handler-kernel_mod-kern_parser.lst parttool-kernel_mod-kern_parser.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_parser-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_parser.lst
+FSFILES += fs-kernel_mod-kern_parser.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_parser.lst
+PARTMAPFILES += partmap-kernel_mod-kern_parser.lst
+HANDLERFILES += handler-kernel_mod-kern_parser.lst
+
+cmd-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_partition.d
+
+clean-module-kernel_mod-kern_partition-extra.1:
+	rm -f cmd-kernel_mod-kern_partition.lst fs-kernel_mod-kern_partition.lst partmap-kernel_mod-kern_partition.lst handler-kernel_mod-kern_partition.lst parttool-kernel_mod-kern_partition.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_partition-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_partition.lst
+FSFILES += fs-kernel_mod-kern_partition.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_partition.lst
+PARTMAPFILES += partmap-kernel_mod-kern_partition.lst
+HANDLERFILES += handler-kernel_mod-kern_partition.lst
+
+cmd-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_env.d
+
+clean-module-kernel_mod-kern_env-extra.1:
+	rm -f cmd-kernel_mod-kern_env.lst fs-kernel_mod-kern_env.lst partmap-kernel_mod-kern_env.lst handler-kernel_mod-kern_env.lst parttool-kernel_mod-kern_env.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_env-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_env.lst
+FSFILES += fs-kernel_mod-kern_env.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_env.lst
+PARTMAPFILES += partmap-kernel_mod-kern_env.lst
+HANDLERFILES += handler-kernel_mod-kern_env.lst
+
+cmd-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-symlist.o: symlist.c $(symlist.c_DEPENDENCIES)
+	$(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-symlist.d
+
+clean-module-kernel_mod-symlist-extra.1:
+	rm -f cmd-kernel_mod-symlist.lst fs-kernel_mod-symlist.lst partmap-kernel_mod-symlist.lst handler-kernel_mod-symlist.lst parttool-kernel_mod-symlist.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-symlist-extra.1
+
+COMMANDFILES += cmd-kernel_mod-symlist.lst
+FSFILES += fs-kernel_mod-symlist.lst
+PARTTOOLFILES += parttool-kernel_mod-symlist.lst
+PARTMAPFILES += partmap-kernel_mod-symlist.lst
+HANDLERFILES += handler-kernel_mod-symlist.lst
+
+cmd-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_efi_efi.o: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_efi_efi.d
+
+clean-module-kernel_mod-kern_efi_efi-extra.1:
+	rm -f cmd-kernel_mod-kern_efi_efi.lst fs-kernel_mod-kern_efi_efi.lst partmap-kernel_mod-kern_efi_efi.lst handler-kernel_mod-kern_efi_efi.lst parttool-kernel_mod-kern_efi_efi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_efi_efi-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_efi_efi.lst
+FSFILES += fs-kernel_mod-kern_efi_efi.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_efi_efi.lst
+PARTMAPFILES += partmap-kernel_mod-kern_efi_efi.lst
+HANDLERFILES += handler-kernel_mod-kern_efi_efi.lst
+
+cmd-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_efi_init.o: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_efi_init.d
+
+clean-module-kernel_mod-kern_efi_init-extra.1:
+	rm -f cmd-kernel_mod-kern_efi_init.lst fs-kernel_mod-kern_efi_init.lst partmap-kernel_mod-kern_efi_init.lst handler-kernel_mod-kern_efi_init.lst parttool-kernel_mod-kern_efi_init.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_efi_init-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_efi_init.lst
+FSFILES += fs-kernel_mod-kern_efi_init.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_efi_init.lst
+PARTMAPFILES += partmap-kernel_mod-kern_efi_init.lst
+HANDLERFILES += handler-kernel_mod-kern_efi_init.lst
+
+cmd-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_efi_mm.o: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_efi_mm.d
+
+clean-module-kernel_mod-kern_efi_mm-extra.1:
+	rm -f cmd-kernel_mod-kern_efi_mm.lst fs-kernel_mod-kern_efi_mm.lst partmap-kernel_mod-kern_efi_mm.lst handler-kernel_mod-kern_efi_mm.lst parttool-kernel_mod-kern_efi_mm.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_efi_mm-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_efi_mm.lst
+FSFILES += fs-kernel_mod-kern_efi_mm.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_efi_mm.lst
+PARTMAPFILES += partmap-kernel_mod-kern_efi_mm.lst
+HANDLERFILES += handler-kernel_mod-kern_efi_mm.lst
+
+cmd-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_time.d
+
+clean-module-kernel_mod-kern_time-extra.1:
+	rm -f cmd-kernel_mod-kern_time.lst fs-kernel_mod-kern_time.lst partmap-kernel_mod-kern_time.lst handler-kernel_mod-kern_time.lst parttool-kernel_mod-kern_time.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_time-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_time.lst
+FSFILES += fs-kernel_mod-kern_time.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_time.lst
+PARTMAPFILES += partmap-kernel_mod-kern_time.lst
+HANDLERFILES += handler-kernel_mod-kern_time.lst
+
+cmd-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_list.o: kern/list.c $(kern/list.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_list.d
+
+clean-module-kernel_mod-kern_list-extra.1:
+	rm -f cmd-kernel_mod-kern_list.lst fs-kernel_mod-kern_list.lst partmap-kernel_mod-kern_list.lst handler-kernel_mod-kern_list.lst parttool-kernel_mod-kern_list.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_list-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_list.lst
+FSFILES += fs-kernel_mod-kern_list.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_list.lst
+PARTMAPFILES += partmap-kernel_mod-kern_list.lst
+HANDLERFILES += handler-kernel_mod-kern_list.lst
+
+cmd-kernel_mod-kern_list.lst: kern/list.c $(kern/list.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_list.lst: kern/list.c $(kern/list.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_list.lst: kern/list.c $(kern/list.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_list.lst: kern/list.c $(kern/list.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_list.lst: kern/list.c $(kern/list.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_handler.o: kern/handler.c $(kern/handler.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_handler.d
+
+clean-module-kernel_mod-kern_handler-extra.1:
+	rm -f cmd-kernel_mod-kern_handler.lst fs-kernel_mod-kern_handler.lst partmap-kernel_mod-kern_handler.lst handler-kernel_mod-kern_handler.lst parttool-kernel_mod-kern_handler.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_handler-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_handler.lst
+FSFILES += fs-kernel_mod-kern_handler.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_handler.lst
+PARTMAPFILES += partmap-kernel_mod-kern_handler.lst
+HANDLERFILES += handler-kernel_mod-kern_handler.lst
+
+cmd-kernel_mod-kern_handler.lst: kern/handler.c $(kern/handler.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_handler.lst: kern/handler.c $(kern/handler.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_handler.lst: kern/handler.c $(kern/handler.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_handler.lst: kern/handler.c $(kern/handler.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_handler.lst: kern/handler.c $(kern/handler.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_command.o: kern/command.c $(kern/command.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_command.d
+
+clean-module-kernel_mod-kern_command-extra.1:
+	rm -f cmd-kernel_mod-kern_command.lst fs-kernel_mod-kern_command.lst partmap-kernel_mod-kern_command.lst handler-kernel_mod-kern_command.lst parttool-kernel_mod-kern_command.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_command-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_command.lst
+FSFILES += fs-kernel_mod-kern_command.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_command.lst
+PARTMAPFILES += partmap-kernel_mod-kern_command.lst
+HANDLERFILES += handler-kernel_mod-kern_command.lst
+
+cmd-kernel_mod-kern_command.lst: kern/command.c $(kern/command.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_command.lst: kern/command.c $(kern/command.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_command.lst: kern/command.c $(kern/command.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_command.lst: kern/command.c $(kern/command.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_command.lst: kern/command.c $(kern/command.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_corecmd.o: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_corecmd.d
+
+clean-module-kernel_mod-kern_corecmd-extra.1:
+	rm -f cmd-kernel_mod-kern_corecmd.lst fs-kernel_mod-kern_corecmd.lst partmap-kernel_mod-kern_corecmd.lst handler-kernel_mod-kern_corecmd.lst parttool-kernel_mod-kern_corecmd.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_corecmd-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_corecmd.lst
+FSFILES += fs-kernel_mod-kern_corecmd.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_corecmd.lst
+PARTMAPFILES += partmap-kernel_mod-kern_corecmd.lst
+HANDLERFILES += handler-kernel_mod-kern_corecmd.lst
+
+cmd-kernel_mod-kern_corecmd.lst: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_corecmd.lst: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_corecmd.lst: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_corecmd.lst: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_corecmd.lst: kern/corecmd.c $(kern/corecmd.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_i386_tsc.o: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_i386_tsc.d
+
+clean-module-kernel_mod-kern_i386_tsc-extra.1:
+	rm -f cmd-kernel_mod-kern_i386_tsc.lst fs-kernel_mod-kern_i386_tsc.lst partmap-kernel_mod-kern_i386_tsc.lst handler-kernel_mod-kern_i386_tsc.lst parttool-kernel_mod-kern_i386_tsc.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_i386_tsc-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_i386_tsc.lst
+FSFILES += fs-kernel_mod-kern_i386_tsc.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_i386_tsc.lst
+PARTMAPFILES += partmap-kernel_mod-kern_i386_tsc.lst
+HANDLERFILES += handler-kernel_mod-kern_i386_tsc.lst
+
+cmd-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_i386_pit.o: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_i386_pit.d
+
+clean-module-kernel_mod-kern_i386_pit-extra.1:
+	rm -f cmd-kernel_mod-kern_i386_pit.lst fs-kernel_mod-kern_i386_pit.lst partmap-kernel_mod-kern_i386_pit.lst handler-kernel_mod-kern_i386_pit.lst parttool-kernel_mod-kern_i386_pit.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_i386_pit-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_i386_pit.lst
+FSFILES += fs-kernel_mod-kern_i386_pit.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_i386_pit.lst
+PARTMAPFILES += partmap-kernel_mod-kern_i386_pit.lst
+HANDLERFILES += handler-kernel_mod-kern_i386_pit.lst
+
+cmd-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_generic_millisleep.d
+
+clean-module-kernel_mod-kern_generic_millisleep-extra.1:
+	rm -f cmd-kernel_mod-kern_generic_millisleep.lst fs-kernel_mod-kern_generic_millisleep.lst partmap-kernel_mod-kern_generic_millisleep.lst handler-kernel_mod-kern_generic_millisleep.lst parttool-kernel_mod-kern_generic_millisleep.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_generic_millisleep-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_generic_millisleep.lst
+FSFILES += fs-kernel_mod-kern_generic_millisleep.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_generic_millisleep.lst
+PARTMAPFILES += partmap-kernel_mod-kern_generic_millisleep.lst
+HANDLERFILES += handler-kernel_mod-kern_generic_millisleep.lst
+
+cmd-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-kern_generic_rtc_get_time_ms.o: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES)
+	$(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-kern_generic_rtc_get_time_ms.d
+
+clean-module-kernel_mod-kern_generic_rtc_get_time_ms-extra.1:
+	rm -f cmd-kernel_mod-kern_generic_rtc_get_time_ms.lst fs-kernel_mod-kern_generic_rtc_get_time_ms.lst partmap-kernel_mod-kern_generic_rtc_get_time_ms.lst handler-kernel_mod-kern_generic_rtc_get_time_ms.lst parttool-kernel_mod-kern_generic_rtc_get_time_ms.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-kern_generic_rtc_get_time_ms-extra.1
+
+COMMANDFILES += cmd-kernel_mod-kern_generic_rtc_get_time_ms.lst
+FSFILES += fs-kernel_mod-kern_generic_rtc_get_time_ms.lst
+PARTTOOLFILES += parttool-kernel_mod-kern_generic_rtc_get_time_ms.lst
+PARTMAPFILES += partmap-kernel_mod-kern_generic_rtc_get_time_ms.lst
+HANDLERFILES += handler-kernel_mod-kern_generic_rtc_get_time_ms.lst
+
+cmd-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-term_efi_console.o: term/efi/console.c $(term/efi/console.c_DEPENDENCIES)
+	$(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-term_efi_console.d
+
+clean-module-kernel_mod-term_efi_console-extra.1:
+	rm -f cmd-kernel_mod-term_efi_console.lst fs-kernel_mod-term_efi_console.lst partmap-kernel_mod-term_efi_console.lst handler-kernel_mod-term_efi_console.lst parttool-kernel_mod-term_efi_console.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-term_efi_console-extra.1
+
+COMMANDFILES += cmd-kernel_mod-term_efi_console.lst
+FSFILES += fs-kernel_mod-term_efi_console.lst
+PARTTOOLFILES += parttool-kernel_mod-term_efi_console.lst
+PARTMAPFILES += partmap-kernel_mod-term_efi_console.lst
+HANDLERFILES += handler-kernel_mod-term_efi_console.lst
+
+cmd-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod-disk_efi_efidisk.o: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES)
+	$(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $<
+-include kernel_mod-disk_efi_efidisk.d
+
+clean-module-kernel_mod-disk_efi_efidisk-extra.1:
+	rm -f cmd-kernel_mod-disk_efi_efidisk.lst fs-kernel_mod-disk_efi_efidisk.lst partmap-kernel_mod-disk_efi_efidisk.lst handler-kernel_mod-disk_efi_efidisk.lst parttool-kernel_mod-disk_efi_efidisk.lst
+
+CLEAN_MODULE_TARGETS += clean-module-kernel_mod-disk_efi_efidisk-extra.1
+
+COMMANDFILES += cmd-kernel_mod-disk_efi_efidisk.lst
+FSFILES += fs-kernel_mod-disk_efi_efidisk.lst
+PARTTOOLFILES += parttool-kernel_mod-disk_efi_efidisk.lst
+PARTMAPFILES += partmap-kernel_mod-disk_efi_efidisk.lst
+HANDLERFILES += handler-kernel_mod-disk_efi_efidisk.lst
+
+cmd-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+fs-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1)
+
+parttool-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh kernel > $@ || (rm -f $@; exit 1)
+
+partmap-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1)
+
+handler-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh kernel > $@ || (rm -f $@; exit 1)
+
+kernel_mod_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	efi/efi.h efi/time.h efi/disk.h machine/loader.h i386/pit.h list.h \
+	handler.h command.h
+kernel_mod_CFLAGS = $(COMMON_CFLAGS)
+kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+MOSTLYCLEANFILES += symlist.c
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+
+clean-module-boot.mod.1:
+	rm -f boot.mod mod-boot.o mod-boot.c pre-boot.o boot_mod-commands_boot.o boot_mod-lib_i386_pc_biosnum.o und-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod.1
+
+ifneq ($(boot_mod_EXPORTS),no)
+clean-module-boot.mod-symbol.1:
+	rm -f def-boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot.mod-symbol.1
+DEFSYMFILES += def-boot.lst
+endif
+mostlyclean-module-boot.mod.1:
+	rm -f boot_mod-commands_boot.d boot_mod-lib_i386_pc_biosnum.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-boot.mod.1
+UNDSYMFILES += und-boot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-boot.o mod-boot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-boot.o mod-boot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-boot.o: $(boot_mod_DEPENDENCIES) boot_mod-commands_boot.o boot_mod-lib_i386_pc_biosnum.o
+	-rm -f $@
+	$(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ boot_mod-commands_boot.o boot_mod-lib_i386_pc_biosnum.o
+
+mod-boot.o: mod-boot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -c -o $@ $<
+
+mod-boot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'boot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(boot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-boot.lst: pre-boot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+else
+def-boot.lst: pre-boot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 boot/' > $@
+endif
+endif
+
+und-boot.lst: pre-boot.o
+	echo 'boot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+boot_mod-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $<
+-include boot_mod-commands_boot.d
+
+clean-module-boot_mod-commands_boot-extra.1:
+	rm -f cmd-boot_mod-commands_boot.lst fs-boot_mod-commands_boot.lst partmap-boot_mod-commands_boot.lst handler-boot_mod-commands_boot.lst parttool-boot_mod-commands_boot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot_mod-commands_boot-extra.1
+
+COMMANDFILES += cmd-boot_mod-commands_boot.lst
+FSFILES += fs-boot_mod-commands_boot.lst
+PARTTOOLFILES += parttool-boot_mod-commands_boot.lst
+PARTMAPFILES += partmap-boot_mod-commands_boot.lst
+HANDLERFILES += handler-boot_mod-commands_boot.lst
+
+cmd-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1)
+
+fs-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1)
+
+parttool-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh boot > $@ || (rm -f $@; exit 1)
+
+partmap-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1)
+
+handler-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh boot > $@ || (rm -f $@; exit 1)
+
+boot_mod-lib_i386_pc_biosnum.o: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $<
+-include boot_mod-lib_i386_pc_biosnum.d
+
+clean-module-boot_mod-lib_i386_pc_biosnum-extra.1:
+	rm -f cmd-boot_mod-lib_i386_pc_biosnum.lst fs-boot_mod-lib_i386_pc_biosnum.lst partmap-boot_mod-lib_i386_pc_biosnum.lst handler-boot_mod-lib_i386_pc_biosnum.lst parttool-boot_mod-lib_i386_pc_biosnum.lst
+
+CLEAN_MODULE_TARGETS += clean-module-boot_mod-lib_i386_pc_biosnum-extra.1
+
+COMMANDFILES += cmd-boot_mod-lib_i386_pc_biosnum.lst
+FSFILES += fs-boot_mod-lib_i386_pc_biosnum.lst
+PARTTOOLFILES += parttool-boot_mod-lib_i386_pc_biosnum.lst
+PARTMAPFILES += partmap-boot_mod-lib_i386_pc_biosnum.lst
+HANDLERFILES += handler-boot_mod-lib_i386_pc_biosnum.lst
+
+cmd-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1)
+
+fs-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1)
+
+parttool-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh boot > $@ || (rm -f $@; exit 1)
+
+partmap-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1)
+
+handler-boot_mod-lib_i386_pc_biosnum.lst: lib/i386/pc/biosnum.c $(lib/i386/pc/biosnum.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/i386/pc -I$(srcdir)/lib/i386/pc $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh boot > $@ || (rm -f $@; exit 1)
+
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For acpi.mod.
+acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c
+
+clean-module-acpi.mod.1:
+	rm -f acpi.mod mod-acpi.o mod-acpi.c pre-acpi.o acpi_mod-commands_acpi.o acpi_mod-commands_efi_acpi.o und-acpi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-acpi.mod.1
+
+ifneq ($(acpi_mod_EXPORTS),no)
+clean-module-acpi.mod-symbol.1:
+	rm -f def-acpi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-acpi.mod-symbol.1
+DEFSYMFILES += def-acpi.lst
+endif
+mostlyclean-module-acpi.mod.1:
+	rm -f acpi_mod-commands_acpi.d acpi_mod-commands_efi_acpi.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-acpi.mod.1
+UNDSYMFILES += und-acpi.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+acpi.mod: pre-acpi.o mod-acpi.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(acpi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-acpi.o mod-acpi.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+acpi.mod: pre-acpi.o mod-acpi.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(acpi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-acpi.o mod-acpi.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-acpi.o: $(acpi_mod_DEPENDENCIES) acpi_mod-commands_acpi.o acpi_mod-commands_efi_acpi.o
+	-rm -f $@
+	$(TARGET_CC) $(acpi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ acpi_mod-commands_acpi.o acpi_mod-commands_efi_acpi.o
+
+mod-acpi.o: mod-acpi.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -c -o $@ $<
+
+mod-acpi.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'acpi' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(acpi_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-acpi.lst: pre-acpi.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 acpi/' > $@
+else
+def-acpi.lst: pre-acpi.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 acpi/' > $@
+endif
+endif
+
+und-acpi.lst: pre-acpi.o
+	echo 'acpi' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+acpi_mod-commands_acpi.o: commands/acpi.c $(commands/acpi.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -MD -c -o $@ $<
+-include acpi_mod-commands_acpi.d
+
+clean-module-acpi_mod-commands_acpi-extra.1:
+	rm -f cmd-acpi_mod-commands_acpi.lst fs-acpi_mod-commands_acpi.lst partmap-acpi_mod-commands_acpi.lst handler-acpi_mod-commands_acpi.lst parttool-acpi_mod-commands_acpi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-acpi_mod-commands_acpi-extra.1
+
+COMMANDFILES += cmd-acpi_mod-commands_acpi.lst
+FSFILES += fs-acpi_mod-commands_acpi.lst
+PARTTOOLFILES += parttool-acpi_mod-commands_acpi.lst
+PARTMAPFILES += partmap-acpi_mod-commands_acpi.lst
+HANDLERFILES += handler-acpi_mod-commands_acpi.lst
+
+cmd-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh acpi > $@ || (rm -f $@; exit 1)
+
+fs-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh acpi > $@ || (rm -f $@; exit 1)
+
+parttool-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh acpi > $@ || (rm -f $@; exit 1)
+
+partmap-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh acpi > $@ || (rm -f $@; exit 1)
+
+handler-acpi_mod-commands_acpi.lst: commands/acpi.c $(commands/acpi.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh acpi > $@ || (rm -f $@; exit 1)
+
+acpi_mod-commands_efi_acpi.o: commands/efi/acpi.c $(commands/efi/acpi.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -MD -c -o $@ $<
+-include acpi_mod-commands_efi_acpi.d
+
+clean-module-acpi_mod-commands_efi_acpi-extra.1:
+	rm -f cmd-acpi_mod-commands_efi_acpi.lst fs-acpi_mod-commands_efi_acpi.lst partmap-acpi_mod-commands_efi_acpi.lst handler-acpi_mod-commands_efi_acpi.lst parttool-acpi_mod-commands_efi_acpi.lst
+
+CLEAN_MODULE_TARGETS += clean-module-acpi_mod-commands_efi_acpi-extra.1
+
+COMMANDFILES += cmd-acpi_mod-commands_efi_acpi.lst
+FSFILES += fs-acpi_mod-commands_efi_acpi.lst
+PARTTOOLFILES += parttool-acpi_mod-commands_efi_acpi.lst
+PARTMAPFILES += partmap-acpi_mod-commands_efi_acpi.lst
+HANDLERFILES += handler-acpi_mod-commands_efi_acpi.lst
+
+cmd-acpi_mod-commands_efi_acpi.lst: commands/efi/acpi.c $(commands/efi/acpi.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh acpi > $@ || (rm -f $@; exit 1)
+
+fs-acpi_mod-commands_efi_acpi.lst: commands/efi/acpi.c $(commands/efi/acpi.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh acpi > $@ || (rm -f $@; exit 1)
+
+parttool-acpi_mod-commands_efi_acpi.lst: commands/efi/acpi.c $(commands/efi/acpi.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh acpi > $@ || (rm -f $@; exit 1)
+
+partmap-acpi_mod-commands_efi_acpi.lst: commands/efi/acpi.c $(commands/efi/acpi.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh acpi > $@ || (rm -f $@; exit 1)
+
+handler-acpi_mod-commands_efi_acpi.lst: commands/efi/acpi.c $(commands/efi/acpi.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(acpi_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh acpi > $@ || (rm -f $@; exit 1)
+
+acpi_mod_CFLAGS = $(COMMON_CFLAGS)
+acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
+		   mmap/efi/mmap.c
+
+clean-module-mmap.mod.1:
+	rm -f mmap.mod mod-mmap.o mod-mmap.c pre-mmap.o mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o mmap_mod-mmap_efi_mmap.o und-mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap.mod.1
+
+ifneq ($(mmap_mod_EXPORTS),no)
+clean-module-mmap.mod-symbol.1:
+	rm -f def-mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap.mod-symbol.1
+DEFSYMFILES += def-mmap.lst
+endif
+mostlyclean-module-mmap.mod.1:
+	rm -f mmap_mod-mmap_mmap.d mmap_mod-mmap_i386_uppermem.d mmap_mod-mmap_i386_mmap.d mmap_mod-mmap_efi_mmap.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-mmap.mod.1
+UNDSYMFILES += und-mmap.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+mmap.mod: pre-mmap.o mod-mmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-mmap.o mod-mmap.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+mmap.mod: pre-mmap.o mod-mmap.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-mmap.o mod-mmap.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-mmap.o: $(mmap_mod_DEPENDENCIES) mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o mmap_mod-mmap_efi_mmap.o
+	-rm -f $@
+	$(TARGET_CC) $(mmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ mmap_mod-mmap_mmap.o mmap_mod-mmap_i386_uppermem.o mmap_mod-mmap_i386_mmap.o mmap_mod-mmap_efi_mmap.o
+
+mod-mmap.o: mod-mmap.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -c -o $@ $<
+
+mod-mmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'mmap' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(mmap_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-mmap.lst: pre-mmap.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 mmap/' > $@
+else
+def-mmap.lst: pre-mmap.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 mmap/' > $@
+endif
+endif
+
+und-mmap.lst: pre-mmap.o
+	echo 'mmap' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+mmap_mod-mmap_mmap.o: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_mmap.d
+
+clean-module-mmap_mod-mmap_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_mmap.lst fs-mmap_mod-mmap_mmap.lst partmap-mmap_mod-mmap_mmap.lst handler-mmap_mod-mmap_mmap.lst parttool-mmap_mod-mmap_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_mmap.lst
+FSFILES += fs-mmap_mod-mmap_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_mmap.lst
+
+cmd-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_mmap.lst: mmap/mmap.c $(mmap/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap -I$(srcdir)/mmap $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_i386_uppermem.o: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_i386_uppermem.d
+
+clean-module-mmap_mod-mmap_i386_uppermem-extra.1:
+	rm -f cmd-mmap_mod-mmap_i386_uppermem.lst fs-mmap_mod-mmap_i386_uppermem.lst partmap-mmap_mod-mmap_i386_uppermem.lst handler-mmap_mod-mmap_i386_uppermem.lst parttool-mmap_mod-mmap_i386_uppermem.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_i386_uppermem-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_i386_uppermem.lst
+FSFILES += fs-mmap_mod-mmap_i386_uppermem.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_i386_uppermem.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_i386_uppermem.lst
+HANDLERFILES += handler-mmap_mod-mmap_i386_uppermem.lst
+
+cmd-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_i386_uppermem.lst: mmap/i386/uppermem.c $(mmap/i386/uppermem.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_i386_mmap.o: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_i386_mmap.d
+
+clean-module-mmap_mod-mmap_i386_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_i386_mmap.lst fs-mmap_mod-mmap_i386_mmap.lst partmap-mmap_mod-mmap_i386_mmap.lst handler-mmap_mod-mmap_i386_mmap.lst parttool-mmap_mod-mmap_i386_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_i386_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_i386_mmap.lst
+FSFILES += fs-mmap_mod-mmap_i386_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_i386_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_i386_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_i386_mmap.lst
+
+cmd-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_i386_mmap.lst: mmap/i386/mmap.c $(mmap/i386/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/i386 -I$(srcdir)/mmap/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod-mmap_efi_mmap.o: mmap/efi/mmap.c $(mmap/efi/mmap.c_DEPENDENCIES)
+	$(TARGET_CC) -Immap/efi -I$(srcdir)/mmap/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -MD -c -o $@ $<
+-include mmap_mod-mmap_efi_mmap.d
+
+clean-module-mmap_mod-mmap_efi_mmap-extra.1:
+	rm -f cmd-mmap_mod-mmap_efi_mmap.lst fs-mmap_mod-mmap_efi_mmap.lst partmap-mmap_mod-mmap_efi_mmap.lst handler-mmap_mod-mmap_efi_mmap.lst parttool-mmap_mod-mmap_efi_mmap.lst
+
+CLEAN_MODULE_TARGETS += clean-module-mmap_mod-mmap_efi_mmap-extra.1
+
+COMMANDFILES += cmd-mmap_mod-mmap_efi_mmap.lst
+FSFILES += fs-mmap_mod-mmap_efi_mmap.lst
+PARTTOOLFILES += parttool-mmap_mod-mmap_efi_mmap.lst
+PARTMAPFILES += partmap-mmap_mod-mmap_efi_mmap.lst
+HANDLERFILES += handler-mmap_mod-mmap_efi_mmap.lst
+
+cmd-mmap_mod-mmap_efi_mmap.lst: mmap/efi/mmap.c $(mmap/efi/mmap.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/efi -I$(srcdir)/mmap/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+fs-mmap_mod-mmap_efi_mmap.lst: mmap/efi/mmap.c $(mmap/efi/mmap.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Immap/efi -I$(srcdir)/mmap/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh mmap > $@ || (rm -f $@; exit 1)
+
+parttool-mmap_mod-mmap_efi_mmap.lst: mmap/efi/mmap.c $(mmap/efi/mmap.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Immap/efi -I$(srcdir)/mmap/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh mmap > $@ || (rm -f $@; exit 1)
+
+partmap-mmap_mod-mmap_efi_mmap.lst: mmap/efi/mmap.c $(mmap/efi/mmap.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Immap/efi -I$(srcdir)/mmap/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh mmap > $@ || (rm -f $@; exit 1)
+
+handler-mmap_mod-mmap_efi_mmap.lst: mmap/efi/mmap.c $(mmap/efi/mmap.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Immap/efi -I$(srcdir)/mmap/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(mmap_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh mmap > $@ || (rm -f $@; exit 1)
+
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For chain.mod.
+chain_mod_SOURCES = loader/efi/chainloader.c
+
+clean-module-chain.mod.1:
+	rm -f chain.mod mod-chain.o mod-chain.c pre-chain.o chain_mod-loader_efi_chainloader.o und-chain.lst
+
+CLEAN_MODULE_TARGETS += clean-module-chain.mod.1
+
+ifneq ($(chain_mod_EXPORTS),no)
+clean-module-chain.mod-symbol.1:
+	rm -f def-chain.lst
+
+CLEAN_MODULE_TARGETS += clean-module-chain.mod-symbol.1
+DEFSYMFILES += def-chain.lst
+endif
+mostlyclean-module-chain.mod.1:
+	rm -f chain_mod-loader_efi_chainloader.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-chain.mod.1
+UNDSYMFILES += und-chain.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+chain.mod: pre-chain.o mod-chain.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-chain.o mod-chain.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+chain.mod: pre-chain.o mod-chain.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-chain.o mod-chain.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-chain.o: $(chain_mod_DEPENDENCIES) chain_mod-loader_efi_chainloader.o
+	-rm -f $@
+	$(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ chain_mod-loader_efi_chainloader.o
+
+mod-chain.o: mod-chain.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -c -o $@ $<
+
+mod-chain.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'chain' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(chain_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-chain.lst: pre-chain.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 chain/' > $@
+else
+def-chain.lst: pre-chain.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 chain/' > $@
+endif
+endif
+
+und-chain.lst: pre-chain.o
+	echo 'chain' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+chain_mod-loader_efi_chainloader.o: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -MD -c -o $@ $<
+-include chain_mod-loader_efi_chainloader.d
+
+clean-module-chain_mod-loader_efi_chainloader-extra.1:
+	rm -f cmd-chain_mod-loader_efi_chainloader.lst fs-chain_mod-loader_efi_chainloader.lst partmap-chain_mod-loader_efi_chainloader.lst handler-chain_mod-loader_efi_chainloader.lst parttool-chain_mod-loader_efi_chainloader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-chain_mod-loader_efi_chainloader-extra.1
+
+COMMANDFILES += cmd-chain_mod-loader_efi_chainloader.lst
+FSFILES += fs-chain_mod-loader_efi_chainloader.lst
+PARTTOOLFILES += parttool-chain_mod-loader_efi_chainloader.lst
+PARTMAPFILES += partmap-chain_mod-loader_efi_chainloader.lst
+HANDLERFILES += handler-chain_mod-loader_efi_chainloader.lst
+
+cmd-chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh chain > $@ || (rm -f $@; exit 1)
+
+fs-chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh chain > $@ || (rm -f $@; exit 1)
+
+parttool-chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh chain > $@ || (rm -f $@; exit 1)
+
+partmap-chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh chain > $@ || (rm -f $@; exit 1)
+
+handler-chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh chain > $@ || (rm -f $@; exit 1)
+
+chain_mod_CFLAGS = $(COMMON_CFLAGS)
+chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For appleldr.mod.
+appleldr_mod_SOURCES = loader/efi/appleloader.c
+
+clean-module-appleldr.mod.1:
+	rm -f appleldr.mod mod-appleldr.o mod-appleldr.c pre-appleldr.o appleldr_mod-loader_efi_appleloader.o und-appleldr.lst
+
+CLEAN_MODULE_TARGETS += clean-module-appleldr.mod.1
+
+ifneq ($(appleldr_mod_EXPORTS),no)
+clean-module-appleldr.mod-symbol.1:
+	rm -f def-appleldr.lst
+
+CLEAN_MODULE_TARGETS += clean-module-appleldr.mod-symbol.1
+DEFSYMFILES += def-appleldr.lst
+endif
+mostlyclean-module-appleldr.mod.1:
+	rm -f appleldr_mod-loader_efi_appleloader.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-appleldr.mod.1
+UNDSYMFILES += und-appleldr.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+appleldr.mod: pre-appleldr.o mod-appleldr.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(appleldr_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-appleldr.o mod-appleldr.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+appleldr.mod: pre-appleldr.o mod-appleldr.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(appleldr_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-appleldr.o mod-appleldr.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-appleldr.o: $(appleldr_mod_DEPENDENCIES) appleldr_mod-loader_efi_appleloader.o
+	-rm -f $@
+	$(TARGET_CC) $(appleldr_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ appleldr_mod-loader_efi_appleloader.o
+
+mod-appleldr.o: mod-appleldr.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -c -o $@ $<
+
+mod-appleldr.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'appleldr' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(appleldr_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-appleldr.lst: pre-appleldr.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 appleldr/' > $@
+else
+def-appleldr.lst: pre-appleldr.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 appleldr/' > $@
+endif
+endif
+
+und-appleldr.lst: pre-appleldr.o
+	echo 'appleldr' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+appleldr_mod-loader_efi_appleloader.o: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -MD -c -o $@ $<
+-include appleldr_mod-loader_efi_appleloader.d
+
+clean-module-appleldr_mod-loader_efi_appleloader-extra.1:
+	rm -f cmd-appleldr_mod-loader_efi_appleloader.lst fs-appleldr_mod-loader_efi_appleloader.lst partmap-appleldr_mod-loader_efi_appleloader.lst handler-appleldr_mod-loader_efi_appleloader.lst parttool-appleldr_mod-loader_efi_appleloader.lst
+
+CLEAN_MODULE_TARGETS += clean-module-appleldr_mod-loader_efi_appleloader-extra.1
+
+COMMANDFILES += cmd-appleldr_mod-loader_efi_appleloader.lst
+FSFILES += fs-appleldr_mod-loader_efi_appleloader.lst
+PARTTOOLFILES += parttool-appleldr_mod-loader_efi_appleloader.lst
+PARTMAPFILES += partmap-appleldr_mod-loader_efi_appleloader.lst
+HANDLERFILES += handler-appleldr_mod-loader_efi_appleloader.lst
+
+cmd-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh appleldr > $@ || (rm -f $@; exit 1)
+
+fs-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh appleldr > $@ || (rm -f $@; exit 1)
+
+parttool-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh appleldr > $@ || (rm -f $@; exit 1)
+
+partmap-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh appleldr > $@ || (rm -f $@; exit 1)
+
+handler-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh appleldr > $@ || (rm -f $@; exit 1)
+
+appleldr_mod_CFLAGS = $(COMMON_CFLAGS)
+appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/i386/efi/linux.c loader/i386/linux_trampoline.S
+
+clean-module-linux.mod.1:
+	rm -f linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_i386_efi_linux.o linux_mod-loader_i386_linux_trampoline.o und-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod.1
+
+ifneq ($(linux_mod_EXPORTS),no)
+clean-module-linux.mod-symbol.1:
+	rm -f def-linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux.mod-symbol.1
+DEFSYMFILES += def-linux.lst
+endif
+mostlyclean-module-linux.mod.1:
+	rm -f linux_mod-loader_i386_efi_linux.d linux_mod-loader_i386_linux_trampoline.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-linux.mod.1
+UNDSYMFILES += und-linux.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-linux.o mod-linux.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_i386_efi_linux.o linux_mod-loader_i386_linux_trampoline.o
+	-rm -f $@
+	$(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_i386_efi_linux.o linux_mod-loader_i386_linux_trampoline.o
+
+mod-linux.o: mod-linux.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $<
+
+mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(linux_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-linux.lst: pre-linux.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+else
+def-linux.lst: pre-linux.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 linux/' > $@
+endif
+endif
+
+und-linux.lst: pre-linux.o
+	echo 'linux' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+linux_mod-loader_i386_efi_linux.o: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $<
+-include linux_mod-loader_i386_efi_linux.d
+
+clean-module-linux_mod-loader_i386_efi_linux-extra.1:
+	rm -f cmd-linux_mod-loader_i386_efi_linux.lst fs-linux_mod-loader_i386_efi_linux.lst partmap-linux_mod-loader_i386_efi_linux.lst handler-linux_mod-loader_i386_efi_linux.lst parttool-linux_mod-loader_i386_efi_linux.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux_mod-loader_i386_efi_linux-extra.1
+
+COMMANDFILES += cmd-linux_mod-loader_i386_efi_linux.lst
+FSFILES += fs-linux_mod-loader_i386_efi_linux.lst
+PARTTOOLFILES += parttool-linux_mod-loader_i386_efi_linux.lst
+PARTMAPFILES += partmap-linux_mod-loader_i386_efi_linux.lst
+HANDLERFILES += handler-linux_mod-loader_i386_efi_linux.lst
+
+cmd-linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1)
+
+fs-linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1)
+
+parttool-linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh linux > $@ || (rm -f $@; exit 1)
+
+partmap-linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1)
+
+handler-linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh linux > $@ || (rm -f $@; exit 1)
+
+linux_mod-loader_i386_linux_trampoline.o: loader/i386/linux_trampoline.S $(loader/i386/linux_trampoline.S_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(linux_mod_ASFLAGS) -MD -c -o $@ $<
+-include linux_mod-loader_i386_linux_trampoline.d
+
+clean-module-linux_mod-loader_i386_linux_trampoline-extra.1:
+	rm -f cmd-linux_mod-loader_i386_linux_trampoline.lst fs-linux_mod-loader_i386_linux_trampoline.lst partmap-linux_mod-loader_i386_linux_trampoline.lst handler-linux_mod-loader_i386_linux_trampoline.lst parttool-linux_mod-loader_i386_linux_trampoline.lst
+
+CLEAN_MODULE_TARGETS += clean-module-linux_mod-loader_i386_linux_trampoline-extra.1
+
+COMMANDFILES += cmd-linux_mod-loader_i386_linux_trampoline.lst
+FSFILES += fs-linux_mod-loader_i386_linux_trampoline.lst
+PARTTOOLFILES += parttool-linux_mod-loader_i386_linux_trampoline.lst
+PARTMAPFILES += partmap-linux_mod-loader_i386_linux_trampoline.lst
+HANDLERFILES += handler-linux_mod-loader_i386_linux_trampoline.lst
+
+cmd-linux_mod-loader_i386_linux_trampoline.lst: loader/i386/linux_trampoline.S $(loader/i386/linux_trampoline.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(linux_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1)
+
+fs-linux_mod-loader_i386_linux_trampoline.lst: loader/i386/linux_trampoline.S $(loader/i386/linux_trampoline.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(linux_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1)
+
+parttool-linux_mod-loader_i386_linux_trampoline.lst: loader/i386/linux_trampoline.S $(loader/i386/linux_trampoline.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(linux_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh linux > $@ || (rm -f $@; exit 1)
+
+partmap-linux_mod-loader_i386_linux_trampoline.lst: loader/i386/linux_trampoline.S $(loader/i386/linux_trampoline.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(linux_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1)
+
+handler-linux_mod-loader_i386_linux_trampoline.lst: loader/i386/linux_trampoline.S $(loader/i386/linux_trampoline.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(linux_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh linux > $@ || (rm -f $@; exit 1)
+
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/halt.c
+
+clean-module-halt.mod.1:
+	rm -f halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_halt.o und-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod.1
+
+ifneq ($(halt_mod_EXPORTS),no)
+clean-module-halt.mod-symbol.1:
+	rm -f def-halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt.mod-symbol.1
+DEFSYMFILES += def-halt.lst
+endif
+mostlyclean-module-halt.mod.1:
+	rm -f halt_mod-commands_halt.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-halt.mod.1
+UNDSYMFILES += und-halt.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-halt.o mod-halt.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_halt.o
+	-rm -f $@
+	$(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_halt.o
+
+mod-halt.o: mod-halt.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $<
+
+mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(halt_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-halt.lst: pre-halt.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+else
+def-halt.lst: pre-halt.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 halt/' > $@
+endif
+endif
+
+und-halt.lst: pre-halt.o
+	echo 'halt' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+halt_mod-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $<
+-include halt_mod-commands_halt.d
+
+clean-module-halt_mod-commands_halt-extra.1:
+	rm -f cmd-halt_mod-commands_halt.lst fs-halt_mod-commands_halt.lst partmap-halt_mod-commands_halt.lst handler-halt_mod-commands_halt.lst parttool-halt_mod-commands_halt.lst
+
+CLEAN_MODULE_TARGETS += clean-module-halt_mod-commands_halt-extra.1
+
+COMMANDFILES += cmd-halt_mod-commands_halt.lst
+FSFILES += fs-halt_mod-commands_halt.lst
+PARTTOOLFILES += parttool-halt_mod-commands_halt.lst
+PARTMAPFILES += partmap-halt_mod-commands_halt.lst
+HANDLERFILES += handler-halt_mod-commands_halt.lst
+
+cmd-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1)
+
+fs-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1)
+
+parttool-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh halt > $@ || (rm -f $@; exit 1)
+
+partmap-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1)
+
+handler-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh halt > $@ || (rm -f $@; exit 1)
+
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod.
+reboot_mod_SOURCES = commands/reboot.c
+
+clean-module-reboot.mod.1:
+	rm -f reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o und-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod.1
+
+ifneq ($(reboot_mod_EXPORTS),no)
+clean-module-reboot.mod-symbol.1:
+	rm -f def-reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot.mod-symbol.1
+DEFSYMFILES += def-reboot.lst
+endif
+mostlyclean-module-reboot.mod.1:
+	rm -f reboot_mod-commands_reboot.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-reboot.mod.1
+UNDSYMFILES += und-reboot.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-reboot.o mod-reboot.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o
+	-rm -f $@
+	$(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o
+
+mod-reboot.o: mod-reboot.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $<
+
+mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(reboot_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-reboot.lst: pre-reboot.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+else
+def-reboot.lst: pre-reboot.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 reboot/' > $@
+endif
+endif
+
+und-reboot.lst: pre-reboot.o
+	echo 'reboot' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $<
+-include reboot_mod-commands_reboot.d
+
+clean-module-reboot_mod-commands_reboot-extra.1:
+	rm -f cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst handler-reboot_mod-commands_reboot.lst parttool-reboot_mod-commands_reboot.lst
+
+CLEAN_MODULE_TARGETS += clean-module-reboot_mod-commands_reboot-extra.1
+
+COMMANDFILES += cmd-reboot_mod-commands_reboot.lst
+FSFILES += fs-reboot_mod-commands_reboot.lst
+PARTTOOLFILES += parttool-reboot_mod-commands_reboot.lst
+PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst
+HANDLERFILES += handler-reboot_mod-commands_reboot.lst
+
+cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1)
+
+parttool-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh reboot > $@ || (rm -f $@; exit 1)
+
+partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1)
+
+handler-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh reboot > $@ || (rm -f $@; exit 1)
+
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pci.mod
+pci_mod_SOURCES = bus/pci.c
+
+clean-module-pci.mod.1:
+	rm -f pci.mod mod-pci.o mod-pci.c pre-pci.o pci_mod-bus_pci.o und-pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci.mod.1
+
+ifneq ($(pci_mod_EXPORTS),no)
+clean-module-pci.mod-symbol.1:
+	rm -f def-pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci.mod-symbol.1
+DEFSYMFILES += def-pci.lst
+endif
+mostlyclean-module-pci.mod.1:
+	rm -f pci_mod-bus_pci.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-pci.mod.1
+UNDSYMFILES += und-pci.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-pci.o mod-pci.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-pci.o mod-pci.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-pci.o: $(pci_mod_DEPENDENCIES) pci_mod-bus_pci.o
+	-rm -f $@
+	$(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pci_mod-bus_pci.o
+
+mod-pci.o: mod-pci.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -c -o $@ $<
+
+mod-pci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'pci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(pci_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-pci.lst: pre-pci.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pci/' > $@
+else
+def-pci.lst: pre-pci.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 pci/' > $@
+endif
+endif
+
+und-pci.lst: pre-pci.o
+	echo 'pci' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+pci_mod-bus_pci.o: bus/pci.c $(bus/pci.c_DEPENDENCIES)
+	$(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -MD -c -o $@ $<
+-include pci_mod-bus_pci.d
+
+clean-module-pci_mod-bus_pci-extra.1:
+	rm -f cmd-pci_mod-bus_pci.lst fs-pci_mod-bus_pci.lst partmap-pci_mod-bus_pci.lst handler-pci_mod-bus_pci.lst parttool-pci_mod-bus_pci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-pci_mod-bus_pci-extra.1
+
+COMMANDFILES += cmd-pci_mod-bus_pci.lst
+FSFILES += fs-pci_mod-bus_pci.lst
+PARTTOOLFILES += parttool-pci_mod-bus_pci.lst
+PARTMAPFILES += partmap-pci_mod-bus_pci.lst
+HANDLERFILES += handler-pci_mod-bus_pci.lst
+
+cmd-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh pci > $@ || (rm -f $@; exit 1)
+
+fs-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh pci > $@ || (rm -f $@; exit 1)
+
+parttool-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh pci > $@ || (rm -f $@; exit 1)
+
+partmap-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh pci > $@ || (rm -f $@; exit 1)
+
+handler-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh pci > $@ || (rm -f $@; exit 1)
+
+pci_mod_CFLAGS = $(COMMON_CFLAGS)
+pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lspci.mod
+lspci_mod_SOURCES = commands/lspci.c
+
+clean-module-lspci.mod.1:
+	rm -f lspci.mod mod-lspci.o mod-lspci.c pre-lspci.o lspci_mod-commands_lspci.o und-lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci.mod.1
+
+ifneq ($(lspci_mod_EXPORTS),no)
+clean-module-lspci.mod-symbol.1:
+	rm -f def-lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci.mod-symbol.1
+DEFSYMFILES += def-lspci.lst
+endif
+mostlyclean-module-lspci.mod.1:
+	rm -f lspci_mod-commands_lspci.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-lspci.mod.1
+UNDSYMFILES += und-lspci.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-lspci.o mod-lspci.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-lspci.o mod-lspci.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-lspci.o: $(lspci_mod_DEPENDENCIES) lspci_mod-commands_lspci.o
+	-rm -f $@
+	$(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lspci_mod-commands_lspci.o
+
+mod-lspci.o: mod-lspci.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -c -o $@ $<
+
+mod-lspci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'lspci' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(lspci_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-lspci.lst: pre-lspci.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lspci/' > $@
+else
+def-lspci.lst: pre-lspci.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 lspci/' > $@
+endif
+endif
+
+und-lspci.lst: pre-lspci.o
+	echo 'lspci' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+lspci_mod-commands_lspci.o: commands/lspci.c $(commands/lspci.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -MD -c -o $@ $<
+-include lspci_mod-commands_lspci.d
+
+clean-module-lspci_mod-commands_lspci-extra.1:
+	rm -f cmd-lspci_mod-commands_lspci.lst fs-lspci_mod-commands_lspci.lst partmap-lspci_mod-commands_lspci.lst handler-lspci_mod-commands_lspci.lst parttool-lspci_mod-commands_lspci.lst
+
+CLEAN_MODULE_TARGETS += clean-module-lspci_mod-commands_lspci-extra.1
+
+COMMANDFILES += cmd-lspci_mod-commands_lspci.lst
+FSFILES += fs-lspci_mod-commands_lspci.lst
+PARTTOOLFILES += parttool-lspci_mod-commands_lspci.lst
+PARTMAPFILES += partmap-lspci_mod-commands_lspci.lst
+HANDLERFILES += handler-lspci_mod-commands_lspci.lst
+
+cmd-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh lspci > $@ || (rm -f $@; exit 1)
+
+fs-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh lspci > $@ || (rm -f $@; exit 1)
+
+parttool-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh lspci > $@ || (rm -f $@; exit 1)
+
+partmap-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh lspci > $@ || (rm -f $@; exit 1)
+
+handler-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh lspci > $@ || (rm -f $@; exit 1)
+
+lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/efi/datetime.c
+
+clean-module-datetime.mod.1:
+	rm -f datetime.mod mod-datetime.o mod-datetime.c pre-datetime.o datetime_mod-lib_efi_datetime.o und-datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime.mod.1
+
+ifneq ($(datetime_mod_EXPORTS),no)
+clean-module-datetime.mod-symbol.1:
+	rm -f def-datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime.mod-symbol.1
+DEFSYMFILES += def-datetime.lst
+endif
+mostlyclean-module-datetime.mod.1:
+	rm -f datetime_mod-lib_efi_datetime.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-datetime.mod.1
+UNDSYMFILES += und-datetime.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-datetime.o mod-datetime.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-datetime.o mod-datetime.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-datetime.o: $(datetime_mod_DEPENDENCIES) datetime_mod-lib_efi_datetime.o
+	-rm -f $@
+	$(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datetime_mod-lib_efi_datetime.o
+
+mod-datetime.o: mod-datetime.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -c -o $@ $<
+
+mod-datetime.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'datetime' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(datetime_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-datetime.lst: pre-datetime.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datetime/' > $@
+else
+def-datetime.lst: pre-datetime.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 datetime/' > $@
+endif
+endif
+
+und-datetime.lst: pre-datetime.o
+	echo 'datetime' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+datetime_mod-lib_efi_datetime.o: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES)
+	$(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $<
+-include datetime_mod-lib_efi_datetime.d
+
+clean-module-datetime_mod-lib_efi_datetime-extra.1:
+	rm -f cmd-datetime_mod-lib_efi_datetime.lst fs-datetime_mod-lib_efi_datetime.lst partmap-datetime_mod-lib_efi_datetime.lst handler-datetime_mod-lib_efi_datetime.lst parttool-datetime_mod-lib_efi_datetime.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datetime_mod-lib_efi_datetime-extra.1
+
+COMMANDFILES += cmd-datetime_mod-lib_efi_datetime.lst
+FSFILES += fs-datetime_mod-lib_efi_datetime.lst
+PARTTOOLFILES += parttool-datetime_mod-lib_efi_datetime.lst
+PARTMAPFILES += partmap-datetime_mod-lib_efi_datetime.lst
+HANDLERFILES += handler-datetime_mod-lib_efi_datetime.lst
+
+cmd-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1)
+
+fs-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1)
+
+parttool-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh datetime > $@ || (rm -f $@; exit 1)
+
+partmap-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1)
+
+handler-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh datetime > $@ || (rm -f $@; exit 1)
+
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For date.mod
+date_mod_SOURCES = commands/date.c
+
+clean-module-date.mod.1:
+	rm -f date.mod mod-date.o mod-date.c pre-date.o date_mod-commands_date.o und-date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date.mod.1
+
+ifneq ($(date_mod_EXPORTS),no)
+clean-module-date.mod-symbol.1:
+	rm -f def-date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date.mod-symbol.1
+DEFSYMFILES += def-date.lst
+endif
+mostlyclean-module-date.mod.1:
+	rm -f date_mod-commands_date.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-date.mod.1
+UNDSYMFILES += und-date.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-date.o mod-date.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-date.o mod-date.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-date.o: $(date_mod_DEPENDENCIES) date_mod-commands_date.o
+	-rm -f $@
+	$(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ date_mod-commands_date.o
+
+mod-date.o: mod-date.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -c -o $@ $<
+
+mod-date.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'date' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(date_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-date.lst: pre-date.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 date/' > $@
+else
+def-date.lst: pre-date.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 date/' > $@
+endif
+endif
+
+und-date.lst: pre-date.o
+	echo 'date' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+date_mod-commands_date.o: commands/date.c $(commands/date.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -MD -c -o $@ $<
+-include date_mod-commands_date.d
+
+clean-module-date_mod-commands_date-extra.1:
+	rm -f cmd-date_mod-commands_date.lst fs-date_mod-commands_date.lst partmap-date_mod-commands_date.lst handler-date_mod-commands_date.lst parttool-date_mod-commands_date.lst
+
+CLEAN_MODULE_TARGETS += clean-module-date_mod-commands_date-extra.1
+
+COMMANDFILES += cmd-date_mod-commands_date.lst
+FSFILES += fs-date_mod-commands_date.lst
+PARTTOOLFILES += parttool-date_mod-commands_date.lst
+PARTMAPFILES += partmap-date_mod-commands_date.lst
+HANDLERFILES += handler-date_mod-commands_date.lst
+
+cmd-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh date > $@ || (rm -f $@; exit 1)
+
+fs-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh date > $@ || (rm -f $@; exit 1)
+
+parttool-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh date > $@ || (rm -f $@; exit 1)
+
+partmap-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh date > $@ || (rm -f $@; exit 1)
+
+handler-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh date > $@ || (rm -f $@; exit 1)
+
+date_mod_CFLAGS = $(COMMON_CFLAGS)
+date_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datehook.mod
+datehook_mod_SOURCES = hook/datehook.c
+
+clean-module-datehook.mod.1:
+	rm -f datehook.mod mod-datehook.o mod-datehook.c pre-datehook.o datehook_mod-hook_datehook.o und-datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook.mod.1
+
+ifneq ($(datehook_mod_EXPORTS),no)
+clean-module-datehook.mod-symbol.1:
+	rm -f def-datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook.mod-symbol.1
+DEFSYMFILES += def-datehook.lst
+endif
+mostlyclean-module-datehook.mod.1:
+	rm -f datehook_mod-hook_datehook.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-datehook.mod.1
+UNDSYMFILES += und-datehook.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-datehook.o mod-datehook.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-datehook.o mod-datehook.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-datehook.o: $(datehook_mod_DEPENDENCIES) datehook_mod-hook_datehook.o
+	-rm -f $@
+	$(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datehook_mod-hook_datehook.o
+
+mod-datehook.o: mod-datehook.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -c -o $@ $<
+
+mod-datehook.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'datehook' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(datehook_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-datehook.lst: pre-datehook.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datehook/' > $@
+else
+def-datehook.lst: pre-datehook.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 datehook/' > $@
+endif
+endif
+
+und-datehook.lst: pre-datehook.o
+	echo 'datehook' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+datehook_mod-hook_datehook.o: hook/datehook.c $(hook/datehook.c_DEPENDENCIES)
+	$(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -MD -c -o $@ $<
+-include datehook_mod-hook_datehook.d
+
+clean-module-datehook_mod-hook_datehook-extra.1:
+	rm -f cmd-datehook_mod-hook_datehook.lst fs-datehook_mod-hook_datehook.lst partmap-datehook_mod-hook_datehook.lst handler-datehook_mod-hook_datehook.lst parttool-datehook_mod-hook_datehook.lst
+
+CLEAN_MODULE_TARGETS += clean-module-datehook_mod-hook_datehook-extra.1
+
+COMMANDFILES += cmd-datehook_mod-hook_datehook.lst
+FSFILES += fs-datehook_mod-hook_datehook.lst
+PARTTOOLFILES += parttool-datehook_mod-hook_datehook.lst
+PARTMAPFILES += partmap-datehook_mod-hook_datehook.lst
+HANDLERFILES += handler-datehook_mod-hook_datehook.lst
+
+cmd-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh datehook > $@ || (rm -f $@; exit 1)
+
+fs-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh datehook > $@ || (rm -f $@; exit 1)
+
+parttool-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh datehook > $@ || (rm -f $@; exit 1)
+
+partmap-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh datehook > $@ || (rm -f $@; exit 1)
+
+handler-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh datehook > $@ || (rm -f $@; exit 1)
+
+datehook_mod_CFLAGS = $(COMMON_CFLAGS)
+datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For loadbios.mod
+loadbios_mod_SOURCES = commands/efi/loadbios.c
+
+clean-module-loadbios.mod.1:
+	rm -f loadbios.mod mod-loadbios.o mod-loadbios.c pre-loadbios.o loadbios_mod-commands_efi_loadbios.o und-loadbios.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loadbios.mod.1
+
+ifneq ($(loadbios_mod_EXPORTS),no)
+clean-module-loadbios.mod-symbol.1:
+	rm -f def-loadbios.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loadbios.mod-symbol.1
+DEFSYMFILES += def-loadbios.lst
+endif
+mostlyclean-module-loadbios.mod.1:
+	rm -f loadbios_mod-commands_efi_loadbios.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-loadbios.mod.1
+UNDSYMFILES += und-loadbios.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+loadbios.mod: pre-loadbios.o mod-loadbios.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(loadbios_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-loadbios.o mod-loadbios.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+loadbios.mod: pre-loadbios.o mod-loadbios.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(loadbios_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-loadbios.o mod-loadbios.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-loadbios.o: $(loadbios_mod_DEPENDENCIES) loadbios_mod-commands_efi_loadbios.o
+	-rm -f $@
+	$(TARGET_CC) $(loadbios_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ loadbios_mod-commands_efi_loadbios.o
+
+mod-loadbios.o: mod-loadbios.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -c -o $@ $<
+
+mod-loadbios.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'loadbios' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(loadbios_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-loadbios.lst: pre-loadbios.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 loadbios/' > $@
+else
+def-loadbios.lst: pre-loadbios.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 loadbios/' > $@
+endif
+endif
+
+und-loadbios.lst: pre-loadbios.o
+	echo 'loadbios' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+loadbios_mod-commands_efi_loadbios.o: commands/efi/loadbios.c $(commands/efi/loadbios.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -MD -c -o $@ $<
+-include loadbios_mod-commands_efi_loadbios.d
+
+clean-module-loadbios_mod-commands_efi_loadbios-extra.1:
+	rm -f cmd-loadbios_mod-commands_efi_loadbios.lst fs-loadbios_mod-commands_efi_loadbios.lst partmap-loadbios_mod-commands_efi_loadbios.lst handler-loadbios_mod-commands_efi_loadbios.lst parttool-loadbios_mod-commands_efi_loadbios.lst
+
+CLEAN_MODULE_TARGETS += clean-module-loadbios_mod-commands_efi_loadbios-extra.1
+
+COMMANDFILES += cmd-loadbios_mod-commands_efi_loadbios.lst
+FSFILES += fs-loadbios_mod-commands_efi_loadbios.lst
+PARTTOOLFILES += parttool-loadbios_mod-commands_efi_loadbios.lst
+PARTMAPFILES += partmap-loadbios_mod-commands_efi_loadbios.lst
+HANDLERFILES += handler-loadbios_mod-commands_efi_loadbios.lst
+
+cmd-loadbios_mod-commands_efi_loadbios.lst: commands/efi/loadbios.c $(commands/efi/loadbios.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh loadbios > $@ || (rm -f $@; exit 1)
+
+fs-loadbios_mod-commands_efi_loadbios.lst: commands/efi/loadbios.c $(commands/efi/loadbios.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh loadbios > $@ || (rm -f $@; exit 1)
+
+parttool-loadbios_mod-commands_efi_loadbios.lst: commands/efi/loadbios.c $(commands/efi/loadbios.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh loadbios > $@ || (rm -f $@; exit 1)
+
+partmap-loadbios_mod-commands_efi_loadbios.lst: commands/efi/loadbios.c $(commands/efi/loadbios.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh loadbios > $@ || (rm -f $@; exit 1)
+
+handler-loadbios_mod-commands_efi_loadbios.lst: commands/efi/loadbios.c $(commands/efi/loadbios.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(loadbios_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh loadbios > $@ || (rm -f $@; exit 1)
+
+loadbios_mod_CFLAGS = $(COMMON_CFLAGS)
+loadbios_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For fixvideo.mod
+fixvideo_mod_SOURCES = commands/efi/fixvideo.c
+
+clean-module-fixvideo.mod.1:
+	rm -f fixvideo.mod mod-fixvideo.o mod-fixvideo.c pre-fixvideo.o fixvideo_mod-commands_efi_fixvideo.o und-fixvideo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fixvideo.mod.1
+
+ifneq ($(fixvideo_mod_EXPORTS),no)
+clean-module-fixvideo.mod-symbol.1:
+	rm -f def-fixvideo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fixvideo.mod-symbol.1
+DEFSYMFILES += def-fixvideo.lst
+endif
+mostlyclean-module-fixvideo.mod.1:
+	rm -f fixvideo_mod-commands_efi_fixvideo.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-fixvideo.mod.1
+UNDSYMFILES += und-fixvideo.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+fixvideo.mod: pre-fixvideo.o mod-fixvideo.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(fixvideo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-fixvideo.o mod-fixvideo.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+fixvideo.mod: pre-fixvideo.o mod-fixvideo.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(fixvideo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-fixvideo.o mod-fixvideo.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-fixvideo.o: $(fixvideo_mod_DEPENDENCIES) fixvideo_mod-commands_efi_fixvideo.o
+	-rm -f $@
+	$(TARGET_CC) $(fixvideo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ fixvideo_mod-commands_efi_fixvideo.o
+
+mod-fixvideo.o: mod-fixvideo.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -c -o $@ $<
+
+mod-fixvideo.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'fixvideo' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(fixvideo_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-fixvideo.lst: pre-fixvideo.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fixvideo/' > $@
+else
+def-fixvideo.lst: pre-fixvideo.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 fixvideo/' > $@
+endif
+endif
+
+und-fixvideo.lst: pre-fixvideo.o
+	echo 'fixvideo' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+fixvideo_mod-commands_efi_fixvideo.o: commands/efi/fixvideo.c $(commands/efi/fixvideo.c_DEPENDENCIES)
+	$(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -MD -c -o $@ $<
+-include fixvideo_mod-commands_efi_fixvideo.d
+
+clean-module-fixvideo_mod-commands_efi_fixvideo-extra.1:
+	rm -f cmd-fixvideo_mod-commands_efi_fixvideo.lst fs-fixvideo_mod-commands_efi_fixvideo.lst partmap-fixvideo_mod-commands_efi_fixvideo.lst handler-fixvideo_mod-commands_efi_fixvideo.lst parttool-fixvideo_mod-commands_efi_fixvideo.lst
+
+CLEAN_MODULE_TARGETS += clean-module-fixvideo_mod-commands_efi_fixvideo-extra.1
+
+COMMANDFILES += cmd-fixvideo_mod-commands_efi_fixvideo.lst
+FSFILES += fs-fixvideo_mod-commands_efi_fixvideo.lst
+PARTTOOLFILES += parttool-fixvideo_mod-commands_efi_fixvideo.lst
+PARTMAPFILES += partmap-fixvideo_mod-commands_efi_fixvideo.lst
+HANDLERFILES += handler-fixvideo_mod-commands_efi_fixvideo.lst
+
+cmd-fixvideo_mod-commands_efi_fixvideo.lst: commands/efi/fixvideo.c $(commands/efi/fixvideo.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh fixvideo > $@ || (rm -f $@; exit 1)
+
+fs-fixvideo_mod-commands_efi_fixvideo.lst: commands/efi/fixvideo.c $(commands/efi/fixvideo.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh fixvideo > $@ || (rm -f $@; exit 1)
+
+parttool-fixvideo_mod-commands_efi_fixvideo.lst: commands/efi/fixvideo.c $(commands/efi/fixvideo.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh fixvideo > $@ || (rm -f $@; exit 1)
+
+partmap-fixvideo_mod-commands_efi_fixvideo.lst: commands/efi/fixvideo.c $(commands/efi/fixvideo.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh fixvideo > $@ || (rm -f $@; exit 1)
+
+handler-fixvideo_mod-commands_efi_fixvideo.lst: commands/efi/fixvideo.c $(commands/efi/fixvideo.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Icommands/efi -I$(srcdir)/commands/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fixvideo_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh fixvideo > $@ || (rm -f $@; exit 1)
+
+fixvideo_mod_CFLAGS = $(COMMON_CFLAGS)
+fixvideo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += xnu.mod
+xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\
+	 loader/macho.c loader/xnu.c loader/i386/xnu_helper.S
+
+clean-module-xnu.mod.1:
+	rm -f xnu.mod mod-xnu.o mod-xnu.c pre-xnu.o xnu_mod-loader_xnu_resume.o xnu_mod-loader_i386_xnu.o xnu_mod-loader_i386_efi_xnu.o xnu_mod-loader_macho.o xnu_mod-loader_xnu.o xnu_mod-loader_i386_xnu_helper.o und-xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu.mod.1
+
+ifneq ($(xnu_mod_EXPORTS),no)
+clean-module-xnu.mod-symbol.1:
+	rm -f def-xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu.mod-symbol.1
+DEFSYMFILES += def-xnu.lst
+endif
+mostlyclean-module-xnu.mod.1:
+	rm -f xnu_mod-loader_xnu_resume.d xnu_mod-loader_i386_xnu.d xnu_mod-loader_i386_efi_xnu.d xnu_mod-loader_macho.d xnu_mod-loader_xnu.d xnu_mod-loader_i386_xnu_helper.d
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-xnu.mod.1
+UNDSYMFILES += und-xnu.lst
+
+ifneq ($(TARGET_APPLE_CC),1)
+xnu.mod: pre-xnu.o mod-xnu.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(xnu_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-xnu.o mod-xnu.o
+	if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+xnu.mod: pre-xnu.o mod-xnu.o $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(xnu_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-xnu.o mod-xnu.o
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+pre-xnu.o: $(xnu_mod_DEPENDENCIES) xnu_mod-loader_xnu_resume.o xnu_mod-loader_i386_xnu.o xnu_mod-loader_i386_efi_xnu.o xnu_mod-loader_macho.o xnu_mod-loader_xnu.o xnu_mod-loader_i386_xnu_helper.o
+	-rm -f $@
+	$(TARGET_CC) $(xnu_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ xnu_mod-loader_xnu_resume.o xnu_mod-loader_i386_xnu.o xnu_mod-loader_i386_efi_xnu.o xnu_mod-loader_macho.o xnu_mod-loader_xnu.o xnu_mod-loader_i386_xnu_helper.o
+
+mod-xnu.o: mod-xnu.c
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -c -o $@ $<
+
+mod-xnu.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'xnu' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(xnu_mod_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+def-xnu.lst: pre-xnu.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 xnu/' > $@
+else
+def-xnu.lst: pre-xnu.o
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\([^ ]*\).*/\1 xnu/' > $@
+endif
+endif
+
+und-xnu.lst: pre-xnu.o
+	echo 'xnu' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+xnu_mod-loader_xnu_resume.o: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_xnu_resume.d
+
+clean-module-xnu_mod-loader_xnu_resume-extra.1:
+	rm -f cmd-xnu_mod-loader_xnu_resume.lst fs-xnu_mod-loader_xnu_resume.lst partmap-xnu_mod-loader_xnu_resume.lst handler-xnu_mod-loader_xnu_resume.lst parttool-xnu_mod-loader_xnu_resume.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_xnu_resume-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_xnu_resume.lst
+FSFILES += fs-xnu_mod-loader_xnu_resume.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_xnu_resume.lst
+PARTMAPFILES += partmap-xnu_mod-loader_xnu_resume.lst
+HANDLERFILES += handler-xnu_mod-loader_xnu_resume.lst
+
+cmd-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_xnu_resume.lst: loader/xnu_resume.c $(loader/xnu_resume.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_i386_xnu.o: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_i386_xnu.d
+
+clean-module-xnu_mod-loader_i386_xnu-extra.1:
+	rm -f cmd-xnu_mod-loader_i386_xnu.lst fs-xnu_mod-loader_i386_xnu.lst partmap-xnu_mod-loader_i386_xnu.lst handler-xnu_mod-loader_i386_xnu.lst parttool-xnu_mod-loader_i386_xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_i386_xnu-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_i386_xnu.lst
+FSFILES += fs-xnu_mod-loader_i386_xnu.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_i386_xnu.lst
+PARTMAPFILES += partmap-xnu_mod-loader_i386_xnu.lst
+HANDLERFILES += handler-xnu_mod-loader_i386_xnu.lst
+
+cmd-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_i386_xnu.lst: loader/i386/xnu.c $(loader/i386/xnu.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_i386_efi_xnu.o: loader/i386/efi/xnu.c $(loader/i386/efi/xnu.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_i386_efi_xnu.d
+
+clean-module-xnu_mod-loader_i386_efi_xnu-extra.1:
+	rm -f cmd-xnu_mod-loader_i386_efi_xnu.lst fs-xnu_mod-loader_i386_efi_xnu.lst partmap-xnu_mod-loader_i386_efi_xnu.lst handler-xnu_mod-loader_i386_efi_xnu.lst parttool-xnu_mod-loader_i386_efi_xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_i386_efi_xnu-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_i386_efi_xnu.lst
+FSFILES += fs-xnu_mod-loader_i386_efi_xnu.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_i386_efi_xnu.lst
+PARTMAPFILES += partmap-xnu_mod-loader_i386_efi_xnu.lst
+HANDLERFILES += handler-xnu_mod-loader_i386_efi_xnu.lst
+
+cmd-xnu_mod-loader_i386_efi_xnu.lst: loader/i386/efi/xnu.c $(loader/i386/efi/xnu.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_i386_efi_xnu.lst: loader/i386/efi/xnu.c $(loader/i386/efi/xnu.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_i386_efi_xnu.lst: loader/i386/efi/xnu.c $(loader/i386/efi/xnu.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_i386_efi_xnu.lst: loader/i386/efi/xnu.c $(loader/i386/efi/xnu.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_i386_efi_xnu.lst: loader/i386/efi/xnu.c $(loader/i386/efi/xnu.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_macho.o: loader/macho.c $(loader/macho.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_macho.d
+
+clean-module-xnu_mod-loader_macho-extra.1:
+	rm -f cmd-xnu_mod-loader_macho.lst fs-xnu_mod-loader_macho.lst partmap-xnu_mod-loader_macho.lst handler-xnu_mod-loader_macho.lst parttool-xnu_mod-loader_macho.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_macho-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_macho.lst
+FSFILES += fs-xnu_mod-loader_macho.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_macho.lst
+PARTMAPFILES += partmap-xnu_mod-loader_macho.lst
+HANDLERFILES += handler-xnu_mod-loader_macho.lst
+
+cmd-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_macho.lst: loader/macho.c $(loader/macho.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_xnu.o: loader/xnu.c $(loader/xnu.c_DEPENDENCIES)
+	$(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_xnu.d
+
+clean-module-xnu_mod-loader_xnu-extra.1:
+	rm -f cmd-xnu_mod-loader_xnu.lst fs-xnu_mod-loader_xnu.lst partmap-xnu_mod-loader_xnu.lst handler-xnu_mod-loader_xnu.lst parttool-xnu_mod-loader_xnu.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_xnu-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_xnu.lst
+FSFILES += fs-xnu_mod-loader_xnu.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_xnu.lst
+PARTMAPFILES += partmap-xnu_mod-loader_xnu.lst
+HANDLERFILES += handler-xnu_mod-loader_xnu.lst
+
+cmd-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_xnu.lst: loader/xnu.c $(loader/xnu.c_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(xnu_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod-loader_i386_xnu_helper.o: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES)
+	$(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -MD -c -o $@ $<
+-include xnu_mod-loader_i386_xnu_helper.d
+
+clean-module-xnu_mod-loader_i386_xnu_helper-extra.1:
+	rm -f cmd-xnu_mod-loader_i386_xnu_helper.lst fs-xnu_mod-loader_i386_xnu_helper.lst partmap-xnu_mod-loader_i386_xnu_helper.lst handler-xnu_mod-loader_i386_xnu_helper.lst parttool-xnu_mod-loader_i386_xnu_helper.lst
+
+CLEAN_MODULE_TARGETS += clean-module-xnu_mod-loader_i386_xnu_helper-extra.1
+
+COMMANDFILES += cmd-xnu_mod-loader_i386_xnu_helper.lst
+FSFILES += fs-xnu_mod-loader_i386_xnu_helper.lst
+PARTTOOLFILES += parttool-xnu_mod-loader_i386_xnu_helper.lst
+PARTMAPFILES += partmap-xnu_mod-loader_i386_xnu_helper.lst
+HANDLERFILES += handler-xnu_mod-loader_i386_xnu_helper.lst
+
+cmd-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) gencmdlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+fs-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) genfslist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh xnu > $@ || (rm -f $@; exit 1)
+
+parttool-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) genparttoollist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genparttoollist.sh xnu > $@ || (rm -f $@; exit 1)
+
+partmap-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) genpartmaplist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genpartmaplist.sh xnu > $@ || (rm -f $@; exit 1)
+
+handler-xnu_mod-loader_i386_xnu_helper.lst: loader/i386/xnu_helper.S $(loader/i386/xnu_helper.S_DEPENDENCIES) genhandlerlist.sh
+	set -e; 	  $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(xnu_mod_ASFLAGS) -E $< 	  | sh $(srcdir)/genhandlerlist.sh xnu > $@ || (rm -f $@; exit 1)
+
+xnu_mod_CFLAGS = $(COMMON_CFLAGS)
+xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+include $(srcdir)/conf/common.mk
+grub-mkimage: $(grub_mkimage_DEPENDENCIES) $(grub_mkimage_OBJECTS)
+	$(CC) -o $@ $(grub_mkimage_OBJECTS) $(LDFLAGS) $(grub_mkimage_LDFLAGS)
+
+grub-mkdevicemap: $(grub_mkdevicemap_DEPENDENCIES) $(grub_mkdevicemap_OBJECTS)
+	$(CC) -o $@ $(grub_mkdevicemap_OBJECTS) $(LDFLAGS) $(grub_mkdevicemap_LDFLAGS)
+
diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk
new file mode 100644
index 0000000..5be1b40
--- /dev/null
+++ b/conf/x86_64-efi.rmk
@@ -0,0 +1,206 @@
+# -*- makefile -*-
+
+COMMON_ASFLAGS = -nostdinc -fno-builtin -m64
+COMMON_CFLAGS = -fno-builtin -m64
+COMMON_LDFLAGS = -melf_x86_64 -nostdlib
+
+# Used by various components.  These rules need to precede them.
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+# Utilities.
+bin_UTILITIES = grub-mkimage
+sbin_UTILITIES = grub-mkdevicemap
+#ifeq ($(enable_grub_emu), yes)
+#sbin_UTILITIES += grub-emu
+#endif
+
+# For grub-mkimage.
+grub_mkimage_SOURCES = util/i386/efi/grub-mkimage.c util/misc.c \
+	util/resolve.c
+
+# For grub-setup.
+#grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c	\
+#	util/misc.c util/getroot.c kern/device.c kern/disk.c	\
+#	kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c	\
+#	fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c		\
+#	fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c	\
+#	kern/fs.c kern/env.c fs/fshelp.c
+
+# For grub-mkdevicemap.
+grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
+	util/devicemap.c util/misc.c
+
+# For grub-emu.
+util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
+grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c 	\
+	commands/configfile.c commands/help.c				\
+	commands/handler.c commands/ls.c commands/test.c 		\
+	commands/search.c commands/hexdump.c lib/hexdump.c		\
+	commands/halt.c commands/reboot.c				\
+	commands/i386/cpuid.c						\
+	commands/password.c commands/keystatus.c			\
+	lib/envblk.c commands/loadenv.c					\
+	disk/loopback.c							\
+	\
+	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c			\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c			\
+	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c					\
+	\
+	io/gzio.c							\
+	kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c	\
+	kern/err.c kern/list.c kern/handler.c				\
+	kern/command.c kern/corecmd.c commands/extcmd.c kern/file.c 	\
+	kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c	\
+	kern/partition.c kern/readerescue.c kern/term.c			\
+	lib/arg.c normal/cmdline.c normal/misc.c normal/auth.c		\
+	normal/autofs.c	\
+	normal/completion.c normal/datetime.c normal/context.c 		\
+	normal/main.c		\
+	normal/menu.c normal/menu_entry.c normal/menu_viewer.c		\
+	normal/menu_text.c						\
+	normal/color.c							\
+	script/sh/main.c script/sh/execute.c script/sh/function.c	\
+	script/sh/lexer.c script/sh/script.c grub_script.tab.c		\
+	partmap/amiga.c	partmap/apple.c partmap/msdos.c partmap/sun.c	\
+	partmap/acorn.c partmap/gpt.c					\
+	util/console.c util/hostfs.c util/grub-emu.c util/misc.c	\
+	util/hostdisk.c util/getroot.c					\
+	\
+	disk/raid.c disk/raid5_recover.c disk/raid6_recover.c		\
+	disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c		\
+	commands/parttool.c parttool/msdospart.c				\
+	grub_emu_init.c
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/i386/efi/grub-install.in
+
+# Modules.
+pkglib_MODULES = kernel.mod chain.mod appleldr.mod \
+	halt.mod reboot.mod linux.mod pci.mod lspci.mod \
+	datetime.mod date.mod datehook.mod loadbios.mod \
+	fixvideo.mod mmap.mod acpi.mod
+
+# For kernel.mod.
+kernel_mod_EXPORTS = no
+kernel_mod_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \
+	kern/main.c kern/device.c \
+	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+	kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+	kern/rescue_parser.c kern/rescue_reader.c \
+	kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
+	kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
+	kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+	kern/i386/tsc.c kern/i386/pit.c \
+	kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c \
+	term/efi/console.c disk/efi/efidisk.c
+kernel_mod_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
+	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
+	partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
+	efi/efi.h efi/time.h efi/disk.h machine/loader.h i386/pit.h list.h \
+	handler.h command.h
+kernel_mod_CFLAGS = $(COMMON_CFLAGS)
+kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+MOSTLYCLEANFILES += symlist.c
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.sh
+	/bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh
+	/bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# For boot.mod.
+pkglib_MODULES += boot.mod 
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For acpi.mod.
+acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c
+acpi_mod_CFLAGS = $(COMMON_CFLAGS)
+acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
+		   mmap/efi/mmap.c
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For chain.mod.
+chain_mod_SOURCES = loader/efi/chainloader.c
+chain_mod_CFLAGS = $(COMMON_CFLAGS)
+chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For appleldr.mod.
+appleldr_mod_SOURCES = loader/efi/appleloader.c
+appleldr_mod_CFLAGS = $(COMMON_CFLAGS)
+appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/i386/efi/linux.c loader/i386/linux_trampoline.S
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod.
+reboot_mod_SOURCES = commands/reboot.c
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pci.mod
+pci_mod_SOURCES = bus/pci.c
+pci_mod_CFLAGS = $(COMMON_CFLAGS)
+pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lspci.mod
+lspci_mod_SOURCES = commands/lspci.c
+lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/efi/datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For date.mod
+date_mod_SOURCES = commands/date.c
+date_mod_CFLAGS = $(COMMON_CFLAGS)
+date_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datehook.mod
+datehook_mod_SOURCES = hook/datehook.c
+datehook_mod_CFLAGS = $(COMMON_CFLAGS)
+datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For loadbios.mod
+loadbios_mod_SOURCES = commands/efi/loadbios.c
+loadbios_mod_CFLAGS = $(COMMON_CFLAGS)
+loadbios_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For fixvideo.mod
+fixvideo_mod_SOURCES = commands/efi/fixvideo.c
+fixvideo_mod_CFLAGS = $(COMMON_CFLAGS)
+fixvideo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += xnu.mod
+xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\
+	 loader/macho.c loader/xnu.c loader/i386/xnu_helper.S
+xnu_mod_CFLAGS = $(COMMON_CFLAGS)
+xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+include $(srcdir)/conf/common.mk
diff --git a/config.guess b/config.guess
new file mode 100644
index 0000000..e792aac
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,1494 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
+
+timestamp='2009-09-18'
+
+# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner.  Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+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="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep -q __ELF__
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[456])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:[3456]*)
+    	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    EM64T | authenticamd | genuineintel)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-gnu
+	else
+	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	echo ${UNAME_MACHINE}-pc-linux-gnu
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-gnu
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    xtensa*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    i386)
+		eval $set_cc_for_build
+		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		      grep IS_64BIT_ARCH >/dev/null
+		  then
+		      UNAME_PROCESSOR="x86_64"
+		  fi
+		fi ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..ba26cd6
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,143 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define it if GAS requires that absolute indirect calls/jumps are not
+   prefixed with an asterisk */
+#undef ABSOLUTE_WITHOUT_ASTERISK
+
+/* Define it to \"addr32\" or \"addr32;\" to make GAS happy */
+#undef ADDR32
+
+/* Define it to one of __bss_start, edata and _edata */
+#undef BSS_START_SYMBOL
+
+/* Define it to \"data32\" or \"data32;\" to make GAS happy */
+#undef DATA32
+
+/* Define it to either end or _end */
+#undef END_SYMBOL
+
+/* Define if C symbols get an underscore after compilation */
+#undef HAVE_ASM_USCORE
+
+/* Define to 1 if you have the `asprintf' function. */
+#undef HAVE_ASPRINTF
+
+/* Define to 1 if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `memalign' function. */
+#undef HAVE_MEMALIGN
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <ncurses/curses.h> header file. */
+#undef HAVE_NCURSES_CURSES_H
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#undef HAVE_NCURSES_H
+
+/* Define to 1 if you have the `posix_memalign' function. */
+#undef HAVE_POSIX_MEMALIGN
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <usb.h> header file. */
+#undef HAVE_USB_H
+
+/* Define to 1 if you have the `__ashldi3' function. */
+#undef HAVE___ASHLDI3
+
+/* Define to 1 if you have the `__ashrdi3' function. */
+#undef HAVE___ASHRDI3
+
+/* Define to 1 if you have the `__bswapdi2' function. */
+#undef HAVE___BSWAPDI2
+
+/* Define to 1 if you have the `__bswapsi2' function. */
+#undef HAVE___BSWAPSI2
+
+/* Define to 1 if you have the `__lshrdi3' function. */
+#undef HAVE___LSHRDI3
+
+/* Define to 1 if you have the `__trampoline_setup' function. */
+#undef HAVE___TRAMPOLINE_SETUP
+
+/* Define to 1 if you have the `__ucmpdi2' function. */
+#undef HAVE___UCMPDI2
+
+/* Define to 1 if you enable memory manager debugging. */
+#undef MM_DEBUG
+
+/* Define to 1 if GCC generates calls to __enable_execute_stack() */
+#undef NEED_ENABLE_EXECUTE_STACK
+
+/* Catch gcc bug */
+#undef NESTED_FUNC_ATTR
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `void *', as computed by sizeof. */
+#undef SIZEOF_VOID_P
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+#if defined(__i386__) && !defined(GRUB_UTIL)
+#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1)))
+#else
+#define NESTED_FUNC_ATTR
+#endif
diff --git a/config.sub b/config.sub
new file mode 100644
index 0000000..5ecc18b
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,1700 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
+
+timestamp='2009-10-07'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+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="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze)
+		os=
+		basic_machine=$1
+		;;
+        -bluegene*)
+	        os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+        cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+        microblaze)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tile*)
+		basic_machine=tile-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -kopensolaris* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+        mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure b/configure
new file mode 100755
index 0000000..f9fe745
--- /dev/null
+++ b/configure
@@ -0,0 +1,10046 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.61 for GRUB 1.97.
+#
+# Report bugs to <bug-grub@gnu.org>.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+  if (eval ":") 2>/dev/null; then
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+
+  if test $as_have_required = yes && 	 (eval ":
+(as_func_return () {
+  (exit \$1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+  as_lineno_1=\$LINENO
+  as_lineno_2=\$LINENO
+  test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+  test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+  :
+else
+  as_candidate_shells=
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  case $as_dir in
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+	   done;;
+       esac
+done
+IFS=$as_save_IFS
+
+
+      for as_shell in $as_candidate_shells $SHELL; do
+	 # Try only shells that exist, to save several forks.
+	 if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		{ ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+  CONFIG_SHELL=$as_shell
+	       as_have_required=yes
+	       if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+  (exit $1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+  break
+fi
+
+fi
+
+      done
+
+      if test "x$CONFIG_SHELL" != x; then
+  for as_var in BASH_ENV ENV
+        do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+        done
+        export CONFIG_SHELL
+        exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+    if test $as_have_required = no; then
+  echo This script requires a shell more modern than all the
+      echo shells that I found on your system.  Please install a
+      echo modern shell, or manually run the script under such a
+      echo shell if you do have one.
+      { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+  (exit \$1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+  echo No shell found that supports shell functions.
+  echo Please tell autoconf@gnu.org about your system,
+  echo including any error possibly output before this
+  echo message
+}
+
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line after each line using $LINENO; the second 'sed'
+  # does the real work.  The second script uses 'N' to pair each
+  # line-number line with the line containing $LINENO, and appends
+  # trailing '-' during substitution so that $LINENO is not a special
+  # case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # scripts with optimization help from Paolo Bonzini.  Blame Lee
+  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+  case `echo 'x\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  *)   ECHO_C='\c';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s='ln -s'
+  # ... but there are two gotchas:
+  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+  # In both cases, we have to default to `cp -p'.
+  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+    as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+        test -d "$1/.";
+      else
+	case $1 in
+        -*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME='GRUB'
+PACKAGE_TARNAME='grub'
+PACKAGE_VERSION='1.97'
+PACKAGE_STRING='GRUB 1.97'
+PACKAGE_BUGREPORT='bug-grub@gnu.org'
+
+ac_unique_file="include/grub/dl.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL
+PATH_SEPARATOR
+PACKAGE_NAME
+PACKAGE_TARNAME
+PACKAGE_VERSION
+PACKAGE_STRING
+PACKAGE_BUGREPORT
+exec_prefix
+prefix
+program_transform_name
+bindir
+sbindir
+libexecdir
+datarootdir
+datadir
+sysconfdir
+sharedstatedir
+localstatedir
+includedir
+oldincludedir
+docdir
+infodir
+htmldir
+dvidir
+pdfdir
+psdir
+libdir
+localedir
+mandir
+DEFS
+ECHO_C
+ECHO_N
+ECHO_T
+LIBS
+build_alias
+host_alias
+target_alias
+build
+build_cpu
+build_vendor
+build_os
+host
+host_cpu
+host_vendor
+host_os
+target
+target_cpu
+target_vendor
+target_os
+host_kernel
+platform
+CMP
+YACC
+UNIFONT_BDF
+INSTALL_PROGRAM
+INSTALL_SCRIPT
+INSTALL_DATA
+AWK
+SET_MAKE
+RUBY
+MAKEINFO
+CC
+CFLAGS
+LDFLAGS
+CPPFLAGS
+ac_ct_CC
+EXEEXT
+OBJEXT
+CPP
+GREP
+EGREP
+HELP2MAN
+TARGET_CC
+ac_ct_TARGET_CC
+OBJCOPY
+STRIP
+NM
+OBJCONV
+TARGET_IMG_LDSCRIPT
+TARGET_IMG_LDFLAGS
+TARGET_IMG_CFLAGS
+TARGET_OBJ2ELF
+TARGET_CFLAGS
+TARGET_MODULE_FORMAT
+TARGET_APPLE_CC
+TARGET_ASFLAGS
+TARGET_CPPFLAGS
+TARGET_LDFLAGS
+enable_efiemu
+LIBCURSES
+LIBUSB
+enable_grub_emu
+enable_grub_emu_usb
+enable_grub_fstest
+FREETYPE
+enable_grub_mkfont
+freetype_cflags
+freetype_libs
+ASFLAGS
+LIBOBJS
+LTLIBOBJS'
+ac_subst_files=''
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)	ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+    eval enable_$ac_feature=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
+    eval enable_$ac_feature=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+    eval with_$ac_package=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
+    eval with_$ac_package=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute directory names.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  { echo "$as_me: error: Working directory cannot be determined" >&2
+   { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  { echo "$as_me: error: pwd does not report name of working directory" >&2
+   { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$0" ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
+   { (exit 1); exit 1; }; }
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures GRUB 1.97 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR          info documentation [DATAROOTDIR/info]
+  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR           man documentation [DATAROOTDIR/man]
+  --docdir=DIR           documentation root [DATAROOTDIR/doc/grub]
+  --htmldir=DIR          html documentation [DOCDIR]
+  --dvidir=DIR           dvi documentation [DOCDIR]
+  --pdfdir=DIR           pdf documentation [DOCDIR]
+  --psdir=DIR            ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of GRUB 1.97:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-largefile     omit support for large files
+  --disable-werror        do not use -Werror when building GRUB
+  --enable-efiemu         build and install the efiemu runtimes
+                          (default=guessed)
+  --enable-mm-debug       include memory manager debugging
+  --enable-grub-emu       build and install the `grub-emu' debugging utility
+                          (default=guessed)
+  --enable-grub-emu-usb   build and install the `grub-emu' debugging utility
+                          with USB support (default=guessed)
+  --enable-grub-fstest    build and install the `grub-fstest' debugging
+                          utility (default=guessed)
+  --enable-grub-mkfont    build and install the `grub-mkfont' utility
+                          (default=guessed)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-platform=PLATFORM
+                          select the host platform [guessed]
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <bug-grub@gnu.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" || continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+GRUB configure 1.97
+generated by GNU Autoconf 2.61
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by GRUB $as_me 1.97, which was
+generated by GNU Autoconf 2.61.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args '$ac_arg'"
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      *) $as_unset $ac_var ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -n "$CONFIG_SITE"; then
+  set x "$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+  set x "$prefix/share/config.site" "$prefix/etc/config.site"
+else
+  set x "$ac_default_prefix/share/config.site" \
+	"$ac_default_prefix/etc/config.site"
+fi
+shift
+for ac_site_file
+do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+# Checks for host and target systems.
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
+echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+{ echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6; }
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
+echo "$as_me: error: invalid value of canonical build" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6; }
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
+echo "$as_me: error: invalid value of canonical host" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6; }
+if test "${ac_cv_target+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "x$target_alias" = x; then
+  ac_cv_target=$ac_cv_host
+else
+  ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+    { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5
+echo "$as_me: error: invalid value of canonical target" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+# Program name transformations
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.  echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm -f conftest.sed
+
+
+case "$target_cpu" in
+  i[3456]86)	target_cpu=i386 ;;
+  sparc)	target_cpu=sparc64 ;;
+esac
+
+# Specify the platform (such as firmware).
+
+# Check whether --with-platform was given.
+if test "${with_platform+set}" = set; then
+  withval=$with_platform;
+fi
+
+
+# Guess the platform if not specified.
+if test "x$with_platform" = x; then
+  case "$target_cpu"-"$target_vendor" in
+    i386-apple) platform=efi ;;
+    i386-*) platform=pc ;;
+    x86_64-apple) platform=efi ;;
+    x86_64-*) platform=pc ;;
+    powerpc-*) platform=ieee1275 ;;
+    powerpc64-*) platform=ieee1275 ;;
+    sparc64-*) platform=ieee1275 ;;
+    *) { { echo "$as_me:$LINENO: error: unsupported CPU: \"$target_cpu\"" >&5
+echo "$as_me: error: unsupported CPU: \"$target_cpu\"" >&2;}
+   { (exit 1); exit 1; }; } ;;
+  esac
+else
+  platform="$with_platform"
+fi
+
+# Adjust CPU unless target was explicitly specified.
+if test -z "$target_alias"; then
+  case "$target_cpu"-"$platform" in
+    x86_64-efi) ;;
+    x86_64-*) target_cpu=i386 ;;
+    powerpc64-ieee1275) target_cpu=powerpc ;;
+  esac
+fi
+
+# Check if the platform is supported, make final adjustments.
+case "$target_cpu"-"$platform" in
+  i386-efi) ;;
+  x86_64-efi) ;;
+  i386-pc) ;;
+  i386-coreboot) ;;
+  i386-linuxbios) platform=coreboot ;;
+  i386-ieee1275) ;;
+  i386-qemu) ;;
+  powerpc-ieee1275) ;;
+  sparc64-ieee1275) ;;
+  *) { { echo "$as_me:$LINENO: error: platform \"$platform\" is not supported for target CPU \"$target_cpu\"" >&5
+echo "$as_me: error: platform \"$platform\" is not supported for target CPU \"$target_cpu\"" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+case "$target_cpu" in
+  i386 | powerpc) target_m32=1 ;;
+  x86_64 | sparc64) target_m64=1 ;;
+esac
+
+case "$host_os" in
+  mingw32) host_os=cygwin ;;
+esac
+
+# This normalizes the names, and creates a new variable ("host_kernel")
+# while at it, since the mapping is not always 1:1 (e.g. different OSes
+# using the same kernel type).
+case "$host_os" in
+  gnu*)				host_kernel=hurd ;;
+  linux*)			host_kernel=linux ;;
+  freebsd* | kfreebsd*-gnu)	host_kernel=freebsd ;;
+  cygwin)			host_kernel=windows ;;
+esac
+
+
+
+
+
+
+
+
+#
+# Checks for build programs.
+#
+
+# Although cmp is listed in the GNU Coding Standards as a command which
+# can used directly, OpenBSD lacks cmp in the default installation.
+for ac_prog in cmp
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CMP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CMP"; then
+  ac_cv_prog_CMP="$CMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CMP="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CMP=$ac_cv_prog_CMP
+if test -n "$CMP"; then
+  { echo "$as_me:$LINENO: result: $CMP" >&5
+echo "${ECHO_T}$CMP" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$CMP" && break
+done
+
+if test "x$CMP" = x; then
+  { { echo "$as_me:$LINENO: error: cmp is not found" >&5
+echo "$as_me: error: cmp is not found" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+for ac_prog in bison
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_YACC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_YACC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+  { echo "$as_me:$LINENO: result: $YACC" >&5
+echo "${ECHO_T}$YACC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$YACC" && break
+done
+
+if test "x$YACC" = x; then
+  { { echo "$as_me:$LINENO: error: bison is not found" >&5
+echo "$as_me: error: bison is not found" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+for file in /usr/src/unifont.bdf ; do
+  if test -e $file ; then
+    UNIFONT_BDF=$file
+
+    break
+  fi
+done
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+done
+IFS=$as_save_IFS
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; }
+set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+  SET_MAKE=
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+{ echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5
+echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; }
+if test -z "$MKDIR_P"; then
+  if test "${ac_cv_path_mkdir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+done
+IFS=$as_save_IFS
+
+fi
+
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    test -d ./--version && rmdir ./--version
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ echo "$as_me:$LINENO: result: $MKDIR_P" >&5
+echo "${ECHO_T}$MKDIR_P" >&6; }
+
+
+# These are not a "must".
+# Extract the first word of "ruby", so it can be a program name with args.
+set dummy ruby; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_RUBY+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $RUBY in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_RUBY="$RUBY" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_RUBY="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+RUBY=$ac_cv_path_RUBY
+if test -n "$RUBY"; then
+  { echo "$as_me:$LINENO: result: $RUBY" >&5
+echo "${ECHO_T}$RUBY" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+# Extract the first word of "makeinfo", so it can be a program name with args.
+set dummy makeinfo; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_MAKEINFO+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAKEINFO in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MAKEINFO="$MAKEINFO" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_MAKEINFO="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+MAKEINFO=$ac_cv_path_MAKEINFO
+if test -n "$MAKEINFO"; then
+  { echo "$as_me:$LINENO: result: $MAKEINFO" >&5
+echo "${ECHO_T}$MAKEINFO" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+
+#
+# Checks for host programs.
+#
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler --version >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -v >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -V >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+#
+# List of possible output files, starting from the most likely.
+# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
+# only as a last resort.  b.out is created by i960 compilers.
+ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
+#
+# The IRIX 6 linker writes into existing files which may not be
+# executable, retaining their permissions.  Remove them first so a
+# subsequent execution test works.
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+        if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+
+{ echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6; }
+if test -z "$ac_file"; then
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+{ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6; }
+
+{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	CFLAGS=""
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main (void)
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_prog_cc_c89=$ac_arg
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6; } ;;
+  xno)
+    { echo "$as_me:$LINENO: result: unsupported" >&5
+echo "${ECHO_T}unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+# Must be GCC.
+test "x$GCC" = xyes || { { echo "$as_me:$LINENO: error: GCC is required" >&5
+echo "$as_me: error: GCC is required" >&2;}
+   { (exit 1); exit 1; }; }
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _GNU_SOURCE 1
+_ACEOF
+
+
+
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then
+  enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+  { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
+echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; }
+if test "${ac_cv_sys_largefile_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_sys_largefile_CC=no
+     if test "$GCC" != yes; then
+       ac_save_CC=$CC
+       while :; do
+	 # IRIX 6.2 and later do not support large files by default,
+	 # so use the C compiler's -n32 option if that helps.
+	 cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+	 rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+	 CC="$CC -n32"
+	 rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_sys_largefile_CC=' -n32'; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+	 break
+       done
+       CC=$ac_save_CC
+       rm -f conftest.$ac_ext
+    fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; }
+  if test "$ac_cv_sys_largefile_CC" != no; then
+    CC=$CC$ac_cv_sys_largefile_CC
+  fi
+
+  { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; }
+if test "${ac_cv_sys_file_offset_bits+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  while :; do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_sys_file_offset_bits=no; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_sys_file_offset_bits=64; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  ac_cv_sys_file_offset_bits=unknown
+  break
+done
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
+echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+  no | unknown) ;;
+  *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -f conftest*
+  if test $ac_cv_sys_file_offset_bits = unknown; then
+    { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
+echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; }
+if test "${ac_cv_sys_large_files+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  while :; do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_sys_large_files=no; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_sys_large_files=1; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  ac_cv_sys_large_files=unknown
+  break
+done
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
+echo "${ECHO_T}$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+  no | unknown) ;;
+  *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -f conftest*
+  fi
+fi
+
+
+# Identify characteristics of the host architecture.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
+echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Extract the first word of "grep ggrep" to use in msg output
+if test -z "$GREP"; then
+set dummy grep ggrep; ac_prog_name=$2
+if test "${ac_cv_path_GREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_path_GREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in grep ggrep; do
+  for ac_exec_ext in '' $ac_executable_extensions; do
+    ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+    { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+    # Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    ac_count=`expr $ac_count + 1`
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+    $ac_path_GREP_found && break 3
+  done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+GREP="$ac_cv_path_GREP"
+if test -z "$GREP"; then
+  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
+echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     # Extract the first word of "egrep" to use in msg output
+if test -z "$EGREP"; then
+set dummy egrep; ac_prog_name=$2
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_path_EGREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in egrep; do
+  for ac_exec_ext in '' $ac_executable_extensions; do
+    ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+    { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+    # Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    ac_count=`expr $ac_count + 1`
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+    $ac_path_EGREP_found && break 3
+  done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+EGREP="$ac_cv_path_EGREP"
+if test -z "$EGREP"; then
+  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+
+   fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
+echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_header_stdc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+{ echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; }
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main (void)
+{
+#if  ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \
+	&& BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN)
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main (void)
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_c_bigendian=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main (void)
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main (void)
+{
+
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long int l;
+    char c[sizeof (long int)];
+  } u;
+  u.l = 1;
+  return u.c[sizeof (long int) - 1] == 1;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6; }
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+{ echo "$as_me:$LINENO: checking for void *" >&5
+echo $ECHO_N "checking for void *... $ECHO_C" >&6; }
+if test "${ac_cv_type_void_p+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+typedef void * ac__type_new_;
+int
+main (void)
+{
+if ((ac__type_new_ *) 0)
+  return 0;
+if (sizeof (ac__type_new_))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_type_void_p=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_type_void_p=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_type_void_p" >&5
+echo "${ECHO_T}$ac_cv_type_void_p" >&6; }
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ echo "$as_me:$LINENO: checking size of void *" >&5
+echo $ECHO_N "checking size of void *... $ECHO_C" >&6; }
+if test "${ac_cv_sizeof_void_p+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+   typedef void * ac__type_sizeof_;
+int
+main (void)
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+   typedef void * ac__type_sizeof_;
+int
+main (void)
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_lo=`expr $ac_mid + 1`
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+   typedef void * ac__type_sizeof_;
+int
+main (void)
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+   typedef void * ac__type_sizeof_;
+int
+main (void)
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_hi=`expr '(' $ac_mid ')' - 1`
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			ac_mid=`expr 2 '*' $ac_mid`
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_lo= ac_hi=
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+   typedef void * ac__type_sizeof_;
+int
+main (void)
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_void_p=$ac_lo;;
+'') if test "$ac_cv_type_void_p" = yes; then
+     { { echo "$as_me:$LINENO: error: cannot compute sizeof (void *)
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (void *)
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+   else
+     ac_cv_sizeof_void_p=0
+   fi ;;
+esac
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+   typedef void * ac__type_sizeof_;
+static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); }
+static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main (void)
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (((long int) (sizeof (ac__type_sizeof_))) < 0)
+    {
+      long int i = longval ();
+      if (i != ((long int) (sizeof (ac__type_sizeof_))))
+	return 1;
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ((long int) (sizeof (ac__type_sizeof_))))
+	return 1;
+      fprintf (f, "%lu\n", i);
+    }
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_void_p=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+if test "$ac_cv_type_void_p" = yes; then
+     { { echo "$as_me:$LINENO: error: cannot compute sizeof (void *)
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (void *)
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+   else
+     ac_cv_sizeof_void_p=0
+   fi
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.val
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_void_p" >&5
+echo "${ECHO_T}$ac_cv_sizeof_void_p" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
+_ACEOF
+
+
+{ echo "$as_me:$LINENO: checking for long" >&5
+echo $ECHO_N "checking for long... $ECHO_C" >&6; }
+if test "${ac_cv_type_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+typedef long ac__type_new_;
+int
+main (void)
+{
+if ((ac__type_new_ *) 0)
+  return 0;
+if (sizeof (ac__type_new_))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_cv_type_long=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_type_long=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
+echo "${ECHO_T}$ac_cv_type_long" >&6; }
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ echo "$as_me:$LINENO: checking size of long" >&5
+echo $ECHO_N "checking size of long... $ECHO_C" >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+   typedef long ac__type_sizeof_;
+int
+main (void)
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+   typedef long ac__type_sizeof_;
+int
+main (void)
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_lo=`expr $ac_mid + 1`
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+   typedef long ac__type_sizeof_;
+int
+main (void)
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+   typedef long ac__type_sizeof_;
+int
+main (void)
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_hi=`expr '(' $ac_mid ')' - 1`
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			ac_mid=`expr 2 '*' $ac_mid`
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_lo= ac_hi=
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+   typedef long ac__type_sizeof_;
+int
+main (void)
+{
+static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long=$ac_lo;;
+'') if test "$ac_cv_type_long" = yes; then
+     { { echo "$as_me:$LINENO: error: cannot compute sizeof (long)
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long)
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+   else
+     ac_cv_sizeof_long=0
+   fi ;;
+esac
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+   typedef long ac__type_sizeof_;
+static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); }
+static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main (void)
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (((long int) (sizeof (ac__type_sizeof_))) < 0)
+    {
+      long int i = longval ();
+      if (i != ((long int) (sizeof (ac__type_sizeof_))))
+	return 1;
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ((long int) (sizeof (ac__type_sizeof_))))
+	return 1;
+      fprintf (f, "%lu\n", i);
+    }
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_long=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+if test "$ac_cv_type_long" = yes; then
+     { { echo "$as_me:$LINENO: error: cannot compute sizeof (long)
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long)
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.val
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+
+
+{ echo "$as_me:$LINENO: checking whether our compiler is apple cc" >&5
+echo $ECHO_N "checking whether our compiler is apple cc... $ECHO_C" >&6; }
+if test "${grub_cv_apple_cc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if $CC -v 2>&1 | grep "Apple Inc." > /dev/null; then
+  grub_cv_apple_cc=yes
+else
+  grub_cv_apple_cc=no
+fi
+
+fi
+
+
+{ echo "$as_me:$LINENO: result: $grub_cv_apple_cc" >&5
+echo "${ECHO_T}$grub_cv_apple_cc" >&6; }
+if test x$grub_cv_apple_cc = xyes ; then
+  CFLAGS="$CFLAGS -DAPPLE_CC=1 -fnested-functions"
+  ASFLAGS="$ASFLAGS -DAPPLE_CC=1"
+fi
+
+if test "x$cross_compiling" = xyes; then
+  { echo "$as_me:$LINENO: WARNING: cannot generate manual pages while cross compiling" >&5
+echo "$as_me: WARNING: cannot generate manual pages while cross compiling" >&2;}
+else
+  # Extract the first word of "help2man", so it can be a program name with args.
+set dummy help2man; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_HELP2MAN+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $HELP2MAN in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_HELP2MAN="$HELP2MAN" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_HELP2MAN="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+HELP2MAN=$ac_cv_path_HELP2MAN
+if test -n "$HELP2MAN"; then
+  { echo "$as_me:$LINENO: result: $HELP2MAN" >&5
+echo "${ECHO_T}$HELP2MAN" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+
+# Check for functions.
+
+
+
+for ac_func in posix_memalign memalign asprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main (void)
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+#
+# Check for target programs.
+#
+
+# Find tools for the target.
+if test "x$target_alias" != x && test "x$host_alias" != "x$target_alias"; then
+  tmp_ac_tool_prefix="$ac_tool_prefix"
+  ac_tool_prefix=$target_alias-
+
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in gcc egcs cc
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_TARGET_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$TARGET_CC"; then
+  ac_cv_prog_TARGET_CC="$TARGET_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_TARGET_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+TARGET_CC=$ac_cv_prog_TARGET_CC
+if test -n "$TARGET_CC"; then
+  { echo "$as_me:$LINENO: result: $TARGET_CC" >&5
+echo "${ECHO_T}$TARGET_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+    test -n "$TARGET_CC" && break
+  done
+fi
+if test -z "$TARGET_CC"; then
+  ac_ct_TARGET_CC=$TARGET_CC
+  for ac_prog in gcc egcs cc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_TARGET_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_TARGET_CC"; then
+  ac_cv_prog_ac_ct_TARGET_CC="$ac_ct_TARGET_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_TARGET_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_TARGET_CC=$ac_cv_prog_ac_ct_TARGET_CC
+if test -n "$ac_ct_TARGET_CC"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_TARGET_CC" >&5
+echo "${ECHO_T}$ac_ct_TARGET_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$ac_ct_TARGET_CC" && break
+done
+
+  if test "x$ac_ct_TARGET_CC" = x; then
+    TARGET_CC="{ { echo "$as_me:$LINENO: error: none of gcc, egcs and cc is found. set TARGET_CC manually." >&5
+echo "$as_me: error: none of gcc, egcs and cc is found. set TARGET_CC manually." >&2;}
+   { (exit 1); exit 1; }; }"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    TARGET_CC=$ac_ct_TARGET_CC
+  fi
+fi
+
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objcopy; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_OBJCOPY+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$OBJCOPY"; then
+  ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJCOPY=$ac_cv_prog_OBJCOPY
+if test -n "$OBJCOPY"; then
+  { echo "$as_me:$LINENO: result: $OBJCOPY" >&5
+echo "${ECHO_T}$OBJCOPY" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJCOPY"; then
+  ac_ct_OBJCOPY=$OBJCOPY
+  # Extract the first word of "objcopy", so it can be a program name with args.
+set dummy objcopy; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_OBJCOPY"; then
+  ac_cv_prog_ac_ct_OBJCOPY="$ac_ct_OBJCOPY" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OBJCOPY="objcopy"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY
+if test -n "$ac_ct_OBJCOPY"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_OBJCOPY" >&5
+echo "${ECHO_T}$ac_ct_OBJCOPY" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJCOPY" = x; then
+    OBJCOPY=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJCOPY=$ac_ct_OBJCOPY
+  fi
+else
+  OBJCOPY="$ac_cv_prog_OBJCOPY"
+fi
+
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nm; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_NM+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$NM"; then
+  ac_cv_prog_NM="$NM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_NM="${ac_tool_prefix}nm"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+NM=$ac_cv_prog_NM
+if test -n "$NM"; then
+  { echo "$as_me:$LINENO: result: $NM" >&5
+echo "${ECHO_T}$NM" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NM"; then
+  ac_ct_NM=$NM
+  # Extract the first word of "nm", so it can be a program name with args.
+set dummy nm; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_NM+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_NM"; then
+  ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_NM="nm"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NM=$ac_cv_prog_ac_ct_NM
+if test -n "$ac_ct_NM"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_NM" >&5
+echo "${ECHO_T}$ac_ct_NM" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_NM" = x; then
+    NM=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    NM=$ac_ct_NM
+  fi
+else
+  NM="$ac_cv_prog_NM"
+fi
+
+
+  ac_tool_prefix="$tmp_ac_tool_prefix"
+else
+  if test "x$TARGET_CC" = x; then
+    TARGET_CC=$CC
+  fi
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objcopy; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_OBJCOPY+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$OBJCOPY"; then
+  ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJCOPY=$ac_cv_prog_OBJCOPY
+if test -n "$OBJCOPY"; then
+  { echo "$as_me:$LINENO: result: $OBJCOPY" >&5
+echo "${ECHO_T}$OBJCOPY" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJCOPY"; then
+  ac_ct_OBJCOPY=$OBJCOPY
+  # Extract the first word of "objcopy", so it can be a program name with args.
+set dummy objcopy; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_OBJCOPY"; then
+  ac_cv_prog_ac_ct_OBJCOPY="$ac_ct_OBJCOPY" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OBJCOPY="objcopy"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY
+if test -n "$ac_ct_OBJCOPY"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_OBJCOPY" >&5
+echo "${ECHO_T}$ac_ct_OBJCOPY" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJCOPY" = x; then
+    OBJCOPY=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJCOPY=$ac_ct_OBJCOPY
+  fi
+else
+  OBJCOPY="$ac_cv_prog_OBJCOPY"
+fi
+
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nm; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_NM+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$NM"; then
+  ac_cv_prog_NM="$NM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_NM="${ac_tool_prefix}nm"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+NM=$ac_cv_prog_NM
+if test -n "$NM"; then
+  { echo "$as_me:$LINENO: result: $NM" >&5
+echo "${ECHO_T}$NM" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NM"; then
+  ac_ct_NM=$NM
+  # Extract the first word of "nm", so it can be a program name with args.
+set dummy nm; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_NM+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_NM"; then
+  ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_NM="nm"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NM=$ac_cv_prog_ac_ct_NM
+if test -n "$ac_ct_NM"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_NM" >&5
+echo "${ECHO_T}$ac_ct_NM" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_NM" = x; then
+    NM=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf@gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    NM=$ac_ct_NM
+  fi
+else
+  NM="$ac_cv_prog_NM"
+fi
+
+fi
+
+
+
+# Test the C compiler for the target environment.
+tmp_CC="$CC"
+tmp_CFLAGS="$CFLAGS"
+tmp_LDFLAGS="$LDFLAGS"
+tmp_CPPFLAGS="$CPPFLAGS"
+tmp_LIBS="$LIBS"
+CC="$TARGET_CC"
+CFLAGS="$TARGET_CFLAGS"
+CPPFLAGS="$TARGET_CPPFLAGS"
+LDFLAGS="$TARGET_LDFLAGS"
+LIBS=""
+
+if test "x$TARGET_CFLAGS" = x; then
+  # debug flags.
+  TARGET_CFLAGS="-Wall -W -Wshadow -Wpointer-arith -Wmissing-prototypes \
+                 -Wundef -Wstrict-prototypes -g"
+
+  # optimization flags.
+  { echo "$as_me:$LINENO: checking whether optimization for size works" >&5
+echo $ECHO_N "checking whether optimization for size works... $ECHO_C" >&6; }
+if test "${grub_cv_cc_Os+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    CFLAGS=-Os
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  grub_cv_cc_Os=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_cc_Os=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ echo "$as_me:$LINENO: result: $grub_cv_cc_Os" >&5
+echo "${ECHO_T}$grub_cv_cc_Os" >&6; }
+  if test "x$grub_cv_cc_Os" = xyes; then
+    TARGET_CFLAGS="$TARGET_CFLAGS -Os"
+  else
+    TARGET_CFLAGS="$TARGET_CFLAGS -O2 -fno-strength-reduce -fno-unroll-loops"
+  fi
+
+  # Force no alignment to save space on i386.
+  if test "x$target_cpu" = xi386; then
+    { echo "$as_me:$LINENO: checking whether -falign-loops works" >&5
+echo $ECHO_N "checking whether -falign-loops works... $ECHO_C" >&6; }
+if test "${grub_cv_cc_falign_loop+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+      CFLAGS="$CFLAGS -falign-loops=1"
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  grub_cv_cc_falign_loop=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_cc_falign_loop=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ echo "$as_me:$LINENO: result: $grub_cv_cc_falign_loop" >&5
+echo "${ECHO_T}$grub_cv_cc_falign_loop" >&6; }
+
+    if test "x$grub_cv_cc_falign_loop" = xyes; then
+      TARGET_CFLAGS="$TARGET_CFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1"
+    else
+      TARGET_CFLAGS="$TARGET_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1"
+    fi
+
+    # Some toolchains enable these features by default, but they need
+    # registers that aren't set up properly in GRUB.
+    TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-3dnow"
+  fi
+
+  # By default, GCC 4.4 generates .eh_frame sections containing unwind
+  # information in some cases where it previously did not. GRUB doesn't need
+  # these and they just use up vital space. Restore the old compiler
+  # behaviour.
+  { echo "$as_me:$LINENO: checking whether -fno-dwarf2-cfi-asm works" >&5
+echo $ECHO_N "checking whether -fno-dwarf2-cfi-asm works... $ECHO_C" >&6; }
+if test "${grub_cv_cc_fno_dwarf2_cfi_asm+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    SAVE_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -fno-dwarf2-cfi-asm"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  grub_cv_cc_fno_dwarf2_cfi_asm=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_cc_fno_dwarf2_cfi_asm=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    CFLAGS="$SAVE_CFLAGS"
+
+fi
+{ echo "$as_me:$LINENO: result: $grub_cv_cc_fno_dwarf2_cfi_asm" >&5
+echo "${ECHO_T}$grub_cv_cc_fno_dwarf2_cfi_asm" >&6; }
+
+  if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then
+    TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm"
+  fi
+fi
+
+
+{ echo "$as_me:$LINENO: checking whether our target compiler is apple cc" >&5
+echo $ECHO_N "checking whether our target compiler is apple cc... $ECHO_C" >&6; }
+if test "${grub_cv_apple_target_cc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if $CC -v 2>&1 | grep "Apple Inc." > /dev/null; then
+  grub_cv_apple_target_cc=yes
+else
+  grub_cv_apple_target_cc=no
+fi
+
+fi
+
+
+{ echo "$as_me:$LINENO: result: $grub_cv_apple_target_cc" >&5
+echo "${ECHO_T}$grub_cv_apple_target_cc" >&6; }
+if test x$grub_cv_apple_target_cc = xyes ; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -DAPPLE_CC=1 -fnested-functions"
+  CFLAGS="$CFLAGS -DAPPLE_CC=1 -fnested-functions"
+  TARGET_ASFLAGS="$TARGET_ASFLAGS -DAPPLE_CC=1"
+  TARGET_APPLE_CC=1
+  # Extract the first word of "objconv", so it can be a program name with args.
+set dummy objconv; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_OBJCONV+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$OBJCONV"; then
+  ac_cv_prog_OBJCONV="$OBJCONV" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OBJCONV="objconv"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJCONV=$ac_cv_prog_OBJCONV
+if test -n "$OBJCONV"; then
+  { echo "$as_me:$LINENO: result: $OBJCONV" >&5
+echo "${ECHO_T}$OBJCONV" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  if test "x$OBJCONV" = x ; then
+     # Extract the first word of "objconv", so it can be a program name with args.
+set dummy objconv; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_OBJCONV+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$OBJCONV"; then
+  ac_cv_prog_OBJCONV="$OBJCONV" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in .
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OBJCONV="./objconv"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJCONV=$ac_cv_prog_OBJCONV
+if test -n "$OBJCONV"; then
+  { echo "$as_me:$LINENO: result: $OBJCONV" >&5
+echo "${ECHO_T}$OBJCONV" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  fi
+  if test "x$OBJCONV" = x ; then
+    { { echo "$as_me:$LINENO: error: objconv not found which is required when building with apple compiler" >&5
+echo "$as_me: error: objconv not found which is required when building with apple compiler" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  TARGET_IMG_LDSCRIPT=
+  TARGET_IMG_CFLAGS="-static"
+  TARGET_IMG_LDFLAGS='-nostdlib -static -Wl,-preload -Wl,-segalign,20 -Wl,-image_base,'
+  TARGET_IMG_LDFLAGS_AC='-nostdlib -static -Wl,-preload -Wl,-segalign,20 -Wl,-image_base,'
+else
+  TARGET_APPLE_CC=0
+# Use linker script if present, otherwise use builtin -N script.
+if test -f "${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"; then
+  TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"
+  TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}  -Wl,-Ttext,"
+  TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"
+else
+  TARGET_IMG_LDSCRIPT=
+  TARGET_IMG_LDFLAGS='-Wl,-N  -Wl,-Ttext,'
+  TARGET_IMG_LDFLAGS_AC='-Wl,-N  -Wl,-Ttext,'
+fi
+TARGET_IMG_CFLAGS=
+fi
+
+
+
+
+
+# For platforms where ELF is not the default link format.
+{ echo "$as_me:$LINENO: checking for command to convert module to ELF format" >&5
+echo $ECHO_N "checking for command to convert module to ELF format... $ECHO_C" >&6; }
+case "${host_os}" in
+  cygwin) TARGET_OBJ2ELF='grub-pe2elf' ;;
+  *) ;;
+esac
+
+{ echo "$as_me:$LINENO: result: $TARGET_OBJ2ELF" >&5
+echo "${ECHO_T}$TARGET_OBJ2ELF" >&6; }
+
+
+if test "x$target_m32" = x1; then
+  # Force 32-bit mode.
+  TARGET_CFLAGS="$TARGET_CFLAGS -m32"
+  TARGET_LDFLAGS="$TARGET_LDFLAGS -m32"
+  TARGET_MODULE_FORMAT="elf32"
+fi
+
+if test "x$target_m64" = x1; then
+  # Force 64-bit mode.
+  TARGET_CFLAGS="$TARGET_CFLAGS -m64"
+  TARGET_LDFLAGS="$TARGET_LDFLAGS -m64"
+  TARGET_MODULE_FORMAT="elf64"
+fi
+
+if test "$target_cpu"-"$platform" = x86_64-efi; then
+  # Use large model to support 4G memory
+  { echo "$as_me:$LINENO: checking whether option -mcmodel=large works" >&5
+echo $ECHO_N "checking whether option -mcmodel=large works... $ECHO_C" >&6; }
+if test "${grub_cv_cc_mcmodel+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    SAVED_CFLAGS=$CFLAGS
+    CFLAGS="$CFLAGS -m64 -mcmodel=large"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  grub_cv_cc_mcmodel=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_cc_mcmodel=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ echo "$as_me:$LINENO: result: $grub_cv_cc_mcmodel" >&5
+echo "${ECHO_T}$grub_cv_cc_mcmodel" >&6; }
+  if test "x$grub_cv_cc_mcmodel" = xno; then
+    CFLAGS="$SAVED_CFLAGS -m64 -DMCMODEL_SMALL=1"
+    TARGET_CFLAGS="$TARGET_CFLAGS -DMCMODEL_SMALL=1"
+    { echo "$as_me:$LINENO: WARNING: -mcmodel=large not supported. You won't be able to use the memory over 4GiB. Upgrade your gcc" >&5
+echo "$as_me: WARNING: -mcmodel=large not supported. You won't be able to use the memory over 4GiB. Upgrade your gcc" >&2;}
+  else
+    TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
+  fi
+
+  # EFI writes to stack below %rsp, we must not use the red zone
+  { echo "$as_me:$LINENO: checking whether option -mno-red-zone works" >&5
+echo $ECHO_N "checking whether option -mno-red-zone works... $ECHO_C" >&6; }
+if test "${grub_cv_cc_no_red_zone+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    CFLAGS="$CFLAGS -m64 -mno-red-zone"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  grub_cv_cc_no_red_zone=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_cc_no_red_zone=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ echo "$as_me:$LINENO: result: $grub_cv_cc_no_red_zone" >&5
+echo "${ECHO_T}$grub_cv_cc_no_red_zone" >&6; }
+  if test "x$grub_cv_cc_no_red_zone" = xno; then
+    { { echo "$as_me:$LINENO: error: -mno-red-zone not supported, upgrade your gcc" >&5
+echo "$as_me: error: -mno-red-zone not supported, upgrade your gcc" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+
+  TARGET_CFLAGS="$TARGET_CFLAGS -mno-red-zone"
+fi
+
+#
+# Compiler features.
+#
+
+# Need __enable_execute_stack() for nested function trampolines?
+
+{ echo "$as_me:$LINENO: checking whether \`$CC' generates calls to \`__enable_execute_stack()'" >&5
+echo $ECHO_N "checking whether \`$CC' generates calls to \`__enable_execute_stack()'... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+
+void f (int (*p) (void));
+void g (int i)
+{
+  int nestedfunc (void) { return i; }
+  f (nestedfunc);
+}
+
+_ACEOF
+if { ac_try='${CC-cc} ${CFLAGS} -S conftest.c'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } && test -s conftest.s; then
+  true
+else
+  { { echo "$as_me:$LINENO: error: ${CC-cc} failed to produce assembly code" >&5
+echo "$as_me: error: ${CC-cc} failed to produce assembly code" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if grep __enable_execute_stack conftest.s >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NEED_ENABLE_EXECUTE_STACK 1
+_ACEOF
+
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+rm -f conftest*
+
+
+# Position independent executable.
+
+# Position independent executable.
+pie_possible=yes
+{ echo "$as_me:$LINENO: checking whether \`$CC' has \`-fPIE' as default" >&5
+echo $ECHO_N "checking whether \`$CC' has \`-fPIE' as default... $ECHO_C" >&6; }
+# Is this a reliable test case?
+cat >conftest.$ac_ext <<_ACEOF
+
+#ifdef __PIE__
+int main() {
+	return 0;
+}
+#else
+#error NO __PIE__ DEFINED
+#endif
+
+_ACEOF
+
+# `$CC -c -o ...' might not be portable.  But, oh, well...  Is calling
+# `ac_compile' like this correct, after all?
+if eval "$ac_compile -S -o conftest.s" 2> /dev/null; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+  # Should we clear up other files as well, having called `AC_LANG_CONFTEST'?
+  rm -f conftest.s
+else
+  pie_possible=no
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+# Need that, because some distributions ship compilers that include
+# `-fPIE' in the default specs.
+if [ x"$pie_possible" = xyes ]; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE"
+fi
+
+# Smashing stack protector.
+
+# Smashing stack protector.
+ssp_possible=yes
+{ echo "$as_me:$LINENO: checking whether \`$CC' accepts \`-fstack-protector'" >&5
+echo $ECHO_N "checking whether \`$CC' accepts \`-fstack-protector'... $ECHO_C" >&6; }
+# Is this a reliable test case?
+cat >conftest.$ac_ext <<_ACEOF
+void foo (void) { volatile char a[8]; a[3]; }
+_ACEOF
+# `$CC -c -o ...' might not be portable.  But, oh, well...  Is calling
+# `ac_compile' like this correct, after all?
+if eval "$ac_compile -S -fstack-protector -o conftest.s" 2> /dev/null; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+  # Should we clear up other files as well, having called `AC_LANG_CONFTEST'?
+  rm -f conftest.s
+else
+  ssp_possible=no
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+# Need that, because some distributions ship compilers that include
+# `-fstack-protector' in the default specs.
+if test "x$ssp_possible" = xyes; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector"
+fi
+
+# Smashing stack arg probe.
+sap_possible=yes
+{ echo "$as_me:$LINENO: checking whether \`$CC' accepts \`-mstack-arg-probe'" >&5
+echo $ECHO_N "checking whether \`$CC' accepts \`-mstack-arg-probe'... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+void foo (void) { volatile char a[8]; a[3]; }
+_ACEOF
+if eval "$ac_compile -S -mstack-arg-probe -o conftest.s" 2> /dev/null; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+  # Should we clear up other files as well, having called `AC_LANG_CONFTEST'?
+  rm -f conftest.s
+else
+  sap_possible=no
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+# Cygwin's GCC uses alloca() to probe the stackframe on static
+# stack allocations above some threshold.
+if test x"$sap_possible" = xyes; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe"
+fi
+
+# Check whether --enable-werror was given.
+if test "${enable_werror+set}" = set; then
+  enableval=$enable_werror;
+fi
+
+if test x"$enable_werror" != xno ; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -Werror"
+fi
+
+
+
+
+
+
+
+
+
+# Check for libgcc symbols (must be performed before we add -nostdlib to LDFLAGS)
+
+
+
+
+
+
+
+for ac_func in __bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main (void)
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# Set them to their new values for the tests below.
+CC="$TARGET_CC"
+if test "x$TARGET_APPLE_CC" = x1 ; then
+CFLAGS="$TARGET_CFLAGS -nostdlib"
+else
+CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100"
+fi
+CPPFLAGS="$TARGET_CPPFLAGS"
+LDFLAGS="$TARGET_LDFLAGS"
+
+# Defined in aclocal.m4.
+{ echo "$as_me:$LINENO: checking whether target compiler is working" >&5
+echo $ECHO_N "checking whether target compiler is working... $ECHO_C" >&6; }
+if test "${grub_cv_prog_target_cc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+asm (".globl start; start: nop");
+int main (void);
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  grub_cv_prog_target_cc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_prog_target_cc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+
+fi
+
+{ echo "$as_me:$LINENO: result: $grub_cv_prog_target_cc" >&5
+echo "${ECHO_T}$grub_cv_prog_target_cc" >&6; }
+
+if test "x$grub_cv_prog_target_cc" = xno; then
+  { { echo "$as_me:$LINENO: error: cannot compile for the target" >&5
+echo "$as_me: error: cannot compile for the target" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+if test "x$TARGET_APPLE_CC" != x1 ; then
+{ echo "$as_me:$LINENO: checking whether ${OBJCOPY} works for absolute addresses" >&5
+echo $ECHO_N "checking whether ${OBJCOPY} works for absolute addresses... $ECHO_C" >&6; }
+if test "${grub_cv_prog_objcopy_absolute+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.c <<\EOF
+void cmain (void);
+void
+cmain (void)
+{
+   *((int *) 0x1000) = 2;
+}
+EOF
+
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest.o; then :
+else
+  { { echo "$as_me:$LINENO: error: ${CC-cc} cannot compile C source code" >&5
+echo "$as_me: error: ${CC-cc} cannot compile C source code" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+grub_cv_prog_objcopy_absolute=yes
+for link_addr in 2000 8000 7C00; do
+  if { ac_try='${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then :
+  else
+    { { echo "$as_me:$LINENO: error: ${CC-cc} cannot link at address $link_addr" >&5
+echo "$as_me: error: ${CC-cc} cannot link at address $link_addr" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  if { ac_try='${OBJCOPY-objcopy} --only-section=.text -O binary conftest.exec conftest'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then :
+  else
+    { { echo "$as_me:$LINENO: error: ${OBJCOPY-objcopy} cannot create binary files" >&5
+echo "$as_me: error: ${OBJCOPY-objcopy} cannot create binary files" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  if test ! -f conftest.old || { ac_try='cmp -s conftest.old conftest'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    mv -f conftest conftest.old
+  else
+    grub_cv_prog_objcopy_absolute=no
+    break
+  fi
+done
+rm -f conftest*
+fi
+
+{ echo "$as_me:$LINENO: result: $grub_cv_prog_objcopy_absolute" >&5
+echo "${ECHO_T}$grub_cv_prog_objcopy_absolute" >&6; }
+
+if test "x$grub_cv_prog_objcopy_absolute" = xno; then
+  { { echo "$as_me:$LINENO: error: GRUB requires a working absolute objcopy; upgrade your binutils" >&5
+echo "$as_me: error: GRUB requires a working absolute objcopy; upgrade your binutils" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+fi
+{ echo "$as_me:$LINENO: checking whether linker accepts --build-id=none" >&5
+echo $ECHO_N "checking whether linker accepts --build-id=none... $ECHO_C" >&6; }
+if test "${grub_cv_prog_ld_build_id_none+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS -Wl,--build-id=none"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  grub_cv_prog_ld_build_id_none=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_prog_ld_build_id_none=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LDFLAGS="$save_LDFLAGS"
+
+fi
+
+{ echo "$as_me:$LINENO: result: $grub_cv_prog_ld_build_id_none" >&5
+echo "${ECHO_T}$grub_cv_prog_ld_build_id_none" >&6; }
+
+if test "x$grub_cv_prog_ld_build_id_none" = xyes; then
+  TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,--build-id=none"
+fi
+
+
+{ echo "$as_me:$LINENO: checking if C symbols get an underscore after compilation" >&5
+echo $ECHO_N "checking if C symbols get an underscore after compilation... $ECHO_C" >&6; }
+if test "${grub_cv_asm_uscore+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.c <<\EOF
+int func (int *);
+int
+func (int *list)
+{
+  *list = 0;
+  return *list;
+}
+EOF
+
+if { ac_try='${CC-cc} ${CFLAGS} -S conftest.c'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } && test -s conftest.s; then
+  true
+else
+  { { echo "$as_me:$LINENO: error: ${CC-cc} failed to produce assembly code" >&5
+echo "$as_me: error: ${CC-cc} failed to produce assembly code" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+if grep _func conftest.s >/dev/null 2>&1; then
+  grub_cv_asm_uscore=yes
+else
+  grub_cv_asm_uscore=no
+fi
+
+rm -f conftest*
+fi
+
+
+if test "x$grub_cv_asm_uscore" = xyes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ASM_USCORE $grub_cv_asm_uscore
+_ACEOF
+
+fi
+
+{ echo "$as_me:$LINENO: result: $grub_cv_asm_uscore" >&5
+echo "${ECHO_T}$grub_cv_asm_uscore" >&6; }
+
+if test "x$target_cpu" = xi386; then
+  if test ! -z "$TARGET_IMG_LDSCRIPT"; then
+    # Check symbols provided by linker script.
+    CFLAGS="$TARGET_CFLAGS -nostdlib $TARGET_IMG_LDFLAGS_AC -Wl,-Ttext,8000,--defsym,___main=0x8100"
+  fi
+  if test "x$TARGET_APPLE_CC" != x1 ; then
+
+{ echo "$as_me:$LINENO: checking if __bss_start is defined by the compiler" >&5
+echo $ECHO_N "checking if __bss_start is defined by the compiler... $ECHO_C" >&6; }
+if test "${grub_cv_check_uscore_uscore_bss_start_symbol+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+asm ("incl __bss_start")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  grub_cv_check_uscore_uscore_bss_start_symbol=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_check_uscore_uscore_bss_start_symbol=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+{ echo "$as_me:$LINENO: result: $grub_cv_check_uscore_uscore_bss_start_symbol" >&5
+echo "${ECHO_T}$grub_cv_check_uscore_uscore_bss_start_symbol" >&6; }
+
+{ echo "$as_me:$LINENO: checking if edata is defined by the compiler" >&5
+echo $ECHO_N "checking if edata is defined by the compiler... $ECHO_C" >&6; }
+if test "${grub_cv_check_edata_symbol+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+asm ("incl edata")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  grub_cv_check_edata_symbol=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_check_edata_symbol=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+{ echo "$as_me:$LINENO: result: $grub_cv_check_edata_symbol" >&5
+echo "${ECHO_T}$grub_cv_check_edata_symbol" >&6; }
+
+{ echo "$as_me:$LINENO: checking if _edata is defined by the compiler" >&5
+echo $ECHO_N "checking if _edata is defined by the compiler... $ECHO_C" >&6; }
+if test "${grub_cv_check_uscore_edata_symbol+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+asm ("incl _edata")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  grub_cv_check_uscore_edata_symbol=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_check_uscore_edata_symbol=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+{ echo "$as_me:$LINENO: result: $grub_cv_check_uscore_edata_symbol" >&5
+echo "${ECHO_T}$grub_cv_check_uscore_edata_symbol" >&6; }
+
+
+
+
+if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" = xyes; then
+  cat >>confdefs.h <<\_ACEOF
+#define BSS_START_SYMBOL __bss_start
+_ACEOF
+
+elif test "x$grub_cv_check_edata_symbol" = xyes; then
+  cat >>confdefs.h <<\_ACEOF
+#define BSS_START_SYMBOL edata
+_ACEOF
+
+elif test "x$grub_cv_check_uscore_edata_symbol" = xyes; then
+  cat >>confdefs.h <<\_ACEOF
+#define BSS_START_SYMBOL _edata
+_ACEOF
+
+else
+  { { echo "$as_me:$LINENO: error: none of __bss_start, edata or _edata is defined" >&5
+echo "$as_me: error: none of __bss_start, edata or _edata is defined" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+{ echo "$as_me:$LINENO: checking if end is defined by the compiler" >&5
+echo $ECHO_N "checking if end is defined by the compiler... $ECHO_C" >&6; }
+if test "${grub_cv_check_end_symbol+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+asm ("incl end")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  grub_cv_check_end_symbol=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_check_end_symbol=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+{ echo "$as_me:$LINENO: result: $grub_cv_check_end_symbol" >&5
+echo "${ECHO_T}$grub_cv_check_end_symbol" >&6; }
+
+{ echo "$as_me:$LINENO: checking if _end is defined by the compiler" >&5
+echo $ECHO_N "checking if _end is defined by the compiler... $ECHO_C" >&6; }
+if test "${grub_cv_check_uscore_end_symbol+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+asm ("incl _end")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  grub_cv_check_uscore_end_symbol=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_check_uscore_end_symbol=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+{ echo "$as_me:$LINENO: result: $grub_cv_check_uscore_end_symbol" >&5
+echo "${ECHO_T}$grub_cv_check_uscore_end_symbol" >&6; }
+
+
+
+
+if test "x$grub_cv_check_end_symbol" = xyes; then
+  cat >>confdefs.h <<\_ACEOF
+#define END_SYMBOL end
+_ACEOF
+
+elif test "x$grub_cv_check_uscore_end_symbol" = xyes; then
+  cat >>confdefs.h <<\_ACEOF
+#define END_SYMBOL _end
+_ACEOF
+
+else
+  { { echo "$as_me:$LINENO: error: neither end nor _end is defined" >&5
+echo "$as_me: error: neither end nor _end is defined" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+  fi
+  CFLAGS="$TARGET_CFLAGS"
+
+{ echo "$as_me:$LINENO: checking whether addr32 must be in the same line as the instruction" >&5
+echo $ECHO_N "checking whether addr32 must be in the same line as the instruction... $ECHO_C" >&6; }
+if test "${grub_cv_i386_asm_prefix_requirement+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.s <<\EOF
+	.code16
+l1:	addr32	movb	%al, l1
+EOF
+
+if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } && test -s conftest.o; then
+  grub_cv_i386_asm_prefix_requirement=yes
+else
+  grub_cv_i386_asm_prefix_requirement=no
+fi
+
+rm -f conftest*
+fi
+
+
+if test "x$grub_cv_i386_asm_prefix_requirement" = xyes; then
+  grub_tmp_addr32="addr32"
+  grub_tmp_data32="data32"
+else
+  grub_tmp_addr32="addr32;"
+  grub_tmp_data32="data32;"
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define ADDR32 $grub_tmp_addr32
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DATA32 $grub_tmp_data32
+_ACEOF
+
+
+{ echo "$as_me:$LINENO: result: $grub_cv_i386_asm_prefix_requirement" >&5
+echo "${ECHO_T}$grub_cv_i386_asm_prefix_requirement" >&6; }
+
+
+{ echo "$as_me:$LINENO: checking for .code16 addr32 assembler support" >&5
+echo $ECHO_N "checking for .code16 addr32 assembler support... $ECHO_C" >&6; }
+if test "${grub_cv_i386_asm_addr32+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.s.in <<\EOF
+	.code16
+l1:	@ADDR32@	movb	%al, l1
+EOF
+
+if test "x$grub_cv_i386_asm_prefix_requirement" = xyes; then
+  sed -e s/@ADDR32@/addr32/ < conftest.s.in > conftest.s
+else
+  sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s
+fi
+
+if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } && test -s conftest.o; then
+  grub_cv_i386_asm_addr32=yes
+else
+  grub_cv_i386_asm_addr32=no
+fi
+
+rm -f conftest*
+fi
+
+
+{ echo "$as_me:$LINENO: result: $grub_cv_i386_asm_addr32" >&5
+echo "${ECHO_T}$grub_cv_i386_asm_addr32" >&6; }
+
+{ echo "$as_me:$LINENO: checking whether an absolute indirect call/jump must not be prefixed with an asterisk" >&5
+echo $ECHO_N "checking whether an absolute indirect call/jump must not be prefixed with an asterisk... $ECHO_C" >&6; }
+if test "${grub_cv_i386_asm_absolute_without_asterisk+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.s <<\EOF
+	lcall	*(offset)
+offset:
+	.long	0
+	.word	0
+EOF
+
+if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } && test -s conftest.o; then
+  grub_cv_i386_asm_absolute_without_asterisk=no
+else
+  grub_cv_i386_asm_absolute_without_asterisk=yes
+fi
+
+rm -f conftest*
+fi
+
+
+if test "x$grub_cv_i386_asm_absolute_without_asterisk" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ABSOLUTE_WITHOUT_ASTERISK 1
+_ACEOF
+
+fi
+
+{ echo "$as_me:$LINENO: result: $grub_cv_i386_asm_absolute_without_asterisk" >&5
+echo "${ECHO_T}$grub_cv_i386_asm_absolute_without_asterisk" >&6; }
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define NESTED_FUNC_ATTR
+_ACEOF
+
+fi
+
+
+
+
+# Check whether --enable-efiemu was given.
+if test "${enable_efiemu+set}" = set; then
+  enableval=$enable_efiemu;
+fi
+
+if test x"$enable_efiemu" = xno ; then
+  efiemu_excuse="explicitly disabled"
+fi
+if test x"$efiemu_excuse" = x ; then
+  { echo "$as_me:$LINENO: checking whether options required for efiemu work" >&5
+echo $ECHO_N "checking whether options required for efiemu work... $ECHO_C" >&6; }
+if test "${grub_cv_cc_efiemu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    CFLAGS="$CFLAGS -m64 -mcmodel=large -mno-red-zone -nostdlib"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  grub_cv_cc_efiemu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	grub_cv_cc_efiemu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ echo "$as_me:$LINENO: result: $grub_cv_cc_efiemu" >&5
+echo "${ECHO_T}$grub_cv_cc_efiemu" >&6; }
+  if test x$grub_cv_cc_efiemu = xno; then
+     efiemu_excuse="cannot compile with -m64 -mcmodel=large -mno-red-zone -nostdlib"
+  fi
+fi
+if test x"$enable_efiemu" = xyes && test x"$efiemu_excuse" != x ; then
+  { { echo "$as_me:$LINENO: error: efiemu runtime was explicitly requested but can't be compiled" >&5
+echo "$as_me: error: efiemu runtime was explicitly requested but can't be compiled" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test x"$efiemu_excuse" = x ; then
+enable_efiemu=yes
+else
+enable_efiemu=no
+fi
+
+
+
+# Restore the flags.
+CC="$tmp_CC"
+CFLAGS="$tmp_CFLAGS"
+CPPFLAGS="$tmp_CPPFLAGS"
+LDFLAGS="$tmp_LDFLAGS"
+LIBS="$tmp_LIBS"
+
+#
+# Check for options.
+#
+
+# Memory manager debugging.
+# Check whether --enable-mm-debug was given.
+if test "${enable_mm_debug+set}" = set; then
+  enableval=$enable_mm_debug;
+cat >>confdefs.h <<\_ACEOF
+#define MM_DEBUG 1
+_ACEOF
+
+fi
+
+
+# Check whether --enable-grub-emu was given.
+if test "${enable_grub_emu+set}" = set; then
+  enableval=$enable_grub_emu;
+fi
+
+# Check whether --enable-grub-emu-usb was given.
+if test "${enable_grub_emu_usb+set}" = set; then
+  enableval=$enable_grub_emu_usb;
+fi
+
+if test x"$enable_grub_emu" = xno ; then
+  grub_emu_excuse="explicitly disabled"
+fi
+
+  # Check for curses libraries.
+if [ x"$grub_emu_excuse" = x ]; then
+  { echo "$as_me:$LINENO: checking for wgetch in -lncurses" >&5
+echo $ECHO_N "checking for wgetch in -lncurses... $ECHO_C" >&6; }
+if test "${ac_cv_lib_ncurses_wgetch+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lncurses  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char wgetch ();
+int
+main (void)
+{
+return wgetch ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_ncurses_wgetch=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_ncurses_wgetch=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_ncurses_wgetch" >&5
+echo "${ECHO_T}$ac_cv_lib_ncurses_wgetch" >&6; }
+if test $ac_cv_lib_ncurses_wgetch = yes; then
+  LIBCURSES="-lncurses"
+else
+  { echo "$as_me:$LINENO: checking for wgetch in -lcurses" >&5
+echo $ECHO_N "checking for wgetch in -lcurses... $ECHO_C" >&6; }
+if test "${ac_cv_lib_curses_wgetch+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcurses  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char wgetch ();
+int
+main (void)
+{
+return wgetch ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_curses_wgetch=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_curses_wgetch=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_curses_wgetch" >&5
+echo "${ECHO_T}$ac_cv_lib_curses_wgetch" >&6; }
+if test $ac_cv_lib_curses_wgetch = yes; then
+  LIBCURSES="-lcurses"
+else
+  grub_emu_excuse="need (n)curses libraries"
+fi
+
+fi
+
+
+fi
+if [ x"$grub_emu_excuse" = x ]; then
+  # Check for headers.
+
+for ac_header in ncurses/curses.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-grub@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+
+for ac_header in ncurses.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-grub@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+
+for ac_header in curses.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-grub@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  grub_emu_excuse="need (n)curses headers"
+fi
+
+done
+
+fi
+
+done
+
+fi
+
+done
+
+fi
+
+if test x"$enable_grub_emu" = xyes && test x"$grub_emu_excuse" != x ; then
+  { { echo "$as_me:$LINENO: error: grub-emu was explicitly requested but can't be compiled" >&5
+echo "$as_me: error: grub-emu was explicitly requested but can't be compiled" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test x"$grub_emu_excuse" = x ; then
+enable_grub_emu=yes
+else
+enable_grub_emu=no
+grub_emu_usb_excuse="grub-emu isn't built"
+fi
+if test x"$enable_grub_emu_usb" = xno ; then
+  grub_emu_usb_excuse="explicitly disabled"
+fi
+if [ x"$grub_emu_usb_excuse" = x ]; then
+    # Check for libusb libraries.
+{ echo "$as_me:$LINENO: checking for usb_claim_interface in -lusb" >&5
+echo $ECHO_N "checking for usb_claim_interface in -lusb... $ECHO_C" >&6; }
+if test "${ac_cv_lib_usb_usb_claim_interface+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lusb  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char usb_claim_interface ();
+int
+main (void)
+{
+return usb_claim_interface ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_usb_usb_claim_interface=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_usb_usb_claim_interface=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_usb_usb_claim_interface" >&5
+echo "${ECHO_T}$ac_cv_lib_usb_usb_claim_interface" >&6; }
+if test $ac_cv_lib_usb_usb_claim_interface = yes; then
+  LIBUSB="-lusb"
+else
+  grub_emu_usb_excuse="need libusb library"
+fi
+
+
+fi
+if [ x"$grub_emu_usb_excuse" = x ]; then
+    # Check for headers.
+
+for ac_header in usb.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-grub@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  grub_emu_usb_excuse="need libusb headers"
+fi
+
+done
+
+fi
+if test x"$enable_grub_emu_usb" = xyes && test x"$grub_emu_usb_excuse" != x ; then
+  { { echo "$as_me:$LINENO: error: USB support for grub-emu was explicitly requested but can't be compiled" >&5
+echo "$as_me: error: USB support for grub-emu was explicitly requested but can't be compiled" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test x"$grub_emu_usb_excuse" = x ; then
+enable_grub_emu_usb=yes
+else
+enable_grub_emu_usb=no
+fi
+
+
+
+
+# Check whether --enable-grub-fstest was given.
+if test "${enable_grub_fstest+set}" = set; then
+  enableval=$enable_grub_fstest;
+fi
+
+if test x"$enable_grub_fstest" = xno ; then
+  grub_fstest_excuse="explicitly disabled"
+fi
+if test x"$grub_fstest_excuse" = x ; then
+enable_grub_fstest=yes
+else
+enable_grub_fstest=no
+fi
+
+
+# Check whether --enable-grub-mkfont was given.
+if test "${enable_grub_mkfont+set}" = set; then
+  enableval=$enable_grub_mkfont;
+fi
+
+if test x"$enable_grub_mkfont" = xno ; then
+  grub_mkfont_excuse="explicitly disabled"
+fi
+
+if test x"$grub_mkfont_excuse" = x ; then
+  # Check for freetype libraries.
+  for ac_prog in freetype-config
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_FREETYPE+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$FREETYPE"; then
+  ac_cv_prog_FREETYPE="$FREETYPE" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_FREETYPE="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+FREETYPE=$ac_cv_prog_FREETYPE
+if test -n "$FREETYPE"; then
+  { echo "$as_me:$LINENO: result: $FREETYPE" >&5
+echo "${ECHO_T}$FREETYPE" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$FREETYPE" && break
+done
+
+  if test "x$FREETYPE" = x ; then
+    grub_mkfont_excuse="need freetype2 library"
+  fi
+  freetype_cflags=`freetype-config --cflags`
+  freetype_libs=`freetype-config --libs`
+fi
+if test x"$enable_grub_mkfont" = xyes && test x"$grub_mkfont_excuse" != x ; then
+  { { echo "$as_me:$LINENO: error: grub-mkfont was explicitly requested but can't be compiled" >&5
+echo "$as_me: error: grub-mkfont was explicitly requested but can't be compiled" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test x"$grub_mkfont_excuse" = x ; then
+enable_grub_mkfont=yes
+else
+enable_grub_mkfont=no
+fi
+
+
+
+
+
+
+# Output files.
+
+{ echo "$as_me:$LINENO: checking whether ln can handle directories properly" >&5
+echo $ECHO_N "checking whether ln can handle directories properly... $ECHO_C" >&6; }
+mkdir testdir 2>/dev/null
+case $srcdir in
+[\\/$]* | ?:[\\/]* ) reldir=$srcdir/include/grub/util ;;
+    *) reldir=../$srcdir/include/grub/util ;;
+esac
+if ln -s $reldir testdir/util 2>/dev/null ; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+  link_dir=yes
+else
+  link_dir=no
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+rm -rf testdir
+
+if test x"$link_dir" = xyes ; then
+  ac_config_links="$ac_config_links include/grub/cpu:include/grub/$target_cpu include/grub/machine:include/grub/$target_cpu/$platform"
+
+else
+  mkdir -p include/grub 2>/dev/null
+  rm -rf include/grub/cpu
+  cp -rp $srcdir/include/grub/$target_cpu include/grub/cpu 2>/dev/null
+  rm -rf include/grub/machine
+  cp -rp $srcdir/include/grub/$target_cpu/$platform include/grub/machine 2>/dev/null
+fi
+ac_config_files="$ac_config_files Makefile gensymlist.sh genkernsyms.sh"
+
+ac_config_files="$ac_config_files stamp-h"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      *) $as_unset $ac_var ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { echo "$as_me:$LINENO: updating cache $cache_file" >&5
+echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in
+  *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line after each line using $LINENO; the second 'sed'
+  # does the real work.  The second script uses 'N' to pair each
+  # line-number line with the line containing $LINENO, and appends
+  # trailing '-' during substitution so that $LINENO is not a special
+  # case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # scripts with optimization help from Paolo Bonzini.  Blame Lee
+  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+  case `echo 'x\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  *)   ECHO_C='\c';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s='ln -s'
+  # ... but there are two gotchas:
+  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+  # In both cases, we have to default to `cp -p'.
+  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+    as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+        test -d "$1/.";
+      else
+	case $1 in
+        -*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by GRUB $as_me 1.97, which was
+generated by GNU Autoconf 2.61.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_links="$ac_config_links"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration links:
+$config_links
+
+Report bugs to <bug-autoconf@gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+GRUB config.status 1.97
+configured by $0, generated by GNU Autoconf 2.61,
+  with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2006 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    echo "$ac_cs_version"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    { echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  CONFIG_SHELL=$SHELL
+  export CONFIG_SHELL
+  exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+    "include/grub/cpu") CONFIG_LINKS="$CONFIG_LINKS include/grub/cpu:include/grub/$target_cpu" ;;
+    "include/grub/machine") CONFIG_LINKS="$CONFIG_LINKS include/grub/machine:include/grub/$target_cpu/$platform" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "gensymlist.sh") CONFIG_FILES="$CONFIG_FILES gensymlist.sh" ;;
+    "genkernsyms.sh") CONFIG_FILES="$CONFIG_FILES genkernsyms.sh" ;;
+    "stamp-h") CONFIG_FILES="$CONFIG_FILES stamp-h" ;;
+
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+#
+# Set up the sed scripts for CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "$CONFIG_FILES"; then
+
+_ACEOF
+
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  cat >conf$$subs.sed <<_ACEOF
+SHELL!$SHELL$ac_delim
+PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
+PACKAGE_NAME!$PACKAGE_NAME$ac_delim
+PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
+PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
+PACKAGE_STRING!$PACKAGE_STRING$ac_delim
+PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
+exec_prefix!$exec_prefix$ac_delim
+prefix!$prefix$ac_delim
+program_transform_name!$program_transform_name$ac_delim
+bindir!$bindir$ac_delim
+sbindir!$sbindir$ac_delim
+libexecdir!$libexecdir$ac_delim
+datarootdir!$datarootdir$ac_delim
+datadir!$datadir$ac_delim
+sysconfdir!$sysconfdir$ac_delim
+sharedstatedir!$sharedstatedir$ac_delim
+localstatedir!$localstatedir$ac_delim
+includedir!$includedir$ac_delim
+oldincludedir!$oldincludedir$ac_delim
+docdir!$docdir$ac_delim
+infodir!$infodir$ac_delim
+htmldir!$htmldir$ac_delim
+dvidir!$dvidir$ac_delim
+pdfdir!$pdfdir$ac_delim
+psdir!$psdir$ac_delim
+libdir!$libdir$ac_delim
+localedir!$localedir$ac_delim
+mandir!$mandir$ac_delim
+DEFS!$DEFS$ac_delim
+ECHO_C!$ECHO_C$ac_delim
+ECHO_N!$ECHO_N$ac_delim
+ECHO_T!$ECHO_T$ac_delim
+LIBS!$LIBS$ac_delim
+build_alias!$build_alias$ac_delim
+host_alias!$host_alias$ac_delim
+target_alias!$target_alias$ac_delim
+build!$build$ac_delim
+build_cpu!$build_cpu$ac_delim
+build_vendor!$build_vendor$ac_delim
+build_os!$build_os$ac_delim
+host!$host$ac_delim
+host_cpu!$host_cpu$ac_delim
+host_vendor!$host_vendor$ac_delim
+host_os!$host_os$ac_delim
+target!$target$ac_delim
+target_cpu!$target_cpu$ac_delim
+target_vendor!$target_vendor$ac_delim
+target_os!$target_os$ac_delim
+host_kernel!$host_kernel$ac_delim
+platform!$platform$ac_delim
+CMP!$CMP$ac_delim
+YACC!$YACC$ac_delim
+UNIFONT_BDF!$UNIFONT_BDF$ac_delim
+INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
+INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
+INSTALL_DATA!$INSTALL_DATA$ac_delim
+AWK!$AWK$ac_delim
+SET_MAKE!$SET_MAKE$ac_delim
+RUBY!$RUBY$ac_delim
+MAKEINFO!$MAKEINFO$ac_delim
+CC!$CC$ac_delim
+CFLAGS!$CFLAGS$ac_delim
+LDFLAGS!$LDFLAGS$ac_delim
+CPPFLAGS!$CPPFLAGS$ac_delim
+ac_ct_CC!$ac_ct_CC$ac_delim
+EXEEXT!$EXEEXT$ac_delim
+OBJEXT!$OBJEXT$ac_delim
+CPP!$CPP$ac_delim
+GREP!$GREP$ac_delim
+EGREP!$EGREP$ac_delim
+HELP2MAN!$HELP2MAN$ac_delim
+TARGET_CC!$TARGET_CC$ac_delim
+ac_ct_TARGET_CC!$ac_ct_TARGET_CC$ac_delim
+OBJCOPY!$OBJCOPY$ac_delim
+STRIP!$STRIP$ac_delim
+NM!$NM$ac_delim
+OBJCONV!$OBJCONV$ac_delim
+TARGET_IMG_LDSCRIPT!$TARGET_IMG_LDSCRIPT$ac_delim
+TARGET_IMG_LDFLAGS!$TARGET_IMG_LDFLAGS$ac_delim
+TARGET_IMG_CFLAGS!$TARGET_IMG_CFLAGS$ac_delim
+TARGET_OBJ2ELF!$TARGET_OBJ2ELF$ac_delim
+TARGET_CFLAGS!$TARGET_CFLAGS$ac_delim
+TARGET_MODULE_FORMAT!$TARGET_MODULE_FORMAT$ac_delim
+TARGET_APPLE_CC!$TARGET_APPLE_CC$ac_delim
+TARGET_ASFLAGS!$TARGET_ASFLAGS$ac_delim
+TARGET_CPPFLAGS!$TARGET_CPPFLAGS$ac_delim
+TARGET_LDFLAGS!$TARGET_LDFLAGS$ac_delim
+enable_efiemu!$enable_efiemu$ac_delim
+LIBCURSES!$LIBCURSES$ac_delim
+LIBUSB!$LIBUSB$ac_delim
+enable_grub_emu!$enable_grub_emu$ac_delim
+enable_grub_emu_usb!$enable_grub_emu_usb$ac_delim
+enable_grub_fstest!$enable_grub_fstest$ac_delim
+FREETYPE!$FREETYPE$ac_delim
+enable_grub_mkfont!$enable_grub_mkfont$ac_delim
+freetype_cflags!$freetype_cflags$ac_delim
+_ACEOF
+
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
+    break
+  elif $ac_last_try; then
+    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+   { (exit 1); exit 1; }; }
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+  ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+CEOF$ac_eof
+_ACEOF
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  cat >conf$$subs.sed <<_ACEOF
+freetype_libs!$freetype_libs$ac_delim
+ASFLAGS!$ASFLAGS$ac_delim
+LIBOBJS!$LIBOBJS$ac_delim
+LTLIBOBJS!$LTLIBOBJS$ac_delim
+_ACEOF
+
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 4; then
+    break
+  elif $ac_last_try; then
+    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+   { (exit 1); exit 1; }; }
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+  ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+:end
+s/|#_!!_#|//g
+CEOF$ac_eof
+_ACEOF
+
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[	 ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+fi # test -n "$CONFIG_FILES"
+
+
+for ac_tag in  :F $CONFIG_FILES  :H $CONFIG_HEADERS  :L $CONFIG_LINKS
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+   { (exit 1); exit 1; }; };;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+   { (exit 1); exit 1; }; };;
+      esac
+      ac_file_inputs="$ac_file_inputs $ac_f"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input="Generated from "`IFS=:
+	  echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    fi
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin";;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  { as_dir="$ac_dir"
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
+   { (exit 1); exit 1; }; }; }
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+case `sed -n '/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+' $ac_file_inputs` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+    s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s&@configure_input@&$configure_input&;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&5
+echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&2;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out"; rm -f "$tmp/out";;
+  *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
+  esac
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+_ACEOF
+
+# Transform confdefs.h into a sed script `conftest.defines', that
+# substitutes the proper values into config.h.in to produce config.h.
+rm -f conftest.defines conftest.tail
+# First, append a space to every undef/define line, to ease matching.
+echo 's/$/ /' >conftest.defines
+# Then, protect against being on the right side of a sed subst, or in
+# an unquoted here document, in config.status.  If some macros were
+# called several times there might be several #defines for the same
+# symbol, which is useless.  But do not sort them, since the last
+# AC_DEFINE must be honored.
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where
+# NAME is the cpp macro being defined, VALUE is the value it is being given.
+# PARAMS is the parameter list in the macro definition--in most cases, it's
+# just an empty string.
+ac_dA='s,^\\([	 #]*\\)[^	 ]*\\([	 ]*'
+ac_dB='\\)[	 (].*,\\1define\\2'
+ac_dC=' '
+ac_dD=' ,'
+
+uniq confdefs.h |
+  sed -n '
+	t rset
+	:rset
+	s/^[	 ]*#[	 ]*define[	 ][	 ]*//
+	t ok
+	d
+	:ok
+	s/[\\&,]/\\&/g
+	s/^\('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p
+	s/^\('"$ac_word_re"'\)[	 ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p
+  ' >>conftest.defines
+
+# Remove the space that was appended to ease matching.
+# Then replace #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+# (The regexp can be short, since the line contains either #define or #undef.)
+echo 's/ $//
+s,^[	 #]*u.*,/* & */,' >>conftest.defines
+
+# Break up conftest.defines:
+ac_max_sed_lines=50
+
+# First sed command is:	 sed -f defines.sed $ac_file_inputs >"$tmp/out1"
+# Second one is:	 sed -f defines.sed "$tmp/out1" >"$tmp/out2"
+# Third one will be:	 sed -f defines.sed "$tmp/out2" >"$tmp/out1"
+# et cetera.
+ac_in='$ac_file_inputs'
+ac_out='"$tmp/out1"'
+ac_nxt='"$tmp/out2"'
+
+while :
+do
+  # Write a here document:
+    cat >>$CONFIG_STATUS <<_ACEOF
+    # First, check the format of the line:
+    cat >"\$tmp/defines.sed" <<\\CEOF
+/^[	 ]*#[	 ]*undef[	 ][	 ]*$ac_word_re[	 ]*\$/b def
+/^[	 ]*#[	 ]*define[	 ][	 ]*$ac_word_re[(	 ]/b def
+b
+:def
+_ACEOF
+  sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+    sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS
+  ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in
+  sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail
+  grep . conftest.tail >/dev/null || break
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines conftest.tail
+
+echo "ac_result=$ac_in" >>$CONFIG_STATUS
+cat >>$CONFIG_STATUS <<\_ACEOF
+  if test x"$ac_file" != x-; then
+    echo "/* $configure_input  */" >"$tmp/config.h"
+    cat "$ac_result" >>"$tmp/config.h"
+    if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f $ac_file
+      mv "$tmp/config.h" $ac_file
+    fi
+  else
+    echo "/* $configure_input  */"
+    cat "$ac_result"
+  fi
+  rm -f "$tmp/out12"
+ ;;
+  :L)
+  #
+  # CONFIG_LINK
+  #
+
+  { echo "$as_me:$LINENO: linking $srcdir/$ac_source to $ac_file" >&5
+echo "$as_me: linking $srcdir/$ac_source to $ac_file" >&6;}
+
+  if test ! -r "$srcdir/$ac_source"; then
+    { { echo "$as_me:$LINENO: error: $srcdir/$ac_source: file not found" >&5
+echo "$as_me: error: $srcdir/$ac_source: file not found" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  rm -f "$ac_file"
+
+  # Try a relative symlink, then a hard link, then a copy.
+  case $srcdir in
+  [\\/$]* | ?:[\\/]* ) ac_rel_source=$srcdir/$ac_source ;;
+      *) ac_rel_source=$ac_top_build_prefix$srcdir/$ac_source ;;
+  esac
+  ln -s "$ac_rel_source" "$ac_file" 2>/dev/null ||
+    ln "$srcdir/$ac_source" "$ac_file" 2>/dev/null ||
+    cp -p "$srcdir/$ac_source" "$ac_file" ||
+    { { echo "$as_me:$LINENO: error: cannot link or copy $srcdir/$ac_source to $ac_file" >&5
+echo "$as_me: error: cannot link or copy $srcdir/$ac_source to $ac_file" >&2;}
+   { (exit 1); exit 1; }; }
+ ;;
+
+  esac
+
+
+  case $ac_file$ac_mode in
+    "stamp-h":F) echo timestamp > stamp-h ;;
+
+  esac
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+
+echo "*******************************************************"
+echo GRUB2 will be compiled with following components:
+echo Platform: "$target_cpu"-"$platform"
+if [ x"$grub_emu_excuse" = x ]; then
+echo grub-emu: Yes
+else
+echo grub-emu: No "($grub_emu_excuse)"
+fi
+if [ x"$grub_emu_usb_excuse" = x ]; then
+echo USB support for grub-emu: Yes
+else
+echo USB support for grub-emu: No "($grub_emu_usb_excuse)"
+fi
+if [ x"$enable_mm_debug" = xyes ]; then
+echo With memory debugging: Yes
+else
+echo With memory debugging: No
+fi
+if [ x"$efiemu_excuse" = x ]; then
+echo efiemu runtime: Yes
+else
+echo efiemu runtime: No "($efiemu_excuse)"
+fi
+if [ x"$grub_fstest_excuse" = x ]; then
+echo grub-fstest: Yes
+else
+echo grub-fstest: No "($grub_fstest_excuse)"
+fi
+if [ x"$grub_mkfont_excuse" = x ]; then
+echo grub-mkfont: Yes
+else
+echo grub-mkfont: No "($grub_mkfont_excuse)"
+fi
+echo "*******************************************************"
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..048333b
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,656 @@
+# Process this file with autoconf to produce a configure script.
+
+# Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+#
+# This configure.ac is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+dnl This configure script is complicated, because GRUB needs to deal
+dnl with three potentially different types:
+dnl
+dnl   build  -- the environment for building GRUB
+dnl   host   -- the environment for running utilities
+dnl   target -- the environment for running GRUB
+dnl
+dnl In addition, GRUB needs to deal with a platform specification
+dnl which specifies the system running GRUB, such as firmware.
+dnl This is necessary because the target type in autoconf does not
+dnl describe such a system very well.
+dnl
+dnl The current strategy is to use variables with no prefix (such as
+dnl CC, CFLAGS, etc.) for the host type as well as the build type,
+dnl because GRUB does not need to use those variables for the build
+dnl type, so there is no conflict. Variables with the prefix "TARGET_"
+dnl (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for the target
+dnl type.
+
+
+AC_INIT([GRUB],[1.97],[bug-grub@gnu.org])
+AC_PREREQ(2.59)
+AC_CONFIG_SRCDIR([include/grub/dl.h])
+AC_CONFIG_HEADER([config.h])
+
+# Checks for host and target systems.
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
+# Program name transformations
+AC_ARG_PROGRAM
+
+case "$target_cpu" in
+  i[[3456]]86)	target_cpu=i386 ;;
+  sparc)	target_cpu=sparc64 ;;
+esac
+
+# Specify the platform (such as firmware).
+AC_ARG_WITH([platform],
+            AS_HELP_STRING([--with-platform=PLATFORM],
+                           [select the host platform [[guessed]]]))
+
+# Guess the platform if not specified.
+if test "x$with_platform" = x; then
+  case "$target_cpu"-"$target_vendor" in
+    i386-apple) platform=efi ;;
+    i386-*) platform=pc ;;
+    x86_64-apple) platform=efi ;;
+    x86_64-*) platform=pc ;;
+    powerpc-*) platform=ieee1275 ;;
+    powerpc64-*) platform=ieee1275 ;;
+    sparc64-*) platform=ieee1275 ;;
+    *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;;
+  esac
+else
+  platform="$with_platform"
+fi
+
+# Adjust CPU unless target was explicitly specified.
+if test -z "$target_alias"; then
+  case "$target_cpu"-"$platform" in
+    x86_64-efi) ;;
+    x86_64-*) target_cpu=i386 ;;
+    powerpc64-ieee1275) target_cpu=powerpc ;;
+  esac
+fi
+
+# Check if the platform is supported, make final adjustments.
+case "$target_cpu"-"$platform" in
+  i386-efi) ;;
+  x86_64-efi) ;;
+  i386-pc) ;;
+  i386-coreboot) ;;
+  i386-linuxbios) platform=coreboot ;;
+  i386-ieee1275) ;;
+  i386-qemu) ;;
+  powerpc-ieee1275) ;;
+  sparc64-ieee1275) ;;
+  *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
+esac
+
+case "$target_cpu" in
+  i386 | powerpc) target_m32=1 ;;
+  x86_64 | sparc64) target_m64=1 ;;
+esac
+
+case "$host_os" in
+  mingw32) host_os=cygwin ;;
+esac
+
+# This normalizes the names, and creates a new variable ("host_kernel")
+# while at it, since the mapping is not always 1:1 (e.g. different OSes
+# using the same kernel type).
+case "$host_os" in
+  gnu*)				host_kernel=hurd ;;
+  linux*)			host_kernel=linux ;;
+  freebsd* | kfreebsd*-gnu)	host_kernel=freebsd ;;
+  cygwin)			host_kernel=windows ;;
+esac
+
+AC_SUBST(host_cpu)
+AC_SUBST(host_os)
+AC_SUBST(host_kernel)
+
+AC_SUBST(target_cpu)
+AC_SUBST(platform)
+
+#
+# Checks for build programs.
+#
+
+# Although cmp is listed in the GNU Coding Standards as a command which
+# can used directly, OpenBSD lacks cmp in the default installation.
+AC_CHECK_PROGS([CMP], [cmp])
+if test "x$CMP" = x; then
+  AC_MSG_ERROR([cmp is not found])
+fi
+
+AC_CHECK_PROGS([YACC], [bison])
+if test "x$YACC" = x; then
+  AC_MSG_ERROR([bison is not found])
+fi
+
+for file in /usr/src/unifont.bdf ; do
+  if test -e $file ; then
+    AC_SUBST([UNIFONT_BDF], [$file])
+    break
+  fi
+done
+
+AC_PROG_INSTALL
+AC_PROG_AWK
+AC_PROG_MAKE_SET
+AC_PROG_MKDIR_P
+
+# These are not a "must".
+AC_PATH_PROG(RUBY, ruby)
+AC_PATH_PROG(MAKEINFO, makeinfo)
+
+#
+# Checks for host programs.
+#
+
+AC_PROG_CC
+# Must be GCC.
+test "x$GCC" = xyes || AC_MSG_ERROR([GCC is required])
+
+AC_GNU_SOURCE
+AC_SYS_LARGEFILE
+
+# Identify characteristics of the host architecture.
+AC_C_BIGENDIAN
+AC_CHECK_SIZEOF(void *)
+AC_CHECK_SIZEOF(long)
+
+grub_apple_cc
+if test x$grub_cv_apple_cc = xyes ; then
+  CFLAGS="$CFLAGS -DAPPLE_CC=1 -fnested-functions"
+  ASFLAGS="$ASFLAGS -DAPPLE_CC=1"
+fi
+
+if test "x$cross_compiling" = xyes; then
+  AC_MSG_WARN([cannot generate manual pages while cross compiling])
+else
+  AC_PATH_PROG(HELP2MAN, help2man)
+fi
+
+# Check for functions.
+AC_CHECK_FUNCS(posix_memalign memalign asprintf)
+
+#
+# Check for target programs.
+#
+
+# Find tools for the target.
+if test "x$target_alias" != x && test "x$host_alias" != "x$target_alias"; then
+  tmp_ac_tool_prefix="$ac_tool_prefix"
+  ac_tool_prefix=$target_alias-
+
+  AC_CHECK_TOOLS(TARGET_CC, [gcc egcs cc],
+                 [AC_MSG_ERROR([none of gcc, egcs and cc is found. set TARGET_CC manually.])])
+  AC_CHECK_TOOL(OBJCOPY, objcopy)
+  AC_CHECK_TOOL(STRIP, strip)
+  AC_CHECK_TOOL(NM, nm)
+
+  ac_tool_prefix="$tmp_ac_tool_prefix"
+else
+  if test "x$TARGET_CC" = x; then
+    TARGET_CC=$CC
+  fi
+  AC_CHECK_TOOL(OBJCOPY, objcopy)
+  AC_CHECK_TOOL(STRIP, strip)
+  AC_CHECK_TOOL(NM, nm)
+fi
+AC_SUBST(TARGET_CC)
+
+
+# Test the C compiler for the target environment.
+tmp_CC="$CC"
+tmp_CFLAGS="$CFLAGS"
+tmp_LDFLAGS="$LDFLAGS"
+tmp_CPPFLAGS="$CPPFLAGS"
+tmp_LIBS="$LIBS"
+CC="$TARGET_CC"
+CFLAGS="$TARGET_CFLAGS"
+CPPFLAGS="$TARGET_CPPFLAGS"
+LDFLAGS="$TARGET_LDFLAGS"
+LIBS=""
+
+if test "x$TARGET_CFLAGS" = x; then
+  # debug flags.
+  TARGET_CFLAGS="-Wall -W -Wshadow -Wpointer-arith -Wmissing-prototypes \
+                 -Wundef -Wstrict-prototypes -g"
+
+  # optimization flags.
+  AC_CACHE_CHECK([whether optimization for size works], grub_cv_cc_Os, [
+    CFLAGS=-Os
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+		      [grub_cv_cc_Os=yes],
+		      [grub_cv_cc_Os=no])
+  ])
+  if test "x$grub_cv_cc_Os" = xyes; then
+    TARGET_CFLAGS="$TARGET_CFLAGS -Os"
+  else
+    TARGET_CFLAGS="$TARGET_CFLAGS -O2 -fno-strength-reduce -fno-unroll-loops"
+  fi
+
+  # Force no alignment to save space on i386.
+  if test "x$target_cpu" = xi386; then
+    AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [
+      CFLAGS="$CFLAGS -falign-loops=1"
+      AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+		        [grub_cv_cc_falign_loop=yes],
+			[grub_cv_cc_falign_loop=no])
+    ])
+
+    if test "x$grub_cv_cc_falign_loop" = xyes; then
+      TARGET_CFLAGS="$TARGET_CFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1"
+    else
+      TARGET_CFLAGS="$TARGET_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1"
+    fi
+
+    # Some toolchains enable these features by default, but they need
+    # registers that aren't set up properly in GRUB.
+    TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-3dnow"
+  fi
+
+  # By default, GCC 4.4 generates .eh_frame sections containing unwind
+  # information in some cases where it previously did not. GRUB doesn't need
+  # these and they just use up vital space. Restore the old compiler
+  # behaviour.
+  AC_CACHE_CHECK([whether -fno-dwarf2-cfi-asm works], [grub_cv_cc_fno_dwarf2_cfi_asm], [
+    SAVE_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -fno-dwarf2-cfi-asm"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+		      [grub_cv_cc_fno_dwarf2_cfi_asm=yes],
+		      [grub_cv_cc_fno_dwarf2_cfi_asm=no])
+    CFLAGS="$SAVE_CFLAGS"
+  ])
+
+  if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then
+    TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm"
+  fi
+fi
+
+grub_apple_target_cc
+if test x$grub_cv_apple_target_cc = xyes ; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -DAPPLE_CC=1 -fnested-functions"
+  CFLAGS="$CFLAGS -DAPPLE_CC=1 -fnested-functions"
+  TARGET_ASFLAGS="$TARGET_ASFLAGS -DAPPLE_CC=1"
+  TARGET_APPLE_CC=1
+  AC_CHECK_PROG([OBJCONV], [objconv], [objconv], [])
+  if test "x$OBJCONV" = x ; then
+     AC_CHECK_PROG([OBJCONV], [objconv], [./objconv], [], [.])
+  fi
+  if test "x$OBJCONV" = x ; then
+    AC_MSG_ERROR([objconv not found which is required when building with apple compiler])
+  fi
+  TARGET_IMG_LDSCRIPT=
+  TARGET_IMG_CFLAGS="-static"
+  TARGET_IMG_LDFLAGS='-nostdlib -static -Wl,-preload -Wl,-segalign,20 -Wl,-image_base,'
+  TARGET_IMG_LDFLAGS_AC='-nostdlib -static -Wl,-preload -Wl,-segalign,20 -Wl,-image_base,'
+else
+  TARGET_APPLE_CC=0
+# Use linker script if present, otherwise use builtin -N script.
+if test -f "${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"; then
+  TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"
+  TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}  -Wl,-Ttext,"
+  TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"
+else
+  TARGET_IMG_LDSCRIPT=
+  TARGET_IMG_LDFLAGS='-Wl,-N  -Wl,-Ttext,'
+  TARGET_IMG_LDFLAGS_AC='-Wl,-N  -Wl,-Ttext,'
+fi
+TARGET_IMG_CFLAGS=
+fi
+
+AC_SUBST(TARGET_IMG_LDSCRIPT)
+AC_SUBST(TARGET_IMG_LDFLAGS)
+AC_SUBST(TARGET_IMG_CFLAGS)
+
+# For platforms where ELF is not the default link format.
+AC_MSG_CHECKING([for command to convert module to ELF format])
+case "${host_os}" in
+  cygwin) TARGET_OBJ2ELF='grub-pe2elf' ;;
+  *) ;;
+esac
+AC_SUBST(TARGET_OBJ2ELF)
+AC_MSG_RESULT([$TARGET_OBJ2ELF])
+
+
+if test "x$target_m32" = x1; then
+  # Force 32-bit mode.
+  TARGET_CFLAGS="$TARGET_CFLAGS -m32"
+  TARGET_LDFLAGS="$TARGET_LDFLAGS -m32"
+  TARGET_MODULE_FORMAT="elf32"
+fi
+
+if test "x$target_m64" = x1; then
+  # Force 64-bit mode.
+  TARGET_CFLAGS="$TARGET_CFLAGS -m64"
+  TARGET_LDFLAGS="$TARGET_LDFLAGS -m64"
+  TARGET_MODULE_FORMAT="elf64"
+fi
+
+if test "$target_cpu"-"$platform" = x86_64-efi; then
+  # Use large model to support 4G memory
+  AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
+    SAVED_CFLAGS=$CFLAGS
+    CFLAGS="$CFLAGS -m64 -mcmodel=large"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+		      [grub_cv_cc_mcmodel=yes],
+		      [grub_cv_cc_mcmodel=no])
+  ])
+  if test "x$grub_cv_cc_mcmodel" = xno; then
+    CFLAGS="$SAVED_CFLAGS -m64 -DMCMODEL_SMALL=1"
+    TARGET_CFLAGS="$TARGET_CFLAGS -DMCMODEL_SMALL=1"
+    AC_MSG_WARN([-mcmodel=large not supported. You won't be able to use the memory over 4GiB. Upgrade your gcc])
+  else
+    TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
+  fi
+
+  # EFI writes to stack below %rsp, we must not use the red zone
+  AC_CACHE_CHECK([whether option -mno-red-zone works], grub_cv_cc_no_red_zone, [
+    CFLAGS="$CFLAGS -m64 -mno-red-zone"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+		      [grub_cv_cc_no_red_zone=yes],
+		      [grub_cv_cc_no_red_zone=no])
+  ])
+  if test "x$grub_cv_cc_no_red_zone" = xno; then
+    AC_MSG_ERROR([-mno-red-zone not supported, upgrade your gcc])
+  fi
+
+  TARGET_CFLAGS="$TARGET_CFLAGS -mno-red-zone"
+fi
+
+#
+# Compiler features.
+#
+
+# Need __enable_execute_stack() for nested function trampolines?
+grub_CHECK_ENABLE_EXECUTE_STACK
+
+# Position independent executable.
+grub_CHECK_PIE
+[# Need that, because some distributions ship compilers that include
+# `-fPIE' in the default specs.
+if [ x"$pie_possible" = xyes ]; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE"
+fi]
+
+# Smashing stack protector.
+grub_CHECK_STACK_PROTECTOR
+# Need that, because some distributions ship compilers that include
+# `-fstack-protector' in the default specs.
+if test "x$ssp_possible" = xyes; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector"
+fi
+grub_CHECK_STACK_ARG_PROBE
+# Cygwin's GCC uses alloca() to probe the stackframe on static
+# stack allocations above some threshold.
+if test x"$sap_possible" = xyes; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe"
+fi
+
+AC_ARG_ENABLE([werror],
+	      [AS_HELP_STRING([--disable-werror],
+                             [do not use -Werror when building GRUB])])
+if test x"$enable_werror" != xno ; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -Werror"
+fi
+
+AC_SUBST(TARGET_CFLAGS)
+AC_SUBST(TARGET_MODULE_FORMAT)
+AC_SUBST(OBJCONV)
+AC_SUBST(TARGET_APPLE_CC)
+AC_SUBST(TARGET_ASFLAGS)
+AC_SUBST(TARGET_CPPFLAGS)
+AC_SUBST(TARGET_LDFLAGS)
+
+# Check for libgcc symbols (must be performed before we add -nostdlib to LDFLAGS)
+AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2)
+
+# Set them to their new values for the tests below.
+CC="$TARGET_CC"
+if test "x$TARGET_APPLE_CC" = x1 ; then
+CFLAGS="$TARGET_CFLAGS -nostdlib"
+else
+CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100"
+fi
+CPPFLAGS="$TARGET_CPPFLAGS"
+LDFLAGS="$TARGET_LDFLAGS"
+
+# Defined in aclocal.m4.
+grub_PROG_TARGET_CC
+if test "x$TARGET_APPLE_CC" != x1 ; then
+grub_PROG_OBJCOPY_ABSOLUTE
+fi
+grub_PROG_LD_BUILD_ID_NONE
+grub_ASM_USCORE
+if test "x$target_cpu" = xi386; then
+  if test ! -z "$TARGET_IMG_LDSCRIPT"; then
+    # Check symbols provided by linker script.
+    CFLAGS="$TARGET_CFLAGS -nostdlib $TARGET_IMG_LDFLAGS_AC -Wl,-Ttext,8000,--defsym,___main=0x8100"
+  fi
+  if test "x$TARGET_APPLE_CC" != x1 ; then
+    grub_CHECK_BSS_START_SYMBOL
+    grub_CHECK_END_SYMBOL
+  fi
+  CFLAGS="$TARGET_CFLAGS"
+  grub_I386_ASM_PREFIX_REQUIREMENT
+  grub_I386_ASM_ADDR32
+  grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK
+else
+  AC_DEFINE([NESTED_FUNC_ATTR], [], [Catch gcc bug])
+fi
+
+AH_BOTTOM([#if defined(__i386__) && !defined(GRUB_UTIL)
+#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1)))
+#else
+#define NESTED_FUNC_ATTR
+#endif])
+
+AC_ARG_ENABLE([efiemu],
+	      [AS_HELP_STRING([--enable-efiemu],
+                             [build and install the efiemu runtimes (default=guessed)])])
+if test x"$enable_efiemu" = xno ; then
+  efiemu_excuse="explicitly disabled"
+fi
+if test x"$efiemu_excuse" = x ; then
+  AC_CACHE_CHECK([whether options required for efiemu work], grub_cv_cc_efiemu, [
+    CFLAGS="$CFLAGS -m64 -mcmodel=large -mno-red-zone -nostdlib"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+		      [grub_cv_cc_efiemu=yes],
+		      [grub_cv_cc_efiemu=no])
+  ])
+  if test x$grub_cv_cc_efiemu = xno; then
+     efiemu_excuse="cannot compile with -m64 -mcmodel=large -mno-red-zone -nostdlib"
+  fi
+fi
+if test x"$enable_efiemu" = xyes && test x"$efiemu_excuse" != x ; then
+  AC_MSG_ERROR([efiemu runtime was explicitly requested but can't be compiled])
+fi
+if test x"$efiemu_excuse" = x ; then
+enable_efiemu=yes
+else
+enable_efiemu=no
+fi
+AC_SUBST([enable_efiemu])
+
+
+# Restore the flags.
+CC="$tmp_CC"
+CFLAGS="$tmp_CFLAGS"
+CPPFLAGS="$tmp_CPPFLAGS"
+LDFLAGS="$tmp_LDFLAGS"
+LIBS="$tmp_LIBS"
+
+#
+# Check for options.
+#
+
+# Memory manager debugging.
+AC_ARG_ENABLE([mm-debug],
+	      AS_HELP_STRING([--enable-mm-debug],
+                             [include memory manager debugging]),
+              [AC_DEFINE([MM_DEBUG], [1],
+                         [Define to 1 if you enable memory manager debugging.])])
+
+AC_ARG_ENABLE([grub-emu],
+	      [AS_HELP_STRING([--enable-grub-emu],
+                             [build and install the `grub-emu' debugging utility (default=guessed)])])
+AC_ARG_ENABLE([grub-emu-usb],
+	      [AS_HELP_STRING([--enable-grub-emu-usb],
+                             [build and install the `grub-emu' debugging utility with USB support (default=guessed)])])
+if test x"$enable_grub_emu" = xno ; then
+  grub_emu_excuse="explicitly disabled"
+fi
+
+  [# Check for curses libraries.]
+[if [ x"$grub_emu_excuse" = x ]; then ]
+  AC_CHECK_LIB([ncurses], [wgetch], [LIBCURSES="-lncurses"],
+    [AC_CHECK_LIB([curses], [wgetch], [LIBCURSES="-lcurses"],
+      [grub_emu_excuse=["need (n)curses libraries"]])])
+  AC_SUBST([LIBCURSES])
+[fi]
+[if [ x"$grub_emu_excuse" = x ]; then ]
+  [# Check for headers.]
+  AC_CHECK_HEADERS([ncurses/curses.h], [],
+    [AC_CHECK_HEADERS([ncurses.h], [],
+      [AC_CHECK_HEADERS([curses.h], [],
+	[grub_emu_excuse=["need (n)curses headers"]])])])
+[fi]
+
+if test x"$enable_grub_emu" = xyes && test x"$grub_emu_excuse" != x ; then
+  AC_MSG_ERROR([grub-emu was explicitly requested but can't be compiled])
+fi
+if test x"$grub_emu_excuse" = x ; then
+enable_grub_emu=yes
+else
+enable_grub_emu=no
+grub_emu_usb_excuse="grub-emu isn't built"
+fi
+if test x"$enable_grub_emu_usb" = xno ; then
+  grub_emu_usb_excuse="explicitly disabled"
+fi
+[if [ x"$grub_emu_usb_excuse" = x ]; then
+    # Check for libusb libraries.]
+AC_CHECK_LIB([usb], [usb_claim_interface], [LIBUSB="-lusb"],
+    [grub_emu_usb_excuse=["need libusb library"]])
+    AC_SUBST([LIBUSB])
+[fi]
+[if [ x"$grub_emu_usb_excuse" = x ]; then
+    # Check for headers.]
+    AC_CHECK_HEADERS([usb.h], [],
+      [grub_emu_usb_excuse=["need libusb headers"]])
+[fi]
+if test x"$enable_grub_emu_usb" = xyes && test x"$grub_emu_usb_excuse" != x ; then
+  AC_MSG_ERROR([USB support for grub-emu was explicitly requested but can't be compiled])
+fi
+if test x"$grub_emu_usb_excuse" = x ; then
+enable_grub_emu_usb=yes
+else
+enable_grub_emu_usb=no
+fi
+
+AC_SUBST([enable_grub_emu])
+AC_SUBST([enable_grub_emu_usb])
+
+AC_ARG_ENABLE([grub-fstest],
+	      [AS_HELP_STRING([--enable-grub-fstest],
+                             [build and install the `grub-fstest' debugging utility (default=guessed)])])
+if test x"$enable_grub_fstest" = xno ; then
+  grub_fstest_excuse="explicitly disabled"
+fi
+if test x"$grub_fstest_excuse" = x ; then
+enable_grub_fstest=yes
+else
+enable_grub_fstest=no
+fi
+AC_SUBST([enable_grub_fstest])
+
+AC_ARG_ENABLE([grub-mkfont],
+	      [AS_HELP_STRING([--enable-grub-mkfont],
+                             [build and install the `grub-mkfont' utility (default=guessed)])])
+if test x"$enable_grub_mkfont" = xno ; then
+  grub_mkfont_excuse="explicitly disabled"
+fi
+
+if test x"$grub_mkfont_excuse" = x ; then
+  # Check for freetype libraries.
+  AC_CHECK_PROGS([FREETYPE], [freetype-config])
+  if test "x$FREETYPE" = x ; then
+    grub_mkfont_excuse=["need freetype2 library"]
+  fi
+  freetype_cflags=`freetype-config --cflags`
+  freetype_libs=`freetype-config --libs`
+fi
+if test x"$enable_grub_mkfont" = xyes && test x"$grub_mkfont_excuse" != x ; then
+  AC_MSG_ERROR([grub-mkfont was explicitly requested but can't be compiled])
+fi
+if test x"$grub_mkfont_excuse" = x ; then
+enable_grub_mkfont=yes
+else
+enable_grub_mkfont=no
+fi
+AC_SUBST([enable_grub_mkfont])
+AC_SUBST([freetype_cflags])
+AC_SUBST([freetype_libs])
+
+AC_SUBST(ASFLAGS)
+
+# Output files.
+grub_CHECK_LINK_DIR
+if test x"$link_dir" = xyes ; then
+  AC_CONFIG_LINKS([include/grub/cpu:include/grub/$target_cpu
+	include/grub/machine:include/grub/$target_cpu/$platform])
+else
+  mkdir -p include/grub 2>/dev/null
+  rm -rf include/grub/cpu
+  cp -rp $srcdir/include/grub/$target_cpu include/grub/cpu 2>/dev/null
+  rm -rf include/grub/machine
+  cp -rp $srcdir/include/grub/$target_cpu/$platform include/grub/machine 2>/dev/null
+fi
+AC_CONFIG_FILES([Makefile gensymlist.sh genkernsyms.sh])
+AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h])
+AC_OUTPUT
+[
+echo "*******************************************************"
+echo GRUB2 will be compiled with following components:
+echo Platform: "$target_cpu"-"$platform"
+if [ x"$grub_emu_excuse" = x ]; then
+echo grub-emu: Yes
+else
+echo grub-emu: No "($grub_emu_excuse)"
+fi
+if [ x"$grub_emu_usb_excuse" = x ]; then
+echo USB support for grub-emu: Yes
+else
+echo USB support for grub-emu: No "($grub_emu_usb_excuse)"
+fi
+if [ x"$enable_mm_debug" = xyes ]; then
+echo With memory debugging: Yes
+else
+echo With memory debugging: No
+fi
+if [ x"$efiemu_excuse" = x ]; then
+echo efiemu runtime: Yes
+else
+echo efiemu runtime: No "($efiemu_excuse)"
+fi
+if [ x"$grub_fstest_excuse" = x ]; then
+echo grub-fstest: Yes
+else
+echo grub-fstest: No "($grub_fstest_excuse)"
+fi
+if [ x"$grub_mkfont_excuse" = x ]; then
+echo grub-mkfont: Yes
+else
+echo grub-mkfont: No "($grub_mkfont_excuse)"
+fi
+echo "*******************************************************"
+]
diff --git a/disk/ata.c b/disk/ata.c
new file mode 100644
index 0000000..78d3965
--- /dev/null
+++ b/disk/ata.c
@@ -0,0 +1,871 @@
+/* ata.c - ATA disk access.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007, 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/ata.h>
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/pci.h>
+#include <grub/scsi.h>
+
+/* At the moment, only two IDE ports are supported.  */
+static const int grub_ata_ioaddress[] = { 0x1f0, 0x170 };
+static const int grub_ata_ioaddress2[] = { 0x3f6, 0x376 };
+
+static struct grub_ata_device *grub_ata_devices;
+
+/* Wait for !BSY.  */
+grub_err_t
+grub_ata_wait_not_busy (struct grub_ata_device *dev, int milliseconds)
+{
+  /* ATA requires 400ns (after a write to CMD register) or
+     1 PIO cycle (after a DRQ block transfer) before
+     first check of BSY.  */
+  grub_millisleep (1);
+
+  int i = 1;
+  grub_uint8_t sts;
+  while ((sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS))
+	 & GRUB_ATA_STATUS_BUSY)
+    {
+      if (i >= milliseconds)
+        {
+	  grub_dprintf ("ata", "timeout: %dms, status=0x%x\n",
+			milliseconds, sts);
+	  return grub_error (GRUB_ERR_TIMEOUT, "ATA timeout");
+	}
+
+      grub_millisleep (1);
+      i++;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static inline void
+grub_ata_wait (void)
+{
+  grub_millisleep (50);
+}
+
+/* Wait for !BSY, DRQ.  */
+grub_err_t
+grub_ata_wait_drq (struct grub_ata_device *dev, int rw,
+		   int milliseconds)
+{
+  if (grub_ata_wait_not_busy (dev, milliseconds))
+    return grub_errno;
+
+  /* !DRQ implies error condition.  */
+  grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
+  if ((sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
+      != GRUB_ATA_STATUS_DRQ)
+    {
+      grub_dprintf ("ata", "ata error: status=0x%x, error=0x%x\n",
+		    sts, grub_ata_regget (dev, GRUB_ATA_REG_ERROR));
+      if (! rw)
+        return grub_error (GRUB_ERR_READ_ERROR, "ATA read error");
+      else
+        return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Byteorder has to be changed before strings can be read.  */
+static void
+grub_ata_strncpy (char *dst, char *src, grub_size_t len)
+{
+  grub_uint16_t *src16 = (grub_uint16_t *) src;
+  grub_uint16_t *dst16 = (grub_uint16_t *) dst;
+  unsigned int i;
+
+  for (i = 0; i < len / 2; i++)
+    *(dst16++) = grub_be_to_cpu16 (*(src16++));
+  dst[len] = '\0';
+}
+
+void
+grub_ata_pio_read (struct grub_ata_device *dev, char *buf, grub_size_t size)
+{
+  grub_uint16_t *buf16 = (grub_uint16_t *) buf;
+  unsigned int i;
+
+  /* Read in the data, word by word.  */
+  for (i = 0; i < size / 2; i++)
+    buf16[i] = grub_le_to_cpu16 (grub_inw(dev->ioaddress + GRUB_ATA_REG_DATA));
+}
+
+static void
+grub_ata_pio_write (struct grub_ata_device *dev, char *buf, grub_size_t size)
+{
+  grub_uint16_t *buf16 = (grub_uint16_t *) buf;
+  unsigned int i;
+
+  /* Write the data, word by word.  */
+  for (i = 0; i < size / 2; i++)
+    grub_outw(grub_cpu_to_le16 (buf16[i]), dev->ioaddress + GRUB_ATA_REG_DATA);
+}
+
+static void
+grub_ata_dumpinfo (struct grub_ata_device *dev, char *info)
+{
+  char text[41];
+
+  /* The device information was read, dump it for debugging.  */
+  grub_ata_strncpy (text, info + 20, 20);
+  grub_dprintf ("ata", "Serial: %s\n", text);
+  grub_ata_strncpy (text, info + 46, 8);
+  grub_dprintf ("ata", "Firmware: %s\n", text);
+  grub_ata_strncpy (text, info + 54, 40);
+  grub_dprintf ("ata", "Model: %s\n", text);
+
+  if (! dev->atapi)
+    {
+      grub_dprintf ("ata", "Addressing: %d\n", dev->addr);
+      grub_dprintf ("ata", "Sectors: %lld\n", dev->size);
+    }
+}
+
+static grub_err_t
+grub_atapi_identify (struct grub_ata_device *dev)
+{
+  char *info;
+
+  info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
+  if (! info)
+    return grub_errno;
+
+  grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
+  grub_ata_wait ();
+  if (grub_ata_check_ready (dev))
+    {
+      grub_free (info);
+      return grub_errno;
+    }
+
+  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE);
+  grub_ata_wait ();
+
+  if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
+    {
+      grub_free (info);
+      return grub_errno;
+    }
+  grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
+
+  dev->atapi = 1;
+
+  grub_ata_dumpinfo (dev, info);
+
+  grub_free (info);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_atapi_wait_drq (struct grub_ata_device *dev,
+		     grub_uint8_t ireason,
+		     int milliseconds)
+{
+  /* Wait for !BSY, DRQ, ireason */
+  if (grub_ata_wait_not_busy (dev, milliseconds))
+    return grub_errno;
+
+  grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
+  grub_uint8_t irs = grub_ata_regget (dev, GRUB_ATAPI_REG_IREASON);
+
+  /* OK if DRQ is asserted and interrupt reason is as expected.  */
+  if ((sts & GRUB_ATA_STATUS_DRQ)
+      && (irs & GRUB_ATAPI_IREASON_MASK) == ireason)
+    return GRUB_ERR_NONE;
+
+  /* !DRQ implies error condition.  */
+  grub_dprintf ("ata", "atapi error: status=0x%x, ireason=0x%x, error=0x%x\n",
+	        sts, irs, grub_ata_regget (dev, GRUB_ATA_REG_ERROR));
+
+  if (! (sts & GRUB_ATA_STATUS_DRQ)
+      && (irs & GRUB_ATAPI_IREASON_MASK) == GRUB_ATAPI_IREASON_ERROR)
+    {
+      if (ireason == GRUB_ATAPI_IREASON_CMD_OUT)
+	return grub_error (GRUB_ERR_READ_ERROR, "ATA PACKET command error");
+      else
+	return grub_error (GRUB_ERR_READ_ERROR, "ATAPI read error");
+    }
+
+  return grub_error (GRUB_ERR_READ_ERROR, "ATAPI protocol error");
+}
+
+static grub_err_t
+grub_atapi_packet (struct grub_ata_device *dev, char *packet,
+		   grub_size_t size)
+{
+  grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
+  if (grub_ata_check_ready (dev))
+    return grub_errno;
+
+  /* Send ATA PACKET command.  */
+  grub_ata_regset (dev, GRUB_ATA_REG_FEATURES, 0);
+  grub_ata_regset (dev, GRUB_ATAPI_REG_IREASON, 0);
+  grub_ata_regset (dev, GRUB_ATAPI_REG_CNTHIGH, size >> 8);
+  grub_ata_regset (dev, GRUB_ATAPI_REG_CNTLOW, size & 0xFF);
+
+  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_PACKET);
+
+  /* Wait for !BSY, DRQ, !I/O, C/D.  */
+  if (grub_atapi_wait_drq (dev, GRUB_ATAPI_IREASON_CMD_OUT, GRUB_ATA_TOUT_STD))
+    return grub_errno;
+
+  /* Write the packet.  */
+  grub_ata_pio_write (dev, packet, 12);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_ata_identify (struct grub_ata_device *dev)
+{
+  char *info;
+  grub_uint16_t *info16;
+
+  info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
+  if (! info)
+    return grub_errno;
+
+  info16 = (grub_uint16_t *) info;
+
+  grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
+  grub_ata_wait ();
+  if (grub_ata_check_ready (dev))
+    {
+      grub_free (info);
+      return grub_errno;
+    }
+
+  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_DEVICE);
+  grub_ata_wait ();
+
+  if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
+    {
+      grub_free (info);
+      grub_errno = GRUB_ERR_NONE;
+      grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
+
+      if ((sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ
+	  | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_ERR
+	  && (grub_ata_regget (dev, GRUB_ATA_REG_ERROR) & 0x04 /* ABRT */))
+	/* Device without ATA IDENTIFY, try ATAPI.  */
+	return grub_atapi_identify (dev);
+
+      else if (sts == 0x00)
+	/* No device, return error but don't print message.  */
+	return GRUB_ERR_UNKNOWN_DEVICE;
+
+      else
+	/* Other Error.  */
+	return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+			   "device can not be identified");
+    }
+
+  grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
+
+  /* Re-check status to avoid bogus identify data due to stuck DRQ.  */
+  grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
+  if (sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
+    {
+      grub_dprintf ("ata", "bad status=0x%x\n", sts);
+      grub_free (info);
+      /* No device, return error but don't print message.  */
+      grub_errno = GRUB_ERR_NONE;
+      return GRUB_ERR_UNKNOWN_DEVICE;
+    }
+
+  /* Now it is certain that this is not an ATAPI device.  */
+  dev->atapi = 0;
+
+  /* CHS is always supported.  */
+  dev->addr = GRUB_ATA_CHS;
+
+  /* Check if LBA is supported.  */
+  if (info16[49] & (1 << 9))
+    {
+      /* Check if LBA48 is supported.  */
+      if (info16[83] & (1 << 10))
+	dev->addr = GRUB_ATA_LBA48;
+      else
+	dev->addr = GRUB_ATA_LBA;
+    }
+
+  /* Determine the amount of sectors.  */
+  if (dev->addr != GRUB_ATA_LBA48)
+    dev->size = grub_le_to_cpu32(*((grub_uint32_t *) &info16[60]));
+  else
+    dev->size = grub_le_to_cpu64(*((grub_uint64_t *) &info16[100]));
+
+  /* Read CHS information.  */
+  dev->cylinders = info16[1];
+  dev->heads = info16[3];
+  dev->sectors_per_track = info16[6];
+
+  grub_ata_dumpinfo (dev, info);
+
+  grub_free(info);
+
+  return 0;
+}
+
+static grub_err_t
+grub_ata_device_initialize (int port, int device, int addr, int addr2)
+{
+  struct grub_ata_device *dev;
+  struct grub_ata_device **devp;
+
+  grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n",
+		port, device, addr, addr2);
+
+  dev = grub_malloc (sizeof(*dev));
+  if (! dev)
+    return grub_errno;
+
+  /* Setup the device information.  */
+  dev->port = port;
+  dev->device = device;
+  dev->ioaddress = addr;
+  dev->ioaddress2 = addr2;
+  dev->next = NULL;
+
+  grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
+  grub_ata_wait ();
+
+  /* Try to detect if the port is in use by writing to it,
+     waiting for a while and reading it again.  If the value
+     was preserved, there is a device connected.  */
+  grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
+  grub_ata_wait ();
+  grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
+  grub_dprintf ("ata", "sectors=0x%x\n", sec);
+  if (sec != 0x5A)
+    {
+      grub_free(dev);
+      return 0;
+    }
+
+  /* The above test may detect a second (slave) device
+     connected to a SATA controller which supports only one
+     (master) device.  It is not safe to use the status register
+     READY bit to check for controller channel existence.  Some
+     ATAPI commands (RESET, DIAGNOSTIC) may clear this bit.  */
+
+  /* Use the IDENTIFY DEVICE command to query the device.  */
+  if (grub_ata_identify (dev))
+    {
+      grub_free (dev);
+      return 0;
+    }
+
+  /* Register the device.  */
+  for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next);
+  *devp = dev;
+
+  return 0;
+}
+
+static int NESTED_FUNC_ATTR
+grub_ata_pciinit (int bus, int device, int func,
+		  grub_pci_id_t pciid __attribute__((unused)))
+{
+  static int compat_use[2] = { 0 };
+  grub_pci_address_t addr;
+  grub_uint32_t class;
+  grub_uint32_t bar1;
+  grub_uint32_t bar2;
+  int rega;
+  int regb;
+  int i;
+  static int controller = 0;
+
+  /* Read class.  */
+  addr = grub_pci_make_address (bus, device, func, 2);
+  class = grub_pci_read (addr);
+
+  /* Check if this class ID matches that of a PCI IDE Controller.  */
+  if (class >> 16 != 0x0101)
+    return 0;
+
+  for (i = 0; i < 2; i++)
+    {
+      /* Set to 0 when the channel operated in compatibility mode.  */
+      int compat = (class >> (8 + 2 * i)) & 1;
+
+      rega = 0;
+      regb = 0;
+
+      /* If the channel is in compatibility mode, just assign the
+	 default registers.  */
+      if (compat == 0 && !compat_use[i])
+	{
+	  rega = grub_ata_ioaddress[i];
+	  regb = grub_ata_ioaddress2[i];
+	  compat_use[i] = 1;
+	}
+      else if (compat)
+	{
+	  /* Read the BARs, which either contain a mmapped IO address
+	     or the IO port address.  */
+	  addr = grub_pci_make_address (bus, device, func, 4 + 2 * i);
+	  bar1 = grub_pci_read (addr);
+	  addr = grub_pci_make_address (bus, device, func, 5 + 2 * i);
+	  bar2 = grub_pci_read (addr);
+
+	  /* Check if the BARs describe an IO region.  */
+	  if ((bar1 & 1) && (bar2 & 1))
+	    {
+	      rega = bar1 & ~3;
+	      regb = bar2 & ~3;
+	    }
+	}
+
+      grub_dprintf ("ata",
+		    "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n",
+		    bus, device, func, compat, rega, regb);
+
+      if (rega && regb)
+	{
+	  grub_errno = GRUB_ERR_NONE;
+	  grub_ata_device_initialize (controller * 2 + i, 0, rega, regb);
+
+	  /* Most errors raised by grub_ata_device_initialize() are harmless.
+	     They just indicate this particular drive is not responding, most
+	     likely because it doesn't exist.  We might want to ignore specific
+	     error types here, instead of printing them.  */
+	  if (grub_errno)
+	    {
+	      grub_print_error ();
+	      grub_errno = GRUB_ERR_NONE;
+	    }
+
+	  grub_ata_device_initialize (controller * 2 + i, 1, rega, regb);
+
+	  /* Likewise.  */
+	  if (grub_errno)
+	    {
+	      grub_print_error ();
+	      grub_errno = GRUB_ERR_NONE;
+	    }
+	}
+    }
+
+  controller++;
+
+  return 0;
+}
+
+static grub_err_t
+grub_ata_initialize (void)
+{
+  grub_pci_iterate (grub_ata_pciinit);
+  return 0;
+}
+
+
+static void
+grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector,
+		 grub_size_t size)
+{
+  grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, size);
+  grub_ata_regset (dev, GRUB_ATA_REG_LBALOW, sector & 0xFF);
+  grub_ata_regset (dev, GRUB_ATA_REG_LBAMID, (sector >> 8) & 0xFF);
+  grub_ata_regset (dev, GRUB_ATA_REG_LBAHIGH, (sector >> 16) & 0xFF);
+}
+
+static grub_err_t
+grub_ata_setaddress (struct grub_ata_device *dev,
+		     grub_ata_addressing_t addressing,
+		     grub_disk_addr_t sector,
+		     grub_size_t size)
+{
+  switch (addressing)
+    {
+    case GRUB_ATA_CHS:
+      {
+	unsigned int cylinder;
+	unsigned int head;
+	unsigned int sect;
+
+	/* Calculate the sector, cylinder and head to use.  */
+	sect = ((grub_uint32_t) sector % dev->sectors_per_track) + 1;
+	cylinder = (((grub_uint32_t) sector / dev->sectors_per_track)
+		    / dev->heads);
+	head = ((grub_uint32_t) sector / dev->sectors_per_track) % dev->heads;
+
+	if (sect > dev->sectors_per_track
+	    || cylinder > dev->cylinders
+	    || head > dev->heads)
+	  return grub_error (GRUB_ERR_OUT_OF_RANGE,
+			     "sector %d can not be addressed "
+			     "using CHS addressing", sector);
+
+	grub_ata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4) | head);
+	if (grub_ata_check_ready (dev))
+	  return grub_errno;
+
+	grub_ata_regset (dev, GRUB_ATA_REG_SECTNUM, sect);
+	grub_ata_regset (dev, GRUB_ATA_REG_CYLLSB, cylinder & 0xFF);
+	grub_ata_regset (dev, GRUB_ATA_REG_CYLMSB, cylinder >> 8);
+
+	break;
+      }
+
+    case GRUB_ATA_LBA:
+      if (size == 256)
+	size = 0;
+      grub_ata_regset (dev, GRUB_ATA_REG_DISK,
+		       0xE0 | (dev->device << 4) | ((sector >> 24) & 0x0F));
+      if (grub_ata_check_ready (dev))
+	return grub_errno;
+
+      grub_ata_setlba (dev, sector, size);
+      break;
+
+    case GRUB_ATA_LBA48:
+      if (size == 65536)
+	size = 0;
+
+      grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | (dev->device << 4));
+      if (grub_ata_check_ready (dev))
+	return grub_errno;
+
+      /* Set "Previous".  */
+      grub_ata_setlba (dev, sector >> 24, size >> 8);
+      /* Set "Current".  */
+      grub_ata_setlba (dev, sector, size);
+
+      break;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
+		    grub_size_t size, char *buf, int rw)
+{
+  struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
+
+  grub_dprintf("ata", "grub_ata_readwrite (size=%u, rw=%d)\n", size, rw);
+
+  grub_ata_addressing_t addressing = dev->addr;
+  grub_size_t batch;
+  int cmd, cmd_write;
+
+  if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0)
+    {
+      batch = 65536;
+      cmd = GRUB_ATA_CMD_READ_SECTORS_EXT;
+      cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_EXT;
+    }
+  else
+    {
+      if (addressing == GRUB_ATA_LBA48)
+	addressing = GRUB_ATA_LBA;
+      batch = 256;
+      cmd = GRUB_ATA_CMD_READ_SECTORS;
+      cmd_write = GRUB_ATA_CMD_WRITE_SECTORS;
+    }
+
+  grub_size_t nsectors = 0;
+  while (nsectors < size)
+    {
+      if (size - nsectors < batch)
+	batch = size - nsectors;
+
+      grub_dprintf("ata", "rw=%d, sector=%llu, batch=%u\n", rw, sector, batch);
+
+      /* Send read/write command.  */
+      if (grub_ata_setaddress (dev, addressing, sector, batch))
+	return grub_errno;
+
+      grub_ata_regset (dev, GRUB_ATA_REG_CMD, (! rw ? cmd : cmd_write));
+
+      unsigned sect;
+      for (sect = 0; sect < batch; sect++)
+	{
+	  /* Wait for !BSY, DRQ.  */
+	  if (grub_ata_wait_drq (dev, rw, GRUB_ATA_TOUT_DATA))
+	    return grub_errno;
+
+	  /* Transfer data.  */
+	  if (! rw)
+	    grub_ata_pio_read (dev, buf, GRUB_DISK_SECTOR_SIZE);
+	  else
+	    grub_ata_pio_write (dev, buf, GRUB_DISK_SECTOR_SIZE);
+
+	  buf += GRUB_DISK_SECTOR_SIZE;
+	}
+
+      if (rw)
+        {
+	  /* Check for write error.  */
+	  if (grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA))
+	    return grub_errno;
+
+	  if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS)
+	      & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
+	    return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
+	}
+
+      sector += batch;
+      nsectors += batch;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+
+
+static int
+grub_ata_iterate (int (*hook) (const char *name))
+{
+  struct grub_ata_device *dev;
+
+  for (dev = grub_ata_devices; dev; dev = dev->next)
+    {
+      char devname[5];
+      grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device);
+
+      if (dev->atapi)
+	continue;
+
+      if (hook (devname))
+	return 1;
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_ata_open (const char *name, grub_disk_t disk)
+{
+  struct grub_ata_device *dev;
+
+  for (dev = grub_ata_devices; dev; dev = dev->next)
+    {
+      char devname[5];
+      grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device);
+      if (grub_strcmp (name, devname) == 0)
+	break;
+    }
+
+  if (! dev)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
+
+  if (dev->atapi)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");
+
+  disk->total_sectors = dev->size;
+
+  disk->id = (unsigned long) dev;
+
+  disk->has_partitions = 1;
+  disk->data = dev;
+
+  return 0;
+}
+
+static void
+grub_ata_close (grub_disk_t disk __attribute__((unused)))
+{
+
+}
+
+static grub_err_t
+grub_ata_read (grub_disk_t disk, grub_disk_addr_t sector,
+	       grub_size_t size, char *buf)
+{
+  return grub_ata_readwrite (disk, sector, size, buf, 0);
+}
+
+static grub_err_t
+grub_ata_write (grub_disk_t disk,
+		grub_disk_addr_t sector,
+		grub_size_t size,
+		const char *buf)
+{
+  return grub_ata_readwrite (disk, sector, size, (char *) buf, 1);
+}
+
+static struct grub_disk_dev grub_atadisk_dev =
+  {
+    .name = "ATA",
+    .id = GRUB_DISK_DEVICE_ATA_ID,
+    .iterate = grub_ata_iterate,
+    .open = grub_ata_open,
+    .close = grub_ata_close,
+    .read = grub_ata_read,
+    .write = grub_ata_write,
+    .next = 0
+  };
+
+
+
+/* ATAPI code.  */
+
+static int
+grub_atapi_iterate (int (*hook) (const char *name, int luns))
+{
+  struct grub_ata_device *dev;
+
+  for (dev = grub_ata_devices; dev; dev = dev->next)
+    {
+      char devname[7];
+      grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device);
+
+      if (! dev->atapi)
+	continue;
+
+      if (hook (devname, 1))
+	return 1;
+    }
+
+  return 0;
+
+}
+
+static grub_err_t
+grub_atapi_read (struct grub_scsi *scsi,
+		 grub_size_t cmdsize __attribute__((unused)),
+		 char *cmd, grub_size_t size, char *buf)
+{
+  struct grub_ata_device *dev = (struct grub_ata_device *) scsi->data;
+
+  grub_dprintf("ata", "grub_atapi_read (size=%u)\n", size);
+
+  if (grub_atapi_packet (dev, cmd, size))
+    return grub_errno;
+
+  grub_size_t nread = 0;
+  while (nread < size)
+    {
+      /* Wait for !BSY, DRQ, I/O, !C/D.  */
+      if (grub_atapi_wait_drq (dev, GRUB_ATAPI_IREASON_DATA_IN, GRUB_ATA_TOUT_DATA))
+	return grub_errno;
+
+      /* Get byte count for this DRQ assertion.  */
+      unsigned cnt = grub_ata_regget (dev, GRUB_ATAPI_REG_CNTHIGH) << 8
+		   | grub_ata_regget (dev, GRUB_ATAPI_REG_CNTLOW);
+      grub_dprintf("ata", "DRQ count=%u\n", cnt);
+
+      /* Count of last transfer may be uneven.  */
+      if (! (0 < cnt && cnt <= size - nread && (! (cnt & 1) || cnt == size - nread)))
+	return grub_error (GRUB_ERR_READ_ERROR, "Invalid ATAPI transfer count");
+
+      /* Read the data.  */
+      grub_ata_pio_read (dev, buf + nread, cnt);
+
+      if (cnt & 1)
+	buf[nread + cnt - 1] = (char) grub_le_to_cpu16 (grub_inw (dev->ioaddress + GRUB_ATA_REG_DATA));
+
+      nread += cnt;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_atapi_write (struct grub_scsi *scsi __attribute__((unused)),
+		  grub_size_t cmdsize __attribute__((unused)),
+		  char *cmd __attribute__((unused)),
+		  grub_size_t size __attribute__((unused)),
+		  char *buf __attribute__((unused)))
+{
+  // XXX: scsi.mod does not use write yet.
+  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ATAPI write not implemented");
+}
+
+static grub_err_t
+grub_atapi_open (const char *name, struct grub_scsi *scsi)
+{
+  struct grub_ata_device *dev;
+  struct grub_ata_device *devfnd = 0;
+
+  for (dev = grub_ata_devices; dev; dev = dev->next)
+    {
+      char devname[7];
+      grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device);
+
+      if (!grub_strcmp (devname, name))
+	{
+	  devfnd = dev;
+	  break;
+	}
+    }
+
+  grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name);
+
+  if (! devfnd)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such ATAPI device");
+
+  scsi->data = devfnd;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_atapi_close (struct grub_scsi *scsi)
+{
+  grub_free (scsi->name);
+}
+
+static struct grub_scsi_dev grub_atapi_dev =
+  {
+    .name = "ATAPI",
+    .iterate = grub_atapi_iterate,
+    .open = grub_atapi_open,
+    .close = grub_atapi_close,
+    .read = grub_atapi_read,
+    .write = grub_atapi_write
+  };
+
+
+
+GRUB_MOD_INIT(ata)
+{
+  /* To prevent two drivers operating on the same disks.  */
+  grub_disk_firmware_is_tainted = 1;
+  if (grub_disk_firmware_fini)
+    {
+      grub_disk_firmware_fini ();
+      grub_disk_firmware_fini = NULL;
+    }
+
+  /* ATA initialization.  */
+  grub_ata_initialize ();
+
+  grub_disk_dev_register (&grub_atadisk_dev);
+
+  /* ATAPI devices are handled by scsi.mod.  */
+  grub_scsi_dev_register (&grub_atapi_dev);
+}
+
+GRUB_MOD_FINI(ata)
+{
+  grub_scsi_dev_unregister (&grub_atapi_dev);
+  grub_disk_dev_unregister (&grub_atadisk_dev);
+}
diff --git a/disk/ata_pthru.c b/disk/ata_pthru.c
new file mode 100644
index 0000000..70d4f3a
--- /dev/null
+++ b/disk/ata_pthru.c
@@ -0,0 +1,107 @@
+/* ata_pthru.c - ATA pass through for ata.mod.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/ata.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+
+
+/* ATA pass through support, used by hdparm.mod.  */
+static grub_err_t
+grub_ata_pass_through (grub_disk_t disk,
+		       struct grub_disk_ata_pass_through_parms *parms)
+{
+  if (disk->dev->id != GRUB_DISK_DEVICE_ATA_ID)
+    return grub_error (GRUB_ERR_BAD_DEVICE,
+		       "Device not accessed via ata.mod");
+
+  struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
+
+  if (! (parms->size == 0 || parms->size == GRUB_DISK_SECTOR_SIZE))
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+		       "ATA multi-sector read and DATA OUT not implemented");
+
+  grub_dprintf ("ata", "ata_pass_through: cmd=0x%x, features=0x%x, sectors=0x%x\n",
+		parms->taskfile[GRUB_ATA_REG_CMD],
+		parms->taskfile[GRUB_ATA_REG_FEATURES],
+		parms->taskfile[GRUB_ATA_REG_SECTORS]);
+  grub_dprintf ("ata", "lba_high=0x%x, lba_mid=0x%x, lba_low=0x%x, size=%d\n",
+	        parms->taskfile[GRUB_ATA_REG_LBAHIGH],
+	        parms->taskfile[GRUB_ATA_REG_LBAMID],
+	        parms->taskfile[GRUB_ATA_REG_LBALOW], parms->size);
+
+  /* Set registers.  */
+  grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4
+		   | (parms->taskfile[GRUB_ATA_REG_DISK] & 0xf));
+  if (grub_ata_check_ready (dev))
+    return grub_errno;
+
+  int i;
+  for (i = GRUB_ATA_REG_FEATURES; i <= GRUB_ATA_REG_LBAHIGH; i++)
+    grub_ata_regset (dev, i, parms->taskfile[i]);
+
+  /* Start command. */
+  grub_ata_regset (dev, GRUB_ATA_REG_CMD, parms->taskfile[GRUB_ATA_REG_CMD]);
+
+  /* Wait for !BSY.  */
+  if (grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA))
+    return grub_errno;
+
+  /* Check status.  */
+  grub_int8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
+  grub_dprintf ("ata", "status=0x%x\n", sts);
+
+  /* Transfer data.  */
+  if ((sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_DRQ)
+    {
+      if (parms->size != GRUB_DISK_SECTOR_SIZE)
+        return grub_error (GRUB_ERR_READ_ERROR, "DRQ unexpected");
+      grub_ata_pio_read (dev, parms->buffer, GRUB_DISK_SECTOR_SIZE);
+    }
+
+  /* Return registers.  */
+  for (i = GRUB_ATA_REG_ERROR; i <= GRUB_ATA_REG_STATUS; i++)
+    parms->taskfile[i] = grub_ata_regget (dev, i);
+
+  grub_dprintf ("ata", "status=0x%x, error=0x%x, sectors=0x%x\n",
+	        parms->taskfile[GRUB_ATA_REG_STATUS],
+	        parms->taskfile[GRUB_ATA_REG_ERROR],
+		parms->taskfile[GRUB_ATA_REG_SECTORS]);
+
+  if (parms->taskfile[GRUB_ATA_REG_STATUS]
+      & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
+    return grub_error (GRUB_ERR_READ_ERROR, "ATA passthrough failed");
+
+  return GRUB_ERR_NONE;
+}
+
+
+
+GRUB_MOD_INIT(ata_pthru)
+{
+  /* Register ATA pass through function.  */
+  grub_disk_ata_pass_through = grub_ata_pass_through;
+}
+
+GRUB_MOD_FINI(ata_pthru)
+{
+  if (grub_disk_ata_pass_through == grub_ata_pass_through)
+    grub_disk_ata_pass_through = NULL;
+}
diff --git a/disk/dmraid_nvidia.c b/disk/dmraid_nvidia.c
new file mode 100644
index 0000000..84dfad8
--- /dev/null
+++ b/disk/dmraid_nvidia.c
@@ -0,0 +1,165 @@
+/* dmraid_nvidia.c - module to handle Nvidia fakeraid.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/raid.h>
+
+#define NV_SIGNATURES		4
+
+#define NV_IDLE			0
+#define NV_SCDB_INIT_RAID	2
+#define NV_SCDB_REBUILD_RAID	3
+#define NV_SCDB_UPGRADE_RAID	4
+#define NV_SCDB_SYNC_RAID	5
+
+#define NV_LEVEL_UNKNOWN	0x00
+#define NV_LEVEL_JBOD		0xFF
+#define NV_LEVEL_0		0x80
+#define NV_LEVEL_1		0x81
+#define NV_LEVEL_3		0x83
+#define NV_LEVEL_5		0x85
+#define NV_LEVEL_10		0x8a
+#define NV_LEVEL_1_0		0x8180
+
+#define NV_ARRAY_FLAG_BOOT		1 /* BIOS use only.  */
+#define NV_ARRAY_FLAG_ERROR		2 /* Degraded or offline.  */
+#define NV_ARRAY_FLAG_PARITY_VALID	4 /* RAID-3/5 parity valid.  */
+
+struct grub_nv_array
+{
+  grub_uint32_t version;
+  grub_uint32_t signature[NV_SIGNATURES];
+  grub_uint8_t raid_job_code;
+  grub_uint8_t stripe_width;
+  grub_uint8_t total_volumes;
+  grub_uint8_t original_width;
+  grub_uint32_t raid_level;
+  grub_uint32_t stripe_block_size;
+  grub_uint32_t stripe_block_size_bytes;
+  grub_uint32_t stripe_block_size_log2;
+  grub_uint32_t stripe_mask;
+  grub_uint32_t stripe_size;
+  grub_uint32_t stripe_size_bytes;
+  grub_uint32_t raid_job_mask;
+  grub_uint32_t original_capacity;
+  grub_uint32_t flags;
+};
+
+#define NV_ID_LEN		8
+#define NV_ID_STRING		"NVIDIA"
+#define NV_VERSION		100
+
+#define	NV_PRODID_LEN		16
+#define	NV_PRODREV_LEN		4
+
+struct grub_nv_super
+{
+  char vendor[NV_ID_LEN];	/* 0x00 - 0x07 ID string.  */
+  grub_uint32_t size;		/* 0x08 - 0x0B Size of metadata in dwords.  */
+  grub_uint32_t chksum;		/* 0x0C - 0x0F Checksum of this struct.  */
+  grub_uint16_t version;	/* 0x10 - 0x11 NV version.  */
+  grub_uint8_t unit_number;	/* 0x12 Disk index in array.  */
+  grub_uint8_t reserved;	/* 0x13.  */
+  grub_uint32_t capacity;	/* 0x14 - 0x17 Array capacity in sectors.  */
+  grub_uint32_t sector_size;	/* 0x18 - 0x1B Sector size.  */
+  char prodid[NV_PRODID_LEN];	/* 0x1C - 0x2B Array product ID.  */
+  char prodrev[NV_PRODREV_LEN];	/* 0x2C - 0x2F Array product revision */
+  grub_uint32_t unit_flags;	/* 0x30 - 0x33 Flags for this disk */
+  struct grub_nv_array array;	/* Array information */
+} __attribute__ ((packed));
+
+static grub_err_t
+grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array)
+{
+  grub_disk_addr_t sector;
+  struct grub_nv_super sb;
+
+  if (disk->partition)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "skip partition");
+
+  sector = grub_disk_get_size (disk) - 2;
+
+  if (grub_disk_read (disk, sector, 0, sizeof (sb), &sb))
+    return grub_errno;
+
+  if (grub_memcmp (sb.vendor, NV_ID_STRING, 6))
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid");
+
+  if (sb.version != NV_VERSION)
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                       "Unknown version: %d.%d", sb.version);
+
+  switch (sb.array.raid_level)
+    {
+    case NV_LEVEL_0:
+      array->level = 0;
+      array->disk_size = sb.capacity / sb.array.total_volumes;
+      break;
+
+    case NV_LEVEL_1:
+      array->level = 1;
+      array->disk_size = sb.capacity;
+      break;
+
+    case NV_LEVEL_5:
+      array->level = 5;
+      array->layout = GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC;
+      array->disk_size = sb.capacity / (sb.array.total_volumes - 1);
+      break;
+
+    default:
+      return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                         "Unsupported RAID level: %d", sb.array.raid_level);
+    }
+
+  array->number = 0;
+  array->total_devs = sb.array.total_volumes;
+  array->chunk_size = sb.array.stripe_block_size;
+  array->index = sb.unit_number;
+  array->uuid_len = sizeof (sb.array.signature);
+  array->uuid = grub_malloc (sizeof (sb.array.signature));
+  if (! array->uuid)
+    return grub_errno;
+
+  grub_memcpy (array->uuid, (char *) &sb.array.signature,
+               sizeof (sb.array.signature));
+
+  return 0;
+}
+
+static struct grub_raid grub_dmraid_nv_dev =
+{
+  .name = "dmraid_nv",
+  .detect = grub_dmraid_nv_detect,
+  .next = 0
+};
+
+GRUB_MOD_INIT(dm_nv)
+{
+  grub_raid_register (&grub_dmraid_nv_dev);
+}
+
+GRUB_MOD_FINI(dm_nv)
+{
+  grub_raid_unregister (&grub_dmraid_nv_dev);
+}
diff --git a/disk/efi/efidisk.c b/disk/efi/efidisk.c
new file mode 100644
index 0000000..de84859
--- /dev/null
+++ b/disk/efi/efidisk.c
@@ -0,0 +1,859 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/term.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/disk.h>
+
+struct grub_efidisk_data
+{
+  grub_efi_handle_t handle;
+  grub_efi_device_path_t *device_path;
+  grub_efi_device_path_t *last_device_path;
+  grub_efi_block_io_t *block_io;
+  grub_efi_disk_io_t *disk_io;
+  struct grub_efidisk_data *next;
+};
+
+/* GUIDs.  */
+static grub_efi_guid_t disk_io_guid = GRUB_EFI_DISK_IO_GUID;
+static grub_efi_guid_t block_io_guid = GRUB_EFI_BLOCK_IO_GUID;
+
+static struct grub_efidisk_data *fd_devices;
+static struct grub_efidisk_data *hd_devices;
+static struct grub_efidisk_data *cd_devices;
+
+/* Duplicate a device path.  */
+static grub_efi_device_path_t *
+duplicate_device_path (const grub_efi_device_path_t *dp)
+{
+  grub_efi_device_path_t *p;
+  grub_size_t total_size = 0;
+
+  for (p = (grub_efi_device_path_t *) dp;
+       ;
+       p = GRUB_EFI_NEXT_DEVICE_PATH (p))
+    {
+      total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
+      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
+	break;
+    }
+
+  p = grub_malloc (total_size);
+  if (! p)
+    return 0;
+
+  grub_memcpy (p, dp, total_size);
+  return p;
+}
+
+/* Return the device path node right before the end node.  */
+static grub_efi_device_path_t *
+find_last_device_path (const grub_efi_device_path_t *dp)
+{
+  grub_efi_device_path_t *next, *p;
+
+  if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
+    return 0;
+
+  for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
+       ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
+       p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
+    ;
+
+  return p;
+}
+
+/* Compare device paths.  */
+static int
+compare_device_paths (const grub_efi_device_path_t *dp1,
+		      const grub_efi_device_path_t *dp2)
+{
+  if (! dp1 || ! dp2)
+    /* Return non-zero.  */
+    return 1;
+
+  while (1)
+    {
+      grub_efi_uint8_t type1, type2;
+      grub_efi_uint8_t subtype1, subtype2;
+      grub_efi_uint16_t len1, len2;
+      int ret;
+
+      type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1);
+      type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
+
+      if (type1 != type2)
+	return (int) type2 - (int) type1;
+
+      subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1);
+      subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
+
+      if (subtype1 != subtype2)
+	return (int) subtype1 - (int) subtype2;
+
+      len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1);
+      len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2);
+
+      if (len1 != len2)
+	return (int) len1 - (int) len2;
+
+      ret = grub_memcmp (dp1, dp2, len1);
+      if (ret != 0)
+	return ret;
+
+      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1))
+	break;
+
+      dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1);
+      dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
+    }
+
+  return 0;
+}
+
+static struct grub_efidisk_data *
+make_devices (void)
+{
+  grub_efi_uintn_t num_handles;
+  grub_efi_handle_t *handles;
+  grub_efi_handle_t *handle;
+  struct grub_efidisk_data *devices = 0;
+
+  /* Find handles which support the disk io interface.  */
+  handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &disk_io_guid,
+				    0, &num_handles);
+  if (! handles)
+    return 0;
+
+  /* Make a linked list of devices.  */
+  for (handle = handles; num_handles--; handle++)
+    {
+      grub_efi_device_path_t *dp;
+      grub_efi_device_path_t *ldp;
+      struct grub_efidisk_data *d;
+      grub_efi_block_io_t *bio;
+      grub_efi_disk_io_t *dio;
+
+      dp = grub_efi_get_device_path (*handle);
+      if (! dp)
+	continue;
+
+      ldp = find_last_device_path (dp);
+      if (! ldp)
+	/* This is empty. Why?  */
+	continue;
+
+      bio = grub_efi_open_protocol (*handle, &block_io_guid,
+				    GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+      dio = grub_efi_open_protocol (*handle, &disk_io_guid,
+				    GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+      if (! bio || ! dio)
+	/* This should not happen... Why?  */
+	continue;
+
+      d = grub_malloc (sizeof (*d));
+      if (! d)
+	{
+	  /* Uggh.  */
+	  grub_free (handles);
+	  return 0;
+	}
+
+      d->handle = *handle;
+      d->device_path = dp;
+      d->last_device_path = ldp;
+      d->block_io = bio;
+      d->disk_io = dio;
+      d->next = devices;
+      devices = d;
+    }
+
+  grub_free (handles);
+
+  return devices;
+}
+
+/* Find the parent device.  */
+static struct grub_efidisk_data *
+find_parent_device (struct grub_efidisk_data *devices,
+		    struct grub_efidisk_data *d)
+{
+  grub_efi_device_path_t *dp, *ldp;
+  struct grub_efidisk_data *parent;
+
+  dp = duplicate_device_path (d->device_path);
+  if (! dp)
+    return 0;
+
+  ldp = find_last_device_path (dp);
+  ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+  ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+  ldp->length[0] = sizeof (*ldp);
+  ldp->length[1] = 0;
+
+  for (parent = devices; parent; parent = parent->next)
+    {
+      /* Ignore itself.  */
+      if (parent == d)
+	continue;
+
+      if (compare_device_paths (parent->device_path, dp) == 0)
+	{
+	  /* Found.  */
+	  if (! parent->last_device_path)
+	    parent = 0;
+
+	  break;
+	}
+    }
+
+  grub_free (dp);
+  return parent;
+}
+
+static int
+iterate_child_devices (struct grub_efidisk_data *devices,
+		       struct grub_efidisk_data *d,
+		       int (*hook) (struct grub_efidisk_data *child))
+{
+  struct grub_efidisk_data *p;
+
+  for (p = devices; p; p = p->next)
+    {
+      grub_efi_device_path_t *dp, *ldp;
+
+      dp = duplicate_device_path (p->device_path);
+      if (! dp)
+	return 0;
+
+      ldp = find_last_device_path (dp);
+      ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+      ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+      ldp->length[0] = sizeof (*ldp);
+      ldp->length[1] = 0;
+
+      if (compare_device_paths (dp, d->device_path) == 0)
+	if (hook (p))
+	  {
+	    grub_free (dp);
+	    return 1;
+	  }
+
+      grub_free (dp);
+    }
+
+  return 0;
+}
+
+/* Add a device into a list of devices in an ascending order.  */
+static void
+add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d)
+{
+  struct grub_efidisk_data **p;
+  struct grub_efidisk_data *n;
+
+  for (p = devices; *p; p = &((*p)->next))
+    {
+      int ret;
+
+      ret = compare_device_paths (find_last_device_path ((*p)->device_path),
+				  find_last_device_path (d->device_path));
+      if (ret == 0)
+	ret = compare_device_paths ((*p)->device_path,
+				    d->device_path);
+      if (ret == 0)
+	return;
+      else if (ret > 0)
+	break;
+    }
+
+  n = grub_malloc (sizeof (*n));
+  if (! n)
+    return;
+
+  grub_memcpy (n, d, sizeof (*n));
+  n->next = (*p);
+  (*p) = n;
+}
+
+/* Name the devices.  */
+static void
+name_devices (struct grub_efidisk_data *devices)
+{
+  struct grub_efidisk_data *d;
+
+  /* First, identify devices by media device paths.  */
+  for (d = devices; d; d = d->next)
+    {
+      grub_efi_device_path_t *dp;
+
+      dp = d->last_device_path;
+      if (! dp)
+	continue;
+
+      if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
+	{
+	  int is_hard_drive = 0;
+
+	  switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp))
+	    {
+	    case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
+	      is_hard_drive = 1;
+	      /* Fall through by intention.  */
+	    case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
+	      {
+		struct grub_efidisk_data *parent;
+
+		parent = find_parent_device (devices, d);
+		if (parent)
+		  {
+		    if (is_hard_drive)
+		      {
+#if 0
+			grub_printf ("adding a hard drive by a partition: ");
+			grub_print_device_path (parent->device_path);
+#endif
+			add_device (&hd_devices, parent);
+		      }
+		    else
+		      {
+#if 0
+			grub_printf ("adding a cdrom by a partition: ");
+			grub_print_device_path (parent->device_path);
+#endif
+			add_device (&cd_devices, parent);
+		      }
+
+		    /* Mark the parent as used.  */
+		    parent->last_device_path = 0;
+		  }
+	      }
+	      /* Mark itself as used.  */
+	      d->last_device_path = 0;
+	      break;
+
+	    default:
+	      /* For now, ignore the others.  */
+	      break;
+	    }
+	}
+    }
+
+  /* Let's see what can be added more.  */
+  for (d = devices; d; d = d->next)
+    {
+      grub_efi_device_path_t *dp;
+      grub_efi_block_io_media_t *m;
+
+      dp = d->last_device_path;
+      if (! dp)
+	continue;
+
+      m = d->block_io->media;
+      if (m->logical_partition)
+	{
+	  /* Only one partition in a non-media device. Assume that this
+	     is a floppy drive.  */
+#if 0
+	  grub_printf ("adding a floppy by guessing: ");
+	  grub_print_device_path (d->device_path);
+#endif
+	  add_device (&fd_devices, d);
+	}
+      else if (m->read_only && m->block_size > GRUB_DISK_SECTOR_SIZE)
+	{
+	  /* This check is too heuristic, but assume that this is a
+	     CDROM drive.  */
+#if 0
+	  grub_printf ("adding a cdrom by guessing: ");
+	  grub_print_device_path (d->device_path);
+#endif
+	  add_device (&cd_devices, d);
+	}
+      else
+	{
+	  /* The default is a hard drive.  */
+#if 0
+	  grub_printf ("adding a hard drive by guessing: ");
+	  grub_print_device_path (d->device_path);
+#endif
+	  add_device (&hd_devices, d);
+	}
+    }
+}
+
+static void
+free_devices (struct grub_efidisk_data *devices)
+{
+  struct grub_efidisk_data *p, *q;
+
+  for (p = devices; p; p = q)
+    {
+      q = p->next;
+      grub_free (p);
+    }
+}
+
+/* Enumerate all disks to name devices.  */
+static void
+enumerate_disks (void)
+{
+  struct grub_efidisk_data *devices;
+
+  devices = make_devices ();
+  if (! devices)
+    return;
+
+  name_devices (devices);
+  free_devices (devices);
+}
+
+static int
+grub_efidisk_iterate (int (*hook) (const char *name))
+{
+  struct grub_efidisk_data *d;
+  char buf[16];
+  int count;
+
+  for (d = fd_devices, count = 0; d; d = d->next, count++)
+    {
+      grub_sprintf (buf, "fd%d", count);
+      grub_dprintf ("efidisk", "iterating %s\n", buf);
+      if (hook (buf))
+	return 1;
+    }
+
+  for (d = hd_devices, count = 0; d; d = d->next, count++)
+    {
+      grub_sprintf (buf, "hd%d", count);
+      grub_dprintf ("efidisk", "iterating %s\n", buf);
+      if (hook (buf))
+	return 1;
+    }
+
+  for (d = cd_devices, count = 0; d; d = d->next, count++)
+    {
+      grub_sprintf (buf, "cd%d", count);
+      grub_dprintf ("efidisk", "iterating %s\n", buf);
+      if (hook (buf))
+	return 1;
+    }
+
+  return 0;
+}
+
+static int
+get_drive_number (const char *name)
+{
+  unsigned long drive;
+
+  if ((name[0] != 'f' && name[0] != 'h' && name[0] != 'c') || name[1] != 'd')
+    goto fail;
+
+  drive = grub_strtoul (name + 2, 0, 10);
+  if (grub_errno != GRUB_ERR_NONE)
+    goto fail;
+
+  return (int) drive ;
+
+ fail:
+  grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a efidisk");
+  return -1;
+}
+
+static struct grub_efidisk_data *
+get_device (struct grub_efidisk_data *devices, int num)
+{
+  struct grub_efidisk_data *d;
+
+  for (d = devices; d && num; d = d->next, num--)
+    ;
+
+  if (num == 0)
+    return d;
+
+  return 0;
+}
+
+static grub_err_t
+grub_efidisk_open (const char *name, struct grub_disk *disk)
+{
+  int num;
+  struct grub_efidisk_data *d = 0;
+  grub_efi_block_io_media_t *m;
+
+  grub_dprintf ("efidisk", "opening %s\n", name);
+
+  num = get_drive_number (name);
+  if (num < 0)
+    return grub_errno;
+
+  switch (name[0])
+    {
+    case 'f':
+      disk->has_partitions = 0;
+      d = get_device (fd_devices, num);
+      break;
+    case 'c':
+      /* FIXME: a CDROM should have partitions, but not implemented yet.  */
+      disk->has_partitions = 0;
+      d = get_device (cd_devices, num);
+      break;
+    case 'h':
+      disk->has_partitions = 1;
+      d = get_device (hd_devices, num);
+      break;
+    default:
+      /* Never reach here.  */
+      break;
+    }
+
+  if (! d)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device");
+
+  disk->id = ((num << 8) | name[0]);
+  m = d->block_io->media;
+  /* FIXME: Probably it is better to store the block size in the disk,
+     and total sectors should be replaced with total blocks.  */
+  grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n",
+		m, (unsigned long long) m->last_block, m->block_size);
+  disk->total_sectors = (m->last_block
+			 * (m->block_size >> GRUB_DISK_SECTOR_BITS));
+  disk->data = d;
+
+  grub_dprintf ("efidisk", "opening %s succeeded\n", name);
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_efidisk_close (struct grub_disk *disk __attribute__ ((unused)))
+{
+  /* EFI disks do not allocate extra memory, so nothing to do here.  */
+  grub_dprintf ("efidisk", "closing %s\n", disk->name);
+}
+
+static grub_err_t
+grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector,
+		   grub_size_t size, char *buf)
+{
+  /* For now, use the disk io interface rather than the block io's.  */
+  struct grub_efidisk_data *d;
+  grub_efi_disk_io_t *dio;
+  grub_efi_block_io_t *bio;
+  grub_efi_status_t status;
+
+  d = disk->data;
+  dio = d->disk_io;
+  bio = d->block_io;
+
+  grub_dprintf ("efidisk",
+		"reading 0x%lx sectors at the sector 0x%llx from %s\n",
+		(unsigned long) size, (unsigned long long) sector, disk->name);
+
+  status = efi_call_5 (dio->read, dio, bio->media->media_id,
+		      (grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS,
+		      (grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS,
+		      buf);
+  if (status != GRUB_EFI_SUCCESS)
+    return grub_error (GRUB_ERR_READ_ERROR, "efidisk read error");
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_efidisk_write (struct grub_disk *disk, grub_disk_addr_t sector,
+		    grub_size_t size, const char *buf)
+{
+  /* For now, use the disk io interface rather than the block io's.  */
+  struct grub_efidisk_data *d;
+  grub_efi_disk_io_t *dio;
+  grub_efi_block_io_t *bio;
+  grub_efi_status_t status;
+
+  d = disk->data;
+  dio = d->disk_io;
+  bio = d->block_io;
+
+  grub_dprintf ("efidisk",
+		"writing 0x%lx sectors at the sector 0x%llx to %s\n",
+		(unsigned long) size, (unsigned long long) sector, disk->name);
+
+  status = efi_call_5 (dio->write, dio, bio->media->media_id,
+		       (grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS,
+		       (grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS,
+		       (void *) buf);
+  if (status != GRUB_EFI_SUCCESS)
+    return grub_error (GRUB_ERR_WRITE_ERROR, "efidisk write error");
+
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_disk_dev grub_efidisk_dev =
+  {
+    .name = "efidisk",
+    .id = GRUB_DISK_DEVICE_EFIDISK_ID,
+    .iterate = grub_efidisk_iterate,
+    .open = grub_efidisk_open,
+    .close = grub_efidisk_close,
+    .read = grub_efidisk_read,
+    .write = grub_efidisk_write,
+    .next = 0
+  };
+
+void
+grub_efidisk_init (void)
+{
+  enumerate_disks ();
+  grub_disk_dev_register (&grub_efidisk_dev);
+}
+
+void
+grub_efidisk_fini (void)
+{
+  free_devices (fd_devices);
+  free_devices (hd_devices);
+  free_devices (cd_devices);
+  grub_disk_dev_unregister (&grub_efidisk_dev);
+}
+
+/* Some utility functions to map GRUB devices with EFI devices.  */
+grub_efi_handle_t
+grub_efidisk_get_device_handle (grub_disk_t disk)
+{
+  struct grub_efidisk_data *d;
+  char type;
+
+  if (disk->dev->id != GRUB_DISK_DEVICE_EFIDISK_ID)
+    return 0;
+
+  d = disk->data;
+  type = disk->name[0];
+
+  switch (type)
+    {
+    case 'f':
+      /* This is the simplest case.  */
+      return d->handle;
+
+    case 'c':
+      /* FIXME: probably this is not correct.  */
+      return d->handle;
+
+    case 'h':
+      /* If this is the whole disk, just return its own data.  */
+      if (! disk->partition)
+	return d->handle;
+
+      /* Otherwise, we must query the corresponding device to the firmware.  */
+      {
+	struct grub_efidisk_data *devices;
+	grub_efi_handle_t handle = 0;
+	auto int find_partition (struct grub_efidisk_data *c);
+
+	int find_partition (struct grub_efidisk_data *c)
+	  {
+	    grub_efi_hard_drive_device_path_t hd;
+
+	    grub_memcpy (&hd, c->last_device_path, sizeof (hd));
+
+	    if ((GRUB_EFI_DEVICE_PATH_TYPE (c->last_device_path)
+		 == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
+		&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (c->last_device_path)
+		    == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)
+		&& (grub_partition_get_start (disk->partition)
+		    == hd.partition_start)
+		&& (grub_partition_get_len (disk->partition)
+		    == hd.partition_size))
+	      {
+		handle = c->handle;
+		return 1;
+	      }
+
+	    return 0;
+	  }
+
+	devices = make_devices ();
+	iterate_child_devices (devices, d, find_partition);
+	free_devices (devices);
+
+	if (handle != 0)
+	  return handle;
+      }
+      break;
+
+    default:
+      break;
+    }
+
+  return 0;
+}
+
+char *
+grub_efidisk_get_device_name (grub_efi_handle_t *handle)
+{
+  grub_efi_device_path_t *dp, *ldp;
+
+  dp = grub_efi_get_device_path (handle);
+  if (! dp)
+    return 0;
+
+  ldp = find_last_device_path (dp);
+  if (! ldp)
+    return 0;
+
+  if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
+      && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp)
+	  == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))
+    {
+      /* This is a hard disk partition.  */
+      grub_disk_t parent = 0;
+      char *partition_name = 0;
+      char *device_name;
+      grub_efi_device_path_t *dup_dp, *dup_ldp;
+      grub_efi_hard_drive_device_path_t hd;
+      auto int find_parent_disk (const char *name);
+      auto int find_partition (grub_disk_t disk, const grub_partition_t part);
+
+      /* Find the disk which is the parent of a given hard disk partition.  */
+      int find_parent_disk (const char *name)
+	{
+	  grub_disk_t disk;
+
+	  disk = grub_disk_open (name);
+	  if (! disk)
+	    return 1;
+
+	  if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
+	    {
+	      struct grub_efidisk_data *d;
+
+	      d = disk->data;
+	      if (compare_device_paths (d->device_path, dup_dp) == 0)
+		{
+		  parent = disk;
+		  return 1;
+		}
+	    }
+
+	  grub_disk_close (disk);
+	  return 0;
+	}
+
+      /* Find the identical partition.  */
+      int find_partition (grub_disk_t disk __attribute__ ((unused)),
+			  const grub_partition_t part)
+	{
+	  if (grub_partition_get_start (part) == hd.partition_start
+	      && grub_partition_get_len (part) == hd.partition_size)
+	    {
+	      partition_name = grub_partition_get_name (part);
+	      return 1;
+	    }
+
+	  return 0;
+	}
+
+      /* It is necessary to duplicate the device path so that GRUB
+	 can overwrite it.  */
+      dup_dp = duplicate_device_path (dp);
+      if (! dup_dp)
+	return 0;
+
+      dup_ldp = find_last_device_path (dup_dp);
+      dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+      dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+      dup_ldp->length[0] = sizeof (*dup_ldp);
+      dup_ldp->length[1] = 0;
+
+      grub_efidisk_iterate (find_parent_disk);
+      grub_free (dup_dp);
+
+      if (! parent)
+	return 0;
+
+      /* Find a partition which matches the hard drive device path.  */
+      grub_memcpy (&hd, ldp, sizeof (hd));
+      grub_partition_iterate (parent, find_partition);
+
+      if (! partition_name)
+	{
+	  grub_disk_close (parent);
+	  return 0;
+	}
+
+      device_name = grub_malloc (grub_strlen (parent->name) + 1
+				 + grub_strlen (partition_name) + 1);
+      if (! device_name)
+	{
+	  grub_free (partition_name);
+	  grub_disk_close (parent);
+	  return 0;
+	}
+
+      grub_sprintf (device_name, "%s,%s", parent->name, partition_name);
+      grub_free (partition_name);
+      grub_disk_close (parent);
+      return device_name;
+    }
+  else
+    {
+      /* This should be an entire disk.  */
+      auto int find_disk (const char *name);
+      char *device_name = 0;
+
+      int find_disk (const char *name)
+	{
+	  grub_disk_t disk;
+
+	  disk = grub_disk_open (name);
+	  if (! disk)
+	    return 1;
+
+	  if (disk->id == GRUB_DISK_DEVICE_EFIDISK_ID)
+	    {
+	      struct grub_efidisk_data *d;
+
+	      d = disk->data;
+	      if (compare_device_paths (d->device_path, dp) == 0)
+		{
+		  device_name = grub_strdup (disk->name);
+		  grub_disk_close (disk);
+		  return 1;
+		}
+	    }
+
+	  grub_disk_close (disk);
+	  return 0;
+
+	}
+
+      grub_efidisk_iterate (find_disk);
+      return device_name;
+    }
+
+  return 0;
+}
diff --git a/disk/fs_file.c b/disk/fs_file.c
new file mode 100644
index 0000000..e095682
--- /dev/null
+++ b/disk/fs_file.c
@@ -0,0 +1,136 @@
+/* fs_file.c - Access partition by a file it contains.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+
+static grub_device_t
+search_fs_file (const char *key, unsigned long *count)
+{
+  char *filename = NULL;
+  grub_device_t ret = NULL;
+  *count = 0;
+
+  auto int iterate_device (const char *name);
+  int iterate_device (const char *name)
+  {
+    int len;
+    grub_file_t file;
+
+    (*count)++;
+
+    len = grub_strlen (name) + 2 + grub_strlen (key) + 1;
+    filename = grub_realloc (filename, len);
+    if (! filename)
+      return 1;
+
+    grub_sprintf (filename, "(%s)%s", name, key);
+    file = grub_file_open (filename);
+    if (file)
+      {
+	grub_file_close (file);
+	ret = grub_device_open (name);
+	return 1;
+      }
+
+    grub_errno = GRUB_ERR_NONE;
+    return 0;
+  }
+
+  grub_device_iterate (iterate_device);
+  grub_free (filename);
+
+  return ret;
+}
+
+static grub_err_t
+grub_fs_file_open (const char *name, grub_disk_t disk)
+{
+  grub_device_t dev;
+
+  if (grub_strncmp (name, "FILE=", sizeof ("FILE=") - 1))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a FILE virtual volume");
+
+  dev = search_fs_file (name + sizeof ("FILE=") - 1, &disk->id);
+  if (! dev)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file found");
+
+  disk->total_sectors = dev->disk->total_sectors;
+  disk->has_partitions = 0;
+  if (dev->disk->partition)
+    {
+      disk->partition = grub_malloc (sizeof (*disk->partition));
+      if (disk->partition)
+	grub_memcpy (disk->partition, dev->disk->partition,
+		     sizeof (*disk->partition));
+    }
+  else
+    disk->partition = NULL;
+
+  disk->data = dev;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_fs_file_close (grub_disk_t disk)
+{
+  grub_device_t parent = disk->data;
+  grub_device_close (parent);
+}
+
+static grub_err_t
+grub_fs_file_read (grub_disk_t disk, grub_disk_addr_t sector,
+		   grub_size_t size, char *buf)
+{
+  grub_device_t parent = disk->data;
+  return parent->disk->dev->read (parent->disk, sector, size, buf);
+}
+
+static grub_err_t
+grub_fs_file_write (grub_disk_t disk, grub_disk_addr_t sector,
+		    grub_size_t size, const char *buf)
+{
+  grub_device_t parent = disk->data;
+  return parent->disk->dev->write (parent->disk, sector, size, buf);
+}
+
+static struct grub_disk_dev grub_fs_file_dev = {
+  .name = "fs_file",
+  .id = GRUB_DISK_DEVICE_FILE_ID,
+  .open = grub_fs_file_open,
+  .close = grub_fs_file_close,
+  .read = grub_fs_file_read,
+  .write = grub_fs_file_write,
+  .next = 0
+};
+
+GRUB_MOD_INIT (fs_file)
+{
+  grub_disk_dev_register (&grub_fs_file_dev);
+}
+
+GRUB_MOD_FINI (fs_file)
+{
+  grub_disk_dev_unregister (&grub_fs_file_dev);
+}
diff --git a/disk/fs_uuid.c b/disk/fs_uuid.c
new file mode 100644
index 0000000..6901dba
--- /dev/null
+++ b/disk/fs_uuid.c
@@ -0,0 +1,149 @@
+/* fs_uuid.c - Access disks by their filesystem UUID.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+
+#include <grub/fs.h>
+#include <grub/partition.h>
+
+static grub_device_t
+search_fs_uuid (const char *key, unsigned long *count)
+{
+  *count = 0;
+  grub_device_t ret = NULL;
+
+  auto int iterate_device (const char *name);
+  int iterate_device (const char *name)
+    {
+      grub_device_t dev;
+
+      dev = grub_device_open (name);
+      if (dev)
+	{
+	  grub_fs_t fs;
+
+	  fs = grub_fs_probe (dev);
+	  if (fs && fs->uuid)
+	    {
+	      char *uuid;
+
+	      (fs->uuid) (dev, &uuid);
+	      if (grub_errno == GRUB_ERR_NONE && uuid)
+		{
+		  (*count)++;
+
+		  if (grub_strcasecmp (uuid, key) == 0)
+		    {
+		      ret = dev;
+		      grub_free (uuid);
+		      return 1;
+		    }
+		  grub_free (uuid);
+		}
+	    }
+
+	  grub_device_close (dev);
+	}
+
+      grub_errno = GRUB_ERR_NONE;
+      return 0;
+    }
+
+  grub_device_iterate (iterate_device);
+
+  return ret;
+}
+
+static grub_err_t
+grub_fs_uuid_open (const char *name, grub_disk_t disk)
+{
+  grub_device_t dev;
+
+  if (grub_strncmp (name, "UUID=", sizeof ("UUID=")-1))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a UUID virtual volume");
+
+  dev = search_fs_uuid (name + sizeof ("UUID=") - 1, &disk->id);
+  if (! dev)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching UUID found");
+
+  disk->total_sectors = dev->disk->total_sectors;
+  disk->has_partitions = 0;
+  if (dev->disk->partition)
+    {
+      disk->partition = grub_malloc (sizeof (*disk->partition));
+      if (disk->partition)
+	grub_memcpy (disk->partition, dev->disk->partition,
+		     sizeof (*disk->partition));
+    }
+  else
+    disk->partition = NULL;
+
+  disk->data = dev;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_fs_uuid_close (grub_disk_t disk __attribute((unused)))
+{
+  grub_device_t parent = disk->data;
+  grub_device_close (parent);
+}
+
+static grub_err_t
+grub_fs_uuid_read (grub_disk_t disk, grub_disk_addr_t sector,
+		   grub_size_t size, char *buf)
+{
+  grub_device_t parent = disk->data;
+  return parent->disk->dev->read (parent->disk, sector, size, buf);
+}
+
+static grub_err_t
+grub_fs_uuid_write (grub_disk_t disk, grub_disk_addr_t sector,
+		    grub_size_t size, const char *buf)
+{
+  grub_device_t parent = disk->data;
+  return parent->disk->dev->write (parent->disk, sector, size, buf);
+}
+
+static struct grub_disk_dev grub_fs_uuid_dev =
+  {
+    .name = "fs_uuid",
+    .id = GRUB_DISK_DEVICE_UUID_ID,
+    .open = grub_fs_uuid_open,
+    .close = grub_fs_uuid_close,
+    .read = grub_fs_uuid_read,
+    .write = grub_fs_uuid_write,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(fs_uuid)
+{
+  grub_disk_dev_register (&grub_fs_uuid_dev);
+}
+
+GRUB_MOD_FINI(fs_uuid)
+{
+  grub_disk_dev_unregister (&grub_fs_uuid_dev);
+}
diff --git a/disk/host.c b/disk/host.c
new file mode 100644
index 0000000..c4f3e71
--- /dev/null
+++ b/disk/host.c
@@ -0,0 +1,96 @@
+/* host.c - Dummy disk driver to provide access to the hosts filesystem  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* When using the disk, make a reference to this module.  Otherwise
+   the user will end up with a useless module :-).  */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+
+int grub_disk_host_i_want_a_reference;
+
+static int
+grub_host_iterate (int (*hook) (const char *name))
+{
+  if (hook ("host"))
+    return 1;
+  return 0;
+}
+
+static grub_err_t
+grub_host_open (const char *name, grub_disk_t disk)
+{
+  if (grub_strcmp (name, "host"))
+      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a host disk");
+
+  disk->total_sectors = 0;
+  disk->id = (unsigned long) "host";
+
+  disk->has_partitions = 0;
+  disk->data = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_host_close (grub_disk_t disk __attribute((unused)))
+{
+}
+
+static grub_err_t
+grub_host_read (grub_disk_t disk __attribute((unused)),
+		grub_disk_addr_t sector __attribute((unused)),
+		grub_size_t size __attribute((unused)),
+		char *buf __attribute((unused)))
+{
+  return GRUB_ERR_OUT_OF_RANGE;
+}
+
+static grub_err_t
+grub_host_write (grub_disk_t disk __attribute ((unused)),
+		     grub_disk_addr_t sector __attribute ((unused)),
+		     grub_size_t size __attribute ((unused)),
+		     const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_OUT_OF_RANGE;
+}
+
+static struct grub_disk_dev grub_host_dev =
+  {
+    /* The only important line in this file :-) */
+    .name = "host",
+    .id = GRUB_DISK_DEVICE_HOST_ID,
+    .iterate = grub_host_iterate,
+    .open = grub_host_open,
+    .close = grub_host_close,
+    .read = grub_host_read,
+    .write = grub_host_write,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(host)
+{
+  grub_disk_dev_register (&grub_host_dev);
+}
+
+GRUB_MOD_FINI(host)
+{
+  grub_disk_dev_unregister (&grub_host_dev);
+}
diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c
new file mode 100644
index 0000000..0a6137f
--- /dev/null
+++ b/disk/i386/pc/biosdisk.c
@@ -0,0 +1,401 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/biosdisk.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/kernel.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/term.h>
+
+static int cd_drive = 0;
+
+static int
+grub_biosdisk_get_drive (const char *name)
+{
+  unsigned long drive;
+
+  if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd')
+    goto fail;
+
+  drive = grub_strtoul (name + 2, 0, 10);
+  if (grub_errno != GRUB_ERR_NONE)
+    goto fail;
+
+  if (name[0] == 'h')
+    drive += 0x80;
+
+  return (int) drive ;
+
+ fail:
+  grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a biosdisk");
+  return -1;
+}
+
+static int
+grub_biosdisk_call_hook (int (*hook) (const char *name), int drive)
+{
+  char name[10];
+
+    grub_sprintf (name, (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
+  return hook (name);
+}
+
+static int
+grub_biosdisk_iterate (int (*hook) (const char *name))
+{
+  int drive;
+  int num_floppies;
+
+  /* For hard disks, attempt to read the MBR.  */
+  for (drive = 0x80; drive < 0x90; drive++)
+    {
+      if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1,
+				     GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0)
+	{
+	  grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive);
+	  break;
+	}
+
+      if (grub_biosdisk_call_hook (hook, drive))
+	return 1;
+    }
+
+  if (cd_drive)
+    {
+      if (grub_biosdisk_call_hook (hook, cd_drive))
+      return 1;
+    }
+
+  /* For floppy disks, we can get the number safely.  */
+  num_floppies = grub_biosdisk_get_num_floppies ();
+  for (drive = 0; drive < num_floppies; drive++)
+    if (grub_biosdisk_call_hook (hook, drive))
+      return 1;
+
+  return 0;
+}
+
+static grub_err_t
+grub_biosdisk_open (const char *name, grub_disk_t disk)
+{
+  grub_uint64_t total_sectors = 0;
+  int drive;
+  struct grub_biosdisk_data *data;
+
+  drive = grub_biosdisk_get_drive (name);
+  if (drive < 0)
+    return grub_errno;
+
+  disk->has_partitions = ((drive & 0x80) && (drive != cd_drive));
+  disk->id = drive;
+
+  data = (struct grub_biosdisk_data *) grub_zalloc (sizeof (*data));
+  if (! data)
+    return grub_errno;
+
+  data->drive = drive;
+
+  if ((cd_drive) && (drive == cd_drive))
+    {
+      data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM;
+      data->sectors = 32;
+      total_sectors = GRUB_ULONG_MAX;  /* TODO: get the correct size.  */
+    }
+  else if (drive & 0x80)
+    {
+      /* HDD */
+      int version;
+
+      version = grub_biosdisk_check_int13_extensions (drive);
+      if (version)
+	{
+	  struct grub_biosdisk_drp *drp
+	    = (struct grub_biosdisk_drp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+
+	  /* Clear out the DRP.  */
+	  grub_memset (drp, 0, sizeof (*drp));
+	  drp->size = sizeof (*drp);
+	  if (! grub_biosdisk_get_diskinfo_int13_extensions (drive, drp))
+	    {
+	      data->flags = GRUB_BIOSDISK_FLAG_LBA;
+
+	      if (drp->total_sectors)
+		total_sectors = drp->total_sectors;
+	      else
+                /* Some buggy BIOSes doesn't return the total sectors
+                   correctly but returns zero. So if it is zero, compute
+                   it by C/H/S returned by the LBA BIOS call.  */
+                total_sectors = drp->cylinders * drp->heads * drp->sectors;
+	    }
+	}
+    }
+
+  if (! (data->flags & GRUB_BIOSDISK_FLAG_CDROM))
+    {
+      if (grub_biosdisk_get_diskinfo_standard (drive,
+					       &data->cylinders,
+					       &data->heads,
+					       &data->sectors) != 0)
+        {
+	  if (total_sectors && (data->flags & GRUB_BIOSDISK_FLAG_LBA))
+	    {
+	      data->sectors = 63;
+	      data->heads = 255;
+	      data->cylinders
+		= grub_divmod64 (total_sectors
+				 + data->heads * data->sectors - 1,
+				 data->heads * data->sectors, 0);
+	    }
+	  else
+	    {
+	      grub_free (data);
+	      return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get C/H/S values");
+	    }
+        }
+
+      if (! total_sectors)
+        total_sectors = data->cylinders * data->heads * data->sectors;
+    }
+
+  disk->total_sectors = total_sectors;
+  disk->data = data;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_biosdisk_close (grub_disk_t disk)
+{
+  grub_free (disk->data);
+}
+
+/* For readability.  */
+#define GRUB_BIOSDISK_READ	0
+#define GRUB_BIOSDISK_WRITE	1
+
+#define GRUB_BIOSDISK_CDROM_RETRY_COUNT 3
+
+static grub_err_t
+grub_biosdisk_rw (int cmd, grub_disk_t disk,
+		  grub_disk_addr_t sector, grub_size_t size,
+		  unsigned segment)
+{
+  struct grub_biosdisk_data *data = disk->data;
+
+  if (data->flags & GRUB_BIOSDISK_FLAG_LBA)
+    {
+      struct grub_biosdisk_dap *dap;
+
+      dap = (struct grub_biosdisk_dap *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR
+					  + (data->sectors
+					     << GRUB_DISK_SECTOR_BITS));
+      dap->length = sizeof (*dap);
+      dap->reserved = 0;
+      dap->blocks = size;
+      dap->buffer = segment << 16;	/* The format SEGMENT:ADDRESS.  */
+      dap->block = sector;
+
+      if (data->flags & GRUB_BIOSDISK_FLAG_CDROM)
+        {
+	  int i;
+
+	  if (cmd)
+	    return grub_error (GRUB_ERR_WRITE_ERROR, "can\'t write to cdrom");
+
+	  dap->blocks = (dap->blocks + 3) >> 2;
+	  dap->block >>= 2;
+
+	  for (i = 0; i < GRUB_BIOSDISK_CDROM_RETRY_COUNT; i++)
+            if (! grub_biosdisk_rw_int13_extensions (0x42, data->drive, dap))
+	      break;
+
+	  if (i == GRUB_BIOSDISK_CDROM_RETRY_COUNT)
+	    return grub_error (GRUB_ERR_READ_ERROR, "cdrom read error");
+	}
+      else
+        if (grub_biosdisk_rw_int13_extensions (cmd + 0x42, data->drive, dap))
+	  {
+	    /* Fall back to the CHS mode.  */
+	    data->flags &= ~GRUB_BIOSDISK_FLAG_LBA;
+	    disk->total_sectors = data->cylinders * data->heads * data->sectors;
+	    return grub_biosdisk_rw (cmd, disk, sector, size, segment);
+	  }
+    }
+  else
+    {
+      unsigned coff, hoff, soff;
+      unsigned head;
+
+      /* It is impossible to reach over 8064 MiB (a bit less than LBA24) with
+	 the traditional CHS access.  */
+      if (sector >
+	  1024 /* cylinders */ *
+	  256 /* heads */ *
+	  63 /* spt */)
+	return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of disk");
+
+      soff = ((grub_uint32_t) sector) % data->sectors + 1;
+      head = ((grub_uint32_t) sector) / data->sectors;
+      hoff = head % data->heads;
+      coff = head / data->heads;
+
+      if (coff >= data->cylinders)
+	return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of disk");
+
+      if (grub_biosdisk_rw_standard (cmd + 0x02, data->drive,
+				     coff, hoff, soff, size, segment))
+	{
+	  switch (cmd)
+	    {
+	    case GRUB_BIOSDISK_READ:
+	      return grub_error (GRUB_ERR_READ_ERROR, "biosdisk read error");
+	    case GRUB_BIOSDISK_WRITE:
+	      return grub_error (GRUB_ERR_WRITE_ERROR, "biosdisk write error");
+	    }
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Return the number of sectors which can be read safely at a time.  */
+static grub_size_t
+get_safe_sectors (grub_disk_addr_t sector, grub_uint32_t sectors)
+{
+  grub_size_t size;
+  grub_uint32_t offset;
+
+  /* OFFSET = SECTOR % SECTORS */
+  grub_divmod64 (sector, sectors, &offset);
+
+  size = sectors - offset;
+
+  /* Limit the max to 0x7f because of Phoenix EDD.  */
+  if (size > 0x7f)
+    size = 0x7f;
+
+  return size;
+}
+
+static grub_err_t
+grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
+		    grub_size_t size, char *buf)
+{
+  struct grub_biosdisk_data *data = disk->data;
+
+  while (size)
+    {
+      grub_size_t len;
+
+      len = get_safe_sectors (sector, data->sectors);
+      if (len > size)
+	len = size;
+
+      if (grub_biosdisk_rw (GRUB_BIOSDISK_READ, disk, sector, len,
+			    GRUB_MEMORY_MACHINE_SCRATCH_SEG))
+	return grub_errno;
+
+      grub_memcpy (buf, (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR,
+		   len << GRUB_DISK_SECTOR_BITS);
+      buf += len << GRUB_DISK_SECTOR_BITS;
+      sector += len;
+      size -= len;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
+		     grub_size_t size, const char *buf)
+{
+  struct grub_biosdisk_data *data = disk->data;
+
+  while (size)
+    {
+      grub_size_t len;
+
+      len = get_safe_sectors (sector, data->sectors);
+      if (len > size)
+	len = size;
+
+      grub_memcpy ((void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, buf,
+		   len << GRUB_DISK_SECTOR_BITS);
+
+      if (grub_biosdisk_rw (GRUB_BIOSDISK_WRITE, disk, sector, len,
+			    GRUB_MEMORY_MACHINE_SCRATCH_SEG))
+	return grub_errno;
+
+      buf += len << GRUB_DISK_SECTOR_BITS;
+      sector += len;
+      size -= len;
+    }
+
+  return grub_errno;
+}
+
+static struct grub_disk_dev grub_biosdisk_dev =
+  {
+    .name = "biosdisk",
+    .id = GRUB_DISK_DEVICE_BIOSDISK_ID,
+    .iterate = grub_biosdisk_iterate,
+    .open = grub_biosdisk_open,
+    .close = grub_biosdisk_close,
+    .read = grub_biosdisk_read,
+    .write = grub_biosdisk_write,
+    .next = 0
+  };
+
+static void
+grub_disk_biosdisk_fini (void)
+{
+  grub_disk_dev_unregister (&grub_biosdisk_dev);
+}
+
+GRUB_MOD_INIT(biosdisk)
+{
+  struct grub_biosdisk_cdrp *cdrp
+        = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+
+  if (grub_disk_firmware_is_tainted)
+    {
+      grub_printf ("Firmware is marked as tainted, refusing to initialize.\n");
+      return;
+    }
+  grub_disk_firmware_fini = grub_disk_biosdisk_fini;
+
+  grub_memset (cdrp, 0, sizeof (*cdrp));
+  cdrp->size = sizeof (*cdrp);
+  cdrp->media_type = 0xFF;
+  if ((! grub_biosdisk_get_cdinfo_int13_extensions (grub_boot_drive, cdrp)) &&
+      ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK)
+       == GRUB_BIOSDISK_CDTYPE_NO_EMUL))
+    cd_drive = cdrp->drive_no;
+
+  grub_disk_dev_register (&grub_biosdisk_dev);
+}
+
+GRUB_MOD_FINI(biosdisk)
+{
+  grub_disk_biosdisk_fini ();
+}
diff --git a/disk/ieee1275/nand.c b/disk/ieee1275/nand.c
new file mode 100644
index 0000000..37427f8
--- /dev/null
+++ b/disk/ieee1275/nand.c
@@ -0,0 +1,215 @@
+/* nand.c - NAND flash disk access.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/ieee1275/ieee1275.h>
+
+struct grub_nand_data
+{
+  grub_ieee1275_ihandle_t handle;
+  grub_uint32_t block_size;
+};
+
+static int
+grub_nand_iterate (int (*hook) (const char *name))
+{
+  auto int dev_iterate (struct grub_ieee1275_devalias *alias);
+  int dev_iterate (struct grub_ieee1275_devalias *alias)
+    {
+      if (! grub_strcmp (alias->name, "nand"))
+        {
+          hook (alias->name);
+          return 1;
+        }
+
+      return 0;
+    }
+
+  return grub_devalias_iterate (dev_iterate);
+}
+
+static grub_err_t
+grub_nand_read (grub_disk_t disk, grub_disk_addr_t sector,
+                grub_size_t size, char *buf);
+
+static grub_err_t
+grub_nand_open (const char *name, grub_disk_t disk)
+{
+  grub_ieee1275_ihandle_t dev_ihandle = 0;
+  struct grub_nand_data *data = 0;
+  struct size_args
+    {
+      struct grub_ieee1275_common_hdr common;
+      grub_ieee1275_cell_t method;
+      grub_ieee1275_cell_t ihandle;
+      grub_ieee1275_cell_t result;
+      grub_ieee1275_cell_t size1;
+      grub_ieee1275_cell_t size2;
+    } args;
+
+  if (! grub_strstr (name, "nand"))
+    return  grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Not a nand device");
+
+  data = grub_malloc (sizeof (*data));
+  if (! data)
+    goto fail;
+
+  grub_ieee1275_open (name, &dev_ihandle);
+  if (! dev_ihandle)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
+      goto fail;
+    }
+
+  data->handle = dev_ihandle;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2);
+  args.method = (grub_ieee1275_cell_t) "block-size";
+  args.ihandle = dev_ihandle;
+  args.result = 1;
+
+  if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't get block size");
+      goto fail;
+    }
+
+  data->block_size = (args.size1 >> GRUB_DISK_SECTOR_BITS);
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3);
+  args.method = (grub_ieee1275_cell_t) "size";
+  args.ihandle = dev_ihandle;
+  args.result = 1;
+
+  if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't get disk size");
+      goto fail;
+    }
+
+  disk->total_sectors = args.size1;
+  disk->total_sectors <<= 32;
+  disk->total_sectors += args.size2;
+  disk->total_sectors >>= GRUB_DISK_SECTOR_BITS;
+
+  disk->id = dev_ihandle;
+
+  disk->has_partitions = 0;
+  disk->data = data;
+
+  return 0;
+
+fail:
+  if (dev_ihandle)
+    grub_ieee1275_close (dev_ihandle);
+  grub_free (data);
+  return grub_errno;
+}
+
+static void
+grub_nand_close (grub_disk_t disk)
+{
+  grub_ieee1275_close (((struct grub_nand_data *) disk->data)->handle);
+  grub_free (disk->data);
+}
+
+static grub_err_t
+grub_nand_read (grub_disk_t disk, grub_disk_addr_t sector,
+                grub_size_t size, char *buf)
+{
+  struct grub_nand_data *data = disk->data;
+  grub_size_t bsize, ofs;
+
+  struct read_args
+    {
+      struct grub_ieee1275_common_hdr common;
+      grub_ieee1275_cell_t method;
+      grub_ieee1275_cell_t ihandle;
+      grub_ieee1275_cell_t ofs;
+      grub_ieee1275_cell_t page;
+      grub_ieee1275_cell_t len;
+      grub_ieee1275_cell_t buf;
+      grub_ieee1275_cell_t result;
+    } args;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
+  args.method = (grub_ieee1275_cell_t) "pio-read";
+  args.ihandle = data->handle;
+  args.buf = (grub_ieee1275_cell_t) buf;
+  args.page = (grub_ieee1275_cell_t) ((grub_size_t) sector / data->block_size);
+
+  ofs = ((grub_size_t) sector % data->block_size) << GRUB_DISK_SECTOR_BITS;
+  size <<= GRUB_DISK_SECTOR_BITS;
+  bsize = (data->block_size << GRUB_DISK_SECTOR_BITS);
+
+  do
+    {
+      grub_size_t len;
+
+      len = (ofs + size > bsize) ? (bsize - ofs) : size;
+
+      args.len = (grub_ieee1275_cell_t) len;
+      args.ofs = (grub_ieee1275_cell_t) ofs;
+      args.result = 1;
+
+      if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result))
+        return grub_error (GRUB_ERR_READ_ERROR, "Read error");
+
+      ofs = 0;
+      size -= len;
+      args.buf += len;
+      args.page++;
+    } while (size);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_nand_write (grub_disk_t disk __attribute ((unused)),
+                 grub_disk_addr_t sector __attribute ((unused)),
+                 grub_size_t size __attribute ((unused)),
+                 const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static struct grub_disk_dev grub_nand_dev =
+  {
+    .name = "nand",
+    .id = GRUB_DISK_DEVICE_NAND_ID,
+    .iterate = grub_nand_iterate,
+    .open = grub_nand_open,
+    .close = grub_nand_close,
+    .read = grub_nand_read,
+    .write = grub_nand_write,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(nand)
+{
+  grub_disk_dev_register (&grub_nand_dev);
+}
+
+GRUB_MOD_FINI(nand)
+{
+  grub_disk_dev_unregister (&grub_nand_dev);
+}
diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c
new file mode 100644
index 0000000..ca257d6
--- /dev/null
+++ b/disk/ieee1275/ofdisk.c
@@ -0,0 +1,289 @@
+/* ofdisk.c - Open Firmware disk access.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/ieee1275/ofdisk.h>
+
+struct ofdisk_hash_ent
+{
+  char *devpath;
+  struct ofdisk_hash_ent *next;
+};
+
+#define OFDISK_HASH_SZ	8
+static struct ofdisk_hash_ent *ofdisk_hash[OFDISK_HASH_SZ];
+
+static int
+ofdisk_hash_fn (const char *devpath)
+{
+  int hash = 0;
+  while (*devpath)
+    hash ^= *devpath++;
+  return (hash & (OFDISK_HASH_SZ - 1));
+}
+
+static struct ofdisk_hash_ent *
+ofdisk_hash_find (const char *devpath)
+{
+  struct ofdisk_hash_ent *p = ofdisk_hash[ofdisk_hash_fn(devpath)];
+
+  while (p)
+    {
+      if (!grub_strcmp (p->devpath, devpath))
+	break;
+      p = p->next;
+    }
+  return p;
+}
+
+static struct ofdisk_hash_ent *
+ofdisk_hash_add (char *devpath)
+{
+  struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)];
+  struct ofdisk_hash_ent *p = grub_malloc(sizeof (*p));
+
+  if (p)
+    {
+      p->devpath = devpath;
+      p->next = *head;
+      *head = p;
+    }
+  return p;
+}
+
+static int
+grub_ofdisk_iterate (int (*hook) (const char *name))
+{
+  auto int dev_iterate (struct grub_ieee1275_devalias *alias);
+
+  int dev_iterate (struct grub_ieee1275_devalias *alias)
+    {
+      int ret = 0;
+
+      grub_dprintf ("disk", "disk name = %s\n", alias->name);
+
+      if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY))
+	{
+	  grub_ieee1275_phandle_t dev;
+	  char tmp[8];
+
+	  if (grub_ieee1275_finddevice (alias->path, &dev))
+	    {
+	      grub_dprintf ("disk", "finddevice (%s) failed\n", alias->path);
+	      return 0;
+	    }
+
+	  if (grub_ieee1275_get_property (dev, "iconname", tmp,
+					  sizeof tmp, 0))
+	    {
+	      grub_dprintf ("disk", "get iconname failed\n");
+	      return 0;
+	    }
+
+	  if (grub_strcmp (tmp, "sdmmc"))
+	    {
+	      grub_dprintf ("disk", "device is not an SD card\n");
+	      return 0;
+	    }
+	}
+
+      if (! grub_strcmp (alias->type, "block") &&
+	  grub_strcmp (alias->name, "cdrom"))
+	ret = hook (alias->name);
+      return ret;
+    }
+
+  return grub_devalias_iterate (dev_iterate);
+}
+
+static char *
+compute_dev_path (const char *name)
+{
+  char *devpath = grub_malloc (grub_strlen (name) + 2);
+  char *p, c;
+
+  if (!devpath)
+    return NULL;
+
+  /* Un-escape commas. */
+  p = devpath;
+  while ((c = *name++) != '\0')
+    {
+      if (c == '\\' && *name == ',')
+	{
+	  *p++ = ',';
+	  name++;
+	}
+      else
+	*p++ = c;
+    }
+
+  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
+    {
+      *p++ = ':';
+      *p++ = '0';
+    }
+  *p++ = '\0';
+
+  return devpath;
+}
+
+static grub_err_t
+grub_ofdisk_open (const char *name, grub_disk_t disk)
+{
+  grub_ieee1275_phandle_t dev;
+  grub_ieee1275_ihandle_t dev_ihandle = 0;
+  struct ofdisk_hash_ent *op;
+  char *devpath;
+  /* XXX: This should be large enough for any possible case.  */
+  char prop[64];
+  grub_ssize_t actual;
+
+  devpath = compute_dev_path (name);
+  if (! devpath)
+    return grub_errno;
+
+  op = ofdisk_hash_find (devpath);
+  if (!op)
+    op = ofdisk_hash_add (devpath);
+
+  grub_free (devpath);
+  if (!op)
+    return grub_errno;
+
+  grub_dprintf ("disk", "Opening `%s'.\n", op->devpath);
+
+  grub_ieee1275_open (op->devpath, &dev_ihandle);
+  if (! dev_ihandle)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
+      goto fail;
+    }
+
+  grub_dprintf ("disk", "Opened `%s' as handle %p.\n", op->devpath,
+		(void *) (unsigned long) dev_ihandle);
+
+  if (grub_ieee1275_finddevice (op->devpath, &dev))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't read device properties");
+      goto fail;
+    }
+
+  if (grub_ieee1275_get_property (dev, "device_type", prop, sizeof (prop),
+				  &actual))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't read the device type");
+      goto fail;
+    }
+
+  if (grub_strcmp (prop, "block"))
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "Not a block device");
+      goto fail;
+    }
+
+  /* XXX: There is no property to read the number of blocks.  There
+     should be a property `#blocks', but it is not there.  Perhaps it
+     is possible to use seek for this.  */
+  disk->total_sectors = 0xFFFFFFFFUL;
+
+  disk->id = (unsigned long) op;
+
+  /* XXX: Read this, somehow.  */
+  disk->has_partitions = 1;
+  disk->data = (void *) (unsigned long) dev_ihandle;
+  return 0;
+
+ fail:
+  if (dev_ihandle)
+    grub_ieee1275_close (dev_ihandle);
+  return grub_errno;
+}
+
+static void
+grub_ofdisk_close (grub_disk_t disk)
+{
+  grub_dprintf ("disk", "Closing handle %p.\n",
+		(void *) disk->data);
+  grub_ieee1275_close ((grub_ieee1275_ihandle_t) (unsigned long) disk->data);
+}
+
+static grub_err_t
+grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
+		  grub_size_t size, char *buf)
+{
+  grub_ssize_t status, actual;
+  unsigned long long pos;
+
+  grub_dprintf ("disk",
+		"Reading handle %p: sector 0x%llx, size 0x%lx, buf %p.\n",
+		(void *) disk->data, (long long) sector, (long) size, buf);
+
+  pos = sector * 512UL;
+
+  grub_ieee1275_seek ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
+		      (int) (pos >> 32), (int) pos & 0xFFFFFFFFUL, &status);
+  if (status < 0)
+    return grub_error (GRUB_ERR_READ_ERROR,
+		       "Seek error, can't seek block %llu",
+		       (long long) sector);
+  grub_ieee1275_read ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
+		      buf, size * 512UL, &actual);
+  if (actual != actual)
+    return grub_error (GRUB_ERR_READ_ERROR, "Read error on block: %llu",
+		       (long long) sector);
+
+  return 0;
+}
+
+static grub_err_t
+grub_ofdisk_write (grub_disk_t disk __attribute ((unused)),
+		   grub_disk_addr_t sector __attribute ((unused)),
+		   grub_size_t size __attribute ((unused)),
+		   const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static struct grub_disk_dev grub_ofdisk_dev =
+  {
+    .name = "ofdisk",
+    .id = GRUB_DISK_DEVICE_OFDISK_ID,
+    .iterate = grub_ofdisk_iterate,
+    .open = grub_ofdisk_open,
+    .close = grub_ofdisk_close,
+    .read = grub_ofdisk_read,
+    .write = grub_ofdisk_write,
+    .next = 0
+  };
+
+void
+grub_ofdisk_init (void)
+{
+  grub_disk_dev_register (&grub_ofdisk_dev);
+}
+
+void
+grub_ofdisk_fini (void)
+{
+  grub_disk_dev_unregister (&grub_ofdisk_dev);
+}
diff --git a/disk/loopback.c b/disk/loopback.c
new file mode 100644
index 0000000..2980518
--- /dev/null
+++ b/disk/loopback.c
@@ -0,0 +1,257 @@
+/* loopback.c - command to add loopback devices.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/extcmd.h>
+
+struct grub_loopback
+{
+  char *devname;
+  char *filename;
+  int has_partitions;
+  struct grub_loopback *next;
+};
+
+static struct grub_loopback *loopback_list;
+
+static const struct grub_arg_option options[] =
+  {
+    {"delete", 'd', 0, "delete the loopback device entry", 0, 0},
+    {"partitions", 'p', 0, "simulate a hard drive with partitions", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+/* Delete the loopback device NAME.  */
+static grub_err_t
+delete_loopback (const char *name)
+{
+  struct grub_loopback *dev;
+  struct grub_loopback **prev;
+
+  /* Search for the device.  */
+  for (dev = loopback_list, prev = &loopback_list;
+       dev;
+       prev = &dev->next, dev = dev->next)
+    if (grub_strcmp (dev->devname, name) == 0)
+      break;
+
+  if (! dev)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "Device not found");
+
+  /* Remove the device from the list.  */
+  *prev = dev->next;
+
+  grub_free (dev->devname);
+  grub_free (dev->filename);
+  grub_free (dev);
+
+  return 0;
+}
+
+/* The command to add and remove loopback devices.  */
+static grub_err_t
+grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = state = cmd->state;
+  grub_file_t file;
+  struct grub_loopback *newdev;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+
+  /* Check if `-d' was used.  */
+  if (state[0].set)
+      return delete_loopback (args[0]);
+
+  if (argc < 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  file = grub_file_open (args[1]);
+  if (! file)
+    return grub_errno;
+
+  /* Close the file, the only reason for opening it is validation.  */
+  grub_file_close (file);
+
+  /* First try to replace the old device.  */
+  for (newdev = loopback_list; newdev; newdev = newdev->next)
+    if (grub_strcmp (newdev->devname, args[0]) == 0)
+      break;
+
+  if (newdev)
+    {
+      char *newname = grub_strdup (args[1]);
+      if (! newname)
+	return grub_errno;
+
+      grub_free (newdev->filename);
+      newdev->filename = newname;
+
+      /* Set has_partitions when `--partitions' was used.  */
+      newdev->has_partitions = state[1].set;
+
+      return 0;
+    }
+
+  /* Unable to replace it, make a new entry.  */
+  newdev = grub_malloc (sizeof (struct grub_loopback));
+  if (! newdev)
+    return grub_errno;
+
+  newdev->devname = grub_strdup (args[0]);
+  if (! newdev->devname)
+    {
+      grub_free (newdev);
+      return grub_errno;
+    }
+
+  newdev->filename = grub_strdup (args[1]);
+  if (! newdev->filename)
+    {
+      grub_free (newdev->devname);
+      grub_free (newdev);
+      return grub_errno;
+    }
+
+  /* Set has_partitions when `--partitions' was used.  */
+  newdev->has_partitions = state[1].set;
+
+  /* Add the new entry to the list.  */
+  newdev->next = loopback_list;
+  loopback_list = newdev;
+
+  return 0;
+}
+
+
+static int
+grub_loopback_iterate (int (*hook) (const char *name))
+{
+  struct grub_loopback *d;
+  for (d = loopback_list; d; d = d->next)
+    {
+      if (hook (d->devname))
+	return 1;
+    }
+  return 0;
+}
+
+static grub_err_t
+grub_loopback_open (const char *name, grub_disk_t disk)
+{
+  grub_file_t file;
+  struct grub_loopback *dev;
+
+  for (dev = loopback_list; dev; dev = dev->next)
+    if (grub_strcmp (dev->devname, name) == 0)
+      break;
+
+  if (! dev)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
+
+  file = grub_file_open (dev->filename);
+  if (! file)
+    return grub_errno;
+
+  /* Use the filesize for the disk size, round up to a complete sector.  */
+  disk->total_sectors = ((file->size + GRUB_DISK_SECTOR_SIZE - 1)
+			 / GRUB_DISK_SECTOR_SIZE);
+  disk->id = (unsigned long) dev;
+
+  disk->has_partitions = dev->has_partitions;
+  disk->data = file;
+
+  return 0;
+}
+
+static void
+grub_loopback_close (grub_disk_t disk)
+{
+  grub_file_t file = (grub_file_t) disk->data;
+
+  grub_file_close (file);
+}
+
+static grub_err_t
+grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector,
+		    grub_size_t size, char *buf)
+{
+  grub_file_t file = (grub_file_t) disk->data;
+  grub_off_t pos;
+
+  grub_file_seek (file, sector << GRUB_DISK_SECTOR_BITS);
+
+  grub_file_read (file, buf, size << GRUB_DISK_SECTOR_BITS);
+  if (grub_errno)
+    return grub_errno;
+
+  /* In case there is more data read than there is available, in case
+     of files that are not a multiple of GRUB_DISK_SECTOR_SIZE, fill
+     the rest with zeros.  */
+  pos = (sector + size) << GRUB_DISK_SECTOR_BITS;
+  if (pos > file->size)
+    {
+      grub_size_t amount = pos - file->size;
+      grub_memset (buf + (size << GRUB_DISK_SECTOR_BITS) - amount, 0, amount);
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_loopback_write (grub_disk_t disk __attribute ((unused)),
+		     grub_disk_addr_t sector __attribute ((unused)),
+		     grub_size_t size __attribute ((unused)),
+		     const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static struct grub_disk_dev grub_loopback_dev =
+  {
+    .name = "loopback",
+    .id = GRUB_DISK_DEVICE_LOOPBACK_ID,
+    .iterate = grub_loopback_iterate,
+    .open = grub_loopback_open,
+    .close = grub_loopback_close,
+    .read = grub_loopback_read,
+    .write = grub_loopback_write,
+    .next = 0
+  };
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(loop)
+{
+  cmd = grub_register_extcmd ("loopback", grub_cmd_loopback,
+			      GRUB_COMMAND_FLAG_BOTH,
+			      "loopback [-d|-p] DEVICENAME FILE",
+			      "Make a device of a file.", options);
+  grub_disk_dev_register (&grub_loopback_dev);
+}
+
+GRUB_MOD_FINI(loop)
+{
+  grub_unregister_extcmd (cmd);
+  grub_disk_dev_unregister (&grub_loopback_dev);
+}
diff --git a/disk/lvm.c b/disk/lvm.c
new file mode 100644
index 0000000..126b494
--- /dev/null
+++ b/disk/lvm.c
@@ -0,0 +1,617 @@
+/* lvm.c - module to read Logical Volumes.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/lvm.h>
+
+static struct grub_lvm_vg *vg_list;
+static int lv_count;
+
+
+/* Go the string STR and return the number after STR.  *P will point
+   at the number.  In case STR is not found, *P will be NULL and the
+   return value will be 0.  */
+static int
+grub_lvm_getvalue (char **p, char *str)
+{
+  *p = grub_strstr (*p, str);
+  if (! *p)
+    return 0;
+  *p += grub_strlen (str);
+  return grub_strtoul (*p, NULL, 10);
+}
+
+static int
+grub_lvm_iterate (int (*hook) (const char *name))
+{
+  struct grub_lvm_vg *vg;
+  for (vg = vg_list; vg; vg = vg->next)
+    {
+      struct grub_lvm_lv *lv;
+      if (vg->lvs)
+	for (lv = vg->lvs; lv; lv = lv->next)
+	  if (hook (lv->name))
+	    return 1;
+    }
+
+  return 0;
+}
+
+#ifdef GRUB_UTIL
+static grub_disk_memberlist_t
+grub_lvm_memberlist (grub_disk_t disk)
+{
+  struct grub_lvm_lv *lv = disk->data;
+  grub_disk_memberlist_t list = NULL, tmp;
+  struct grub_lvm_pv *pv;
+
+  if (lv->vg->pvs)
+    for (pv = lv->vg->pvs; pv; pv = pv->next)
+      {
+	tmp = grub_malloc (sizeof (*tmp));
+	tmp->disk = pv->disk;
+	tmp->next = list;
+	list = tmp;
+      }
+
+  return list;
+}
+#endif
+
+static grub_err_t
+grub_lvm_open (const char *name, grub_disk_t disk)
+{
+  struct grub_lvm_vg *vg;
+  struct grub_lvm_lv *lv = NULL;
+  for (vg = vg_list; vg; vg = vg->next)
+    {
+      if (vg->lvs)
+	for (lv = vg->lvs; lv; lv = lv->next)
+	  if (! grub_strcmp (lv->name, name))
+	    break;
+
+      if (lv)
+	break;
+    }
+
+  if (! lv)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown LVM device %s", name);
+
+  disk->has_partitions = 0;
+  disk->id = lv->number;
+  disk->data = lv;
+  disk->total_sectors = lv->size;
+
+  return 0;
+}
+
+static void
+grub_lvm_close (grub_disk_t disk __attribute ((unused)))
+{
+  return;
+}
+
+static grub_err_t
+grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector,
+		grub_size_t size, char *buf)
+{
+  grub_err_t err = 0;
+  struct grub_lvm_lv *lv = disk->data;
+  struct grub_lvm_vg *vg = lv->vg;
+  struct grub_lvm_segment *seg = lv->segments;
+  struct grub_lvm_pv *pv;
+  grub_uint64_t offset;
+  grub_uint64_t extent;
+  unsigned int i;
+
+  extent = grub_divmod64 (sector, vg->extent_size, NULL);
+
+  /* Find the right segment.  */
+  for (i = 0; i < lv->segment_count; i++)
+    {
+      if ((seg->start_extent <= extent)
+	  && ((seg->start_extent + seg->extent_count) > extent))
+	{
+	  break;
+	}
+
+      seg++;
+    }
+
+  if (seg->stripe_count == 1)
+    {
+      /* This segment is linear, so that's easy.  We just need to find
+	 out the offset in the physical volume and read SIZE bytes
+	 from that.  */
+      struct grub_lvm_stripe *stripe = seg->stripes;
+      grub_uint64_t seg_offset; /* Offset of the segment in PV device.  */
+
+      pv = stripe->pv;
+      seg_offset = ((grub_uint64_t) stripe->start
+		    * (grub_uint64_t) vg->extent_size) + pv->start;
+
+      offset = sector - ((grub_uint64_t) seg->start_extent
+			 * (grub_uint64_t) vg->extent_size) + seg_offset;
+    }
+  else
+    {
+      /* This is a striped segment. We have to find the right PV
+	 similar to RAID0. */
+      struct grub_lvm_stripe *stripe = seg->stripes;
+      grub_uint32_t a, b;
+      grub_uint64_t seg_offset; /* Offset of the segment in PV device.  */
+      unsigned int stripenr;
+
+      offset = sector - ((grub_uint64_t) seg->start_extent
+			 * (grub_uint64_t) vg->extent_size);
+
+      a = grub_divmod64 (offset, seg->stripe_size, NULL);
+      grub_divmod64 (a, seg->stripe_count, &stripenr);
+
+      a = grub_divmod64 (offset, seg->stripe_size * seg->stripe_count, NULL);
+      grub_divmod64 (offset, seg->stripe_size, &b);
+      offset = a * seg->stripe_size + b;
+
+      stripe += stripenr;
+      pv = stripe->pv;
+
+      seg_offset = ((grub_uint64_t) stripe->start
+		    * (grub_uint64_t) vg->extent_size) + pv->start;
+
+      offset += seg_offset;
+    }
+
+  /* Check whether we actually know the physical volume we want to
+     read from.  */
+  if (pv->disk)
+    err = grub_disk_read (pv->disk, offset, 0,
+			  size << GRUB_DISK_SECTOR_BITS, buf);
+  else
+    err = grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+		      "Physical volume %s not found", pv->name);
+
+  return err;
+}
+
+static grub_err_t
+grub_lvm_write (grub_disk_t disk __attribute ((unused)),
+		 grub_disk_addr_t sector __attribute ((unused)),
+		 grub_size_t size __attribute ((unused)),
+		 const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static int
+grub_lvm_scan_device (const char *name)
+{
+  grub_err_t err;
+  grub_disk_t disk;
+  grub_uint64_t da_offset, da_size, mda_offset, mda_size;
+  char buf[GRUB_LVM_LABEL_SIZE];
+  char vg_id[GRUB_LVM_ID_STRLEN+1];
+  char pv_id[GRUB_LVM_ID_STRLEN+1];
+  char *metadatabuf, *p, *q, *vgname;
+  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
+  struct grub_lvm_pv_header *pvh;
+  struct grub_lvm_disk_locn *dlocn;
+  struct grub_lvm_mda_header *mdah;
+  struct grub_lvm_raw_locn *rlocn;
+  unsigned int i, j, vgname_len;
+  struct grub_lvm_vg *vg;
+  struct grub_lvm_pv *pv;
+
+  disk = grub_disk_open (name);
+  if (!disk)
+    return 0;
+
+  /* Search for label. */
+  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
+    {
+      err = grub_disk_read (disk, i, 0, sizeof(buf), buf);
+      if (err)
+	goto fail;
+
+      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
+			   sizeof (lh->id)))
+	  && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
+			      sizeof (lh->type))))
+	break;
+    }
+
+  /* Return if we didn't find a label. */
+  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
+    goto fail;
+
+  pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
+
+  for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
+    {
+      pv_id[j++] = pvh->pv_uuid[i];
+      if ((i != 1) && (i != 29) && (i % 4 == 1))
+	pv_id[j++] = '-';
+    }
+  pv_id[j] = '\0';
+
+  dlocn = pvh->disk_areas_xl;
+  da_offset = grub_le_to_cpu64 (dlocn->offset);
+  da_size = grub_le_to_cpu64 (dlocn->size);
+
+  dlocn++;
+  /* Is it possible to have multiple data/metadata areas? I haven't
+     seen devices that have it. */
+  if (dlocn->offset)
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+		  "We don't support multiple LVM data areas");
+
+      goto fail;
+    }
+
+  dlocn++;
+  mda_offset = grub_le_to_cpu64 (dlocn->offset);
+  mda_size = grub_le_to_cpu64 (dlocn->size);
+
+  /* It's possible to have multiple copies of metadata areas, we just use the
+     first one.  */
+
+  /* Allocate buffer space for the circular worst-case scenario. */
+  metadatabuf = grub_malloc (2 * mda_size);
+  if (! metadatabuf)
+    goto fail;
+
+  err = grub_disk_read (disk, 0, mda_offset, mda_size, metadatabuf);
+  if (err)
+    goto fail2;
+
+  mdah = (struct grub_lvm_mda_header *) metadatabuf;
+  if ((grub_strncmp ((char *)mdah->magic, GRUB_LVM_FMTT_MAGIC,
+		     sizeof (mdah->magic)))
+      || (grub_le_to_cpu32 (mdah->version) != GRUB_LVM_FMTT_VERSION))
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+		  "Unknown LVM metadata header");
+      goto fail2;
+    }
+
+  rlocn = mdah->raw_locns;
+  if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) >
+      grub_le_to_cpu64 (mdah->size))
+    {
+      /* Metadata is circular. Copy the wrap in place. */
+      grub_memcpy (metadatabuf + mda_size,
+                   metadatabuf + GRUB_LVM_MDA_HEADER_SIZE,
+                   grub_le_to_cpu64 (rlocn->offset) +
+                   grub_le_to_cpu64 (rlocn->size) -
+                   grub_le_to_cpu64 (mdah->size));
+    }
+  p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset);
+
+  while (*q != ' ' && q < metadatabuf + mda_size)
+    q++;
+
+  if (q == metadatabuf + mda_size)
+    goto fail2;
+
+  vgname_len = q - p;
+  vgname = grub_malloc (vgname_len + 1);
+  if (!vgname)
+    goto fail2;
+
+  grub_memcpy (vgname, p, vgname_len);
+  vgname[vgname_len] = '\0';
+
+  p = grub_strstr (q, "id = \"");
+  if (p == NULL)
+    goto fail3;
+  p += sizeof ("id = \"") - 1;
+  grub_memcpy (vg_id, p, GRUB_LVM_ID_STRLEN);
+  vg_id[GRUB_LVM_ID_STRLEN] = '\0';
+
+  for (vg = vg_list; vg; vg = vg->next)
+    {
+      if (! grub_memcmp(vg_id, vg->id, GRUB_LVM_ID_STRLEN))
+	break;
+    }
+
+  if (! vg)
+    {
+      /* First time we see this volume group. We've to create the
+	 whole volume group structure. */
+      vg = grub_malloc (sizeof (*vg));
+      if (! vg)
+	goto fail3;
+      vg->name = vgname;
+      grub_memcpy (vg->id, vg_id, GRUB_LVM_ID_STRLEN+1);
+
+      vg->extent_size = grub_lvm_getvalue (&p, "extent_size = ");
+      if (p == NULL)
+	goto fail4;
+
+      vg->lvs = NULL;
+      vg->pvs = NULL;
+
+      p = grub_strstr (p, "physical_volumes {");
+      if (p)
+	{
+	  p += sizeof ("physical_volumes {") - 1;
+
+	  /* Add all the pvs to the volume group. */
+	  while (1)
+	    {
+	      int s;
+	      while (grub_isspace (*p))
+		p++;
+
+	      if (*p == '}')
+		break;
+
+	      pv = grub_malloc (sizeof (*pv));
+	      q = p;
+	      while (*q != ' ')
+		q++;
+
+	      s = q - p;
+	      pv->name = grub_malloc (s + 1);
+	      grub_memcpy (pv->name, p, s);
+	      pv->name[s] = '\0';
+
+	      p = grub_strstr (p, "id = \"");
+	      if (p == NULL)
+		goto pvs_fail;
+	      p += sizeof("id = \"") - 1;
+
+	      grub_memcpy (pv->id, p, GRUB_LVM_ID_STRLEN);
+	      pv->id[GRUB_LVM_ID_STRLEN] = '\0';
+
+	      pv->start = grub_lvm_getvalue (&p, "pe_start = ");
+	      if (p == NULL)
+		goto pvs_fail;
+
+	      p = grub_strchr (p, '}');
+	      if (p == NULL)
+		goto pvs_fail;
+	      p++;
+
+	      pv->disk = NULL;
+	      pv->next = vg->pvs;
+	      vg->pvs = pv;
+
+	      continue;
+	    pvs_fail:
+	      grub_free (pv->name);
+	      grub_free (pv);
+	      goto fail4;
+	    }
+	}
+
+      p = grub_strstr (p, "logical_volumes");
+      if (p)
+	{
+	  p += 18;
+
+	  /* And add all the lvs to the volume group. */
+	  while (1)
+	    {
+	      int s;
+	      struct grub_lvm_lv *lv;
+	      struct grub_lvm_segment *seg;
+
+	      while (grub_isspace (*p))
+		p++;
+
+	      if (*p == '}')
+		break;
+
+	      lv = grub_malloc (sizeof (*lv));
+
+	      q = p;
+	      while (*q != ' ')
+		q++;
+
+	      s = q - p;
+	      lv->name = grub_malloc (vgname_len + 1 + s + 1);
+	      grub_memcpy (lv->name, vgname, vgname_len);
+	      lv->name[vgname_len] = '-';
+	      grub_memcpy (lv->name + vgname_len + 1, p, s);
+	      lv->name[vgname_len + 1 + s] = '\0';
+
+	      lv->size = 0;
+
+	      lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
+	      if (p == NULL)
+		goto lvs_fail;
+	      lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count);
+	      seg = lv->segments;
+
+	      for (i = 0; i < lv->segment_count; i++)
+		{
+		  struct grub_lvm_stripe *stripe;
+
+		  p = grub_strstr (p, "segment");
+		  if (p == NULL)
+		    goto lvs_segment_fail;
+
+		  seg->start_extent = grub_lvm_getvalue (&p, "start_extent = ");
+		  if (p == NULL)
+		    goto lvs_segment_fail;
+		  seg->extent_count = grub_lvm_getvalue (&p, "extent_count = ");
+		  if (p == NULL)
+		    goto lvs_segment_fail;
+		  seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
+		  if (p == NULL)
+		    goto lvs_segment_fail;
+
+		  lv->size += seg->extent_count * vg->extent_size;
+
+		  if (seg->stripe_count != 1)
+		    seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
+
+		  seg->stripes = grub_malloc (sizeof (*stripe)
+					      * seg->stripe_count);
+		  stripe = seg->stripes;
+
+		  p = grub_strstr (p, "stripes = [");
+		  if (p == NULL)
+		    goto lvs_segment_fail2;
+		  p += sizeof("stripes = [") - 1;
+
+		  for (j = 0; j < seg->stripe_count; j++)
+		    {
+		      char *pvname;
+
+		      p = grub_strchr (p, '"');
+		      if (p == NULL)
+			continue;
+		      q = ++p;
+		      while (*q != '"')
+			q++;
+
+		      s = q - p;
+
+		      pvname = grub_malloc (s + 1);
+                      if (pvname == NULL)
+                        goto lvs_segment_fail2;
+
+		      grub_memcpy (pvname, p, s);
+		      pvname[s] = '\0';
+
+		      if (vg->pvs)
+			for (pv = vg->pvs; pv; pv = pv->next)
+			  {
+			    if (! grub_strcmp (pvname, pv->name))
+			      {
+				stripe->pv = pv;
+				break;
+			      }
+			  }
+
+		      grub_free(pvname);
+
+		      stripe->start = grub_lvm_getvalue (&p, ",");
+		      if (p == NULL)
+			continue;
+
+		      stripe++;
+		    }
+
+		  seg++;
+
+		  continue;
+		lvs_segment_fail2:
+		  grub_free (seg->stripes);
+		lvs_segment_fail:
+		  goto fail4;
+		}
+
+	      if (p != NULL)
+		p = grub_strchr (p, '}');
+	      if (p == NULL)
+		goto lvs_fail;
+	      p += 3;
+
+	      lv->number = lv_count++;
+	      lv->vg = vg;
+	      lv->next = vg->lvs;
+	      vg->lvs = lv;
+
+	      continue;
+	    lvs_fail:
+	      grub_free (lv->name);
+	      grub_free (lv);
+	      goto fail4;
+	    }
+	}
+
+	vg->next = vg_list;
+	vg_list = vg;
+    }
+  else
+    {
+      grub_free (vgname);
+    }
+
+  /* Match the device we are currently reading from with the right
+     PV. */
+  if (vg->pvs)
+    for (pv = vg->pvs; pv; pv = pv->next)
+      {
+	if (! grub_memcmp (pv->id, pv_id, GRUB_LVM_ID_STRLEN))
+	  {
+	    /* This could happen to LVM on RAID, pv->disk points to the
+	       raid device, we shouldn't change it.  */
+	    if (! pv->disk)
+	      pv->disk = grub_disk_open (name);
+	    break;
+	  }
+      }
+
+  goto fail2;
+
+  /* Failure path.  */
+ fail4:
+  grub_free (vg);
+ fail3:
+  grub_free (vgname);
+
+  /* Normal exit path.  */
+ fail2:
+  grub_free (metadatabuf);
+ fail:
+  grub_disk_close (disk);
+  return 0;
+}
+
+static struct grub_disk_dev grub_lvm_dev =
+  {
+    .name = "lvm",
+    .id = GRUB_DISK_DEVICE_LVM_ID,
+    .iterate = grub_lvm_iterate,
+    .open = grub_lvm_open,
+    .close = grub_lvm_close,
+    .read = grub_lvm_read,
+    .write = grub_lvm_write,
+#ifdef GRUB_UTIL
+    .memberlist = grub_lvm_memberlist,
+#endif
+    .next = 0
+  };
+
+
+GRUB_MOD_INIT(lvm)
+{
+  grub_device_iterate (&grub_lvm_scan_device);
+  if (grub_errno)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+    }
+
+  grub_disk_dev_register (&grub_lvm_dev);
+}
+
+GRUB_MOD_FINI(lvm)
+{
+  grub_disk_dev_unregister (&grub_lvm_dev);
+  /* FIXME: free the lvm list. */
+}
diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c
new file mode 100644
index 0000000..29a21b4
--- /dev/null
+++ b/disk/mdraid_linux.c
@@ -0,0 +1,233 @@
+/* mdraid_linux.c - module to handle linux softraid.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/raid.h>
+
+/* Linux RAID on disk structures and constants,
+   copied from include/linux/raid/md_p.h.  */
+
+#define RESERVED_BYTES			(64 * 1024)
+#define RESERVED_SECTORS		(RESERVED_BYTES / 512)
+
+#define NEW_SIZE_SECTORS(x)		((x & ~(RESERVED_SECTORS - 1)) \
+					- RESERVED_SECTORS)
+
+#define SB_BYTES			4096
+#define SB_WORDS			(SB_BYTES / 4)
+#define SB_SECTORS			(SB_BYTES / 512)
+
+/*
+ * The following are counted in 32-bit words
+ */
+#define	SB_GENERIC_OFFSET		0
+
+#define SB_PERSONALITY_OFFSET		64
+#define SB_DISKS_OFFSET			128
+#define SB_DESCRIPTOR_OFFSET		992
+
+#define SB_GENERIC_CONSTANT_WORDS	32
+#define SB_GENERIC_STATE_WORDS		32
+#define SB_GENERIC_WORDS		(SB_GENERIC_CONSTANT_WORDS + \
+                                         SB_GENERIC_STATE_WORDS)
+
+#define SB_PERSONALITY_WORDS		64
+#define SB_DESCRIPTOR_WORDS		32
+#define SB_DISKS			27
+#define SB_DISKS_WORDS			(SB_DISKS * SB_DESCRIPTOR_WORDS)
+
+#define SB_RESERVED_WORDS		(1024 \
+                                         - SB_GENERIC_WORDS \
+                                         - SB_PERSONALITY_WORDS \
+                                         - SB_DISKS_WORDS \
+                                         - SB_DESCRIPTOR_WORDS)
+
+#define SB_EQUAL_WORDS			(SB_GENERIC_WORDS \
+                                         + SB_PERSONALITY_WORDS \
+                                         + SB_DISKS_WORDS)
+
+/*
+ * Device "operational" state bits
+ */
+#define DISK_FAULTY			0
+#define DISK_ACTIVE			1
+#define DISK_SYNC			2
+#define DISK_REMOVED			3
+
+#define	DISK_WRITEMOSTLY		9
+
+#define SB_MAGIC			0xa92b4efc
+
+/*
+ * Superblock state bits
+ */
+#define SB_CLEAN			0
+#define SB_ERRORS			1
+
+#define	SB_BITMAP_PRESENT		8
+
+struct grub_raid_disk_09
+{
+  grub_uint32_t number;		/* Device number in the entire set.  */
+  grub_uint32_t major;		/* Device major number.  */
+  grub_uint32_t minor;		/* Device minor number.  */
+  grub_uint32_t raid_disk;	/* The role of the device in the raid set.  */
+  grub_uint32_t state;		/* Operational state.  */
+  grub_uint32_t reserved[SB_DESCRIPTOR_WORDS - 5];
+};
+
+struct grub_raid_super_09
+{
+  /*
+   * Constant generic information
+   */
+  grub_uint32_t md_magic;	/* MD identifier.  */
+  grub_uint32_t major_version;	/* Major version.  */
+  grub_uint32_t minor_version;	/* Minor version.  */
+  grub_uint32_t patch_version;	/* Patchlevel version.  */
+  grub_uint32_t gvalid_words;	/* Number of used words in this section.  */
+  grub_uint32_t set_uuid0;	/* Raid set identifier.  */
+  grub_uint32_t ctime;		/* Creation time.  */
+  grub_uint32_t level;		/* Raid personality.  */
+  grub_uint32_t size;		/* Apparent size of each individual disk.  */
+  grub_uint32_t nr_disks;	/* Total disks in the raid set.  */
+  grub_uint32_t raid_disks;	/* Disks in a fully functional raid set.  */
+  grub_uint32_t md_minor;	/* Preferred MD minor device number.  */
+  grub_uint32_t not_persistent;	/* Does it have a persistent superblock.  */
+  grub_uint32_t set_uuid1;	/* Raid set identifier #2.  */
+  grub_uint32_t set_uuid2;	/* Raid set identifier #3.  */
+  grub_uint32_t set_uuid3;	/* Raid set identifier #4.  */
+  grub_uint32_t gstate_creserved[SB_GENERIC_CONSTANT_WORDS - 16];
+
+  /*
+   * Generic state information
+   */
+  grub_uint32_t utime;		/* Superblock update time.  */
+  grub_uint32_t state;		/* State bits (clean, ...).  */
+  grub_uint32_t active_disks;	/* Number of currently active disks.  */
+  grub_uint32_t working_disks;	/* Number of working disks.  */
+  grub_uint32_t failed_disks;	/* Number of failed disks.  */
+  grub_uint32_t spare_disks;	/* Number of spare disks.  */
+  grub_uint32_t sb_csum;	/* Checksum of the whole superblock.  */
+  grub_uint64_t events;		/* Superblock update count.  */
+  grub_uint64_t cp_events;	/* Checkpoint update count.  */
+  grub_uint32_t recovery_cp;	/* Recovery checkpoint sector count.  */
+  grub_uint32_t gstate_sreserved[SB_GENERIC_STATE_WORDS - 12];
+
+  /*
+   * Personality information
+   */
+  grub_uint32_t layout;		/* The array's physical layout.  */
+  grub_uint32_t chunk_size;	/* Chunk size in bytes.  */
+  grub_uint32_t root_pv;	/* LV root PV.  */
+  grub_uint32_t root_block;	/* LV root block.  */
+  grub_uint32_t pstate_reserved[SB_PERSONALITY_WORDS - 4];
+
+  /*
+   * Disks information
+   */
+  struct grub_raid_disk_09 disks[SB_DISKS];
+
+  /*
+   * Reserved
+   */
+  grub_uint32_t reserved[SB_RESERVED_WORDS];
+
+  /*
+   * Active descriptor
+   */
+  struct grub_raid_disk_09 this_disk;
+} __attribute__ ((packed));
+
+static grub_err_t
+grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array)
+{
+  grub_disk_addr_t sector;
+  grub_uint64_t size;
+  struct grub_raid_super_09 sb;
+  grub_uint32_t *uuid;
+
+  /* The sector where the RAID superblock is stored, if available. */
+  size = grub_disk_get_size (disk);
+  sector = NEW_SIZE_SECTORS (size);
+
+  if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb))
+    return grub_errno;
+
+  /* Look whether there is a RAID superblock. */
+  if (sb.md_magic != SB_MAGIC)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid");
+
+  /* FIXME: Also support version 1.0. */
+  if (sb.major_version != 0 || sb.minor_version != 90)
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+		       "Unsupported RAID version: %d.%d",
+		       sb.major_version, sb.minor_version);
+
+  /* FIXME: Check the checksum. */
+
+  /* Multipath.  */
+  if ((int) sb.level == -4)
+    sb.level = 1;
+
+  if (sb.level != 0 && sb.level != 1 && sb.level != 4 &&
+      sb.level != 5 && sb.level != 6 && sb.level != 10)
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+		       "Unsupported RAID level: %d", sb.level);
+
+  array->number = sb.md_minor;
+  array->level = sb.level;
+  array->layout = sb.layout;
+  array->total_devs = sb.raid_disks;
+  array->disk_size = (sb.size) ? sb.size * 2 : sector;
+  array->chunk_size = sb.chunk_size >> 9;
+  array->index = sb.this_disk.number;
+  array->uuid_len = 16;
+  array->uuid = grub_malloc (16);
+  if (!array->uuid)
+    return grub_errno;
+
+  uuid = (grub_uint32_t *) array->uuid;
+  uuid[0] = sb.set_uuid0;
+  uuid[1] = sb.set_uuid1;
+  uuid[2] = sb.set_uuid2;
+  uuid[3] = sb.set_uuid3;
+
+  return 0;
+}
+
+static struct grub_raid grub_mdraid_dev = {
+  .name = "mdraid",
+  .detect = grub_mdraid_detect,
+  .next = 0
+};
+
+GRUB_MOD_INIT (mdraid)
+{
+  grub_raid_register (&grub_mdraid_dev);
+}
+
+GRUB_MOD_FINI (mdraid)
+{
+  grub_raid_unregister (&grub_mdraid_dev);
+}
diff --git a/disk/memdisk.c b/disk/memdisk.c
new file mode 100644
index 0000000..4a04708
--- /dev/null
+++ b/disk/memdisk.c
@@ -0,0 +1,117 @@
+/* memdisk.c - Access embedded memory disk.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/machine/kernel.h>
+
+static char *memdisk_addr;
+static grub_off_t memdisk_size = 0;
+
+static int
+grub_memdisk_iterate (int (*hook) (const char *name))
+{
+  return hook ("memdisk");
+}
+
+static grub_err_t
+grub_memdisk_open (const char *name, grub_disk_t disk)
+{
+  if (grub_strcmp (name, "memdisk"))
+      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a memdisk");
+
+  disk->total_sectors = memdisk_size / GRUB_DISK_SECTOR_SIZE;
+  disk->id = (unsigned long) "mdsk";
+  disk->has_partitions = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_memdisk_close (grub_disk_t disk __attribute((unused)))
+{
+}
+
+static grub_err_t
+grub_memdisk_read (grub_disk_t disk __attribute((unused)), grub_disk_addr_t sector,
+		    grub_size_t size, char *buf)
+{
+  grub_memcpy (buf, memdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), size << GRUB_DISK_SECTOR_BITS);
+  return 0;
+}
+
+static grub_err_t
+grub_memdisk_write (grub_disk_t disk __attribute((unused)), grub_disk_addr_t sector,
+		     grub_size_t size, const char *buf)
+{
+  grub_memcpy (memdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), buf, size << GRUB_DISK_SECTOR_BITS);
+  return 0;
+}
+
+static struct grub_disk_dev grub_memdisk_dev =
+  {
+    .name = "memdisk",
+    .id = GRUB_DISK_DEVICE_MEMDISK_ID,
+    .iterate = grub_memdisk_iterate,
+    .open = grub_memdisk_open,
+    .close = grub_memdisk_close,
+    .read = grub_memdisk_read,
+    .write = grub_memdisk_write,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(memdisk)
+{
+  auto int hook (struct grub_module_header *);
+  int hook (struct grub_module_header *header)
+    {
+      if (header->type == OBJ_TYPE_MEMDISK)
+	{
+	  char *memdisk_orig_addr;
+	  memdisk_orig_addr = (char *) header + sizeof (struct grub_module_header);
+
+	  grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr);
+
+	  memdisk_size = header->size - sizeof (struct grub_module_header);
+	  memdisk_addr = grub_malloc (memdisk_size);
+
+	  grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n");
+	  grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size);
+
+	  grub_disk_dev_register (&grub_memdisk_dev);
+	  return 1;
+	}
+
+      return 0;
+    }
+
+  grub_module_iterate (hook);
+}
+
+GRUB_MOD_FINI(memdisk)
+{
+  if (! memdisk_size)
+    return;
+  grub_free (memdisk_addr);
+  grub_disk_dev_unregister (&grub_memdisk_dev);
+}
diff --git a/disk/raid.c b/disk/raid.c
new file mode 100644
index 0000000..c720fb3
--- /dev/null
+++ b/disk/raid.c
@@ -0,0 +1,693 @@
+/* raid.c - module to read RAID arrays.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/raid.h>
+
+/* Linked list of RAID arrays. */
+static struct grub_raid_array *array_list;
+grub_raid5_recover_func_t grub_raid5_recover_func;
+grub_raid6_recover_func_t grub_raid6_recover_func;
+
+
+static char
+grub_is_array_readable (struct grub_raid_array *array)
+{
+  switch (array->level)
+    {
+    case 0:
+      if (array->nr_devs == array->total_devs)
+	return 1;
+      break;
+
+    case 1:
+      if (array->nr_devs >= 1)
+	return 1;
+      break;
+
+    case 4:
+    case 5:
+    case 6:
+    case 10:
+      {
+        unsigned int n;
+
+        if (array->level == 10)
+          {
+            n = array->layout & 0xFF;
+            if (n == 1)
+              n = (array->layout >> 8) & 0xFF;
+
+            n--;
+          }
+        else
+          n = array->level / 3;
+
+        if (array->nr_devs >= array->total_devs - n)
+          return 1;
+
+        break;
+      }
+    }
+
+  return 0;
+}
+
+static int
+grub_raid_iterate (int (*hook) (const char *name))
+{
+  struct grub_raid_array *array;
+
+  for (array = array_list; array != NULL; array = array->next)
+    {
+      if (grub_is_array_readable (array))
+	if (hook (array->name))
+	  return 1;
+    }
+
+  return 0;
+}
+
+#ifdef GRUB_UTIL
+static grub_disk_memberlist_t
+grub_raid_memberlist (grub_disk_t disk)
+{
+  struct grub_raid_array *array = disk->data;
+  grub_disk_memberlist_t list = NULL, tmp;
+  unsigned int i;
+
+  for (i = 0; i < array->total_devs; i++)
+    if (array->device[i])
+      {
+        tmp = grub_malloc (sizeof (*tmp));
+        tmp->disk = array->device[i];
+        tmp->next = list;
+        list = tmp;
+      }
+
+  return list;
+}
+#endif
+
+static grub_err_t
+grub_raid_open (const char *name, grub_disk_t disk)
+{
+  struct grub_raid_array *array;
+  unsigned n;
+
+  for (array = array_list; array != NULL; array = array->next)
+    {
+      if (!grub_strcmp (array->name, name))
+	if (grub_is_array_readable (array))
+	  break;
+    }
+
+  if (!array)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown RAID device %s",
+                       name);
+
+  disk->has_partitions = 1;
+  disk->id = array->number;
+  disk->data = array;
+
+  grub_dprintf ("raid", "%s: total_devs=%d, disk_size=%lld\n", name,
+		array->total_devs, (unsigned long long) array->disk_size);
+
+  switch (array->level)
+    {
+    case 1:
+      disk->total_sectors = array->disk_size;
+      break;
+
+    case 10:
+      n = array->layout & 0xFF;
+      if (n == 1)
+        n = (array->layout >> 8) & 0xFF;
+
+      disk->total_sectors = grub_divmod64 (array->total_devs *
+                                           array->disk_size,
+                                           n, 0);
+      break;
+
+    case 0:
+    case 4:
+    case 5:
+    case 6:
+      n = array->level / 3;
+
+      disk->total_sectors = (array->total_devs - n) * array->disk_size;
+      break;
+    }
+
+  grub_dprintf ("raid", "%s: level=%d, total_sectors=%lld\n", name,
+		array->level, (unsigned long long) disk->total_sectors);
+
+  return 0;
+}
+
+static void
+grub_raid_close (grub_disk_t disk __attribute ((unused)))
+{
+  return;
+}
+
+void
+grub_raid_block_xor (char *buf1, const char *buf2, int size)
+{
+  grub_size_t *p1;
+  const grub_size_t *p2;
+
+  p1 = (grub_size_t *) buf1;
+  p2 = (const grub_size_t *) buf2;
+  size /= GRUB_CPU_SIZEOF_VOID_P;
+
+  while (size)
+    {
+      *(p1++) ^= *(p2++);
+      size--;
+    }
+}
+
+static grub_err_t
+grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
+		grub_size_t size, char *buf)
+{
+  struct grub_raid_array *array = disk->data;
+  grub_err_t err = 0;
+
+  switch (array->level)
+    {
+    case 0:
+    case 1:
+    case 10:
+      {
+        grub_disk_addr_t read_sector, far_ofs;
+	grub_uint32_t disknr, b, near, far, ofs;
+
+        read_sector = grub_divmod64 (sector, array->chunk_size, &b);
+        far = ofs = near = 1;
+        far_ofs = 0;
+
+        if (array->level == 1)
+          near = array->total_devs;
+        else if (array->level == 10)
+          {
+            near = array->layout & 0xFF;
+            far = (array->layout >> 8) & 0xFF;
+            if (array->layout >> 16)
+              {
+                ofs = far;
+                far_ofs = 1;
+              }
+            else
+              far_ofs = grub_divmod64 (array->disk_size,
+                                       far * array->chunk_size, 0);
+
+            far_ofs *= array->chunk_size;
+          }
+
+        read_sector = grub_divmod64 (read_sector * near, array->total_devs,
+                                     &disknr);
+
+        ofs *= array->chunk_size;
+        read_sector *= ofs;
+
+        while (1)
+          {
+            grub_size_t read_size;
+            unsigned int i, j;
+
+            read_size = array->chunk_size - b;
+            if (read_size > size)
+              read_size = size;
+
+            for (i = 0; i < near; i++)
+              {
+                unsigned int k;
+
+                k = disknr;
+                for (j = 0; j < far; j++)
+                  {
+                    if (array->device[k])
+                      {
+                        if (grub_errno == GRUB_ERR_READ_ERROR)
+                          grub_errno = GRUB_ERR_NONE;
+
+                        err = grub_disk_read (array->device[k],
+                                              read_sector + j * far_ofs + b,
+                                              0,
+                                              read_size << GRUB_DISK_SECTOR_BITS,
+                                              buf);
+                        if (! err)
+                          break;
+                        else if (err != GRUB_ERR_READ_ERROR)
+                          return err;
+                      }
+                    else
+                      err = grub_error (GRUB_ERR_READ_ERROR,
+                                        "disk missing.");
+
+                    k++;
+                    if (k == array->total_devs)
+                      k = 0;
+                  }
+
+                if (! err)
+                  break;
+
+                disknr++;
+                if (disknr == array->total_devs)
+                  {
+                    disknr = 0;
+                    read_sector += ofs;
+                  }
+              }
+
+            if (err)
+              return err;
+
+            buf += read_size << GRUB_DISK_SECTOR_BITS;
+	    size -= read_size;
+	    if (! size)
+	      break;
+
+            b = 0;
+            disknr += (near - i);
+            while (disknr >= array->total_devs)
+              {
+                disknr -= array->total_devs;
+                read_sector += ofs;
+              }
+          }
+        break;
+      }
+
+    case 4:
+    case 5:
+    case 6:
+      {
+	grub_disk_addr_t read_sector;
+	grub_uint32_t b, p, n, disknr, e;
+
+        /* n = 1 for level 4 and 5, 2 for level 6.  */
+        n = array->level / 3;
+
+	/* Find the first sector to read. */
+	read_sector = grub_divmod64 (sector, array->chunk_size, &b);
+	read_sector = grub_divmod64 (read_sector, array->total_devs - n,
+                                     &disknr);
+        if (array->level >= 5)
+          {
+            grub_divmod64 (read_sector, array->total_devs, &p);
+
+            if (! (array->layout & GRUB_RAID_LAYOUT_RIGHT_MASK))
+              p = array->total_devs - 1 - p;
+
+            if (array->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK)
+              {
+                disknr += p + n;
+              }
+            else
+              {
+                grub_uint32_t q;
+
+                q = p + (n - 1);
+                if (q >= array->total_devs)
+                  q -= array->total_devs;
+
+                if (disknr >= p)
+                  disknr += n;
+                else if (disknr >= q)
+                  disknr += q + 1;
+              }
+
+            if (disknr >= array->total_devs)
+              disknr -= array->total_devs;
+          }
+        else
+          p = array->total_devs - n;
+
+	read_sector *= array->chunk_size;
+
+	while (1)
+	  {
+            grub_size_t read_size;
+            int next_level;
+
+            read_size = array->chunk_size - b;
+            if (read_size > size)
+              read_size = size;
+
+            e = 0;
+            if (array->device[disknr])
+              {
+                /* Reset read error.  */
+                if (grub_errno == GRUB_ERR_READ_ERROR)
+                  grub_errno = GRUB_ERR_NONE;
+
+                err = grub_disk_read (array->device[disknr],
+                                      read_sector + b, 0,
+                                      read_size << GRUB_DISK_SECTOR_BITS,
+                                      buf);
+
+                if ((err) && (err != GRUB_ERR_READ_ERROR))
+                  break;
+                e++;
+              }
+            else
+              err = GRUB_ERR_READ_ERROR;
+
+	    if (err)
+              {
+                if (array->nr_devs < array->total_devs - n + e)
+                  break;
+
+                grub_errno = GRUB_ERR_NONE;
+                if (array->level == 6)
+                  {
+                    err = ((grub_raid6_recover_func) ?
+                           (*grub_raid6_recover_func) (array, disknr, p,
+                                                       buf, read_sector + b,
+                                                       read_size) :
+                           grub_error (GRUB_ERR_BAD_DEVICE,
+                                       "raid6rec is not loaded"));
+                  }
+                else
+                  {
+                    err = ((grub_raid5_recover_func) ?
+                           (*grub_raid5_recover_func) (array, disknr,
+                                                       buf, read_sector + b,
+                                                       read_size) :
+                           grub_error (GRUB_ERR_BAD_DEVICE,
+                                       "raid5rec is not loaded"));
+                  }
+
+                if (err)
+                  break;
+              }
+
+	    buf += read_size << GRUB_DISK_SECTOR_BITS;
+	    size -= read_size;
+	    if (! size)
+	      break;
+
+            b = 0;
+	    disknr++;
+
+            if (array->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK)
+              {
+                if (disknr == array->total_devs)
+                  disknr = 0;
+
+                next_level = (disknr == p);
+              }
+            else
+              {
+                if (disknr == p)
+                  disknr += n;
+
+                next_level = (disknr >= array->total_devs);
+              }
+
+            if (next_level)
+              {
+                read_sector += array->chunk_size;
+
+                if (array->level >= 5)
+                  {
+                    if (array->layout & GRUB_RAID_LAYOUT_RIGHT_MASK)
+                      p = (p == array->total_devs - 1) ? 0 : p + 1;
+                    else
+                      p = (p == 0) ? array->total_devs - 1 : p - 1;
+
+                    if (array->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK)
+                      {
+                        disknr = p + n;
+                        if (disknr >= array->total_devs)
+                          disknr -= array->total_devs;
+                      }
+                    else
+                      {
+                        disknr -= array->total_devs;
+                        if (disknr == p)
+                          disknr += n;
+                      }
+                  }
+                else
+                  disknr = 0;
+              }
+	  }
+      }
+      break;
+    }
+
+  return err;
+}
+
+static grub_err_t
+grub_raid_write (grub_disk_t disk __attribute ((unused)),
+		 grub_disk_addr_t sector __attribute ((unused)),
+		 grub_size_t size __attribute ((unused)),
+		 const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static grub_err_t
+insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
+              const char *scanner_name)
+{
+  struct grub_raid_array *array = 0, *p;
+
+  /* See whether the device is part of an array we have already seen a
+     device from. */
+  for (p = array_list; p != NULL; p = p->next)
+    if ((p->uuid_len == new_array->uuid_len) &&
+        (! grub_memcmp (p->uuid, new_array->uuid, p->uuid_len)))
+      {
+        grub_free (new_array->uuid);
+        array = p;
+
+        /* Do some checks before adding the device to the array.  */
+
+        /* FIXME: Check whether the update time of the superblocks are
+           the same. */
+
+        if (array->total_devs == array->nr_devs)
+          /* We found more members of the array than the array
+             actually has according to its superblock.  This shouldn't
+             happen normally.  */
+          grub_dprintf ("raid", "array->nr_devs > array->total_devs (%d)?!?",
+			array->total_devs);
+
+        if (array->device[new_array->index] != NULL)
+          /* We found multiple devices with the same number. Again,
+             this shouldn't happen.*/
+          grub_dprintf ("raid", "Found two disks with the number %d?!?",
+			new_array->number);
+
+        if (new_array->disk_size < array->disk_size)
+          array->disk_size = new_array->disk_size;
+        break;
+      }
+
+  /* Add an array to the list if we didn't find any.  */
+  if (!array)
+    {
+      array = grub_malloc (sizeof (*array));
+      if (!array)
+        {
+          grub_free (new_array->uuid);
+          return grub_errno;
+        }
+
+      *array = *new_array;
+      array->nr_devs = 0;
+      grub_memset (&array->device, 0, sizeof (array->device));
+
+      /* Check whether we don't have multiple arrays with the same number. */
+      for (p = array_list; p != NULL; p = p->next)
+        {
+          if (p->number == array->number)
+            break;
+        }
+
+      if (p)
+        {
+          /* The number is already in use, so we need to find an new number. */
+          int i = 0;
+
+          while (1)
+            {
+              for (p = array_list; p != NULL; p = p->next)
+                {
+                  if (p->number == i)
+                    break;
+                }
+
+              if (!p)
+                {
+                  /* We found an unused number.  */
+                  array->number = i;
+                  break;
+                }
+
+              i++;
+            }
+        }
+
+      array->name = grub_malloc (13);
+      if (! array->name)
+        {
+          grub_free (array->uuid);
+          grub_free (array);
+
+          return grub_errno;
+        }
+
+      grub_sprintf (array->name, "md%d", array->number);
+
+      grub_dprintf ("raid", "Found array %s (%s)\n", array->name,
+                    scanner_name);
+
+      /* Add our new array to the list.  */
+      array->next = array_list;
+      array_list = array;
+
+      /* RAID 1 doesn't use a chunksize but code assumes one so set
+	 one. */
+      if (array->level == 1)
+	array->chunk_size = 64;
+    }
+
+  /* Add the device to the array. */
+  array->device[new_array->index] = disk;
+  array->nr_devs++;
+
+  return 0;
+}
+
+static grub_raid_t grub_raid_list;
+
+static void
+free_array (void)
+{
+  struct grub_raid_array *array;
+
+  array = array_list;
+  while (array)
+    {
+      struct grub_raid_array *p;
+      int i;
+
+      p = array;
+      array = array->next;
+
+      for (i = 0; i < GRUB_RAID_MAX_DEVICES; i++)
+        if (p->device[i])
+          grub_disk_close (p->device[i]);
+
+      grub_free (p->uuid);
+      grub_free (p->name);
+      grub_free (p);
+    }
+
+  array_list = 0;
+}
+
+void
+grub_raid_register (grub_raid_t raid)
+{
+  auto int hook (const char *name);
+  int hook (const char *name)
+    {
+      grub_disk_t disk;
+      struct grub_raid_array array;
+
+      grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name);
+
+      disk = grub_disk_open (name);
+      if (!disk)
+        return 0;
+
+      if ((disk->total_sectors != GRUB_ULONG_MAX) &&
+	  (! grub_raid_list->detect (disk, &array)) &&
+	  (! insert_array (disk, &array, grub_raid_list->name)))
+	return 0;
+
+      /* This error usually means it's not raid, no need to display
+	 it.  */
+      if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
+	grub_print_error ();
+
+      grub_errno = GRUB_ERR_NONE;
+
+      grub_disk_close (disk);
+
+      return 0;
+    }
+
+  raid->next = grub_raid_list;
+  grub_raid_list = raid;
+  grub_device_iterate (&hook);
+}
+
+void
+grub_raid_unregister (grub_raid_t raid)
+{
+  grub_raid_t *p, q;
+
+  for (p = &grub_raid_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == raid)
+      {
+	*p = q->next;
+	break;
+      }
+}
+
+static struct grub_disk_dev grub_raid_dev =
+  {
+    .name = "raid",
+    .id = GRUB_DISK_DEVICE_RAID_ID,
+    .iterate = grub_raid_iterate,
+    .open = grub_raid_open,
+    .close = grub_raid_close,
+    .read = grub_raid_read,
+    .write = grub_raid_write,
+#ifdef GRUB_UTIL
+    .memberlist = grub_raid_memberlist,
+#endif
+    .next = 0
+  };
+
+
+GRUB_MOD_INIT(raid)
+{
+  grub_disk_dev_register (&grub_raid_dev);
+}
+
+GRUB_MOD_FINI(raid)
+{
+  grub_disk_dev_unregister (&grub_raid_dev);
+  free_array ();
+}
diff --git a/disk/raid5_recover.c b/disk/raid5_recover.c
new file mode 100644
index 0000000..31cef88
--- /dev/null
+++ b/disk/raid5_recover.c
@@ -0,0 +1,72 @@
+/* raid5_recover.c - module to recover from faulty RAID4/5 arrays.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/raid.h>
+
+static grub_err_t
+grub_raid5_recover (struct grub_raid_array *array, int disknr,
+                    char *buf, grub_disk_addr_t sector, int size)
+{
+  char *buf2;
+  int i;
+
+  size <<= GRUB_DISK_SECTOR_BITS;
+  buf2 = grub_malloc (size);
+  if (!buf2)
+    return grub_errno;
+
+  grub_memset (buf, 0, size);
+
+  for (i = 0; i < (int) array->total_devs; i++)
+    {
+      grub_err_t err;
+
+      if (i == disknr)
+        continue;
+
+      err = grub_disk_read (array->device[i], sector, 0, size, buf2);
+
+      if (err)
+        {
+          grub_free (buf2);
+          return err;
+        }
+
+      grub_raid_block_xor (buf, buf2, size);
+    }
+
+  grub_free (buf2);
+
+  return GRUB_ERR_NONE;
+}
+
+GRUB_MOD_INIT(raid5rec)
+{
+  grub_raid5_recover_func = grub_raid5_recover;
+}
+
+GRUB_MOD_FINI(raid5rec)
+{
+  grub_raid5_recover_func = 0;
+}
diff --git a/disk/raid6_recover.c b/disk/raid6_recover.c
new file mode 100644
index 0000000..7bbf8ea
--- /dev/null
+++ b/disk/raid6_recover.c
@@ -0,0 +1,219 @@
+/* raid6_recover.c - module to recover from faulty RAID6 arrays.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/raid.h>
+
+static grub_uint8_t raid6_table1[256][256];
+static grub_uint8_t raid6_table2[256][256];
+
+static void
+grub_raid_block_mul (grub_uint8_t mul, char *buf, int size)
+{
+  int i;
+  grub_uint8_t *p;
+
+  p = (grub_uint8_t *) buf;
+  for (i = 0; i < size; i++, p++)
+    *p = raid6_table1[mul][*p];
+}
+
+static void
+grub_raid6_init_table (void)
+{
+  int i, j;
+
+  for (i = 0; i < 256; i++)
+    raid6_table1[i][1] = raid6_table1[1][i] = i;
+
+  for (i = 2; i < 256; i++)
+    for (j = i; j < 256; j++)
+      {
+        int n;
+        grub_uint8_t c;
+
+        n = i >> 1;
+
+        c = raid6_table1[n][j];
+        c = (c << 1) ^ ((c & 0x80) ? 0x1d : 0);
+        if (i & 1)
+          c ^= j;
+
+        raid6_table1[j][i] = raid6_table1[i][j] = c;
+      }
+
+  raid6_table2[0][0] = 1;
+  for (i = 1; i < 256; i++)
+    raid6_table2[i][i] = raid6_table1[raid6_table2[i - 1][i - 1]][2];
+
+  for (i = 0; i < 254; i++)
+    for (j = 0; j < 254; j++)
+      {
+        grub_uint8_t c, n;
+        int k;
+
+        if (i == j)
+          continue;
+
+        k = i - j;
+        if (k < 0)
+          k += 255;
+
+        c = n = raid6_table2[k][k] ^ 1;
+        for (k = 0; k < 253; k++)
+          c = raid6_table1[c][n];
+
+        raid6_table2[i][j] = raid6_table1[raid6_table2[255 - j][255 - j]][c];
+      }
+}
+
+static grub_err_t
+grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
+                    char *buf, grub_disk_addr_t sector, int size)
+{
+  int i, q, pos;
+  int bad1 = -1, bad2 = -1;
+  char *pbuf = 0, *qbuf = 0;
+
+  size <<= GRUB_DISK_SECTOR_BITS;
+  pbuf = grub_zalloc (size);
+  if (!pbuf)
+    goto quit;
+
+  qbuf = grub_zalloc (size);
+  if (!qbuf)
+    goto quit;
+
+  q = p + 1;
+  if (q == (int) array->total_devs)
+    q = 0;
+
+  pos = q + 1;
+  if (pos == (int) array->total_devs)
+    pos = 0;
+
+  for (i = 0; i < (int) array->total_devs - 2; i++)
+    {
+      if (pos == disknr)
+        bad1 = i;
+      else
+        {
+          if ((array->device[pos]) &&
+              (! grub_disk_read (array->device[pos], sector, 0, size, buf)))
+            {
+              grub_raid_block_xor (pbuf, buf, size);
+              grub_raid_block_mul (raid6_table2[i][i], buf, size);
+              grub_raid_block_xor (qbuf, buf, size);
+            }
+          else
+            {
+              /* Too many bad devices */
+              if (bad2 >= 0)
+                goto quit;
+
+              bad2 = i;
+              grub_errno = GRUB_ERR_NONE;
+            }
+        }
+
+      pos++;
+      if (pos == (int) array->total_devs)
+        pos = 0;
+    }
+
+  /* Invalid disknr or p */
+  if (bad1 < 0)
+    goto quit;
+
+  if (bad2 < 0)
+    {
+      /* One bad device */
+      if ((array->device[p]) &&
+          (! grub_disk_read (array->device[p], sector, 0, size, buf)))
+        {
+          grub_raid_block_xor (buf, pbuf, size);
+          goto quit;
+        }
+
+      if (! array->device[q])
+        {
+          grub_error (GRUB_ERR_READ_ERROR, "Not enough disk to restore");
+          goto quit;
+        }
+
+      grub_errno = GRUB_ERR_NONE;
+      if (grub_disk_read (array->device[q], sector, 0, size, buf))
+        goto quit;
+
+      grub_raid_block_xor (buf, qbuf, size);
+      grub_raid_block_mul (raid6_table2[255 - bad1][255 - bad1], buf,
+                           size);
+    }
+  else
+    {
+      /* Two bad devices */
+      grub_uint8_t c;
+
+      if ((! array->device[p]) || (! array->device[q]))
+        {
+          grub_error (GRUB_ERR_READ_ERROR, "Not enough disk to restore");
+          goto quit;
+        }
+
+      if (grub_disk_read (array->device[p], sector, 0, size, buf))
+        goto quit;
+
+      grub_raid_block_xor (pbuf, buf, size);
+
+      if (grub_disk_read (array->device[q], sector, 0, size, buf))
+        goto quit;
+
+      grub_raid_block_xor (qbuf, buf, size);
+
+      c = raid6_table2[bad2][bad1];
+      grub_raid_block_mul (c, qbuf, size);
+
+      c = raid6_table1[raid6_table2[bad2][bad2]][c];
+      grub_raid_block_mul (c, pbuf, size);
+
+      grub_raid_block_xor (pbuf, qbuf, size);
+      grub_memcpy (buf, pbuf, size);
+    }
+
+quit:
+  grub_free (pbuf);
+  grub_free (qbuf);
+
+  return grub_errno;
+}
+
+GRUB_MOD_INIT(raid6rec)
+{
+  grub_raid6_init_table ();
+  grub_raid6_recover_func = grub_raid6_recover;
+}
+
+GRUB_MOD_FINI(raid6rec)
+{
+  grub_raid6_recover_func = 0;
+}
diff --git a/disk/scsi.c b/disk/scsi.c
new file mode 100644
index 0000000..24ebdb6
--- /dev/null
+++ b/disk/scsi.c
@@ -0,0 +1,403 @@
+/* scsi.c - scsi support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/machine/kernel.h>
+#include <grub/scsi.h>
+#include <grub/scsicmd.h>
+
+
+static grub_scsi_dev_t grub_scsi_dev_list;
+
+void
+grub_scsi_dev_register (grub_scsi_dev_t dev)
+{
+  dev->next = grub_scsi_dev_list;
+  grub_scsi_dev_list = dev;
+}
+
+void
+grub_scsi_dev_unregister (grub_scsi_dev_t dev)
+{
+  grub_scsi_dev_t *p, q;
+
+  for (p = &grub_scsi_dev_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == dev)
+      {
+        *p = q->next;
+	break;
+      }
+}
+
+
+/* Determine the the device is removable and the type of the device
+   SCSI.  */
+static grub_err_t
+grub_scsi_inquiry (grub_scsi_t scsi)
+{
+  struct grub_scsi_inquiry iq;
+  struct grub_scsi_inquiry_data iqd;
+  grub_err_t err;
+
+  iq.opcode = grub_scsi_cmd_inquiry;
+  iq.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  iq.reserved = 0;
+  iq.alloc_length = 0x24; /* XXX: Hardcoded for now */
+  iq.reserved2 = 0;
+
+  err = scsi->dev->read (scsi, sizeof (iq), (char *) &iq,
+			 sizeof (iqd), (char *) &iqd);
+  if (err)
+    return err;
+
+  scsi->devtype = iqd.devtype & GRUB_SCSI_DEVTYPE_MASK;
+  scsi->removable = iqd.rmb >> GRUB_SCSI_REMOVABLE_BIT;
+
+  return GRUB_ERR_NONE;
+}
+
+/* Read the capacity and block size of SCSI.  */
+static grub_err_t
+grub_scsi_read_capacity (grub_scsi_t scsi)
+{
+  struct grub_scsi_read_capacity rc;
+  struct grub_scsi_read_capacity_data rcd;
+  grub_err_t err;
+
+  rc.opcode = grub_scsi_cmd_read_capacity;
+  rc.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  grub_memset (rc.reserved, 0, sizeof (rc.reserved));
+
+  err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc,
+			 sizeof (rcd), (char *) &rcd);
+  if (err)
+    return err;
+
+  scsi->size = grub_be_to_cpu32 (rcd.size);
+  scsi->blocksize = grub_be_to_cpu32 (rcd.blocksize);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Send a SCSI request for DISK: read SIZE sectors starting with
+   sector SECTOR to BUF.  */
+static grub_err_t
+grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector,
+		  grub_size_t size, char *buf)
+{
+  grub_scsi_t scsi;
+  struct grub_scsi_read10 rd;
+
+  scsi = disk->data;
+
+  rd.opcode = grub_scsi_cmd_read10;
+  rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  rd.lba = grub_cpu_to_be32 (sector);
+  rd.reserved = 0;
+  rd.size = grub_cpu_to_be16 (size);
+  rd.reserved2 = 0;
+  rd.pad = 0;
+
+  return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
+}
+
+/* Send a SCSI request for DISK: read SIZE sectors starting with
+   sector SECTOR to BUF.  */
+static grub_err_t
+grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector,
+		  grub_size_t size, char *buf)
+{
+  grub_scsi_t scsi;
+  struct grub_scsi_read12 rd;
+
+  scsi = disk->data;
+
+  rd.opcode = grub_scsi_cmd_read12;
+  rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  rd.lba = grub_cpu_to_be32 (sector);
+  rd.size = grub_cpu_to_be32 (size);
+  rd.reserved = 0;
+  rd.control = 0;
+
+  return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
+}
+
+#if 0
+/* Send a SCSI request for DISK: write the data stored in BUF to SIZE
+   sectors starting with SECTOR.  */
+static grub_err_t
+grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector,
+		   grub_size_t size, char *buf)
+{
+  grub_scsi_t scsi;
+  struct grub_scsi_write10 wr;
+
+  scsi = disk->data;
+
+  wr.opcode = grub_scsi_cmd_write10;
+  wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  wr.lba = grub_cpu_to_be32 (sector);
+  wr.reserved = 0;
+  wr.size = grub_cpu_to_be16 (size);
+  wr.reserved2 = 0;
+  wr.pad = 0;
+
+  return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
+}
+
+/* Send a SCSI request for DISK: write the data stored in BUF to SIZE
+   sectors starting with SECTOR.  */
+static grub_err_t
+grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector,
+		   grub_size_t size, char *buf)
+{
+  grub_scsi_t scsi;
+  struct grub_scsi_write10 wr;
+
+  scsi = disk->data;
+
+  wr.opcode = grub_scsi_cmd_write12;
+  wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  wr.lba = grub_cpu_to_be32 (sector);
+  wr.size = grub_cpu_to_be32 (size);
+  wr.reserved = 0;
+  wr.pad = 0;
+
+  return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
+}
+#endif
+
+
+static int
+grub_scsi_iterate (int (*hook) (const char *name))
+{
+  grub_scsi_dev_t p;
+
+  auto int scsi_iterate (const char *name, int luns);
+
+  int scsi_iterate (const char *name, int luns)
+    {
+      char sname[40];
+      int i;
+
+      /* In case of a single LUN, just return `usbX'.  */
+      if (luns == 1)
+	return hook (name);
+
+      /* In case of multiple LUNs, every LUN will get a prefix to
+	 distinguish it.  */
+      for (i = 0; i < luns; i++)
+	{
+	  grub_sprintf (sname, "%s%c", name, 'a' + i);
+	  if (hook (sname))
+	    return 1;
+	}
+      return 0;
+    }
+
+  for (p = grub_scsi_dev_list; p; p = p->next)
+    if (p->iterate && (p->iterate) (scsi_iterate))
+      return 1;
+
+  return 0;
+}
+
+static grub_err_t
+grub_scsi_open (const char *name, grub_disk_t disk)
+{
+  grub_scsi_dev_t p;
+  grub_scsi_t scsi;
+  grub_err_t err;
+  int len;
+  int lun;
+
+  scsi = grub_malloc (sizeof (*scsi));
+  if (! scsi)
+    return grub_errno;
+
+  len = grub_strlen (name);
+  lun = name[len - 1] - 'a';
+
+  /* Try to detect a LUN ('a'-'z'), otherwise just use the first
+     LUN.  */
+  if (lun < 0 || lun > 26)
+    lun = 0;
+
+  for (p = grub_scsi_dev_list; p; p = p->next)
+    {
+      if (p->open (name, scsi))
+	continue;
+
+      disk->id = (unsigned long) "scsi"; /* XXX */
+      disk->data = scsi;
+      scsi->dev = p;
+      scsi->lun = lun;
+      scsi->name = grub_strdup (name);
+      if (! scsi->name)
+	{
+	  grub_free (scsi);
+	  return grub_errno;
+	}
+
+      grub_dprintf ("scsi", "dev opened\n");
+
+      err = grub_scsi_inquiry (scsi);
+      if (err)
+	{
+	  grub_free (scsi);
+	  grub_dprintf ("scsi", "inquiry failed\n");
+	  return err;
+	}
+
+      grub_dprintf ("scsi", "inquiry: devtype=0x%02x removable=%d\n",
+		    scsi->devtype, scsi->removable);
+
+      /* Try to be conservative about the device types
+	 supported.  */
+      if (scsi->devtype != grub_scsi_devtype_direct
+	  && scsi->devtype != grub_scsi_devtype_cdrom)
+	{
+	  grub_free (scsi);
+	  return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+			     "unknown SCSI device");
+	}
+
+      if (scsi->devtype == grub_scsi_devtype_cdrom)
+	disk->has_partitions = 0;
+      else
+	disk->has_partitions = 1;
+
+      err = grub_scsi_read_capacity (scsi);
+      if (err)
+	{
+	  grub_free (scsi);
+	  grub_dprintf ("scsi", "READ CAPACITY failed\n");
+	  return err;
+	}
+
+      /* SCSI blocks can be something else than 512, although GRUB
+	 wants 512 byte blocks.  */
+      disk->total_sectors = ((scsi->size * scsi->blocksize)
+			     << GRUB_DISK_SECTOR_BITS);
+
+      grub_dprintf ("scsi", "capacity=%llu, blksize=%d\n",
+		    (unsigned long long) disk->total_sectors,
+		    scsi->blocksize);
+
+      return GRUB_ERR_NONE;
+    }
+
+  grub_free (scsi);
+
+  return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk");
+}
+
+static void
+grub_scsi_close (grub_disk_t disk)
+{
+  grub_scsi_t scsi;
+
+  scsi = disk->data;
+  scsi->dev->close (scsi);
+  grub_free (scsi);
+}
+
+static grub_err_t
+grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
+		grub_size_t size, char *buf)
+{
+  grub_scsi_t scsi;
+
+  scsi = disk->data;
+
+  /* SCSI sectors are variable in size.  GRUB uses 512 byte
+     sectors.  */
+  if (scsi->blocksize != GRUB_DISK_SECTOR_SIZE)
+    {
+      unsigned spb = scsi->blocksize >> GRUB_DISK_SECTOR_BITS;
+      if (! (spb != 0 && (scsi->blocksize & GRUB_DISK_SECTOR_SIZE) == 0))
+	return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+			   "Unsupported SCSI block size");
+
+      grub_uint32_t sector_mod = 0;
+      sector = grub_divmod64 (sector, spb, &sector_mod);
+
+      if (! (sector_mod == 0 && size % spb == 0))
+	return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+			   "Unaligned SCSI read not supported");
+
+      size /= spb;
+    }
+
+  /* Depending on the type, select a read function.  */
+  switch (scsi->devtype)
+    {
+    case grub_scsi_devtype_direct:
+      return grub_scsi_read10 (disk, sector, size, buf);
+
+    case grub_scsi_devtype_cdrom:
+      return grub_scsi_read12 (disk, sector, size, buf);
+    }
+
+  /* XXX: Never reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_scsi_write (grub_disk_t disk __attribute((unused)),
+		 grub_disk_addr_t sector __attribute((unused)),
+		 grub_size_t size __attribute((unused)),
+		 const char *buf __attribute((unused)))
+{
+#if 0
+  /* XXX: Not tested yet!  */
+
+  /* XXX: This should depend on the device type?  */
+  return grub_scsi_write10 (disk, sector, size, buf);
+#endif
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+
+static struct grub_disk_dev grub_scsi_dev =
+  {
+    .name = "scsi",
+    .id = GRUB_DISK_DEVICE_SCSI_ID,
+    .iterate = grub_scsi_iterate,
+    .open = grub_scsi_open,
+    .close = grub_scsi_close,
+    .read = grub_scsi_read,
+    .write = grub_scsi_write,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(scsi)
+{
+  grub_disk_dev_register (&grub_scsi_dev);
+}
+
+GRUB_MOD_FINI(scsi)
+{
+  grub_disk_dev_unregister (&grub_scsi_dev);
+}
diff --git a/disk/usbms.c b/disk/usbms.c
new file mode 100644
index 0000000..51e8865
--- /dev/null
+++ b/disk/usbms.c
@@ -0,0 +1,390 @@
+/* usbms.c - USB Mass Storage Support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/scsi.h>
+#include <grub/scsicmd.h>
+#include <grub/misc.h>
+
+#define GRUB_USBMS_DIRECTION_BIT	7
+
+/* The USB Mass Storage Command Block Wrapper.  */
+struct grub_usbms_cbw
+{
+  grub_uint32_t signature;
+  grub_uint32_t tag;
+  grub_uint32_t transfer_length;
+  grub_uint8_t flags;
+  grub_uint8_t lun;
+  grub_uint8_t length;
+  grub_uint8_t cbwcb[16];
+} __attribute__ ((packed));
+
+struct grub_usbms_csw
+{
+  grub_uint32_t signature;
+  grub_uint32_t tag;
+  grub_uint32_t residue;
+  grub_uint8_t status;
+} __attribute__ ((packed));
+
+struct grub_usbms_dev
+{
+  struct grub_usb_device *dev;
+
+  int luns;
+
+  int interface;
+  struct grub_usb_desc_endp *in;
+  struct grub_usb_desc_endp *out;
+
+  int in_maxsz;
+  int out_maxsz;
+
+  struct grub_usbms_dev *next;
+};
+typedef struct grub_usbms_dev *grub_usbms_dev_t;
+
+static grub_usbms_dev_t grub_usbms_dev_list;
+
+static int devcnt;
+
+static grub_err_t
+grub_usbms_reset (grub_usb_device_t dev, int interface)
+{
+  return grub_usb_control_msg (dev, 0x21, 255, 0, interface, 0, 0);
+}
+
+static void
+grub_usbms_finddevs (void)
+{
+  auto int usb_iterate (grub_usb_device_t dev);
+
+  int usb_iterate (grub_usb_device_t usbdev)
+    {
+      grub_usb_err_t err;
+      struct grub_usb_desc_device *descdev = &usbdev->descdev;
+      int i;
+
+      if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0)
+	return 0;
+
+      /* XXX: Just check configuration 0 for now.  */
+      for (i = 0; i < usbdev->config[0].descconf->numif; i++)
+	{
+	  struct grub_usbms_dev *usbms;
+	  struct grub_usb_desc_if *interf;
+	  int j;
+	  grub_uint8_t luns;
+
+	  interf = usbdev->config[0].interf[i].descif;
+
+	  /* If this is not a USB Mass Storage device with a supported
+	     protocol, just skip it.  */
+	  if (interf->class != GRUB_USB_CLASS_MASS_STORAGE
+	      || interf->subclass != GRUB_USBMS_SUBCLASS_BULK
+	      || interf->protocol != GRUB_USBMS_PROTOCOL_BULK)
+	    {
+	      continue;
+	    }
+
+	  devcnt++;
+	  usbms = grub_zalloc (sizeof (struct grub_usbms_dev));
+	  if (! usbms)
+	    return 1;
+
+	  usbms->dev = usbdev;
+	  usbms->interface = i;
+
+	  /* Iterate over all endpoints of this interface, at least a
+	     IN and OUT bulk endpoint are required.  */
+	  for (j = 0; j < interf->endpointcnt; j++)
+	    {
+	      struct grub_usb_desc_endp *endp;
+	      endp = &usbdev->config[0].interf[i].descendp[j];
+
+	      if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2)
+		{
+		  /* Bulk IN endpoint.  */
+		  usbms->in = endp;
+		  grub_usb_clear_halt (usbdev, endp->endp_addr & 128);
+		  usbms->in_maxsz = endp->maxpacket;
+		}
+	      else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2)
+		{
+		  /* Bulk OUT endpoint.  */
+		  usbms->out = endp;
+		  grub_usb_clear_halt (usbdev, endp->endp_addr & 128);
+		  usbms->out_maxsz = endp->maxpacket;
+		}
+	    }
+
+	  if (!usbms->in || !usbms->out)
+	    {
+	      grub_free (usbms);
+	      return 0;
+	    }
+
+	  /* Query the amount of LUNs.  */
+	  err = grub_usb_control_msg (usbdev, 0xA1, 254,
+				      0, i, 1, (char *) &luns);
+	  if (err)
+	    {
+	      /* In case of a stall, clear the stall.  */
+	      if (err == GRUB_USB_ERR_STALL)
+		{
+		  grub_usb_clear_halt (usbdev, usbms->in->endp_addr & 3);
+		  grub_usb_clear_halt (usbdev, usbms->out->endp_addr & 3);
+		}
+
+	      /* Just set the amount of LUNs to one.  */
+	      grub_errno = GRUB_ERR_NONE;
+	      usbms->luns = 1;
+	    }
+	  else
+	    usbms->luns = luns;
+
+	  /* XXX: Check the magic values, does this really make
+	     sense?  */
+	  grub_usb_control_msg (usbdev, (1 << 6) | 1, 255,
+				0, i, 0, 0);
+
+	  /* XXX: To make Qemu work?  */
+	  if (usbms->luns == 0)
+	    usbms->luns = 1;
+
+	  usbms->next = grub_usbms_dev_list;
+	  grub_usbms_dev_list = usbms;
+
+	  /* XXX: Activate the first configuration.  */
+	  grub_usb_set_configuration (usbdev, 1);
+
+	  /* Bulk-Only Mass Storage Reset, after the reset commands
+	     will be accepted.  */
+	  grub_usbms_reset (usbdev, i);
+
+	  return 0;
+	}
+
+      return 0;
+    }
+
+  grub_usb_iterate (usb_iterate);
+}
+
+
+
+static int
+grub_usbms_iterate (int (*hook) (const char *name, int luns))
+{
+  grub_usbms_dev_t p;
+  int cnt = 0;
+
+  for (p = grub_usbms_dev_list; p; p = p->next)
+    {
+      char devname[20];
+      grub_sprintf (devname, "usb%d", cnt);
+
+      if (hook (devname, p->luns))
+	return 1;
+      cnt++;
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+		     grub_size_t size, char *buf, int read_write)
+{
+  struct grub_usbms_cbw cbw;
+  grub_usbms_dev_t dev = (grub_usbms_dev_t) scsi->data;
+  struct grub_usbms_csw status;
+  static grub_uint32_t tag = 0;
+  grub_usb_err_t err = GRUB_USB_ERR_NONE;
+  int retrycnt = 3 + 1;
+
+ retry:
+  retrycnt--;
+  if (retrycnt == 0)
+    return grub_error (GRUB_ERR_IO, "USB Mass Storage stalled");
+
+  /* Setup the request.  */
+  grub_memset (&cbw, 0, sizeof (cbw));
+  cbw.signature = grub_cpu_to_le32 (0x43425355);
+  cbw.tag = tag++;
+  cbw.transfer_length = grub_cpu_to_le32 (size);
+  cbw.flags = (!read_write) << GRUB_USBMS_DIRECTION_BIT;
+  cbw.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  cbw.length = cmdsize;
+  grub_memcpy (cbw.cbwcb, cmd, cmdsize);
+
+  /* Write the request.  */
+  err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr & 15,
+			     sizeof (cbw), (char *) &cbw);
+  if (err)
+    {
+      if (err == GRUB_USB_ERR_STALL)
+	{
+	  grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
+	  goto retry;
+	}
+      return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed");
+    }
+
+  /* Read/write the data.  */
+  if (read_write == 0)
+    {
+      err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15, size, buf);
+      grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL);
+      if (err)
+	{
+	  if (err == GRUB_USB_ERR_STALL)
+	    {
+	      grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
+	      goto retry;
+	    }
+	  return grub_error (GRUB_ERR_READ_ERROR,
+			     "can't read from USB Mass Storage device");
+	}
+    }
+  else
+    {
+      err = grub_usb_bulk_write (dev->dev, dev->in->endp_addr & 15, size, buf);
+      grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL);
+      if (err)
+	{
+	  if (err == GRUB_USB_ERR_STALL)
+	    {
+	      grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
+	      goto retry;
+	    }
+	  return grub_error (GRUB_ERR_WRITE_ERROR,
+			     "can't write to USB Mass Storage device");
+	}
+    }
+
+  /* Read the status.  */
+  err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15,
+			    sizeof (status), (char *) &status);
+  if (err)
+    {
+      if (err == GRUB_USB_ERR_STALL)
+	{
+	  grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
+	  goto retry;
+	}
+      return grub_error (GRUB_ERR_READ_ERROR,
+			 "can't read status from USB Mass Storage device");
+    }
+
+  /* XXX: Magic and check this code.  */
+  if (status.status == 2)
+    {
+      /* XXX: Phase error, reset device.  */
+      grub_usbms_reset (dev->dev, dev->interface);
+      grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
+      grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
+
+      goto retry;
+    }
+
+  if (status.status)
+    return grub_error (GRUB_ERR_READ_ERROR,
+		       "error communication with USB Mass Storage device");
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_err_t
+grub_usbms_read (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+		 grub_size_t size, char *buf)
+{
+  return grub_usbms_transfer (scsi, cmdsize, cmd, size, buf, 0);
+}
+
+static grub_err_t
+grub_usbms_write (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+		  grub_size_t size, char *buf)
+{
+  return grub_usbms_transfer (scsi, cmdsize, cmd, size, buf, 1);
+}
+
+static grub_err_t
+grub_usbms_open (const char *name, struct grub_scsi *scsi)
+{
+  grub_usbms_dev_t p;
+  int devnum;
+  int i = 0;
+
+  if (grub_strncmp (name, "usb", 3))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+		       "not a USB Mass Storage device");
+
+  devnum = grub_strtoul (name + 3, NULL, 10);
+  for (p = grub_usbms_dev_list; p; p = p->next)
+    {
+      /* Check if this is the devnumth device.  */
+      if (devnum == i)
+	{
+	  scsi->data = p;
+	  scsi->name = grub_strdup (name);
+	  scsi->luns = p->luns;
+	  if (! scsi->name)
+	    return grub_errno;
+
+	  return GRUB_ERR_NONE;
+	}
+
+      i++;
+    }
+
+  return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+		     "not a USB Mass Storage device");
+}
+
+static void
+grub_usbms_close (struct grub_scsi *scsi)
+{
+  grub_free (scsi->name);
+}
+
+static struct grub_scsi_dev grub_usbms_dev =
+  {
+    .name = "usb",
+    .iterate = grub_usbms_iterate,
+    .open = grub_usbms_open,
+    .close = grub_usbms_close,
+    .read = grub_usbms_read,
+    .write = grub_usbms_write
+  };
+
+GRUB_MOD_INIT(usbms)
+{
+  grub_usbms_finddevs ();
+  grub_scsi_dev_register (&grub_usbms_dev);
+}
+
+GRUB_MOD_FINI(usbms)
+{
+  grub_scsi_dev_unregister (&grub_usbms_dev);
+}
diff --git a/docs/fdl.texi b/docs/fdl.texi
new file mode 100644
index 0000000..fe78df8
--- /dev/null
+++ b/docs/fdl.texi
@@ -0,0 +1,452 @@
+
+@node GNU Free Documentation License
+@appendixsec GNU Free Documentation License
+
+@cindex FDL, GNU Free Documentation License
+@center Version 1.2, November 2002
+
+@display
+Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc.
+51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@enumerate 0
+@item
+PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document @dfn{free} in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of ``copyleft'', which means that derivative
+works of the document must themselves be free in the same sense.  It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does.  But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book.  We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@item
+APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License.  Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein.  The ``Document'', below,
+refers to any such manual or work.  Any member of the public is a
+licensee, and is addressed as ``you''.  You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A ``Modified Version'' of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A ``Secondary Section'' is a named appendix or a front-matter section
+of the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject.  (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.)  The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The ``Invariant Sections'' are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License.  If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant.  The Document may contain zero
+Invariant Sections.  If the Document does not identify any Invariant
+Sections then there are none.
+
+The ``Cover Texts'' are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License.  A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A ``Transparent'' copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters.  A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text.  A copy that is not ``Transparent'' is called ``Opaque''.
+
+Examples of suitable formats for Transparent copies include plain
+@sc{ascii} without markup, Texinfo input format, La@TeX{} input
+format, @acronym{SGML} or @acronym{XML} using a publicly available
+@acronym{DTD}, and standard-conforming simple @acronym{HTML},
+PostScript or @acronym{PDF} designed for human modification.  Examples
+of transparent image formats include @acronym{PNG}, @acronym{XCF} and
+@acronym{JPG}.  Opaque formats include proprietary formats that can be
+read and edited only by proprietary word processors, @acronym{SGML} or
+@acronym{XML} for which the @acronym{DTD} and/or processing tools are
+not generally available, and the machine-generated @acronym{HTML},
+PostScript or @acronym{PDF} produced by some word processors for
+output purposes only.
+
+The ``Title Page'' means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page.  For works in
+formats which do not have any title page as such, ``Title Page'' means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+A section ``Entitled XYZ'' means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language.  (Here XYZ stands for a
+specific section name mentioned below, such as ``Acknowledgements'',
+``Dedications'', ``Endorsements'', or ``History''.)  To ``Preserve the Title''
+of such a section when you modify the Document means that it remains a
+section ``Entitled XYZ'' according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document.  These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+@item
+VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License.  You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute.  However, you may accept
+compensation in exchange for copies.  If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@item
+COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover.  Both covers must also clearly and legibly identify
+you as the publisher of these copies.  The front cover must present
+the full title with all words of the title equally prominent and
+visible.  You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@item
+MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it.  In addition, you must do these things in the Modified Version:
+
+@enumerate A
+@item
+Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions
+(which should, if there were any, be listed in the History section
+of the Document).  You may use the same title as a previous version
+if the original publisher of that version gives permission.
+
+@item
+List on the Title Page, as authors, one or more persons or entities
+responsible for authorship of the modifications in the Modified
+Version, together with at least five of the principal authors of the
+Document (all of its principal authors, if it has fewer than five),
+unless they release you from this requirement.
+
+@item
+State on the Title page the name of the publisher of the
+Modified Version, as the publisher.
+
+@item
+Preserve all the copyright notices of the Document.
+
+@item
+Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+Preserve in that license notice the full lists of Invariant Sections
+and required Cover Texts given in the Document's license notice.
+
+@item
+Include an unaltered copy of this License.
+
+@item
+Preserve the section Entitled ``History'', Preserve its Title, and add
+to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page.  If
+there is no section Entitled ``History'' in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise
+the network locations given in the Document for previous versions
+it was based on.  These may be placed in the ``History'' section.
+You may omit a network location for a work that was published at
+least four years before the Document itself, or if the original
+publisher of the version it refers to gives permission.
+
+@item
+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
+the Title of the section, and preserve in the section all the
+substance and tone of each of the contributor acknowledgements and/or
+dedications given therein.
+
+@item
+Preserve all the Invariant Sections of the Document,
+unaltered in their text and in their titles.  Section numbers
+or the equivalent are not considered part of the section titles.
+
+@item
+Delete any section Entitled ``Endorsements''.  Such a section
+may not be included in the Modified Version.
+
+@item
+Do not retitle any existing section to be Entitled ``Endorsements'' or
+to conflict in title with any Invariant Section.
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant.  To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled ``Endorsements'', provided it contains
+nothing but endorsements of your Modified Version by various
+parties---for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version.  Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity.  If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@item
+COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy.  If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled ``History''
+in the various original documents, forming one section Entitled
+``History''; likewise combine any sections Entitled ``Acknowledgements'',
+and any sections Entitled ``Dedications''.  You must delete all
+sections Entitled ``Endorsements.''
+
+@item
+COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@item
+AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an ``aggregate'' if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+@item
+TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections.  You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers.  In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled ``Acknowledgements'',
+``Dedications'', or ``History'', the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+@item
+TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License.  Any other attempt to
+copy, modify, sublicense or distribute the Document 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.
+
+@item
+FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation 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.  See
+@uref{http://www.gnu.org/copyleft/}.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation.  If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+@end enumerate
+
+@page
+@appendixsubsec ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+@group
+  Copyright (C)  @var{year}  @var{your name}.
+  Permission is granted to copy, distribute and/or modify this document
+  under the terms of the GNU Free Documentation License, Version 1.2
+  or any later version published by the Free Software Foundation;
+  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+  Texts.  A copy of the license is included in the section entitled ``GNU
+  Free Documentation License''.
+@end group
+@end smallexample
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the ``with...Texts.'' line with this:
+
+@smallexample
+@group
+    with the Invariant Sections being @var{list their titles}, with
+    the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
+    being @var{list}.
+@end group
+@end smallexample
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@c Local Variables:
+@c ispell-local-pdict: "ispell-dict"
+@c End:
+
diff --git a/docs/grub.cfg b/docs/grub.cfg
new file mode 100644
index 0000000..0a9ab6b
--- /dev/null
+++ b/docs/grub.cfg
@@ -0,0 +1,75 @@
+#
+# Sample GRUB configuration file
+#
+
+# Boot automatically after 30 secs.
+set timeout=30
+
+# By default, boot the first entry.
+set default=0
+
+# Fallback to the second entry.
+set fallback=1
+
+# For booting GNU/Hurd
+menuentry "GNU (aka GNU/Hurd)" {
+	set root=(hd0,1)
+	multiboot /boot/gnumach.gz root=device:hd0s1
+	module /hurd/ext2fs.static ext2fs --readonly \
+			--multiboot-command-line='${kernel-command-line}' \
+			--host-priv-port='${host-port}' \
+			--device-master-port='${device-port}' \
+			--exec-server-task='${exec-task}' -T typed '${root}' \
+			'$(task-create)' '$(task-resume)'
+	module /lib/ld.so.1 exec /hurd/exec '$(exec-task=task-create)'
+}
+
+# For booting GNU/Linux
+menuentry "GNU/Linux" {
+	set root=(hd0,1)
+	linux /vmlinuz root=/dev/sda1
+	initrd /initrd.img
+}
+
+# For booting FreeBSD
+menuentry "FreeBSD (or GNU/kFreeBSD), direct boot" {
+	set root=(hd0,1,a)
+	freebsd /boot/kernel/kernel
+	freebsd_loadenv /boot/device.hints
+	freebsd_module /boot/splash.bmp type=splash_image_data
+	set FreeBSD.vfs.root.mountfrom=ufs:ad0s1a
+}
+menuentry "FreeBSD (or GNU/kFreeBSD), via /boot/loader" {
+	set root=(hd0,1,a)
+	freebsd /boot/loader
+}
+
+# For booting NetBSD
+menuentry "NetBSD" {
+	set root=(hd0,1,a)
+	netbsd /netbsd
+}
+
+# For booting OpenBSD
+menuentry "OpenBSD" {
+	set root=(hd0,1,a)
+	openbsd /bsd
+}
+
+# For booting Microsoft Windows
+menuentry "Microsoft Windows" {
+	set root=(hd0,1)
+	chainloader +1
+}
+
+# For booting Memtest86+
+menuentry "Memtest86+" {
+	set root=(hd0,1)
+	linux16 /memtest86+.bin
+}
+
+# Change the colors.
+menuentry "Change the colors" {
+	set menu_color_normal=light-green/brown
+	set menu_color_highlight=red/blue
+}
diff --git a/docs/grub.texi b/docs/grub.texi
new file mode 100644
index 0000000..4fa4446
--- /dev/null
+++ b/docs/grub.texi
@@ -0,0 +1,1575 @@
+\input texinfo
+@c -*-texinfo-*-
+@c %**start of header
+@setfilename grub.info
+@include version.texi
+@settitle GNU GRUB Manual @value{VERSION}
+@c Unify all our little indices for now.
+@syncodeindex fn cp
+@syncodeindex vr cp
+@syncodeindex ky cp
+@syncodeindex pg cp
+@syncodeindex tp cp
+@c %**end of header
+
+@footnotestyle separate
+@paragraphindent 3
+@finalout
+
+@copying
+This manual is for GNU GRUB (version @value{VERSION},
+@value{UPDATED}).
+
+Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009 Free Software Foundation, Inc.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections.
+@end quotation
+@end copying
+
+@dircategory Kernel
+@direntry
+* GRUB: (grub).                 The GRand Unified Bootloader
+* grub-install: (grub)Invoking grub-install.    Install GRUB on your drive
+* grub-terminfo: (grub)Invoking grub-terminfo.  Generate a terminfo
+                                                command from a
+                                                terminfo name
+@end direntry
+
+@setchapternewpage odd
+
+@titlepage
+@sp 10
+@title the GNU GRUB manual
+@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}.
+@author Gordon Matzigkeit
+@author Yoshinori K. Okuji
+@c The following two commands start the copyright page.
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@c Output the table of contents at the beginning.
+@contents
+
+@finalout
+@headings double
+
+@ifnottex
+@node Top
+@top GNU GRUB manual
+
+This is the documentation of GNU GRUB, the GRand Unified Bootloader,
+a flexible and powerful boot loader program for a wide range of
+architectures.
+
+This edition documents version @value{VERSION}.
+
+@insertcopying
+@end ifnottex
+
+@menu
+* Introduction::                Capturing the spirit of GRUB
+* Naming convention::           Names of your drives in GRUB
+* Installation::                Installing GRUB on your drive
+* Booting::                     How to boot different operating systems
+* Configuration::               Writing your own configuration file
+* Network::                     Downloading OS images from a network
+* Serial terminal::             Using GRUB via a serial line
+* Preset Menu::                 Embedding a configuration file into GRUB
+* Images::                      GRUB image files
+* Filesystem::                  Filesystem syntax and semantics
+* Interface::                   The menu and the command-line
+* Commands::                    The list of available builtin commands
+* Troubleshooting::             Error messages produced by GRUB
+* Invoking the grub shell::     How to use the grub shell
+* Invoking grub-install::       How to use the GRUB installer
+* Invoking grub-terminfo::      How to generate a terminfo command
+* Obtaining and Building GRUB:: How to obtain and build GRUB
+* Reporting bugs::              Where you should send a bug report
+* Future::                      Some future plans on GRUB
+* Internals::                   Hacking GRUB
+* Copying This Manual::         Copying This Manual
+* Index::
+@end menu
+
+
+@node Introduction
+@chapter Introduction to GRUB
+
+@menu
+* Overview::                    What exactly GRUB is and how to use it
+* History::                     From maggot to house fly
+* Features::                    GRUB features
+* Role of a boot loader::       The role of a boot loader
+@end menu
+
+
+@node Overview
+@section Overview
+
+Briefly, a @dfn{boot loader} is the first software program that runs when
+a computer starts.  It is responsible for loading and transferring
+control to an operating system @dfn{kernel} software (such as Linux or
+GNU Mach).  The kernel, in turn, initializes the rest of the operating
+system (e.g. a GNU system).
+
+GNU GRUB is a very powerful boot loader, which can load a wide variety
+of free operating systems, as well as proprietary operating systems with
+chain-loading@footnote{@dfn{chain-load} is the mechanism for loading
+unsupported operating systems by loading another boot loader. It is
+typically used for loading DOS or Windows.}. GRUB is designed to
+address the complexity of booting a personal computer; both the
+program and this manual are tightly bound to that computer platform,
+although porting to other platforms may be addressed in the future.
+
+One of the important features in GRUB is flexibility; GRUB understands
+filesystems and kernel executable formats, so you can load an arbitrary
+operating system the way you like, without recording the physical
+position of your kernel on the disk. Thus you can load the kernel
+just by specifying its file name and the drive and partition where the
+kernel resides.
+
+When booting with GRUB, you can use either a command-line interface
+(@pxref{Command-line interface}), or a menu interface (@pxref{Menu
+interface}). Using the command-line interface, you type the drive
+specification and file name of the kernel manually. In the menu
+interface, you just select an OS using the arrow keys. The menu is
+based on a configuration file which you prepare beforehand
+(@pxref{Configuration}). While in the menu, you can switch to the
+command-line mode, and vice-versa. You can even edit menu entries
+before using them.
+
+In the following chapters, you will learn how to specify a drive, a
+partition, and a file name (@pxref{Naming convention}) to GRUB, how to
+install GRUB on your drive (@pxref{Installation}), and how to boot your
+OSes (@pxref{Booting}), step by step.
+
+
+@node History
+@section History of GRUB
+
+GRUB originated in 1995 when Erich Boleyn was trying to boot the GNU
+Hurd with the University of Utah's Mach 4 microkernel (now known as GNU
+Mach).  Erich and Brian Ford designed the Multiboot Specification
+(@pxref{Top, Multiboot Specification, Motivation, multiboot, The Multiboot
+Specification}), because they were determined not to add to the large
+number of mutually-incompatible PC boot methods.
+
+Erich then began modifying the FreeBSD boot loader so that it would
+understand Multiboot. He soon realized that it would be a lot easier
+to write his own boot loader from scratch than to keep working on the
+FreeBSD boot loader, and so GRUB was born.
+
+Erich added many features to GRUB, but other priorities prevented him
+from keeping up with the demands of its quickly-expanding user base. In
+1999, Gordon Matzigkeit and Yoshinori K. Okuji adopted GRUB as an
+official GNU package, and opened its development by making the latest
+sources available via anonymous CVS. @xref{Obtaining and Building
+GRUB}, for more information.
+
+
+@node Features
+@section GRUB features
+
+The primary requirement for GRUB is that it be compliant with the
+@dfn{Multiboot Specification}, which is described in @ref{Top, Multiboot
+Specification, Motivation, multiboot, The Multiboot Specification}.
+
+The other goals, listed in approximate order of importance, are:
+
+@itemize @bullet{}
+@item
+Basic functions must be straightforward for end-users.
+
+@item
+Rich functionality to support kernel experts and designers.
+
+@item
+Backward compatibility for booting FreeBSD, NetBSD, OpenBSD, and
+Linux. Proprietary kernels (such as DOS, Windows NT, and OS/2) are
+supported via a chain-loading function.
+@end itemize
+
+Except for specific compatibility modes (chain-loading and the Linux
+@dfn{piggyback} format), all kernels will be started in much the same
+state as in the Multiboot Specification. Only kernels loaded at 1 megabyte
+or above are presently supported. Any attempt to load below that
+boundary will simply result in immediate failure and an error message
+reporting the problem.
+
+In addition to the requirements above, GRUB has the following features
+(note that the Multiboot Specification doesn't require all the features
+that GRUB supports):
+
+@table @asis
+@item Recognize multiple executable formats
+Support many of the @dfn{a.out} variants plus @dfn{ELF}. Symbol
+tables are also loaded.
+
+@item Support non-Multiboot kernels
+Support many of the various free 32-bit kernels that lack Multiboot
+compliance (primarily FreeBSD, NetBSD, OpenBSD, and
+Linux). Chain-loading of other boot loaders is also supported.
+
+@item Load multiples modules
+Fully support the Multiboot feature of loading multiple modules.
+
+@item Load a configuration file
+Support a human-readable text configuration file with preset boot
+commands. You can also load another configuration file dynamically and
+embed a preset configuration file in a GRUB image file. The list of
+commands (@pxref{Commands}) are a superset of those supported on the
+command-line. An example configuration file is provided in
+@ref{Configuration}.
+
+@item Provide a menu interface
+A menu interface listing preset boot commands, with a programmable
+timeout, is available. There is no fixed limit on the number of boot
+entries, and the current implementation has space for several hundred.
+
+@item Have a flexible command-line interface
+A fairly flexible command-line interface, accessible from the menu,
+is available to edit any preset commands, or write a new boot command
+set from scratch. If no configuration file is present, GRUB drops to
+the command-line.
+
+The list of commands (@pxref{Commands}) are a subset of those supported
+for configuration files. Editing commands closely resembles the Bash
+command-line (@pxref{Command Line Editing, Bash, Command Line Editing,
+features, Bash Features}), with @key{TAB}-completion of commands,
+devices, partitions, and files in a directory depending on context.
+
+@item Support multiple filesystem types
+Support multiple filesystem types transparently, plus a useful explicit
+blocklist notation. The currently supported filesystem types are
+@dfn{BSD FFS}, @dfn{DOS FAT16 and FAT32}, @dfn{Minix fs}, @dfn{Linux
+ext2fs}, @dfn{ReiserFS}, @dfn{JFS}, @dfn{XFS}, and @dfn{VSTa
+fs}. @xref{Filesystem}, for more information.
+
+@item Support automatic decompression
+Can decompress files which were compressed by @command{gzip}. This
+function is both automatic and transparent to the user (i.e. all
+functions operate upon the uncompressed contents of the specified
+files). This greatly reduces a file size and loading time, a
+particularly great benefit for floppies.@footnote{There are a few
+pathological cases where loading a very badly organized ELF kernel might
+take longer, but in practice this never happen.}
+
+It is conceivable that some kernel modules should be loaded in a
+compressed state, so a different module-loading command can be specified
+to avoid uncompressing the modules.
+
+@item Access data on any installed device
+Support reading data from any or all floppies or hard disk(s) recognized
+by the BIOS, independent of the setting of the root device.
+
+@item Be independent of drive geometry translations
+Unlike many other boot loaders, GRUB makes the particular drive
+translation irrelevant. A drive installed and running with one
+translation may be converted to another translation without any adverse
+effects or changes in GRUB's configuration.
+
+@item Detect all installed @sc{ram}
+GRUB can generally find all the installed @sc{ram} on a PC-compatible
+machine. It uses an advanced BIOS query technique for finding all
+memory regions. As described on the Multiboot Specification (@pxref{Top,
+Multiboot Specification, Motivation, multiboot, The Multiboot
+Specification}), not all kernels make use of this information, but GRUB
+provides it for those who do.
+
+@item Support Logical Block Address mode
+In traditional disk calls (called @dfn{CHS mode}), there is a geometry
+translation problem, that is, the BIOS cannot access over 1024
+cylinders, so the accessible space is limited to at least 508 MB and to
+at most 8GB. GRUB can't universally solve this problem, as there is no
+standard interface used in all machines. However, several newer machines
+have the new interface, Logical Block Address (@dfn{LBA}) mode. GRUB
+automatically detects if LBA mode is available and uses it if
+available. In LBA mode, GRUB can access the entire disk.
+
+@item Support network booting
+GRUB is basically a disk-based boot loader but also has network
+support. You can load OS images from a network by using the @dfn{TFTP}
+protocol.
+
+@item Support remote terminals
+To support computers with no console, GRUB provides remote terminal
+support, so that you can control GRUB from a remote host. Only serial
+terminal support is implemented at the moment.
+@end table
+
+
+@node Role of a boot loader
+@section The role of a boot loader
+
+The following is a quotation from Gordon Matzigkeit, a GRUB fanatic:
+
+@quotation
+Some people like to acknowledge both the operating system and kernel when
+they talk about their computers, so they might say they use
+``GNU/Linux'' or ``GNU/Hurd''.  Other people seem to think that the
+kernel is the most important part of the system, so they like to call
+their GNU operating systems ``Linux systems.''
+
+I, personally, believe that this is a grave injustice, because the
+@emph{boot loader} is the most important software of all. I used to
+refer to the above systems as either ``LILO''@footnote{The LInux LOader,
+a boot loader that everybody uses, but nobody likes.} or ``GRUB''
+systems.
+
+Unfortunately, nobody ever understood what I was talking about; now I
+just use the word ``GNU'' as a pseudonym for GRUB.
+
+So, if you ever hear people talking about their alleged ``GNU'' systems,
+remember that they are actually paying homage to the best boot loader
+around@dots{} GRUB!
+@end quotation
+
+We, the GRUB maintainers, do not (usually) encourage Gordon's level of
+fanaticism, but it helps to remember that boot loaders deserve
+recognition.  We hope that you enjoy using GNU GRUB as much as we did
+writing it.
+
+
+@node Naming convention
+@chapter Naming convention
+
+The device syntax used in GRUB is a wee bit different from what you may
+have seen before in your operating system(s), and you need to know it so
+that you can specify a drive/partition.
+
+Look at the following examples and explanations:
+
+@example
+(fd0)
+@end example
+
+First of all, GRUB requires that the device name be enclosed with
+@samp{(} and @samp{)}. The @samp{fd} part means that it is a floppy
+disk. The number @samp{0} is the drive number, which is counted from
+@emph{zero}. This expression means that GRUB will use the whole floppy
+disk.
+
+@example
+(hd0,2)
+@end example
+
+Here, @samp{hd} means it is a hard disk drive. The first integer
+@samp{0} indicates the drive number, that is, the first hard disk, while
+the second integer, @samp{1}, indicates the partition number (or the
+@sc{pc} slice number in the BSD terminology). The partition numbers are
+counted from @emph{one}, not from zero (as was the case in previous
+versions of GRUB). This expression means the second partition of the
+first hard disk drive. In this case, GRUB uses one partition of the
+disk, instead of the whole disk.
+
+@example
+(hd0,5)
+@end example
+
+This specifies the first @dfn{extended partition} of the first hard disk
+drive. Note that the partition numbers for extended partitions are
+counted from @samp{5}, regardless of the actual number of primary
+partitions on your hard disk.
+
+@example
+(hd1,a)
+@end example
+
+This means the BSD @samp{a} partition of the second hard disk. If you
+need to specify which @sc{pc} slice number should be used, use something
+like this: @samp{(hd1,1,a)}. If the @sc{pc} slice number is omitted,
+GRUB searches for the first @sc{pc} slice which has a BSD @samp{a}
+partition.
+
+Of course, to actually access the disks or partitions with GRUB, you
+need to use the device specification in a command, like @samp{root
+(fd0)} or @samp{unhide (hd0,3)}. To help you find out which number
+specifies a partition you want, the GRUB command-line
+(@pxref{Command-line interface}) options have argument
+completion. This means that, for example, you only need to type
+
+@example
+root (
+@end example
+
+followed by a @key{TAB}, and GRUB will display the list of drives,
+partitions, or file names. So it should be quite easy to determine the
+name of your target partition, even with minimal knowledge of the
+syntax.
+
+Note that GRUB does @emph{not} distinguish IDE from SCSI - it simply
+counts the drive numbers from zero, regardless of their type. Normally,
+any IDE drive number is less than any SCSI drive number, although that
+is not true if you change the boot sequence by swapping IDE and SCSI
+drives in your BIOS.
+
+Now the question is, how to specify a file? Again, consider an
+example:
+
+@example
+(hd0,1)/vmlinuz
+@end example
+
+This specifies the file named @samp{vmlinuz}, found on the first
+partition of the first hard disk drive. Note that the argument
+completion works with file names, too.
+
+That was easy, admit it. Now read the next chapter, to find out how to
+actually install GRUB on your drive.
+
+
+@node Installation
+@chapter Installation
+
+In order to install GRUB as your boot loader, you need to first
+install the GRUB system and utilities under your UNIX-like operating
+system (@pxref{Obtaining and Building GRUB}). You can do this either
+from the source tarball, or as a package for your OS.
+
+After you have done that, you need to install the boot loader on a
+drive (floppy or hard disk). There are two ways of doing that - either
+using the utility @command{grub-install} (@pxref{Invoking
+grub-install}) on a UNIX-like OS, or by running GRUB itself from a
+floppy. These are quite similar, however the utility might probe a
+wrong BIOS drive, so you should be careful.
+
+Also, if you install GRUB on a UNIX-like OS, please make sure that you
+have an emergency boot disk ready, so that you can rescue your computer
+if, by any chance, your hard drive becomes unusable (unbootable).
+
+GRUB comes with boot images, which are normally put in the directory
+@file{/usr/lib/grub/i386-pc}. Hereafter, the directory where GRUB images are
+initially placed (normally @file{/usr/lib/grub/i386-pc}) will be
+called the @dfn{image directory}, and the directory where the boot
+loader needs to find them (usually @file{/boot/grub}) will be called
+the @dfn{boot directory}.
+
+@menu
+* Installing GRUB using grub-install::
+@end menu
+
+
+@node Installing GRUB using grub-install
+@section Installing GRUB using grub-install
+
+@strong{Caution:} This procedure is definitely less safe, because
+there are several ways in which your computer can become
+unbootable. For example, most operating systems don't tell GRUB how to
+map BIOS drives to OS devices correctly---GRUB merely @dfn{guesses}
+the mapping. This will succeed in most cases, but not
+always. Therefore, GRUB provides you with a map file called the
+@dfn{device map}, which you must fix if it is wrong. @xref{Device
+map}, for more details.
+
+If you still do want to install GRUB under a UNIX-like OS (such
+as @sc{gnu}), invoke the program @command{grub-install} (@pxref{Invoking
+grub-install}) as the superuser (@dfn{root}).
+
+The usage is basically very simple. You only need to specify one
+argument to the program, namely, where to install the boot loader. The
+argument can be either a device file (like @samp{/dev/hda}) or a
+partition specified in GRUB's notation. For example, under Linux the
+following will install GRUB into the MBR of the first IDE disk:
+
+@example
+# @kbd{grub-install /dev/hda}
+@end example
+
+Likewise, under GNU/Hurd, this has the same effect:
+
+@example
+# @kbd{grub-install /dev/hd0}
+@end example
+
+If it is the first BIOS drive, this is the same as well:
+
+@example
+# @kbd{grub-install '(hd0)'}
+@end example
+
+Or you can omit the parentheses:
+
+@example
+# @kbd{grub-install hd0}
+@end example
+
+But all the above examples assume that GRUB should use images under
+the root directory. If you want GRUB to use images under a directory
+other than the root directory, you need to specify the option
+@option{--root-directory}. The typical usage is that you create a GRUB
+boot floppy with a filesystem. Here is an example:
+
+@example
+@group
+# @kbd{mke2fs /dev/fd0}
+# @kbd{mount -t ext2 /dev/fd0 /mnt}
+# @kbd{grub-install --root-directory=/mnt fd0}
+# @kbd{umount /mnt}
+@end group
+@end example
+
+Another example is when you have a separate boot partition
+which is mounted at @file{/boot}. Since GRUB is a boot loader, it
+doesn't know anything about mountpoints at all. Thus, you need to run
+@command{grub-install} like this:
+
+@example
+# @kbd{grub-install --root-directory=/boot /dev/hda}
+@end example
+
+By the way, as noted above, it is quite difficult to guess BIOS drives
+correctly under a UNIX-like OS. Thus, @command{grub-install} will prompt
+you to check if it could really guess the correct mappings, after the
+installation. The format is defined in @ref{Device map}. Please be
+quite careful. If the output is wrong, it is unlikely that your
+computer will be able to boot with no problem.
+
+Note that @command{grub-install} is actually just a shell script and the
+real task is done by the grub shell @command{grub} (@pxref{Invoking the
+grub shell}). Therefore, you may run @command{grub} directly to install
+GRUB, without using @command{grub-install}. Don't do that, however,
+unless you are very familiar with the internals of GRUB. Installing a
+boot loader on a running OS may be extremely dangerous.
+
+
+@node Making a GRUB bootable CD-ROM
+@section Making a GRUB bootable CD-ROM
+
+GRUB supports the @dfn{no emulation mode} in the El Torito
+specification@footnote{El Torito is a specification for bootable CD
+using BIOS functions.}. This means that you can use the whole CD-ROM
+from GRUB and you don't have to make a floppy or hard disk image file,
+which can cause compatibility problems.
+
+For booting from a CD-ROM, GRUB uses a special Stage 2 called
+@file{stage2_eltorito}. The only GRUB files you need to have in your
+bootable CD-ROM are this @file{stage2_eltorito} and optionally a config file
+@file{grub.cfg}. You don't need to use @file{stage1} or @file{stage2},
+because El Torito is quite different from the standard boot process.
+
+Here is an example of procedures to make a bootable CD-ROM
+image. First, make a top directory for the bootable image, say,
+@samp{iso}:
+
+@example
+$ @kbd{mkdir iso}
+@end example
+
+Make a directory for GRUB:
+
+@example
+$ @kbd{mkdir -p iso/boot/grub}
+@end example
+
+Copy the file @file{stage2_eltorito}:
+
+@example
+$ @kbd{cp /usr/lib/grub/i386-pc/stage2_eltorito iso/boot/grub}
+@end example
+
+If desired, make the config file @file{grub.cfg} under @file{iso/boot/grub}
+(@pxref{Configuration}), and copy any files and directories for the disc to the
+directory @file{iso/}.
+
+Finally, make a ISO9660 image file like this:
+
+@example
+$ @kbd{mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot \
+    -boot-load-size 4 -boot-info-table -o grub.iso iso}
+@end example
+
+This produces a file named @file{grub.iso}, which then can be burned
+into a CD (or a DVD).  @kbd{mkisofs} has already set up the disc to boot
+from the @kbd{boot/grub/stage2_eltorito} file, so there is no need to
+setup GRUB on the disc.  (Note that the @kbd{-boot-load-size 4} bit is
+required for compatibility with the BIOS on many older machines.)
+
+You can use the device @samp{(cd)} to access a CD-ROM in your
+config file. This is not required; GRUB automatically sets the root device
+to @samp{(cd)} when booted from a CD-ROM. It is only necessary to refer to
+@samp{(cd)} if you want to access other drives as well.
+
+
+@node Booting
+@chapter Booting
+
+GRUB can load Multiboot-compliant kernels in a consistent way,
+but for some free operating systems you need to use some OS-specific
+magic.
+
+@menu
+* General boot methods::        How to boot OSes with GRUB generally
+* OS-specific notes::           Notes on some operating systems
+@end menu
+
+
+@node General boot methods
+@section How to boot operating systems
+
+GRUB has two distinct boot methods. One of the two is to load an
+operating system directly, and the other is to chain-load another boot
+loader which then will load an operating system actually. Generally
+speaking, the former is more desirable, because you don't need to
+install or maintain other boot loaders and GRUB is flexible enough to
+load an operating system from an arbitrary disk/partition. However,
+the latter is sometimes required, since GRUB doesn't support all the
+existing operating systems natively.
+
+@menu
+* Loading an operating system directly::
+* Chain-loading::
+@end menu
+
+
+@node Loading an operating system directly
+@subsection How to boot an OS directly with GRUB
+
+Multiboot (@pxref{Top, Multiboot Specification, Motivation, multiboot,
+The Multiboot Specification}) is the native format supported by GRUB.
+For the sake of convenience, there is also support for Linux, FreeBSD,
+NetBSD and OpenBSD. If you want to boot other operating systems, you
+will have to chain-load them (@pxref{Chain-loading}).
+
+FIXME: this section is incomplete.
+
+@enumerate
+@item
+Run the command @command{boot} (@pxref{boot}).
+@end enumerate
+
+However, DOS and Windows have some deficiencies, so you might have to
+use more complicated instructions. @xref{DOS/Windows}, for more
+information.
+
+
+@node OS-specific notes
+@section Some caveats on OS-specific issues
+
+Here, we describe some caveats on several operating systems.
+
+@menu
+* GNU/Hurd::
+* GNU/Linux::
+@end menu
+
+
+@node GNU/Hurd
+@subsection GNU/Hurd
+
+Since GNU/Hurd is Multiboot-compliant, it is easy to boot it; there is
+nothing special about it. But do not forget that you have to specify a
+root partition to the kernel.
+
+FIXME: this section is incomplete.
+
+@enumerate
+@item
+Run the command @command{boot} (@pxref{boot}).
+@end enumerate
+
+
+@node GNU/Linux
+@subsection GNU/Linux
+
+It is relatively easy to boot GNU/Linux from GRUB, because it somewhat
+resembles to boot a Multiboot-compliant OS.
+
+FIXME: this section is incomplete.
+
+@enumerate
+@item
+Set GRUB's root device to the same drive as GNU/Linux's.
+
+@item
+Finally, run the command @command{boot} (@pxref{boot}).
+@end enumerate
+
+@strong{Caution:} If you use an initrd and specify the @samp{mem=}
+option to the kernel to let it use less than actual memory size, you
+will also have to specify the same memory size to GRUB. To let GRUB know
+the size, run the command @command{uppermem} @emph{before} loading the
+kernel. @xref{uppermem}, for more information.
+
+
+@node Serial terminal
+@chapter Using GRUB via a serial line
+
+This chapter describes how to use the serial terminal support in GRUB.
+
+If you have many computers or computers with no display/keyboard, it
+could be very useful to control the computers through serial
+communications. To connect one computer with another via a serial line,
+you need to prepare a null-modem (cross) serial cable, and you may need
+to have multiport serial boards, if your computer doesn't have extra
+serial ports. In addition, a terminal emulator is also required, such as
+minicom. Refer to a manual of your operating system, for more
+information.
+
+As for GRUB, the instruction to set up a serial terminal is quite
+simple. First of all, make sure that you haven't specified the option
+@option{--disable-serial} to the configure script when you built your
+GRUB images. If you get them in binary form, probably they have serial
+terminal support already.
+
+Then, initialize your serial terminal after GRUB starts up. Here is an
+example:
+
+@example
+@group
+grub> @kbd{serial --unit=0 --speed=9600}
+grub> @kbd{terminal serial}
+@end group
+@end example
+
+The command @command{serial} initializes the serial unit 0 with the
+speed 9600bps. The serial unit 0 is usually called @samp{COM1}, so, if
+you want to use COM2, you must specify @samp{--unit=1} instead. This
+command accepts many other options, so please refer to @ref{serial},
+for more details.
+
+The command @command{terminal} (@pxref{terminal}) chooses which type of
+terminal you want to use. In the case above, the terminal will be a
+serial terminal, but you can also pass @code{console} to the command,
+as @samp{terminal serial console}. In this case, a terminal in which
+you press any key will be selected as a GRUB terminal.
+
+However, note that GRUB assumes that your terminal emulator is
+compatible with VT100 by default. This is true for most terminal
+emulators nowadays, but you should pass the option @option{--dumb} to
+the command if your terminal emulator is not VT100-compatible or
+implements few VT100 escape sequences. If you specify this option then
+GRUB provides you with an alternative menu interface, because the normal
+menu requires several fancy features of your terminal.
+
+
+@node Filesystem
+@chapter Filesystem syntax and semantics
+
+GRUB uses a special syntax for specifying disk drives which can be
+accessed by BIOS. Because of BIOS limitations, GRUB cannot distinguish
+between IDE, ESDI, SCSI, or others. You must know yourself which BIOS
+device is equivalent to which OS device. Normally, that will be clear if
+you see the files in a device or use the command @command{find}
+(@pxref{find}).
+
+@menu
+* Device syntax::               How to specify devices
+* File name syntax::            How to specify files
+* Block list syntax::           How to specify block lists
+@end menu
+
+
+@node Device syntax
+@section How to specify devices
+
+The device syntax is like this:
+
+@example
+@code{(@var{device}[,@var{part-num}][,@var{bsd-subpart-letter}])}
+@end example
+
+@samp{[]} means the parameter is optional. @var{device} should be
+either @samp{fd} or @samp{hd} followed by a digit, like @samp{fd0}.
+But you can also set @var{device} to a hexadecimal or a decimal number
+which is a BIOS drive number, so the following are equivalent:
+
+@example
+(hd0)
+(0x80)
+(128)
+@end example
+
+@var{part-num} represents the partition number of @var{device}, starting
+from one for primary partitions and from five for extended partitions,
+and @var{bsd-subpart-letter} represents the BSD disklabel subpartition,
+such as @samp{a} or @samp{e}.
+
+A shortcut for specifying BSD subpartitions is
+@code{(@var{device},@var{bsd-subpart-letter})}, in this case, GRUB
+searches for the first PC partition containing a BSD disklabel, then
+finds the subpartition @var{bsd-subpart-letter}. Here is an example:
+
+@example
+(hd0,a)
+@end example
+
+The syntax @samp{(hd0)} represents using the entire disk (or the
+MBR when installing GRUB), while the syntax @samp{(hd0,1)}
+represents using the first partition of the disk (or the boot sector
+of the partition when installing GRUB).
+
+If you enabled the network support, the special drive, @samp{(nd)}, is
+also available. Before using the network drive, you must initialize the
+network. @xref{Network}, for more information.
+
+If you boot GRUB from a CD-ROM, @samp{(cd)} is available. @xref{Making
+a GRUB bootable CD-ROM}, for details.
+
+
+@node File name syntax
+@section How to specify files
+
+There are two ways to specify files, by @dfn{absolute file name} and by
+@dfn{block list}.
+
+An absolute file name resembles a Unix absolute file name, using
+@samp{/} for the directory separator (not @samp{\} as in DOS). One
+example is @samp{(hd0,1)/boot/grub/grub.cfg}. This means the file
+@file{/boot/grub/grub.cfg} in the first partition of the first hard
+disk. If you omit the device name in an absolute file name, GRUB uses
+GRUB's @dfn{root device} implicitly. So if you set the root device to,
+say, @samp{(hd1,1)} by the command @command{root} (@pxref{root}), then
+@code{/boot/kernel} is the same as @code{(hd1,1)/boot/kernel}.
+
+
+@node Block list syntax
+@section How to specify block lists
+
+A block list is used for specifying a file that doesn't appear in the
+filesystem, like a chainloader. The syntax is
+@code{[@var{offset}]+@var{length}[,[@var{offset}]+@var{length}]@dots{}}.
+Here is an example:
+
+@example
+@code{0+100,200+1,300+300}
+@end example
+
+This represents that GRUB should read blocks 0 through 99, block 200,
+and blocks 300 through 599. If you omit an offset, then GRUB assumes
+the offset is zero.
+
+Like the file name syntax (@pxref{File name syntax}), if a blocklist
+does not contain a device name, then GRUB uses GRUB's @dfn{root
+device}. So @code{(hd0,2)+1} is the same as @code{+1} when the root
+device is @samp{(hd0,2)}.
+
+
+@node Interface
+@chapter GRUB's user interface
+
+GRUB has both a simple menu interface for choosing preset entries from a
+configuration file, and a highly flexible command-line for performing
+any desired combination of boot commands.
+
+GRUB looks for its configuration file as soon as it is loaded. If one
+is found, then the full menu interface is activated using whatever
+entries were found in the file. If you choose the @dfn{command-line} menu
+option, or if the configuration file was not found, then GRUB drops to
+the command-line interface.
+
+@menu
+* Command-line interface::      The flexible command-line interface
+* Menu interface::              The simple menu interface
+@end menu
+
+
+@node Command-line interface
+@section The flexible command-line interface
+
+The command-line interface provides a prompt and after it an editable
+text area much like a command-line in Unix or DOS. Each command is
+immediately executed after it is entered@footnote{However, this
+behavior will be changed in the future version, in a user-invisible
+way.}. The commands (@pxref{Command-line and menu entry commands}) are a
+subset of those available in the configuration file, used with exactly
+the same syntax.
+
+Cursor movement and editing of the text on the line can be done via a
+subset of the functions available in the Bash shell:
+
+@table @key
+@item C-f
+@itemx PC right key
+Move forward one character.
+
+@item C-b
+@itemx PC left key
+Move back one character.
+
+@item C-a
+@itemx HOME
+Move to the start of the line.
+
+@item C-e
+@itemx END
+Move the the end of the line.
+
+@item C-d
+@itemx DEL
+Delete the character underneath the cursor.
+
+@item C-h
+@itemx BS
+Delete the character to the left of the cursor.
+
+@item C-k
+Kill the text from the current cursor position to the end of the line.
+
+@item C-u
+Kill backward from the cursor to the beginning of the line.
+
+@item C-y
+Yank the killed text back into the buffer at the cursor.
+
+@item C-p
+@itemx PC up key
+Move up through the history list.
+
+@item C-n
+@itemx PC down key
+Move down through the history list.
+@end table
+
+When typing commands interactively, if the cursor is within or before
+the first word in the command-line, pressing the @key{TAB} key (or
+@key{C-i}) will display a listing of the available commands, and if the
+cursor is after the first word, the @kbd{@key{TAB}} will provide a
+completion listing of disks, partitions, and file names depending on the
+context. Note that to obtain a list of drives, one must open a
+parenthesis, as @command{root (}.
+
+Note that you cannot use the completion functionality in the TFTP
+filesystem. This is because TFTP doesn't support file name listing for
+the security.
+
+
+@node Menu interface
+@section The simple menu interface
+
+The menu interface is quite easy to use. Its commands are both
+reasonably intuitive and described on screen.
+
+Basically, the menu interface provides a list of @dfn{boot entries} to
+the user to choose from. Use the arrow keys to select the entry of
+choice, then press @key{RET} to run it.  An optional timeout is
+available to boot the default entry (the first one if not set), which is
+aborted by pressing any key.
+
+Commands are available to enter a bare command-line by pressing @key{c}
+(which operates exactly like the non-config-file version of GRUB, but
+allows one to return to the menu if desired by pressing @key{ESC}) or to
+edit any of the @dfn{boot entries} by pressing @key{e}.
+
+If you protect the menu interface with a password (@pxref{Security}),
+all you can do is choose an entry by pressing @key{RET}, or press
+@key{p} to enter the password.
+
+
+@node Menu entry editor
+@section Editing a menu entry
+
+The menu entry editor looks much like the main menu interface, but the
+lines in the menu are individual commands in the selected entry instead
+of entry names.
+
+If an @key{ESC} is pressed in the editor, it aborts all the changes made
+to the configuration entry and returns to the main menu interface.
+
+When a particular line is selected, the editor places the user in a
+special version of the GRUB command-line to edit that line.  When the
+user hits @key{RET}, GRUB replaces the line in question in the boot
+entry with the changes (unless it was aborted via @key{ESC},
+in which case the changes are thrown away).
+
+If you want to add a new line to the menu entry, press @key{o} if adding
+a line after the current line or press @key{O} if before the current
+line.
+
+To delete a line, hit the key @key{d}. Although GRUB unfortunately
+does not support @dfn{undo}, you can do almost the same thing by just
+returning to the main menu.
+
+
+@node Commands
+@chapter The list of available commands
+
+In this chapter, we list all commands that are available in GRUB.
+
+Commands belong to different groups. A few can only be used in
+the global section of the configuration file (or ``menu''); most
+of them can be entered on the command-line and can be used either
+anywhere in the menu or specifically in the menu entries.
+
+@menu
+* Menu-specific commands::
+* General commands::
+* Command-line and menu entry commands::
+@end menu
+
+
+@node Menu-specific commands
+@section The list of commands for the menu only
+
+The semantics used in parsing the configuration file are the following:
+
+@itemize @bullet
+@item
+The menu-specific commands have to be used before any others.
+
+@item
+The files @emph{must} be in plain-text format.
+
+@item
+@samp{#} at the beginning of a line in a configuration file means it is
+only a comment.
+
+@item
+Options are separated by spaces.
+
+@item
+All numbers can be either decimal or hexadecimal. A hexadecimal number
+must be preceded by @samp{0x}, and is case-insensitive.
+
+@item
+Extra options or text at the end of the line are ignored unless otherwise
+specified.
+
+@item
+Unrecognized commands are added to the current entry, except before entries
+start, where they are ignored.
+@end itemize
+
+These commands can only be used in the menu:
+
+@menu
+* menuentry::                   Start a menu entry
+@end menu
+
+
+@node menuentry
+@subsection menuentry
+
+@deffn Command title name @dots{}
+Start a new boot entry, and set its name to the contents of the rest of
+the line, starting with the first non-space character.
+@end deffn
+
+
+@node General commands
+@section The list of general commands
+
+Commands usable anywhere in the menu and in the command-line.
+
+@menu
+* serial::                      Set up a serial device
+* terminfo::                    Define escape sequences for a terminal
+@end menu
+
+
+@node serial
+@subsection serial
+
+@deffn Command serial [@option{--unit=unit}] [@option{--port=port}] [@option{--speed=speed}] [@option{--word=word}] [@option{--parity=parity}] [@option{--stop=stop}] [@option{--device=dev}]
+Initialize a serial device. @var{unit} is a number in the range 0-3
+specifying which serial port to use; default is 0, which corresponds to
+the port often called COM1. @var{port} is the I/O port where the UART
+is to be found; if specified it takes precedence over @var{unit}.
+@var{speed} is the transmission speed; default is 9600. @var{word} and
+@var{stop} are the number of data bits and stop bits. Data bits must
+be in the range 5-8 and stop bits must be 1 or 2. Default is 8 data
+bits and one stop bit. @var{parity} is one of @samp{no}, @samp{odd},
+@samp{even} and defaults to @samp{no}. The option @option{--device}
+can only be used in the grub shell and is used to specify the
+tty device to be used in the host operating system (@pxref{Invoking the
+grub shell}).
+
+The serial port is not used as a communication channel unless the
+@command{terminal} command is used (@pxref{terminal}).
+
+This command is only available if GRUB is compiled with serial
+support. See also @ref{Serial terminal}.
+@end deffn
+
+
+@node terminfo
+@subsection terminfo
+
+@deffn Command terminfo @option{--name=name} @option{--cursor-address=seq} [@option{--clear-screen=seq}] [@option{--enter-standout-mode=seq}] [@option{--exit-standout-mode=seq}]
+Define the capabilities of your terminal. Use this command to define
+escape sequences, if it is not vt100-compatible. You may use @samp{\e}
+for @key{ESC} and @samp{^X} for a control character.
+
+You can use the utility @command{grub-terminfo} to generate
+appropriate arguments to this command. @xref{Invoking grub-terminfo}.
+
+If no option is specified, the current settings are printed.
+@end deffn
+
+
+@node Command-line and menu entry commands
+@section The list of command-line and menu entry commands
+
+These commands are usable in the command-line and in menu entries.  If
+you forget a command, you can run the command @command{help}
+(@pxref{help}).
+
+@menu
+* acpi::                        Load ACPI tables
+* blocklist::                   Print a block list
+* boot::                        Start up your operating system
+* cat::                         Show the contents of a file
+* chainloader::                 Chain-load another boot loader
+* cmp::                         Compare two files
+* configfile::                  Load a configuration file
+* crc::                         Calculate CRC32 checksums
+* date::                        Display or set current date and time
+* echo::                        Display a line of text
+* export::                      Export an environment variable
+* halt::                        Shut down your computer
+* help::                        Show help messages
+* insmod::                      Insert a module
+* keystatus::                   Check key modifier status
+* ls::                          List devices or files
+* reboot::                      Reboot your computer
+* set::                         Set an environment variable
+* unset::                       Unset an environment variable
+@end menu
+
+
+@node acpi
+@subsection acpi
+
+@deffn Command acpi [@option{-1}|@option{-2}] @
+ [@option{--exclude=table1,@dots{}}|@option{--load-only=table1,@dots{}}] @
+ [@option{--oemid=id}] [@option{--oemtable=table}] @
+ [@option{--oemtablerev=rev}] [@option{--oemtablecreator=creator}] @
+ [@option{--oemtablecreatorrev=rev}] [@option{--no-ebda}] @
+ filename @dots{}
+Modern BIOS systems normally implement the Advanced Configuration and Power
+Interface (ACPI), and define various tables that describe the interface
+between an ACPI-compliant operating system and the firmware. In some cases,
+the tables provided by default only work well with certain operating
+systems, and it may be necessary to replace some of them.
+
+Normally, this command will replace the Root System Description Pointer
+(RSDP) in the Extended BIOS Data Area to point to the new tables. If the
+@option{--no-ebda} option is used, the new tables will be known only to
+GRUB, but may be used by GRUB's EFI emulation.
+@end deffn
+
+
+@node blocklist
+@subsection blocklist
+
+@deffn Command blocklist file
+Print a block list (@pxref{Block list syntax}) for @var{file}.
+@end deffn
+
+
+@node boot
+@subsection boot
+
+@deffn Command boot
+Boot the OS or chain-loader which has been loaded. Only necessary if
+running the fully interactive command-line (it is implicit at the end of
+a menu entry).
+@end deffn
+
+
+@node cat
+@subsection cat
+
+@deffn Command cat file
+Display the contents of the file @var{file}. This command may be useful
+to remind you of your OS's root partition:
+
+@example
+grub> @kbd{cat /etc/fstab}
+@end example
+@end deffn
+
+
+@node chainloader
+@subsection chainloader
+
+@deffn Command chainloader [@option{--force}] file
+Load @var{file} as a chain-loader. Like any other file loaded by the
+filesystem code, it can use the blocklist notation to grab the first
+sector of the current partition with @samp{+1}. If you specify the
+option @option{--force}, then load @var{file} forcibly, whether it has a
+correct signature or not. This is required when you want to load a
+defective boot loader, such as SCO UnixWare 7.1 (@pxref{SCO UnixWare}).
+@end deffn
+
+
+@node cmp
+@subsection cmp
+
+@deffn Command cmp file1 file2
+Compare the file @var{file1} with the file @var{file2}. If they differ
+in size, print the sizes like this:
+
+@example
+Differ in size: 0x1234 [foo], 0x4321 [bar]
+@end example
+
+If the sizes are equal but the bytes at an offset differ, then print the
+bytes like this:
+
+@example
+Differ at the offset 777: 0xbe [foo], 0xef [bar]
+@end example
+
+If they are completely identical, nothing will be printed.
+@end deffn
+
+
+@node configfile
+@subsection configfile
+
+@deffn Command configfile file
+Load @var{file} as a configuration file.
+@end deffn
+
+
+@node crc
+@subsection crc
+
+@deffn Command crc file
+Display the CRC32 checksum of @var{file}.
+@end deffn
+
+
+@node date
+@subsection date
+
+@deffn Command date [[year-]month-day] [hour:minute[:second]]
+With no arguments, print the current date and time.
+
+Otherwise, take the current date and time, change any elements specified as
+arguments, and set the result as the new date and time.  For example, `date
+01-01' will set the current month and day to January 1, but leave the year,
+hour, minute, and second unchanged.
+@end deffn
+
+
+@node echo
+@subsection echo
+
+@deffn Command echo [@option{-n}] [@option{-e}] string @dots{}
+Display the requested text and, unless the @option{-n} option is used, a
+trailing new line.  If there is more than one string, they are separated by
+spaces in the output.  As usual in GRUB commands, variables may be
+substituted using @samp{$@{var@}}.
+
+The @option{-e} option enables interpretation of backslash escapes.  The
+following sequences are recognised:
+
+@table @code
+@item \\
+backslash
+
+@item \a
+alert (BEL)
+
+@item \c
+suppress trailing new line
+
+@item \f
+form feed
+
+@item \n
+new line
+
+@item \r
+carriage return
+
+@item \t
+horizontal tab
+
+@item \v
+vertical tab
+@end table
+
+When interpreting backslash escapes, backslash followed by any other
+character will print that character.
+@end deffn
+
+
+@node export
+@subsection export
+
+@deffn Command export envvar
+Export the environment variable @var{envvar}. Exported variables are visible
+to subsidiary configuration files loaded using @command{configfile}.
+@end deffn
+
+
+@node halt
+@subsection halt
+
+@deffn Command halt @option{--no-apm}
+The command halts the computer. If the @option{--no-apm} option
+is specified, no APM BIOS call is performed. Otherwise, the computer
+is shut down using APM.
+@end deffn
+
+
+@node help
+@subsection help
+
+@deffn Command help @option{--all} [pattern @dots{}]
+Display helpful information about builtin commands. If you do not
+specify @var{pattern}, this command shows short descriptions of most of
+available commands. If you specify the option @option{--all} to this
+command, short descriptions of rarely used commands (such as
+@ref{testload}) are displayed as well.
+
+If you specify any @var{patterns}, it displays longer information
+about each of the commands which match those @var{patterns}.
+@end deffn
+
+
+@node insmod
+@subsection insmod
+
+@deffn Command insmod module
+Insert the dynamic GRUB module called @var{module}.
+@end deffn
+
+
+@node keystatus
+@subsection keystatus
+
+@deffn Command keystatus [@option{--shift}] [@option{--ctrl}] [@option{--alt}]
+Return true if the Shift, Control, or Alt modifier keys are held down, as
+requested by options. This is useful in scripting, to allow some user
+control over behaviour without having to wait for a keypress.
+
+Checking key modifier status is only supported on some platforms. If invoked
+without any options, the @command{keystatus} command returns true if and
+only if checking key modifier status is supported.
+@end deffn
+
+
+@node ls
+@subsection ls
+
+@deffn Command ls [arg]
+List devices or files.
+
+With no arguments, print all devices known to GRUB.
+
+If the argument is a device name enclosed in parentheses (@pxref{Device
+syntax}), then list all files at the root directory of that device.
+
+If the argument is a directory given as an absolute file name (@pxref{File
+name syntax}), then list the contents of that directory.
+@end deffn
+
+
+@node reboot
+@subsection reboot
+
+@deffn Command reboot
+Reboot the computer.
+@end deffn
+
+
+@node set
+@subsection set
+
+@deffn Command set [envvar=value]
+Set the environment variable @var{envvar} to @var{value}. If invoked with no
+arguments, print all environment variables with their values.
+@end deffn
+
+
+@node unset
+@subsection unset
+
+@deffn Command unset envvar
+Unset the environment variable @var{envvar}.
+@end deffn
+
+
+@node Invoking grub-install
+@chapter Invoking grub-install
+
+The program @command{grub-install} installs GRUB on your drive using the
+grub shell (@pxref{Invoking the grub shell}). You must specify the
+device name on which you want to install GRUB, like this:
+
+@example
+grub-install @var{install_device}
+@end example
+
+The device name @var{install_device} is an OS device name or a GRUB
+device name.
+
+@command{grub-install} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version number of GRUB and exit.
+
+@item --root-directory=@var{dir}
+Install GRUB images under the directory @var{dir} instead of the root
+directory. This option is useful when you want to install GRUB into a
+separate partition or a removable disk. Here is an example in which
+you have a separate @dfn{boot} partition which is mounted on
+@file{/boot}:
+
+@example
+@kbd{grub-install --root-directory=/boot hd0}
+@end example
+
+@item --recheck
+Recheck the device map, even if @file{/boot/grub/device.map} already
+exists. You should use this option whenever you add/remove a disk
+into/from your computer.
+@end table
+
+
+@node Obtaining and Building GRUB
+@appendix How to obtain and build GRUB
+
+@quotation
+@strong{Caution:} GRUB requires binutils-2.9.1.0.23 or later because the
+GNU assembler has been changed so that it can produce real 16bits
+machine code between 2.9.1 and 2.9.1.0.x. See
+@uref{http://sources.redhat.com/binutils/}, to obtain information on
+how to get the latest version.
+@end quotation
+
+GRUB is available from the GNU alpha archive site
+@uref{ftp://alpha.gnu.org/gnu/grub} or any of its mirrors. The file
+will be named grub-version.tar.gz. The current version is
+@value{VERSION}, so the file you should grab is:
+
+@uref{ftp://alpha.gnu.org/gnu/grub/grub-@value{VERSION}.tar.gz}
+
+To unbundle GRUB use the instruction:
+
+@example
+@kbd{zcat grub-@value{VERSION}.tar.gz | tar xvf -}
+@end example
+
+which will create a directory called @file{grub-@value{VERSION}} with
+all the sources. You can look at the file @file{INSTALL} for detailed
+instructions on how to build and install GRUB, but you should be able to
+just do:
+
+@example
+@group
+@kbd{cd grub-@value{VERSION}}
+@kbd{./configure}
+@kbd{make install}
+@end group
+@end example
+
+Also, the latest version is available from the SVN. See
+@uref{http://savannah.gnu.org/svn/?group=grub} for more information.
+
+@node Reporting bugs
+@appendix Reporting bugs
+
+These are the guideline for how to report bugs. Take a look at this
+list below before you submit bugs:
+
+@enumerate
+@item
+Before getting unsettled, read this manual through and through. Also,
+see the @uref{http://www.gnu.org/software/grub/grub-faq.html, GNU GRUB FAQ}.
+
+@item
+Always mention the information on your GRUB. The version number and the
+configuration are quite important. If you build it yourself, write the
+options specified to the configure script and your operating system,
+including the versions of gcc and binutils.
+
+@item
+If you have trouble with the installation, inform us of how you
+installed GRUB. Don't omit error messages, if any. Just @samp{GRUB hangs
+up when it boots} is not enough.
+
+The information on your hardware is also essential. These are especially
+important: the geometries and the partition tables of your hard disk
+drives and your BIOS.
+
+@item
+If GRUB cannot boot your operating system, write down
+@emph{everything} you see on the screen. Don't paraphrase them, like
+@samp{The foo OS crashes with GRUB, even though it can boot with the
+bar boot loader just fine}. Mention the commands you executed, the
+messages printed by them, and information on your operating system
+including the version number.
+
+@item
+Explain what you wanted to do. It is very useful to know your purpose
+and your wish, and how GRUB didn't satisfy you.
+
+@item
+If you can investigate the problem yourself, please do. That will give
+you and us much more information on the problem. Attaching a patch is
+even better.
+
+When you attach a patch, make the patch in unified diff format, and
+write ChangeLog entries. But, even when you make a patch, don't forget
+to explain the problem, so that we can understand what your patch is
+for.
+
+@item
+Write down anything that you think might be related. Please understand
+that we often need to reproduce the same problem you encounterred in our
+environment. So your information should be sufficient for us to do the
+same thing---Don't forget that we cannot see your computer directly. If
+you are not sure whether to state a fact or leave it out, state it!
+Reporting too many things is much better than omitting something
+important.
+@end enumerate
+
+If you follow the guideline above, submit a report to the
+@uref{http://savannah.gnu.org/bugs/?group=grub, Bug Tracking System}.
+Alternatively, you can submit a report via electronic mail to
+@email{bug-grub@@gnu.org}, but we strongly recommend that you use the
+Bug Tracking System, because e-mail can be passed over easily.
+
+Once we get your report, we will try to fix the bugs.
+
+
+@node Future
+@appendix Where GRUB will go
+
+We started the next generation of GRUB, GRUB 2. GRUB 2 includes
+internationalization, dynamic module loading, real memory management,
+multiple architecture support, a scripting language, and many other
+nice feature. If you are interested in the development of GRUB 2, take
+a look at @uref{http://www.gnu.org/software/grub/grub.html, the
+homepage}.
+
+
+
+@node Copying This Manual
+@appendix Copying This Manual
+
+@menu
+* GNU Free Documentation License::  License for copying this manual.
+@end menu
+
+@include fdl.texi
+
+
+@node Index
+@unnumbered Index
+
+@c Currently, we use only the Concept Index.
+@printindex cp
+
+
+@bye
+
+Some notes:
+
+  This is an attempt to make a manual for GRUB 2. The contents are
+  copied from the GRUB manual in GRUB Legacy, so they are not always
+  appropriate yet for GRUB 2.
diff --git a/docs/mdate-sh b/docs/mdate-sh
new file mode 100755
index 0000000..22f2f8b
--- /dev/null
+++ b/docs/mdate-sh
@@ -0,0 +1,205 @@
+#!/bin/sh
+# Get modification time of a file or directory and pretty-print it.
+
+scriptversion=2007-03-30.02
+
+# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005, 2007 Free Software
+# Foundation, Inc.
+# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
+#
+# 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 3, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+  '')
+     echo "$0: No file.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: mdate-sh [--help] [--version] FILE
+
+Pretty-print the modification time of FILE.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "mdate-sh $scriptversion"
+    exit $?
+    ;;
+esac
+
+# Prevent date giving response in another language.
+LANG=C
+export LANG
+LC_ALL=C
+export LC_ALL
+LC_TIME=C
+export LC_TIME
+
+# GNU ls changes its time format in response to the TIME_STYLE
+# variable.  Since we cannot assume `unset' works, revert this
+# variable to its documented default.
+if test "${TIME_STYLE+set}" = set; then
+  TIME_STYLE=posix-long-iso
+  export TIME_STYLE
+fi
+
+save_arg1=$1
+
+# Find out how to get the extended ls output of a file or directory.
+if ls -L /dev/null 1>/dev/null 2>&1; then
+  ls_command='ls -L -l -d'
+else
+  ls_command='ls -l -d'
+fi
+# Avoid user/group names that might have spaces, when possible.
+if ls -n /dev/null 1>/dev/null 2>&1; then
+  ls_command="$ls_command -n"
+fi
+
+# A `ls -l' line looks as follows on OS/2.
+#  drwxrwx---        0 Aug 11  2001 foo
+# This differs from Unix, which adds ownership information.
+#  drwxrwx---   2 root  root      4096 Aug 11  2001 foo
+#
+# To find the date, we split the line on spaces and iterate on words
+# until we find a month.  This cannot work with files whose owner is a
+# user named `Jan', or `Feb', etc.  However, it's unlikely that `/'
+# will be owned by a user whose name is a month.  So we first look at
+# the extended ls output of the root directory to decide how many
+# words should be skipped to get the date.
+
+# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
+set x`$ls_command /`
+
+# Find which argument is the month.
+month=
+command=
+until test $month
+do
+  shift
+  # Add another shift to the command.
+  command="$command shift;"
+  case $1 in
+    Jan) month=January; nummonth=1;;
+    Feb) month=February; nummonth=2;;
+    Mar) month=March; nummonth=3;;
+    Apr) month=April; nummonth=4;;
+    May) month=May; nummonth=5;;
+    Jun) month=June; nummonth=6;;
+    Jul) month=July; nummonth=7;;
+    Aug) month=August; nummonth=8;;
+    Sep) month=September; nummonth=9;;
+    Oct) month=October; nummonth=10;;
+    Nov) month=November; nummonth=11;;
+    Dec) month=December; nummonth=12;;
+  esac
+done
+
+# Get the extended ls output of the file or directory.
+set dummy x`eval "$ls_command \"\$save_arg1\""`
+
+# Remove all preceding arguments
+eval $command
+
+# Because of the dummy argument above, month is in $2.
+#
+# On a POSIX system, we should have
+#
+# $# = 5
+# $1 = file size
+# $2 = month
+# $3 = day
+# $4 = year or time
+# $5 = filename
+#
+# On Darwin 7.7.0 and 7.6.0, we have
+#
+# $# = 4
+# $1 = day
+# $2 = month
+# $3 = year or time
+# $4 = filename
+
+# Get the month.
+case $2 in
+  Jan) month=January; nummonth=1;;
+  Feb) month=February; nummonth=2;;
+  Mar) month=March; nummonth=3;;
+  Apr) month=April; nummonth=4;;
+  May) month=May; nummonth=5;;
+  Jun) month=June; nummonth=6;;
+  Jul) month=July; nummonth=7;;
+  Aug) month=August; nummonth=8;;
+  Sep) month=September; nummonth=9;;
+  Oct) month=October; nummonth=10;;
+  Nov) month=November; nummonth=11;;
+  Dec) month=December; nummonth=12;;
+esac
+
+case $3 in
+  ???*) day=$1;;
+  *) day=$3; shift;;
+esac
+
+# Here we have to deal with the problem that the ls output gives either
+# the time of day or the year.
+case $3 in
+  *:*) set `date`; eval year=\$$#
+       case $2 in
+	 Jan) nummonthtod=1;;
+	 Feb) nummonthtod=2;;
+	 Mar) nummonthtod=3;;
+	 Apr) nummonthtod=4;;
+	 May) nummonthtod=5;;
+	 Jun) nummonthtod=6;;
+	 Jul) nummonthtod=7;;
+	 Aug) nummonthtod=8;;
+	 Sep) nummonthtod=9;;
+	 Oct) nummonthtod=10;;
+	 Nov) nummonthtod=11;;
+	 Dec) nummonthtod=12;;
+       esac
+       # For the first six month of the year the time notation can also
+       # be used for files modified in the last year.
+       if (expr $nummonth \> $nummonthtod) > /dev/null;
+       then
+	 year=`expr $year - 1`
+       fi;;
+  *) year=$3;;
+esac
+
+# The result.
+echo $day $month $year
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/docs/texinfo.tex b/docs/texinfo.tex
new file mode 100644
index 0000000..0135d0c
--- /dev/null
+++ b/docs/texinfo.tex
@@ -0,0 +1,8959 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2007-09-03.05}
+%
+% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 2007,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+% 2007 Free Software Foundation, Inc.
+%
+% This texinfo.tex file 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 3 of the
+% License, or (at your option) any later version.
+%
+% This texinfo.tex file 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, see <http://www.gnu.org/licenses/>.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction.  (This has been our intent since Texinfo was invented.)
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+%   http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+%   ftp://tug.org/tex/texinfo.tex
+%     (and all CTAN mirrors, see http://www.ctan.org).
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo@gnu.org.  Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem.  Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution.  For a simple
+% manual foo.texi, however, you can get away with this:
+%   tex foo.texi
+%   texindex foo.??
+%   tex foo.texi
+%   tex foo.texi
+%   dvips foo.dvi -o  # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent.  You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+  \catcode`+=\active \catcode`\_=\active}
+
+
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+  \let\linenumber = \empty % Pre-3.0.
+\else
+  \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined  \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined   \gdef\putwordChapter{Chapter}\fi
+\ifx\putwordfile\undefined      \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined        \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined     \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined      \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined  \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined   \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined        \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined        \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined      \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined   \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined   \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined       \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined       \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined  \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined       \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined    \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined   \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined    \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined    \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined   \gdef\putwordDeffunc{Function}\fi
+
+% Since the category of space is not known, we have to be careful.
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode`\ =\spacecat}
+
+% sometimes characters are active, so we need control sequences.
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dashChar  = `\-
+\chardef\dotChar   = `\.
+\chardef\exclamChar= `\!
+\chardef\lquoteChar= `\`
+\chardef\questChar = `\?
+\chardef\rquoteChar= `\'
+\chardef\semiChar  = `\;
+\chardef\underChar = `\_
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+  Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+  ap-pen-dix bit-map bit-maps
+  data-base data-bases eshell fall-ing half-way long-est man-u-script
+  man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+  par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+  spell-ing spell-ings
+  stand-alone strong-est time-stamp time-stamps which-ever white-space
+  wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+% @| inserts a changebar to the left of the current line.  It should
+% surround any changed text.  This approach does *not* work if the
+% change spans more than two lines of output.  To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+  % \vadjust can only be used in horizontal mode.
+  \leavevmode
+  %
+  % Append this vertical mode material after the current line in the output.
+  \vadjust{%
+    % We want to insert a rule with the height and depth of the current
+    % leading; that is exactly what \strutbox is supposed to record.
+    \vskip-\baselineskip
+    %
+    % \vadjust-items are inserted at the left edge of the type.  So
+    % the \llap here moves out into the left-hand margin.
+    \llap{%
+      %
+      % For a thicker or thinner bar, change the `1pt'.
+      \vrule height\baselineskip width1pt
+      %
+      % This is the space between the bar and the text.
+      \hskip 12pt
+    }%
+  }%
+}
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal.  We don't just call \tracingall here,
+% since that produces some useless output on the terminal.  We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+  \tracingstats2
+  \tracingpages1
+  \tracinglostchars2  % 2 gives us more in etex
+  \tracingparagraphs1
+  \tracingoutput1
+  \tracingmacros2
+  \tracingrestores1
+  \showboxbreadth\maxdimen \showboxdepth\maxdimen
+  \ifx\eTeXversion\undefined\else % etex gives us more logging
+    \tracingscantokens1
+    \tracingifs1
+    \tracinggroups1
+    \tracingnesting2
+    \tracingassigns1
+  \fi
+  \tracingcommands3  % 3 gives us more in etex
+  \errorcontextlines16
+}%
+
+% add check for \lastpenalty to plain's definitions.  If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+  \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+  \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+  \removelastskip\penalty-200\bigskip\fi\fi}
+
+% For @cropmarks command.
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong  \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Output a mark which sets \thischapter, \thissection and \thiscolor.
+% We dump everything together because we only have one kind of mark.
+% This works because we only use \botmark / \topmark, not \firstmark.
+%
+% A mark contains a subexpression of the \ifcase ... \fi construct.
+% \get*marks macros below extract the needed part using \ifcase.
+%
+% Another complication is to let the user choose whether \thischapter
+% (\thissection) refers to the chapter (section) in effect at the top
+% of a page, or that at the bottom of a page.  The solution is
+% described on page 260 of The TeXbook.  It involves outputting two
+% marks for the sectioning macros, one before the section break, and
+% one after.  I won't pretend I can describe this better than DEK...
+\def\domark{%
+  \toks0=\expandafter{\lastchapterdefs}%
+  \toks2=\expandafter{\lastsectiondefs}%
+  \toks4=\expandafter{\prevchapterdefs}%
+  \toks6=\expandafter{\prevsectiondefs}%
+  \toks8=\expandafter{\lastcolordefs}%
+  \mark{%
+                   \the\toks0 \the\toks2
+      \noexpand\or \the\toks4 \the\toks6
+    \noexpand\else \the\toks8
+  }%
+}
+% \topmark doesn't work for the very first chapter (after the title
+% page or the contents), so we use \firstmark there -- this gets us
+% the mark with the chapter defs, unless the user sneaks in, e.g.,
+% @setcolor (or @url, or @link, etc.) between @contents and the very
+% first @chapter.
+\def\gettopheadingmarks{%
+  \ifcase0\topmark\fi
+  \ifx\thischapter\empty \ifcase0\firstmark\fi \fi
+}
+\def\getbottomheadingmarks{\ifcase1\botmark\fi}
+\def\getcolormarks{\ifcase2\topmark\fi}
+
+% Avoid "undefined control sequence" errors.
+\def\lastchapterdefs{}
+\def\lastsectiondefs{}
+\def\prevchapterdefs{}
+\def\prevsectiondefs{}
+\def\lastcolordefs{}
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument.  Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+  \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+  %
+  \ifodd\pageno  \advance\hoffset by \bindingoffset
+  \else \advance\hoffset by -\bindingoffset\fi
+  %
+  % Do this outside of the \shipout so @code etc. will be expanded in
+  % the headline as they should be, not taken literally (outputting ''code).
+  \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
+  \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+  \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
+  \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+  %
+  {%
+    % Have to do this stuff outside the \shipout because we want it to
+    % take effect in \write's, yet the group defined by the \vbox ends
+    % before the \shipout runs.
+    %
+    \indexdummies         % don't expand commands in the output.
+    \normalturnoffactive  % \ in index entries must not stay \, e.g., if
+               % the page break happens to be in the middle of an example.
+               % We don't want .vr (or whatever) entries like this:
+               % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
+               % "\acronym" won't work when it's read back in;
+               % it needs to be
+               % {\code {{\tt \backslashcurfont }acronym}
+    \shipout\vbox{%
+      % Do this early so pdf references go to the beginning of the page.
+      \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+      %
+      \ifcropmarks \vbox to \outervsize\bgroup
+        \hsize = \outerhsize
+        \vskip-\topandbottommargin
+        \vtop to0pt{%
+          \line{\ewtop\hfil\ewtop}%
+          \nointerlineskip
+          \line{%
+            \vbox{\moveleft\cornerthick\nstop}%
+            \hfill
+            \vbox{\moveright\cornerthick\nstop}%
+          }%
+          \vss}%
+        \vskip\topandbottommargin
+        \line\bgroup
+          \hfil % center the page within the outer (page) hsize.
+          \ifodd\pageno\hskip\bindingoffset\fi
+          \vbox\bgroup
+      \fi
+      %
+      \unvbox\headlinebox
+      \pagebody{#1}%
+      \ifdim\ht\footlinebox > 0pt
+        % Only leave this space if the footline is nonempty.
+        % (We lessened \vsize for it in \oddfootingyyy.)
+        % The \baselineskip=24pt in plain's \makefootline has no effect.
+        \vskip 24pt
+        \unvbox\footlinebox
+      \fi
+      %
+      \ifcropmarks
+          \egroup % end of \vbox\bgroup
+        \hfil\egroup % end of (centering) \line\bgroup
+        \vskip\topandbottommargin plus1fill minus1fill
+        \boxmaxdepth = \cornerthick
+        \vbox to0pt{\vss
+          \line{%
+            \vbox{\moveleft\cornerthick\nsbot}%
+            \hfill
+            \vbox{\moveright\cornerthick\nsbot}%
+          }%
+          \nointerlineskip
+          \line{\ewbot\hfil\ewbot}%
+        }%
+      \egroup % \vbox from first cropmarks clause
+      \fi
+    }% end of \shipout\vbox
+  }% end of group with \indexdummies
+  \advancepageno
+  \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+  \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1\relax \unvbox#1\relax
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks.  Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+  {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+  {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1.  The argument is the rest of
+% the input line (except we remove a trailing comment).  #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+  \def\argtorun{#2}%
+  \begingroup
+    \obeylines
+    \spaceisspace
+    #1%
+    \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+  \gdef\parseargline#1^^M{%
+    \endgroup % End of the group started in \parsearg.
+    \argremovecomment #1\comment\ArgTerm%
+  }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+%    @end itemize  @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+  \def\temp{#3}%
+  \ifx\temp\empty
+    % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
+    \let\temp\finishparsearg
+  \else
+    \let\temp\argcheckspaces
+  \fi
+  % Put the space token in:
+  \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \argtorun.
+% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+
+% \parseargdef\foo{...}
+%	is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick.  --kasal, 16nov03
+
+\def\parseargdef#1{%
+  \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+  \def#2{\parsearg#1}%
+  \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+  \obeyspaces
+  \gdef\obeyedspace{ }
+
+  % Make each space character in the input produce a normal interword
+  % space in the output.  Don't allow a line break at this space, as this
+  % is used only in environments like @example, where each line of input
+  % should produce a line of output anyway.
+  %
+  \gdef\sepspaces{\obeyspaces\let =\tie}
+
+  % If an index command is used in an @example environment, any spaces
+  % therein should become regular spaces in the raw index file, not the
+  % expansion of \tie (\leavevmode \penalty \@M \ ).
+  \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex.  It's used like this:
+%
+%   \envdef\foo{...}
+%   \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo.  \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches.  The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as enviroments; they don't open a group.  (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At runtime, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+  \def\temp{#1}%
+  \ifx\thisenv\temp
+  \else
+    \badenverr
+  \fi
+}
+
+% Evironment mismatch, #1 expected:
+\def\badenverr{%
+  \errhelp = \EMsimple
+  \errmessage{This command can appear only \inenvironment\temp,
+    not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+  \ifx#1\empty
+    out of any environment%
+  \else
+    in environment \expandafter\string#1%
+  \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+  \if 1\csname iscond.#1\endcsname
+  \else
+    % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+    \expandafter\checkenv\csname#1\endcsname
+    \csname E#1\endcsname
+    \endgroup
+  \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt\char64}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+\def\mylbrace {{\tt\char123}}
+\def\myrbrace {{\tt\char125}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+\begingroup
+  % Definitions to produce \{ and \} commands for indices,
+  % and @{ and @} for the aux/toc files.
+  \catcode`\{ = \other \catcode`\} = \other
+  \catcode`\[ = 1 \catcode`\] = 2
+  \catcode`\! = 0 \catcode`\\ = \other
+  !gdef!lbracecmd[\{]%
+  !gdef!rbracecmd[\}]%
+  !gdef!lbraceatcmd[@{]%
+  !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+  \def\temp{#1}%
+  \ifx\temp\imacro \ptexi
+  \else\ifx\temp\jmacro \j
+  \else \errmessage{@dotless can be used only with i or j}%
+  \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence.  (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo.  Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+  L\kern-.36em
+  {\setbox0=\hbox{T}%
+   \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
+  \kern-.15em
+  \TeX
+}
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=\endofsentencespacefactor\space}
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off  says whether to put extra space after punctuation.
+%
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+  \def\temp{#1}%
+  \ifx\temp\onword \plainfrenchspacing
+  \else\ifx\temp\offword \plainnonfrenchspacing
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @frenchspacing option `\temp', must be on/off}%
+  \fi\fi
+}
+
+% @w prevents a word break.  Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox.  We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line.  According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0).  If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large.  This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material.  In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom.  The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+  \ifnum\catcode`\^^M=\active \else
+    \errhelp = \groupinvalidhelp
+    \errmessage{@group invalid in context where filling is enabled}%
+  \fi
+  \startsavinginserts
+  %
+  \setbox\groupbox = \vtop\bgroup
+    % Do @comment since we are called inside an environment such as
+    % @example, where each end-of-line in the input causes an
+    % end-of-line in the output.  We don't want the end-of-line after
+    % the `@group' to put extra space in the output.  Since @group
+    % should appear on a line by itself (according to the Texinfo
+    % manual), we don't worry about eating any user text.
+    \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it.  Thus, space below is not quite equal to space
+% above.  But it's pretty close.
+\def\Egroup{%
+    % To get correct interline space between the last line of the group
+    % and the first line afterwards, we have to propagate \prevdepth.
+    \endgraf % Not \par, as it may have been set to \lisppar.
+    \global\dimen1 = \prevdepth
+  \egroup           % End the \vtop.
+  % \dimen0 is the vertical size of the group's box.
+  \dimen0 = \ht\groupbox  \advance\dimen0 by \dp\groupbox
+  % \dimen2 is how much space is left on the page (more or less).
+  \dimen2 = \pageheight   \advance\dimen2 by -\pagetotal
+  % if the group doesn't fit on the current page, and it's a big big
+  % group, force a page break.
+  \ifdim \dimen0 > \dimen2
+    \ifdim \pagetotal < \vfilllimit\pageheight
+      \page
+    \fi
+  \fi
+  \box\groupbox
+  \prevdepth = \dimen1
+  \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil  \mil=0.001in
+
+% Old definition--didn't work.
+%\parseargdef\need{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
+%\prevdepth=-1000pt
+%}}
+
+\parseargdef\need{%
+  % Ensure vertical mode, so we don't make a big box in the middle of a
+  % paragraph.
+  \par
+  %
+  % If the @need value is less than one line space, it's useless.
+  \dimen0 = #1\mil
+  \dimen2 = \ht\strutbox
+  \advance\dimen2 by \dp\strutbox
+  \ifdim\dimen0 > \dimen2
+    %
+    % Do a \strut just to make the height of this box be normal, so the
+    % normal leading is inserted relative to the preceding line.
+    % And a page break here is fine.
+    \vtop to #1\mil{\strut\vfil}%
+    %
+    % TeX does not even consider page breaks if a penalty added to the
+    % main vertical list is 10000 or more.  But in order to see if the
+    % empty box we just added fits on the page, we must make it consider
+    % page breaks.  On the other hand, we don't want to actually break the
+    % page after the empty box.  So we use a penalty of 9999.
+    %
+    % There is an extremely small chance that TeX will actually break the
+    % page at this \penalty, if there are no other feasible breakpoints in
+    % sight.  (If the user is using lots of big @group commands, which
+    % almost-but-not-quite fill up a page, TeX will have a hard time doing
+    % good page breaking, for example.)  However, I could not construct an
+    % example where a page broke at this \penalty; if it happens in a real
+    % document, then we can reconsider our strategy.
+    \penalty9999
+    %
+    % Back up by the size of the box, whether we did a page break or not.
+    \kern -#1\mil
+    %
+    % Do not allow a page break right after this kern.
+    \nobreak
+  \fi
+}
+
+% @br   forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+  \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph.  For more general purposes, use the \margin insertion
+% class.  WHICH is `l' or `r'.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+  \nobreak
+  \kern-\strutdepth
+  \vtop to \strutdepth{%
+    \baselineskip=\strutdepth
+    \vss
+    % if you have multiple lines of stuff to put here, you'll need to
+    % make the vbox yourself of the appropriate size.
+    \ifx#1l%
+      \llap{\ignorespaces #2\hskip\inmarginspacing}%
+    \else
+      \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+    \fi
+    \null
+  }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+  \setbox0 = \hbox{\ignorespaces #2}%
+  \ifdim\wd0 > 0pt
+    \def\lefttext{#1}%  have both texts
+    \def\righttext{#2}%
+  \else
+    \def\lefttext{#1}%  have only one text
+    \def\righttext{#1}%
+  \fi
+  %
+  \ifodd\pageno
+    \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+  \else
+    \def\temp{\inleftmargin\lefttext}%
+  \fi
+  \temp
+}
+
+% @include file    insert text of that file as input.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+  \pushthisfilestack
+  \def\thisfile{#1}%
+  {%
+    \makevalueexpandable
+    \def\temp{\input #1 }%
+    \expandafter
+  }\temp
+  \popthisfilestack
+}
+\def\filenamecatcodes{%
+  \catcode`\\=\other
+  \catcode`~=\other
+  \catcode`^=\other
+  \catcode`_=\other
+  \catcode`|=\other
+  \catcode`<=\other
+  \catcode`>=\other
+  \catcode`+=\other
+  \catcode`-=\other
+}
+
+\def\pushthisfilestack{%
+  \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+  \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+  \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+  the stack of filenames is empty.}}
+
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+  \ifhmode
+    \let\next\centerH
+  \else
+    \let\next\centerV
+  \fi
+  \next{\hfil \ignorespaces#1\unskip \hfil}%
+}
+\def\centerH#1{%
+  {%
+    \hfil\break
+    \advance\hsize by -\leftskip
+    \advance\hsize by -\rightskip
+    \line{#1}%
+    \break
+  }%
+}
+\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
+
+% @sp n   outputs n lines of vertical space
+
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore  is another way to write a comment
+
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+  \def\temp{#1}%
+  \ifx\temp\asisword
+  \else
+    \ifx\temp\noneword
+      \defaultparindent = 0pt
+    \else
+      \defaultparindent = #1em
+    \fi
+  \fi
+  \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+  \def\temp{#1}%
+  \ifx\temp\asisword
+  \else
+    \ifx\temp\noneword
+      \lispnarrowing = 0pt
+    \else
+      \lispnarrowing = #1em
+    \fi
+  \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading.  If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+  \def\temp{#1}%
+  \ifx\temp\noneword
+    \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+  \else\ifx\temp\insertword
+    \let\suppressfirstparagraphindent = \relax
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @firstparagraphindent option `\temp'}%
+  \fi\fi
+}
+
+% Here is how we actually suppress indentation.  Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+  \gdef\indent{%
+    \restorefirstparagraphindent
+    \indent
+  }%
+  \gdef\noindent{%
+    \restorefirstparagraphindent
+    \noindent
+  }%
+  \global\everypar = {%
+    \kern -\parindent
+    \restorefirstparagraphindent
+  }%
+}
+
+\gdef\restorefirstparagraphindent{%
+  \global \let \indent = \ptexindent
+  \global \let \noindent = \ptexnoindent
+  \global \everypar = {}%
+}
+
+
+% @asis just yields its argument.  Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}.  So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+  \catcode`\_ = \active
+  \gdef\mathunderscore{%
+    \catcode`\_=\active
+    \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+  }
+}
+% Another complication: we want \\ (and @\) to output a \ character.
+% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
+% this is not advertised and we don't care.  Texinfo does not
+% otherwise define @\.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+  \tex
+  \mathunderscore
+  \let\\ = \mathbackslash
+  \mathactive
+  $\finishmath
+}
+\def\finishmath#1{#1$\endgroup}  % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+  \catcode`^ = \active
+  \catcode`< = \active
+  \catcode`> = \active
+  \catcode`+ = \active
+  \gdef\mathactive{%
+    \let^ = \ptexhat
+    \let< = \ptexless
+    \let> = \ptexgtr
+    \let+ = \ptexplus
+  }
+}
+
+% @bullet and @minus need the same treatment as @math, just above.
+\def\bullet{$\ptexbullet$}
+\def\minus{$-$}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in the cm
+% typewriter fonts as three actual period characters; on the other hand,
+% in other typewriter fonts three periods are wider than 1.5em.  So do
+% whichever is larger.
+%
+\def\dots{%
+  \leavevmode
+  \setbox0=\hbox{...}% get width of three periods
+  \ifdim\wd0 > 1.5em
+    \dimen0 = \wd0
+  \else
+    \dimen0 = 1.5em
+  \fi
+  \hbox to \dimen0{%
+    \hskip 0pt plus.25fil
+    .\hskip 0pt plus1fil
+    .\hskip 0pt plus1fil
+    .\hskip 0pt plus.5fil
+  }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+  \dots
+  \spacefactor=\endofsentencespacefactor
+}
+
+% @comma{} is so commas can be inserted into text without messing up
+% Texinfo's parsing.
+%
+\let\comma = ,
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+   \fixbackslash  % Turn off hack to swallow `\input texinfo'.
+   \iflinks
+     \tryauxfile
+     % Open the new aux file.  TeX will close it automatically at exit.
+     \immediate\openout\auxfile=\jobname.aux
+   \fi % \openindices needs to do some work in any case.
+   \openindices
+   \let\setfilename=\comment % Ignore extra @setfilename cmds.
+   %
+   % If texinfo.cnf is present on the system, read it.
+   % Useful for site-wide @afourpaper, etc.
+   \openin 1 texinfo.cnf
+   \ifeof 1 \else \input texinfo.cnf \fi
+   \closein 1
+   %
+   \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+  \newindex{cp}%
+  \newcodeindex{fn}%
+  \newcodeindex{vr}%
+  \newcodeindex{tp}%
+  \newcodeindex{ky}%
+  \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set).  So we test for \relax and 0 as well as \undefined,
+% borrowed from ifpdf.sty.
+\ifx\pdfoutput\undefined
+\else
+  \ifx\pdfoutput\relax
+  \else
+    \ifcase\pdfoutput
+    \else
+      \pdftrue
+    \fi
+  \fi
+\fi
+
+% PDF uses PostScript string constants for the names of xref targets,
+% for display in the outlines, and in other places.  Thus, we have to
+% double any backslashes.  Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e.  Not good.
+% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html
+% (and related messages, the final outcome is that it is up to the TeX
+% user to double the backslashes and otherwise make the string valid, so
+% that's what we do).
+
+% double active backslashes.
+%
+{\catcode`\@=0 \catcode`\\=\active
+ @gdef@activebackslashdouble{%
+   @catcode`@\=@active
+   @let\=@doublebackslash}
+}
+
+% To handle parens, we must adopt a different approach, since parens are
+% not active characters.  hyperref.dtx (which has the same problem as
+% us) handles it with this amazing macro to replace tokens, with minor
+% changes for Texinfo.  It is included here under the GPL by permission
+% from the author, Heiko Oberdiek.
+%
+% #1 is the tokens to replace.
+% #2 is the replacement.
+% #3 is the control sequence with the string.
+%
+\def\HyPsdSubst#1#2#3{%
+  \def\HyPsdReplace##1#1##2\END{%
+    ##1%
+    \ifx\\##2\\%
+    \else
+      #2%
+      \HyReturnAfterFi{%
+        \HyPsdReplace##2\END
+      }%
+    \fi
+  }%
+  \xdef#3{\expandafter\HyPsdReplace#3#1\END}%
+}
+\long\def\HyReturnAfterFi#1\fi{\fi#1}
+
+% #1 is a control sequence in which to do the replacements.
+\def\backslashparens#1{%
+  \xdef#1{#1}% redefine it as its expansion; the definition is simply
+             % \lastnode when called from \setref -> \pdfmkdest.
+  \HyPsdSubst{(}{\realbackslash(}{#1}%
+  \HyPsdSubst{)}{\realbackslash)}{#1}%
+}
+
+\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
+with PDF output, and none of those formats could be found.  (.eps cannot
+be supported due to the design of the PDF format; use regular TeX (DVI
+output) for that.)}
+
+\ifpdf
+  %
+  % Color manipulation macros based on pdfcolor.tex.
+  \def\cmykDarkRed{0.28 1 1 0.35}
+  \def\cmykBlack{0 0 0 1}
+  %
+  \def\pdfsetcolor#1{\pdfliteral{#1 k}}
+  % Set color, and create a mark which defines \thiscolor accordingly,
+  % so that \makeheadline knows which color to restore.
+  \def\setcolor#1{%
+    \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}%
+    \domark
+    \pdfsetcolor{#1}%
+  }
+  %
+  \def\maincolor{\cmykBlack}
+  \pdfsetcolor{\maincolor}
+  \edef\thiscolor{\maincolor}
+  \def\lastcolordefs{}
+  %
+  \def\makefootline{%
+    \baselineskip24pt
+    \line{\pdfsetcolor{\maincolor}\the\footline}%
+  }
+  %
+  \def\makeheadline{%
+    \vbox to 0pt{%
+      \vskip-22.5pt
+      \line{%
+        \vbox to8.5pt{}%
+        % Extract \thiscolor definition from the marks.
+        \getcolormarks
+        % Typeset the headline with \maincolor, then restore the color.
+        \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}%
+      }%
+      \vss
+    }%
+    \nointerlineskip
+  }
+  %
+  %
+  \pdfcatalog{/PageMode /UseOutlines}
+  %
+  % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
+  \def\dopdfimage#1#2#3{%
+    \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+    \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+    %
+    % pdftex (and the PDF format) support .png, .jpg, .pdf (among
+    % others).  Let's try in that order.
+    \let\pdfimgext=\empty
+    \begingroup
+      \openin 1 #1.png \ifeof 1
+        \openin 1 #1.jpg \ifeof 1
+          \openin 1 #1.jpeg \ifeof 1
+            \openin 1 #1.JPG \ifeof 1
+              \openin 1 #1.pdf \ifeof 1
+                \errhelp = \nopdfimagehelp
+                \errmessage{Could not find image file #1 for pdf}%
+              \else \gdef\pdfimgext{pdf}%
+              \fi
+            \else \gdef\pdfimgext{JPG}%
+            \fi
+          \else \gdef\pdfimgext{jpeg}%
+          \fi
+        \else \gdef\pdfimgext{jpg}%
+        \fi
+      \else \gdef\pdfimgext{png}%
+      \fi
+      \closein 1
+    \endgroup
+    %
+    % without \immediate, pdftex seg faults when the same image is
+    % included twice.  (Version 3.14159-pre-1.0-unofficial-20010704.)
+    \ifnum\pdftexversion < 14
+      \immediate\pdfimage
+    \else
+      \immediate\pdfximage
+    \fi
+      \ifdim \wd0 >0pt width \imagewidth \fi
+      \ifdim \wd2 >0pt height \imageheight \fi
+      \ifnum\pdftexversion<13
+         #1.\pdfimgext
+       \else
+         {#1.\pdfimgext}%
+       \fi
+    \ifnum\pdftexversion < 14 \else
+      \pdfrefximage \pdflastximage
+    \fi}
+  %
+  \def\pdfmkdest#1{{%
+    % We have to set dummies so commands such as @code, and characters
+    % such as \, aren't expanded when present in a section title.
+    \indexnofonts
+    \turnoffactive
+    \activebackslashdouble
+    \makevalueexpandable
+    \def\pdfdestname{#1}%
+    \backslashparens\pdfdestname
+    \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
+  }}
+  %
+  % used to mark target names; must be expandable.
+  \def\pdfmkpgn#1{#1}
+  %
+  % by default, use a color that is dark enough to print on paper as
+  % nearly black, but still distinguishable for online viewing.
+  \def\urlcolor{\cmykDarkRed}
+  \def\linkcolor{\cmykDarkRed}
+  \def\endlink{\setcolor{\maincolor}\pdfendlink}
+  %
+  % Adding outlines to PDF; macros for calculating structure of outlines
+  % come from Petr Olsak
+  \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+    \else \csname#1\endcsname \fi}
+  \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+    \advance\tempnum by 1
+    \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+  %
+  % #1 is the section text, which is what will be displayed in the
+  % outline by the pdf viewer.  #2 is the pdf expression for the number
+  % of subentries (or empty, for subsubsections).  #3 is the node text,
+  % which might be empty if this toc entry had no corresponding node.
+  % #4 is the page number
+  %
+  \def\dopdfoutline#1#2#3#4{%
+    % Generate a link to the node text if that exists; else, use the
+    % page number.  We could generate a destination for the section
+    % text in the case where a section has no node, but it doesn't
+    % seem worth the trouble, since most documents are normally structured.
+    \def\pdfoutlinedest{#3}%
+    \ifx\pdfoutlinedest\empty
+      \def\pdfoutlinedest{#4}%
+    \else
+      % Doubled backslashes in the name.
+      {\activebackslashdouble \xdef\pdfoutlinedest{#3}%
+       \backslashparens\pdfoutlinedest}%
+    \fi
+    %
+    % Also double the backslashes in the display string.
+    {\activebackslashdouble \xdef\pdfoutlinetext{#1}%
+     \backslashparens\pdfoutlinetext}%
+    %
+    \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
+  }
+  %
+  \def\pdfmakeoutlines{%
+    \begingroup
+      % Thanh's hack / proper braces in bookmarks
+      \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
+      \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
+      %
+      % Read toc silently, to get counts of subentries for \pdfoutline.
+      \def\numchapentry##1##2##3##4{%
+	\def\thischapnum{##2}%
+	\def\thissecnum{0}%
+	\def\thissubsecnum{0}%
+      }%
+      \def\numsecentry##1##2##3##4{%
+	\advancenumber{chap\thischapnum}%
+	\def\thissecnum{##2}%
+	\def\thissubsecnum{0}%
+      }%
+      \def\numsubsecentry##1##2##3##4{%
+	\advancenumber{sec\thissecnum}%
+	\def\thissubsecnum{##2}%
+      }%
+      \def\numsubsubsecentry##1##2##3##4{%
+	\advancenumber{subsec\thissubsecnum}%
+      }%
+      \def\thischapnum{0}%
+      \def\thissecnum{0}%
+      \def\thissubsecnum{0}%
+      %
+      % use \def rather than \let here because we redefine \chapentry et
+      % al. a second time, below.
+      \def\appentry{\numchapentry}%
+      \def\appsecentry{\numsecentry}%
+      \def\appsubsecentry{\numsubsecentry}%
+      \def\appsubsubsecentry{\numsubsubsecentry}%
+      \def\unnchapentry{\numchapentry}%
+      \def\unnsecentry{\numsecentry}%
+      \def\unnsubsecentry{\numsubsecentry}%
+      \def\unnsubsubsecentry{\numsubsubsecentry}%
+      \readdatafile{toc}%
+      %
+      % Read toc second time, this time actually producing the outlines.
+      % The `-' means take the \expnumber as the absolute number of
+      % subentries, which we calculated on our first read of the .toc above.
+      %
+      % We use the node names as the destinations.
+      \def\numchapentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+      \def\numsecentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+      \def\numsubsecentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+      \def\numsubsubsecentry##1##2##3##4{% count is always zero
+        \dopdfoutline{##1}{}{##3}{##4}}%
+      %
+      % PDF outlines are displayed using system fonts, instead of
+      % document fonts.  Therefore we cannot use special characters,
+      % since the encoding is unknown.  For example, the eogonek from
+      % Latin 2 (0xea) gets translated to a | character.  Info from
+      % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+      %
+      % xx to do this right, we have to translate 8-bit characters to
+      % their "best" equivalent, based on the @documentencoding.  Right
+      % now, I guess we'll just let the pdf reader have its way.
+      \indexnofonts
+      \setupdatafile
+      \catcode`\\=\active \otherbackslash
+      \input \tocreadfilename
+    \endgroup
+  }
+  %
+  \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+    \ifx\PP\D\let\nextsp\relax
+    \else\let\nextsp\skipspaces
+      \ifx\p\space\else\addtokens{\filename}{\PP}%
+        \advance\filenamelength by 1
+      \fi
+    \fi
+    \nextsp}
+  \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+  \ifnum\pdftexversion < 14
+    \let \startlink \pdfannotlink
+  \else
+    \let \startlink \pdfstartlink
+  \fi
+  % make a live url in pdf output.
+  \def\pdfurl#1{%
+    \begingroup
+      % it seems we really need yet another set of dummies; have not
+      % tried to figure out what each command should do in the context
+      % of @url.  for now, just make @/ a no-op, that's the only one
+      % people have actually reported a problem with.
+      %
+      \normalturnoffactive
+      \def\@{@}%
+      \let\/=\empty
+      \makevalueexpandable
+      \leavevmode\setcolor{\urlcolor}%
+      \startlink attr{/Border [0 0 0]}%
+        user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+    \endgroup}
+  \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+  \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+  \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+  \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+  \def\maketoks{%
+    \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+    \ifx\first0\adn0
+    \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+    \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+    \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+    \else
+      \ifnum0=\countA\else\makelink\fi
+      \ifx\first.\let\next=\done\else
+        \let\next=\maketoks
+        \addtokens{\toksB}{\the\toksD}
+        \ifx\first,\addtokens{\toksB}{\space}\fi
+      \fi
+    \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+    \next}
+  \def\makelink{\addtokens{\toksB}%
+    {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+  \def\pdflink#1{%
+    \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+    \setcolor{\linkcolor}#1\endlink}
+  \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+  \let\pdfmkdest = \gobble
+  \let\pdfurl = \gobble
+  \let\endlink = \relax
+  \let\setcolor = \gobble
+  \let\pdfsetcolor = \gobble
+  \let\pdfmakeoutlines = \relax
+\fi  % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+  \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+  \csname ten#1\endcsname  % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+
+% Default leading.
+\newdimen\textleading  \textleading = 13.2pt
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly.  There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+% can get a sort of poor man's double spacing by redefining this.
+\def\baselinefactor{1}
+%
+\def\setleading#1{%
+  \dimen0 = #1\relax
+  \normalbaselineskip = \baselinefactor\dimen0
+  \normallineskip = \lineskipfactor\normalbaselineskip
+  \normalbaselines
+  \setbox\strutbox =\hbox{%
+    \vrule width0pt height\strutheightpercent\baselineskip
+                    depth \strutdepthpercent \baselineskip
+  }%
+}
+
+%
+% PDF CMaps.  See also LaTeX's t1.cmap.
+%
+% \cmapOT1
+\ifpdf
+  \begingroup
+    \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+    \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1-0)
+%%Title: (TeX-OT1-0 TeX OT1 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<23> <26> <0023>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+40 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+    }\endgroup
+  \expandafter\edef\csname cmapOT1\endcsname#1{%
+    \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+  }%
+%
+% \cmapOT1IT
+  \begingroup
+    \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+    \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1IT-0)
+%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1IT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1IT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<25> <26> <0025>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+42 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<23> <0023>
+<24> <00A3>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+    }\endgroup
+  \expandafter\edef\csname cmapOT1IT\endcsname#1{%
+    \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+  }%
+%
+% \cmapOT1TT
+  \begingroup
+    \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+    \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1TT-0)
+%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1TT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1TT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+5 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<21> <26> <0021>
+<28> <5F> <0028>
+<61> <7E> <0061>
+endbfrange
+32 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <2191>
+<0C> <2193>
+<0D> <0027>
+<0E> <00A1>
+<0F> <00BF>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<20> <2423>
+<27> <2019>
+<60> <2018>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+    }\endgroup
+  \expandafter\edef\csname cmapOT1TT\endcsname#1{%
+    \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+  }%
+\else
+  \expandafter\let\csname cmapOT1\endcsname\gobble
+  \expandafter\let\csname cmapOT1IT\endcsname\gobble
+  \expandafter\let\csname cmapOT1TT\endcsname\gobble
+\fi
+
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
+% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
+% empty to omit).
+\def\setfont#1#2#3#4#5{%
+  \font#1=\fontprefix#2#3 scaled #4
+  \csname cmap#5\endcsname#1%
+}
+% This is what gets called when #5 of \setfont is empty.
+\let\cmap\gobble
+
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\undefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx}               %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Definitions for a main text size of 11pt.  This is the default in
+% Texinfo.
+%
+\def\definetextfontsizexi{%
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1095}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}{OT1}
+\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+\def\titleecsize{2074}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
+\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
+\setfont\chapsf\sfbshape{17}{1000}{OT1}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+\def\chapecsize{1728}
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
+\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep2}{OT1}
+\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}{OT1}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+\def\sececsize{1440}
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
+\setfont\ssecit\itbshape{10}{1315}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1315}{OT1}
+\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}{OT1}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+\def\ssececsize{1200}
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}{OT1}
+\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{1000}{OT1}
+\setfont\reducedit\itshape{10}{1000}{OT1IT}
+\setfont\reducedsl\slshape{10}{1000}{OT1}
+\setfont\reducedsf\sfshape{10}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{1000}{OT1}
+\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+\def\reducedecsize{1000}
+
+% reset the current fonts
+\textfonts
+\rm
+} % end of 11pt text font size definitions
+
+
+% Definitions to make the main text be 10pt Computer Modern, with
+% section, chapter, etc., sizes following suit.  This is for the GNU
+% Press printing of the Emacs 22 manual.  Maybe other manuals in the
+% future.  Used with @smallbook, which sets the leading to 12pt.
+%
+\def\definetextfontsizex{%
+% Text fonts (10pt).
+\def\textnominalsize{10pt}
+\edef\mainmagstep{1000}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1000}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
+\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+\def\titleecsize{2074}
+
+% Chapter fonts (14.4pt).
+\def\chapnominalsize{14pt}
+\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
+\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
+\let\chapbf\chaprm
+\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
+\font\chapi=cmmi12 scaled \magstep1
+\font\chapsy=cmsy10 scaled \magstep2
+\def\chapecsize{1440}
+
+% Section fonts (12pt).
+\def\secnominalsize{12pt}
+\setfont\secrm\rmbshape{12}{1000}{OT1}
+\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep1}{OT1}
+\setfont\sectt\ttbshape{12}{1000}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
+\setfont\secsf\sfbshape{12}{1000}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep1}{OT1}
+\font\seci=cmmi12
+\font\secsy=cmsy10 scaled \magstep1
+\def\sececsize{1200}
+
+% Subsection fonts (10pt).
+\def\ssecnominalsize{10pt}
+\setfont\ssecrm\rmbshape{10}{1000}{OT1}
+\setfont\ssecit\itbshape{10}{1000}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1000}{OT1}
+\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
+\setfont\ssecsf\sfbshape{10}{1000}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1000}{OT1}
+\font\sseci=cmmi10
+\font\ssecsy=cmsy10
+\def\ssececsize{1000}
+
+% Reduced fonts for @acro in text (9pt).
+\def\reducednominalsize{9pt}
+\setfont\reducedrm\rmshape{9}{1000}{OT1}
+\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{900}{OT1}
+\setfont\reducedit\itshape{9}{1000}{OT1IT}
+\setfont\reducedsl\slshape{9}{1000}{OT1}
+\setfont\reducedsf\sfshape{9}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{900}{OT1}
+\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
+\font\reducedi=cmmi9
+\font\reducedsy=cmsy9
+\def\reducedecsize{0900}
+
+% reduce space between paragraphs
+\divide\parskip by 2
+
+% reset the current fonts
+\textfonts
+\rm
+} % end of 10pt text font size definitions
+
+
+% We provide the user-level command
+%   @fonttextsize 10
+% (or 11) to redefine the text font size.  pt is assumed.
+%
+\def\xword{10}
+\def\xiword{11}
+%
+\parseargdef\fonttextsize{%
+  \def\textsizearg{#1}%
+  \wlog{doing @fonttextsize \textsizearg}%
+  %
+  % Set \globaldefs so that documents can use this inside @tex, since
+  % makeinfo 4.8 does not support it, but we need it nonetheless.
+  %
+ \begingroup \globaldefs=1
+  \ifx\textsizearg\xword \definetextfontsizex
+  \else \ifx\textsizearg\xiword \definetextfontsizexi
+  \else
+    \errhelp=\EMsimple
+    \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'}
+  \fi\fi
+ \endgroup
+}
+
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families.  Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+  \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+  \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+  \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE.  We do this because \STYLE needs to also set the
+% current \fam for math mode.  Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower).  These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+  \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+  \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+  \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+  \let\tenttsl=\textttsl
+  \def\curfontsize{text}%
+  \def\lsize{reduced}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+  \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+  \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+  \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+  \let\tenttsl=\titlettsl
+  \def\curfontsize{title}%
+  \def\lsize{chap}\def\lllsize{subsec}%
+  \resetmathfonts \setleading{25pt}}
+\def\titlefont#1{{\titlefonts\rm #1}}
+\def\chapfonts{%
+  \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+  \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+  \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+  \let\tenttsl=\chapttsl
+  \def\curfontsize{chap}%
+  \def\lsize{sec}\def\lllsize{text}%
+  \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+  \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+  \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+  \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+  \let\tenttsl=\secttsl
+  \def\curfontsize{sec}%
+  \def\lsize{subsec}\def\lllsize{reduced}%
+  \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+  \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+  \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+  \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+  \let\tenttsl=\ssecttsl
+  \def\curfontsize{ssec}%
+  \def\lsize{text}\def\lllsize{small}%
+  \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+  \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+  \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+  \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+  \let\tenttsl=\reducedttsl
+  \def\curfontsize{reduced}%
+  \def\lsize{small}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+  \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+  \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+  \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+  \let\tenttsl=\smallttsl
+  \def\curfontsize{small}%
+  \def\lsize{smaller}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+  \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+  \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+  \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+  \let\tenttsl=\smallerttsl
+  \def\curfontsize{smaller}%
+  \def\lsize{smaller}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{9.5pt}}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts.  If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+%   8.5x11=86   smallbook=72  a4=90  a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+%   8.5x11=90+  smallbook=80  a4=90+  a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt.  So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+%   8.5x11=71  smallbook=60  a4=75  a5=58
+%
+% I wish the USA used A4 paper.
+% --karl, 24jan03.
+
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\definetextfontsizexi
+
+% Define these so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}{OT1}
+\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1}  % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}{OT1}
+\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
+                    \ptexslash\fi\fi\fi}
+\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
+\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally uses \ttsl.
+% @var is set to this for defun arguments.
+\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally use \sl.  We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\let\var=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% @b, explicit bold.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph.  Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1  \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+  \def\plainfrenchspacing{%
+    \sfcode\dotChar  =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+    \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+    \def\endofsentencespacefactor{1000}% for @. and friends
+  }
+  \def\plainnonfrenchspacing{%
+    \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+    \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+    \def\endofsentencespacefactor{3000}% for @. and friends
+  }
+\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+
+\def\t#1{%
+  {\tt \rawbackslash \plainfrenchspacing #1}%
+  \null
+}
+\def\samp#1{`\tclose{#1}'\null}
+\setfont\keyrm\rmshape{8}{1000}{OT1}
+\font\keysy=cmsy9
+\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+  \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+    \vbox{\hrule\kern-0.4pt
+     \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+    \kern-0.4pt\hrule}%
+  \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+\def\key #1{{\nohyphenation \uppercase{#1}}\null}
+% The old definition, with no lozenge:
+%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @file, @option are the same as @samp.
+\let\file=\samp
+\let\option=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+  {%
+    % Change normal interword space to be same as for the current font.
+    \spaceskip = \fontdimen2\font
+    %
+    % Switch to typewriter.
+    \tt
+    %
+    % But `\ ' produces the large typewriter interword space.
+    \def\ {{\spaceskip = 0pt{} }}%
+    %
+    % Turn off hyphenation.
+    \nohyphenation
+    %
+    \rawbackslash
+    \plainfrenchspacing
+    #1%
+  }%
+  \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+%  -- rms.
+{
+  \catcode`\-=\active \catcode`\_=\active
+  \catcode`\'=\active \catcode`\`=\active
+  %
+  \global\def\code{\begingroup
+    \catcode\rquoteChar=\active \catcode\lquoteChar=\active
+    \let'\codequoteright \let`\codequoteleft
+    %
+    \catcode\dashChar=\active  \catcode\underChar=\active
+    \ifallowcodebreaks
+     \let-\codedash
+     \let_\codeunder
+    \else
+     \let-\realdash
+     \let_\realunder
+    \fi
+    \codex
+  }
+}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+  % this is all so @math{@code{var_name}+1} can work.  In math mode, _
+  % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+  % will therefore expand the active definition of _, which is us
+  % (inside @code that is), therefore an endless loop.
+  \ifusingtt{\ifmmode
+               \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+             \else\normalunderscore \fi
+             \discretionary{}{}{}}%
+            {\_}%
+}
+\def\codex #1{\tclose{#1}\endgroup}
+
+% An additional complication: the above will allow breaks after, e.g.,
+% each of the four underscores in __typeof__.  This is undesirable in
+% some manuals, especially if they don't have long identifiers in
+% general.  @allowcodebreaks provides a way to control this.
+%
+\newif\ifallowcodebreaks  \allowcodebreakstrue
+
+\def\keywordtrue{true}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+  \def\txiarg{#1}%
+  \ifx\txiarg\keywordtrue
+    \allowcodebreakstrue
+  \else\ifx\txiarg\keywordfalse
+    \allowcodebreaksfalse
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @allowcodebreaks option `\txiarg'}%
+  \fi\fi
+}
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+%   `example' (@kbd uses ttsl only inside of @example and friends),
+%   or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+  \def\txiarg{#1}%
+  \ifx\txiarg\worddistinct
+    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+  \else\ifx\txiarg\wordexample
+    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+  \else\ifx\txiarg\wordcode
+    \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @kbdinputstyle option `\txiarg'}%
+  \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct.'
+\kbdinputstyle distinct
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\kbdfont\look}}\fi
+\else{\tclose{\kbdfont\look}}\fi}
+
+% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+\let\indicateurl=\code
+\let\env=\code
+\let\command=\code
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself.  First (mandatory) arg is the url.  Perhaps eventually put in
+% a hypertex \special here.
+%
+\def\uref#1{\douref #1,,,\finish}
+\def\douref#1,#2,#3,#4\finish{\begingroup
+  \unsepspaces
+  \pdfurl{#1}%
+  \setbox0 = \hbox{\ignorespaces #3}%
+  \ifdim\wd0 > 0pt
+    \unhbox0 % third arg given, show only that
+  \else
+    \setbox0 = \hbox{\ignorespaces #2}%
+    \ifdim\wd0 > 0pt
+      \ifpdf
+        \unhbox0             % PDF: 2nd arg given, show only it
+      \else
+        \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+      \fi
+    \else
+      \code{#1}% only url given, so show it
+    \fi
+  \fi
+  \endlink
+\endgroup}
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+  \def\email#1{\doemail#1,,\finish}
+  \def\doemail#1,#2,#3\finish{\begingroup
+    \unsepspaces
+    \pdfurl{mailto:#1}%
+    \setbox0 = \hbox{\ignorespaces #2}%
+    \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+    \endlink
+  \endgroup}
+\else
+  \let\email=\uref
+\fi
+
+% Check if we are currently using a typewriter font.  Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Typeset a dimension, e.g., `in' or `pt'.  The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find.  We need it for
+% Polish suppressed-l.  --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}}              % roman font
+\def\sc#1{{\smallcaps#1}}       % smallcaps font
+\def\ii#1{{\it #1}}             % italic font
+
+% @acronym for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+%
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+  {\selectfonts\lsize #1}%
+  \def\temp{#2}%
+  \ifx\temp\empty \else
+    \space ({\unsepspaces \ignorespaces \temp \unskip})%
+  \fi
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+%
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+  {\plainfrenchspacing #1}%
+  \def\temp{#2}%
+  \ifx\temp\empty \else
+    \space ({\unsepspaces \ignorespaces \temp \unskip})%
+  \fi
+}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+%
+% Although only regular is the truly official Euro symbol, we ignore
+% that.  The Euro is designed to be slightly taller than the regular
+% font height.
+%
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+%
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+%
+% Also doesn't work in math.  Do we need to do math with euro symbols?
+% Hope not.
+%
+%
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+  % We set the font at each command, rather than predefining it in
+  % \textfonts and the other font-switching commands, so that
+  % installations which never need the symbol don't have to have the
+  % font installed.
+  %
+  % There is only one designed size (nominal 10pt), so we always scale
+  % that to the current nominal size.
+  %
+  % By the way, simply using "at 1em" works for cmr10 and the like, but
+  % does not work for cmbx10 and other extended/shrunken fonts.
+  %
+  \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+  %
+  \ifx\curfontstyle\bfstylename
+    % bold:
+    \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+  \else
+    % regular:
+    \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+  \fi
+  \thiseurofont
+}
+
+% Hacks for glyphs from the EC fonts similar to \euro.  We don't
+% use \let for the aliases, because sometimes we redefine the original
+% macro, and the alias should reflect the redefinition.
+\def\guillemetleft{{\ecfont \char"13}}
+\def\guillemotleft{\guillemetleft}
+\def\guillemetright{{\ecfont \char"14}}
+\def\guillemotright{\guillemetright}
+\def\guilsinglleft{{\ecfont \char"0E}}
+\def\guilsinglright{{\ecfont \char"0F}}
+\def\quotedblbase{{\ecfont \char"12}}
+\def\quotesinglbase{{\ecfont \char"0D}}
+%
+\def\ecfont{%
+  % We can't distinguish serif/sanserif and italic/slanted, but this
+  % is used for crude hacks anyway (like adding French and German
+  % quotes to documents typeset with CM, where we lose kerning), so
+  % hopefully nobody will notice/care.
+  \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
+  \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
+  \ifx\curfontstyle\bfstylename
+    % bold:
+    \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+  \else
+    % regular:
+    \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+  \fi
+  \thisecfont
+}
+
+% @registeredsymbol - R in a circle.  The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+  $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+               \hfil\crcr\Orb}}%
+    }$%
+}
+
+% @textdegree - the normal degrees sign.
+%
+\def\textdegree{$^\circ$}
+
+% Laurent Siebenmann reports \Orb undefined with:
+%  Textures 1.7.7 (preloaded format=plain 93.10.14)  (68K)  16 APR 2004 02:38
+% so we'll define it if necessary.
+%
+\ifx\Orb\undefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+% Quotes.
+\chardef\quotedblleft="5C
+\chardef\quotedblright=`\"
+\chardef\quoteleft=`\`
+\chardef\quoteright=`\'
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page.  Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+        \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+  % Open one extra group, as we want to close it in the middle of \Etitlepage.
+  \begingroup
+    \parindent=0pt \textfonts
+    % Leave some space at the very top of the page.
+    \vglue\titlepagetopglue
+    % No rule at page bottom unless we print one at the top with @title.
+    \finishedtitlepagetrue
+    %
+    % Most title ``pages'' are actually two pages long, with space
+    % at the top of the second.  We don't want the ragged left on the second.
+    \let\oldpage = \page
+    \def\page{%
+      \iffinishedtitlepage\else
+	 \finishtitlepage
+      \fi
+      \let\page = \oldpage
+      \page
+      \null
+    }%
+}
+
+\def\Etitlepage{%
+    \iffinishedtitlepage\else
+	\finishtitlepage
+    \fi
+    % It is important to do the page break before ending the group,
+    % because the headline and footline are only empty inside the group.
+    % If we use the new definition of \page, we always get a blank page
+    % after the title page, which we certainly don't want.
+    \oldpage
+  \endgroup
+  %
+  % Need this before the \...aftertitlepage checks so that if they are
+  % in effect the toc pages will come out with page numbers.
+  \HEADINGSon
+  %
+  % If they want short, they certainly want long too.
+  \ifsetshortcontentsaftertitlepage
+    \shortcontents
+    \contents
+    \global\let\shortcontents = \relax
+    \global\let\contents = \relax
+  \fi
+  %
+  \ifsetcontentsaftertitlepage
+    \contents
+    \global\let\contents = \relax
+    \global\let\shortcontents = \relax
+  \fi
+}
+
+\def\finishtitlepage{%
+  \vskip4pt \hrule height 2pt width \hsize
+  \vskip\titlepagebottomglue
+  \finishedtitlepagetrue
+}
+
+%%% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
+		\let\tt=\authortt}
+
+\parseargdef\title{%
+  \checkenv\titlepage
+  \leftline{\titlefonts\rm #1}
+  % print a rule at the page bottom also.
+  \finishedtitlepagefalse
+  \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+  \checkenv\titlepage
+  {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+  \def\temp{\quotation}%
+  \ifx\thisenv\temp
+    \def\quotationauthor{#1}% printed in \Equotation.
+  \else
+    \checkenv\titlepage
+    \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+    {\authorfont \leftline{#1}}%
+  \fi
+}
+
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline    % headline on even pages
+\newtoks\oddheadline     % headline on odd pages
+\newtoks\evenfootline    % footline on even pages
+\newtoks\oddfootline     % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+                            \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+                            \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what  @headings on  does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+  \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+  %
+  % Leave some space for the footline.  Hopefully ok to assume
+  % @evenfooting will not be used by itself.
+  \global\advance\pageheight by -12pt
+  \global\advance\vsize by -12pt
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+% @evenheadingmarks top     \thischapter <- chapter at the top of a page
+% @evenheadingmarks bottom  \thischapter <- chapter at the bottom of a page
+%
+% The same set of arguments for:
+%
+% @oddheadingmarks
+% @evenfootingmarks
+% @oddfootingmarks
+% @everyheadingmarks
+% @everyfootingmarks
+
+\def\evenheadingmarks{\headingmarks{even}{heading}}
+\def\oddheadingmarks{\headingmarks{odd}{heading}}
+\def\evenfootingmarks{\headingmarks{even}{footing}}
+\def\oddfootingmarks{\headingmarks{odd}{footing}}
+\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1}
+                          \headingmarks{odd}{heading}{#1} }
+\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1}
+                          \headingmarks{odd}{footing}{#1} }
+% #1 = even/odd, #2 = heading/footing, #3 = top/bottom.
+\def\headingmarks#1#2#3 {%
+  \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname
+  \global\expandafter\let\csname get#1#2marks\endcsname \temp
+}
+
+\everyheadingmarks bottom
+\everyfootingmarks bottom
+
+% @headings double      turns headings on for double-sided printing.
+% @headings single      turns headings on for single-sided printing.
+% @headings off         turns them off.
+% @headings on          same as @headings double, retained for compatibility.
+% @headings after       turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{%
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\undefined
+\def\today{%
+  \number\day\space
+  \ifcase\month
+  \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+  \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+  \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+  \fi
+  \space\number\year}
+\fi
+
+% @settitle line...  specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent  \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin  \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+  \advance\hsize by -\rightskip
+  \advance\hsize by -\tableindent
+  \setbox0=\hbox{\itemindicate{#1}}%
+  \itemindex{#1}%
+  \nobreak % This prevents a break before @itemx.
+  %
+  % If the item text does not fit in the space we have, put it on a line
+  % by itself, and do not allow a page break either before or after that
+  % line.  We do not start a paragraph here because then if the next
+  % command is, e.g., @kindex, the whatsit would get put into the
+  % horizontal list on a line by itself, resulting in extra blank space.
+  \ifdim \wd0>\itemmax
+    %
+    % Make this a paragraph so we get the \parskip glue and wrapping,
+    % but leave it ragged-right.
+    \begingroup
+      \advance\leftskip by-\tableindent
+      \advance\hsize by\tableindent
+      \advance\rightskip by0pt plus1fil
+      \leavevmode\unhbox0\par
+    \endgroup
+    %
+    % We're going to be starting a paragraph, but we don't want the
+    % \parskip glue -- logically it's part of the @item we just started.
+    \nobreak \vskip-\parskip
+    %
+    % Stop a page break at the \parskip glue coming up.  However, if
+    % what follows is an environment such as @example, there will be no
+    % \parskip glue; then the negative vskip we just inserted would
+    % cause the example and the item to crash together.  So we use this
+    % bizarre value of 10001 as a signal to \aboveenvbreak to insert
+    % \parskip glue after all.  Section titles are handled this way also.
+    %
+    \penalty 10001
+    \endgroup
+    \itemxneedsnegativevskipfalse
+  \else
+    % The item text fits into the space.  Start a paragraph, so that the
+    % following text (if any) will end up on the same line.
+    \noindent
+    % Do this with kerns and \unhbox so that if there is a footnote in
+    % the item text, it can migrate to the main vertical list and
+    % eventually be printed.
+    \nobreak\kern-\tableindent
+    \dimen0 = \itemmax  \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+    \unhbox0
+    \nobreak\kern\dimen0
+    \endgroup
+    \itemxneedsnegativevskiptrue
+  \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+  \let\itemindex\gobble
+  \tablecheck{table}%
+}
+\envdef\ftable{%
+  \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+  \tablecheck{ftable}%
+}
+\envdef\vtable{%
+  \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+  \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+  \ifnum \the\catcode`\^^M=\active
+    \endgroup
+    \errmessage{This command won't work in this context; perhaps the problem is
+      that we are \inenvironment\thisenv}%
+    \def\next{\doignore{#1}}%
+  \else
+    \let\next\tablex
+  \fi
+  \next
+}
+\def\tablex#1{%
+  \def\itemindicate{#1}%
+  \parsearg\tabley
+}
+\def\tabley#1{%
+  {%
+    \makevalueexpandable
+    \edef\temp{\noexpand\tablez #1\space\space\space}%
+    \expandafter
+  }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+  \aboveenvbreak
+  \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+  \ifnum 0#2>0 \tableindent=#2\mil \fi
+  \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+  \itemmax=\tableindent
+  \advance \itemmax by -\itemmargin
+  \advance \leftskip by \tableindent
+  \exdentamount=\tableindent
+  \parindent = 0pt
+  \parskip = \smallskipamount
+  \ifdim \parskip=0pt \parskip=2pt \fi
+  \let\item = \internalBitem
+  \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+  \aboveenvbreak
+  \itemmax=\itemindent
+  \advance\itemmax by -\itemmargin
+  \advance\leftskip by \itemindent
+  \exdentamount=\itemindent
+  \parindent=0pt
+  \parskip=\smallskipamount
+  \ifdim\parskip=0pt \parskip=2pt \fi
+  \def\itemcontents{#1}%
+  % @itemize with no arg is equivalent to @itemize @bullet.
+  \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+  \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+  \advance\itemno by 1  % for enumerations
+  {\let\par=\endgraf \smallbreak}% reasonable place to break
+  {%
+   % If the document has an @itemize directly after a section title, a
+   % \nobreak will be last on the list, and \sectionheading will have
+   % done a \vskip-\parskip.  In that case, we don't want to zero
+   % parskip, or the item text will crash with the heading.  On the
+   % other hand, when there is normal text preceding the item (as there
+   % usually is), we do want to zero parskip, or there would be too much
+   % space.  In that case, we won't have a \nobreak before.  At least
+   % that's the theory.
+   \ifnum\lastpenalty<10000 \parskip=0in \fi
+   \noindent
+   \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+   \vadjust{\penalty 1200}}% not good to break after first line of item.
+  \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list.  No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1  \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+  % If we were given no argument, pretend we were given `1'.
+  \def\thearg{#1}%
+  \ifx\thearg\empty \def\thearg{1}\fi
+  %
+  % Detect if the argument is a single token.  If so, it might be a
+  % letter.  Otherwise, the only valid thing it can be is a number.
+  % (We will always have one token, because of the test we just made.
+  % This is a good thing, since \splitoff doesn't work given nothing at
+  % all -- the first parameter is undelimited.)
+  \expandafter\splitoff\thearg\endmark
+  \ifx\rest\empty
+    % Only one token in the argument.  It could still be anything.
+    % A ``lowercase letter'' is one whose \lccode is nonzero.
+    % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+    %   not equal to itself.
+    % Otherwise, we assume it's a number.
+    %
+    % We need the \relax at the end of the \ifnum lines to stop TeX from
+    % continuing to look for a <number>.
+    %
+    \ifnum\lccode\expandafter`\thearg=0\relax
+      \numericenumerate % a number (we hope)
+    \else
+      % It's a letter.
+      \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+        \lowercaseenumerate % lowercase letter
+      \else
+        \uppercaseenumerate % uppercase letter
+      \fi
+    \fi
+  \else
+    % Multiple tokens in the argument.  We hope it's a number.
+    \numericenumerate
+  \fi
+}
+
+% An @enumerate whose labels are integers.  The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+  \itemno = \thearg
+  \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more lowercase letters in @enumerate; get a bigger
+                  alphabet}%
+    \fi
+    \char\lccode\itemno
+  }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more uppercase letters in @enumerate; get a bigger
+                  alphabet}
+    \fi
+    \char\uccode\itemno
+  }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments.  Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+  \advance\itemno by -1
+  \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble.  Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+%   @multitable @columnfractions .25 .3 .45
+%   @item ...
+%
+%   Numbers following @columnfractions are the percent of the total
+%   current hsize to be used for each column. You may use as many
+%   columns as desired.
+
+
+% Or use a template:
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item ...
+%   using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item first col stuff @tab second col stuff @tab third col
+%   @item
+%   first col stuff
+%   @tab
+%   second col stuff
+%   @tab
+%   third col
+%   @item first col stuff @tab second col stuff
+%   @tab Many paragraphs of text may be used in any column.
+%
+%         They will wrap at the width determined by the template.
+%   @item@tab@tab This will be in third column.
+%   @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+%                                                            to baseline.
+%   0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1.  We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+  \global\advance\colcount by 1
+  \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+  \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+  \def\firstarg{#1}%
+  \ifx\firstarg\xendsetuptable
+    \let\go = \relax
+  \else
+    \ifx\firstarg\xcolumnfractions
+      \global\setpercenttrue
+    \else
+      \ifsetpercent
+         \let\go\pickupwholefraction
+      \else
+         \global\advance\colcount by 1
+         \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+                   % separator; typically that is always in the input, anyway.
+         \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+      \fi
+    \fi
+    \ifx\go\pickupwholefraction
+      % Put the argument back for the \pickupwholefraction call, so
+      % we'll always have a period there to be parsed.
+      \def\go{\pickupwholefraction#1}%
+    \else
+      \let\go = \setuptable
+    \fi%
+  \fi
+  \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry.  Note that \everycr resets \everytab.
+\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}%
+%
+% A \tab used to include \hskip1sp.  But then the space in a template
+% line is not enough.  That is bad.  So let's go back to just `&' until
+% we encounter the problem it was intended to solve again.
+%					--karl, nathan@acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab  % insert after every tab.
+%
+\envdef\multitable{%
+  \vskip\parskip
+  \startsavinginserts
+  %
+  % @item within a multitable starts a normal row.
+  % We use \def instead of \let so that if one of the multitable entries
+  % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+  % \endtemplate) expanding \doitemize.
+  \def\item{\crcr}%
+  %
+  \tolerance=9500
+  \hbadness=9500
+  \setmultitablespacing
+  \parskip=\multitableparskip
+  \parindent=\multitableparindent
+  \overfullrule=0pt
+  \global\colcount=0
+  %
+  \everycr = {%
+    \noalign{%
+      \global\everytab={}%
+      \global\colcount=0 % Reset the column counter.
+      % Check for saved footnotes, etc.
+      \checkinserts
+      % Keeps underfull box messages off when table breaks over pages.
+      %\filbreak
+	% Maybe so, but it also creates really weird page breaks when the
+	% table breaks over pages. Wouldn't \vfil be better?  Wait until the
+	% problem manifests itself, so it can be fixed for real --karl.
+    }%
+  }%
+  %
+  \parsearg\domultitable
+}
+\def\domultitable#1{%
+  % To parse everything between @multitable and @item:
+  \setuptable#1 \endsetuptable
+  %
+  % This preamble sets up a generic column definition, which will
+  % be used as many times as user calls for columns.
+  % \vtop will set a single line and will also let text wrap and
+  % continue for many paragraphs if desired.
+  \halign\bgroup &%
+    \global\advance\colcount by 1
+    \multistrut
+    \vtop{%
+      % Use the current \colcount to find the correct column width:
+      \hsize=\expandafter\csname col\the\colcount\endcsname
+      %
+      % In order to keep entries from bumping into each other
+      % we will add a \leftskip of \multitablecolspace to all columns after
+      % the first one.
+      %
+      % If a template has been used, we will add \multitablecolspace
+      % to the width of each template entry.
+      %
+      % If the user has set preamble in terms of percent of \hsize we will
+      % use that dimension as the width of the column, and the \leftskip
+      % will keep entries from bumping into each other.  Table will start at
+      % left margin and final column will justify at right margin.
+      %
+      % Make sure we don't inherit \rightskip from the outer environment.
+      \rightskip=0pt
+      \ifnum\colcount=1
+	% The first column will be indented with the surrounding text.
+	\advance\hsize by\leftskip
+      \else
+	\ifsetpercent \else
+	  % If user has not set preamble in terms of percent of \hsize
+	  % we will advance \hsize by \multitablecolspace.
+	  \advance\hsize by \multitablecolspace
+	\fi
+       % In either case we will make \leftskip=\multitablecolspace:
+      \leftskip=\multitablecolspace
+      \fi
+      % Ignoring space at the beginning and end avoids an occasional spurious
+      % blank line, when TeX decides to break the line at the space before the
+      % box from the multistrut, so the strut ends up on a line by itself.
+      % For example:
+      % @multitable @columnfractions .11 .89
+      % @item @code{#}
+      % @tab Legal holiday which is valid in major parts of the whole country.
+      % Is automatically provided with highlighting sequences respectively
+      % marking characters.
+      \noindent\ignorespaces##\unskip\multistrut
+    }\cr
+}
+\def\Emultitable{%
+  \crcr
+  \egroup % end the \halign
+  \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+  \def\multistrut{\strut}% just use the standard line spacing
+  %
+  % Compute \multitablelinespace (if not defined by user) for use in
+  % \multitableparskip calculation.  We used define \multistrut based on
+  % this, but (ironically) that caused the spacing to be off.
+  % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing.
+%%        If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed.  They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested.  But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+  \expandafter\let\csname #1\endcsname = \relax
+  \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+  % Scan in ``verbatim'' mode:
+  \obeylines
+  \catcode`\@ = \other
+  \catcode`\{ = \other
+  \catcode`\} = \other
+  %
+  % Make sure that spaces turn into tokens that match what \doignoretext wants.
+  \spaceisspace
+  %
+  % Count number of #1's that we've seen.
+  \doignorecount = 0
+  %
+  % Swallow text until we reach the matching `@end #1'.
+  \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+  \obeylines %
+  %
+  \gdef\dodoignore#1{%
+    % #1 contains the command name as a string, e.g., `ifinfo'.
+    %
+    % Define a command to find the next `@end #1'.
+    \long\def\doignoretext##1^^M@end #1{%
+      \doignoretextyyy##1^^M@#1\_STOP_}%
+    %
+    % And this command to find another #1 command, at the beginning of a
+    % line.  (Otherwise, we would consider a line `@c @ifset', for
+    % example, to count as an @ifset for nesting.)
+    \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+    %
+    % And now expand that command.
+    \doignoretext ^^M%
+  }%
+}
+
+\def\doignoreyyy#1{%
+  \def\temp{#1}%
+  \ifx\temp\empty			% Nothing found.
+    \let\next\doignoretextzzz
+  \else					% Found a nested condition, ...
+    \advance\doignorecount by 1
+    \let\next\doignoretextyyy		% ..., look for another.
+    % If we're here, #1 ends with ^^M\ifinfo (for example).
+  \fi
+  \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+  \ifnum\doignorecount = 0	% We have just found the outermost @end.
+    \let\next\enddoignore
+  \else				% Still inside a nested condition.
+    \advance\doignorecount by -1
+    \let\next\doignoretext      % Look for the next @end.
+  \fi
+  \next
+}
+
+% Finish off ignored text.
+{ \obeylines%
+  % Ignore anything after the last `@end #1'; this matters in verbatim
+  % environments, where otherwise the newline after an ignored conditional
+  % would result in a blank line in the output.
+  \gdef\enddoignore#1^^M{\endgroup\ignorespaces}%
+}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+  {%
+    \makevalueexpandable
+    \def\temp{#2}%
+    \edef\next{\gdef\makecsname{SET#1}}%
+    \ifx\temp\empty
+      \next{}%
+    \else
+      \setzzz#2\endsetzzz
+    \fi
+  }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+  {%
+    \makevalueexpandable
+    \global\expandafter\let\csname SET#1\endcsname=\relax
+  }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+  \catcode`\- = \active \catcode`\_ = \active
+  %
+  \gdef\makevalueexpandable{%
+    \let\value = \expandablevalue
+    % We don't want these characters active, ...
+    \catcode`\-=\other \catcode`\_=\other
+    % ..., but we might end up with active ones in the argument if
+    % we're called from @code, as @code{@value{foo-bar_}}, though.
+    % So \let them to their normal equivalents.
+    \let-\realdash \let_\normalunderscore
+  }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file.  This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+  \expandafter\ifx\csname SET#1\endcsname\relax
+    {[No value for ``#1'']}%
+    \message{Variable `#1', used in @value, is not set.}%
+  \else
+    \csname SET#1\endcsname
+  \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+  {%
+    \makevalueexpandable
+    \let\next=\empty
+    \expandafter\ifx\csname SET#2\endcsname\relax
+      #1% If not set, redefine \next.
+    \fi
+    \expandafter
+  }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @dircategory CATEGORY  -- specify a category of the dir file
+% which this file should belong to.  Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index.  The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+  \iflinks
+    \expandafter\newwrite \csname#1indfile\endcsname
+    \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+  \fi
+  \expandafter\xdef\csname#1index\endcsname{%     % Define @#1index
+    \noexpand\doindex{#1}}
+}
+
+% @defindex foo  ==  \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+  \iflinks
+    \expandafter\newwrite \csname#1indfile\endcsname
+    \openout \csname#1indfile\endcsname \jobname.#1
+  \fi
+  \expandafter\xdef\csname#1index\endcsname{%
+    \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar    makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar   similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+  % Only do \closeout if we haven't already done it, else we'll end up
+  % closing the target index.
+  \expandafter \ifx\csname donesynindex#2\endcsname \undefined
+    % The \closeout helps reduce unnecessary open files; the limit on the
+    % Acorn RISC OS is a mere 16 files.
+    \expandafter\closeout\csname#2indfile\endcsname
+    \expandafter\let\csname\donesynindex#2\endcsname = 1
+  \fi
+  % redefine \fooindfile:
+  \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+  \expandafter\let\csname#2indfile\endcsname=\temp
+  % redefine \fooindex:
+  \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+%  and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+  \escapechar = `\\     % use backslash in output files.
+  \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+  \def\ {\realbackslash\space }%
+  %
+  % Need these in case \tex is in effect and \{ is a \delimiter again.
+  % But can't use \lbracecmd and \rbracecmd because texindex assumes
+  % braces and backslashes are used only as delimiters.
+  \let\{ = \mylbrace
+  \let\} = \myrbrace
+  %
+  % I don't entirely understand this, but when an index entry is
+  % generated from a macro call, the \endinput which \scanmacro inserts
+  % causes processing to be prematurely terminated.  This is,
+  % apparently, because \indexsorttmp is fully expanded, and \endinput
+  % is an expandable command.  The redefinition below makes \endinput
+  % disappear altogether for that purpose -- although logging shows that
+  % processing continues to some further point.  On the other hand, it
+  % seems \endinput does not hurt in the printed index arg, since that
+  % is still getting written without apparent harm.
+  %
+  % Sample source (mac-idx3.tex, reported by Graham Percival to
+  % help-texinfo, 22may06):
+  % @macro funindex {WORD}
+  % @findex xyz
+  % @end macro
+  % ...
+  % @funindex commtest
+  %
+  % The above is not enough to reproduce the bug, but it gives the flavor.
+  %
+  % Sample whatsit resulting:
+  % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
+  %
+  % So:
+  \let\endinput = \empty
+  %
+  % Do the redefinitions.
+  \commondummies
+}
+
+% For the aux and toc files, @ is the escape character.  So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files).  When everything uses @,
+% this will be simpler.
+%
+\def\atdummies{%
+  \def\@{@@}%
+  \def\ {@ }%
+  \let\{ = \lbraceatcmd
+  \let\} = \rbraceatcmd
+  %
+  % Do the redefinitions.
+  \commondummies
+  \otherbackslash
+}
+
+% Called from \indexdummies and \atdummies.
+%
+\def\commondummies{%
+  %
+  % \definedummyword defines \#1 as \string\#1\space, thus effectively
+  % preventing its expansion.  This is used only for control% words,
+  % not control letters, because the \space would be incorrect for
+  % control characters, but is needed to separate the control word
+  % from whatever follows.
+  %
+  % For control letters, we have \definedummyletter, which omits the
+  % space.
+  %
+  % These can be used both for control words that take an argument and
+  % those that do not.  If it is followed by {arg} in the input, then
+  % that will dutifully get written to the index (or wherever).
+  %
+  \def\definedummyword  ##1{\def##1{\string##1\space}}%
+  \def\definedummyletter##1{\def##1{\string##1}}%
+  \let\definedummyaccent\definedummyletter
+  %
+  \commondummiesnofonts
+  %
+  \definedummyletter\_%
+  %
+  % Non-English letters.
+  \definedummyword\AA
+  \definedummyword\AE
+  \definedummyword\L
+  \definedummyword\OE
+  \definedummyword\O
+  \definedummyword\aa
+  \definedummyword\ae
+  \definedummyword\l
+  \definedummyword\oe
+  \definedummyword\o
+  \definedummyword\ss
+  \definedummyword\exclamdown
+  \definedummyword\questiondown
+  \definedummyword\ordf
+  \definedummyword\ordm
+  %
+  % Although these internal commands shouldn't show up, sometimes they do.
+  \definedummyword\bf
+  \definedummyword\gtr
+  \definedummyword\hat
+  \definedummyword\less
+  \definedummyword\sf
+  \definedummyword\sl
+  \definedummyword\tclose
+  \definedummyword\tt
+  %
+  \definedummyword\LaTeX
+  \definedummyword\TeX
+  %
+  % Assorted special characters.
+  \definedummyword\bullet
+  \definedummyword\comma
+  \definedummyword\copyright
+  \definedummyword\registeredsymbol
+  \definedummyword\dots
+  \definedummyword\enddots
+  \definedummyword\equiv
+  \definedummyword\error
+  \definedummyword\euro
+  \definedummyword\guillemetleft
+  \definedummyword\guillemetright
+  \definedummyword\guilsinglleft
+  \definedummyword\guilsinglright
+  \definedummyword\expansion
+  \definedummyword\minus
+  \definedummyword\pounds
+  \definedummyword\point
+  \definedummyword\print
+  \definedummyword\quotedblbase
+  \definedummyword\quotedblleft
+  \definedummyword\quotedblright
+  \definedummyword\quoteleft
+  \definedummyword\quoteright
+  \definedummyword\quotesinglbase
+  \definedummyword\result
+  \definedummyword\textdegree
+  %
+  % We want to disable all macros so that they are not expanded by \write.
+  \macrolist
+  %
+  \normalturnoffactive
+  %
+  % Handle some cases of @value -- where it does not contain any
+  % (non-fully-expandable) commands.
+  \makevalueexpandable
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+\def\commondummiesnofonts{%
+  % Control letters and accents.
+  \definedummyletter\!%
+  \definedummyaccent\"%
+  \definedummyaccent\'%
+  \definedummyletter\*%
+  \definedummyaccent\,%
+  \definedummyletter\.%
+  \definedummyletter\/%
+  \definedummyletter\:%
+  \definedummyaccent\=%
+  \definedummyletter\?%
+  \definedummyaccent\^%
+  \definedummyaccent\`%
+  \definedummyaccent\~%
+  \definedummyword\u
+  \definedummyword\v
+  \definedummyword\H
+  \definedummyword\dotaccent
+  \definedummyword\ringaccent
+  \definedummyword\tieaccent
+  \definedummyword\ubaraccent
+  \definedummyword\udotaccent
+  \definedummyword\dotless
+  %
+  % Texinfo font commands.
+  \definedummyword\b
+  \definedummyword\i
+  \definedummyword\r
+  \definedummyword\sc
+  \definedummyword\t
+  %
+  % Commands that take arguments.
+  \definedummyword\acronym
+  \definedummyword\cite
+  \definedummyword\code
+  \definedummyword\command
+  \definedummyword\dfn
+  \definedummyword\emph
+  \definedummyword\env
+  \definedummyword\file
+  \definedummyword\kbd
+  \definedummyword\key
+  \definedummyword\math
+  \definedummyword\option
+  \definedummyword\pxref
+  \definedummyword\ref
+  \definedummyword\samp
+  \definedummyword\strong
+  \definedummyword\tie
+  \definedummyword\uref
+  \definedummyword\url
+  \definedummyword\var
+  \definedummyword\verb
+  \definedummyword\w
+  \definedummyword\xref
+}
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names.  It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+  % Accent commands should become @asis.
+  \def\definedummyaccent##1{\let##1\asis}%
+  % We can just ignore other control letters.
+  \def\definedummyletter##1{\let##1\empty}%
+  % Hopefully, all control words can become @asis.
+  \let\definedummyword\definedummyaccent
+  %
+  \commondummiesnofonts
+  %
+  % Don't no-op \tt, since it isn't a user-level command
+  % and is used in the definitions of the active chars like <, >, |, etc.
+  % Likewise with the other plain tex font commands.
+  %\let\tt=\asis
+  %
+  \def\ { }%
+  \def\@{@}%
+  % how to handle braces?
+  \def\_{\normalunderscore}%
+  %
+  % Non-English letters.
+  \def\AA{AA}%
+  \def\AE{AE}%
+  \def\L{L}%
+  \def\OE{OE}%
+  \def\O{O}%
+  \def\aa{aa}%
+  \def\ae{ae}%
+  \def\l{l}%
+  \def\oe{oe}%
+  \def\o{o}%
+  \def\ss{ss}%
+  \def\exclamdown{!}%
+  \def\questiondown{?}%
+  \def\ordf{a}%
+  \def\ordm{o}%
+  %
+  \def\LaTeX{LaTeX}%
+  \def\TeX{TeX}%
+  %
+  % Assorted special characters.
+  % (The following {} will end up in the sort string, but that's ok.)
+  \def\bullet{bullet}%
+  \def\comma{,}%
+  \def\copyright{copyright}%
+  \def\registeredsymbol{R}%
+  \def\dots{...}%
+  \def\enddots{...}%
+  \def\equiv{==}%
+  \def\error{error}%
+  \def\euro{euro}%
+  \def\guillemetleft{<<}%
+  \def\guillemetright{>>}%
+  \def\guilsinglleft{<}%
+  \def\guilsinglright{>}%
+  \def\expansion{==>}%
+  \def\minus{-}%
+  \def\pounds{pounds}%
+  \def\point{.}%
+  \def\print{-|}%
+  \def\quotedblbase{"}%
+  \def\quotedblleft{"}%
+  \def\quotedblright{"}%
+  \def\quoteleft{`}%
+  \def\quoteright{'}%
+  \def\quotesinglbase{,}%
+  \def\result{=>}%
+  \def\textdegree{degrees}%
+  %
+  % We need to get rid of all macros, leaving only the arguments (if present).
+  % Of course this is not nearly correct, but it is the best we can do for now.
+  % makeinfo does not expand macros in the argument to @deffn, which ends up
+  % writing an index entry, and texindex isn't prepared for an index sort entry
+  % that starts with \.
+  %
+  % Since macro invocations are followed by braces, we can just redefine them
+  % to take a single TeX argument.  The case of a macro invocation that
+  % goes to end-of-line is not handled.
+  %
+  \macrolist
+}
+
+\let\indexbackslash=0  %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+  \iflinks
+  {%
+    % Store the main index entry text (including the third arg).
+    \toks0 = {#2}%
+    % If third arg is present, precede it with a space.
+    \def\thirdarg{#3}%
+    \ifx\thirdarg\empty \else
+      \toks0 = \expandafter{\the\toks0 \space #3}%
+    \fi
+    %
+    \edef\writeto{\csname#1indfile\endcsname}%
+    %
+    \safewhatsit\dosubindwrite
+  }%
+  \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+  % Put the index entry in the margin if desired.
+  \ifx\SETmarginindex\relax\else
+    \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+  \fi
+  %
+  % Remember, we are within a group.
+  \indexdummies % Must do this here, since \bf, etc expand at this stage
+  \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+      % so it will be output as is; and it will print as backslash.
+  %
+  % Process the index entry with all font commands turned off, to
+  % get the string to sort by.
+  {\indexnofonts
+   \edef\temp{\the\toks0}% need full expansion
+   \xdef\indexsorttmp{\temp}%
+  }%
+  %
+  % Set up the complete index entry, with both the sort key and
+  % the original text, including any font commands.  We write
+  % three arguments to \entry to the .?? file (four in the
+  % subentry case), texindex reduces to two when writing the .??s
+  % sorted result.
+  \edef\temp{%
+    \write\writeto{%
+      \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+  }%
+  \temp
+}
+
+% Take care of unwanted page breaks/skips around a whatsit:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again.  Otherwise, the whatsit generated by the
+% \write or \pdfdest will make \lastskip zero.  The result is that
+% sequences like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode.  We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip.  \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip.  The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+\newskip\whatsitskip
+\newcount\whatsitpenalty
+%
+% ..., ready, GO:
+%
+\def\safewhatsit#1{%
+\ifhmode
+  #1%
+\else
+  % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+  \whatsitskip = \lastskip
+  \edef\lastskipmacro{\the\lastskip}%
+  \whatsitpenalty = \lastpenalty
+  %
+  % If \lastskip is nonzero, that means the last item was a
+  % skip.  And since a skip is discardable, that means this
+  % -\whatsitskip glue we're inserting is preceded by a
+  % non-discardable item, therefore it is not a potential
+  % breakpoint, therefore no \nobreak needed.
+  \ifx\lastskipmacro\zeroskipmacro
+  \else
+    \vskip-\whatsitskip
+  \fi
+  %
+  #1%
+  %
+  \ifx\lastskipmacro\zeroskipmacro
+    % If \lastskip was zero, perhaps the last item was a penalty, and
+    % perhaps it was >=10000, e.g., a \nobreak.  In that case, we want
+    % to re-insert the same penalty (values >10000 are used for various
+    % signals); since we just inserted a non-discardable item, any
+    % following glue (such as a \parskip) would be a breakpoint.  For example:
+    %
+    %   @deffn deffn-whatever
+    %   @vindex index-whatever
+    %   Description.
+    % would allow a break between the index-whatever whatsit
+    % and the "Description." paragraph.
+    \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi
+  \else
+    % On the other hand, if we had a nonzero \lastskip,
+    % this make-up glue would be preceded by a non-discardable item
+    % (the whatsit from the \write), so we must insert a \nobreak.
+    \nobreak\vskip\whatsitskip
+  \fi
+\fi
+}
+
+% The index entry written in the file actually looks like
+%  \entry {sortstring}{page}{topic}
+% or
+%  \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+%  \initial {c}
+%     before the first topic whose initial is c
+%  \entry {topic}{pagelist}
+%     for a topic that is used without subtopics
+%  \primary {topic}
+%     for the beginning of a topic that is used with subtopics
+%  \secondary {subtopic}{pagelist}
+%     for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+  \dobreak \chapheadingskip{10000}%
+  %
+  \smallfonts \rm
+  \tolerance = 9500
+  \plainfrenchspacing
+  \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+  %
+  % See if the index file exists and is nonempty.
+  % Change catcode of @ here so that if the index file contains
+  % \initial {@}
+  % as its first line, TeX doesn't complain about mismatched braces
+  % (because it thinks @} is a control sequence).
+  \catcode`\@ = 11
+  \openin 1 \jobname.#1s
+  \ifeof 1
+    % \enddoublecolumns gets confused if there is no text in the index,
+    % and it loses the chapter title and the aux file entries for the
+    % index.  The easiest way to prevent this problem is to make sure
+    % there is some text.
+    \putwordIndexNonexistent
+  \else
+    %
+    % If the index file exists but is empty, then \openin leaves \ifeof
+    % false.  We have to make TeX try to read something from the file, so
+    % it can discover if there is anything in it.
+    \read 1 to \temp
+    \ifeof 1
+      \putwordIndexIsEmpty
+    \else
+      % Index files are almost Texinfo source, but we use \ as the escape
+      % character.  It would be better to use @, but that's too big a change
+      % to make right now.
+      \def\indexbackslash{\backslashcurfont}%
+      \catcode`\\ = 0
+      \escapechar = `\\
+      \begindoublecolumns
+      \input \jobname.#1s
+      \enddoublecolumns
+    \fi
+  \fi
+  \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+  % Some minor font changes for the special characters.
+  \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+  %
+  % Remove any glue we may have, we'll be inserting our own.
+  \removelastskip
+  %
+  % We like breaks before the index initials, so insert a bonus.
+  \nobreak
+  \vskip 0pt plus 3\baselineskip
+  \penalty 0
+  \vskip 0pt plus -3\baselineskip
+  %
+  % Typeset the initial.  Making this add up to a whole number of
+  % baselineskips increases the chance of the dots lining up from column
+  % to column.  It still won't often be perfect, because of the stretch
+  % we need before each entry, but it's better.
+  %
+  % No shrink because it confuses \balancecolumns.
+  \vskip 1.67\baselineskip plus .5\baselineskip
+  \leftline{\secbf #1}%
+  % Do our best not to break after the initial.
+  \nobreak
+  \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin.  It is used for index
+% and table of contents entries.  The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+%	\def\entry#1#2{...
+% But this frozes the catcodes in the argument, and can cause problems to
+% @code, which sets - active.  This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+%
+% The right solution is to prevent \entry from swallowing the whole text.
+%                                 --kasal, 21nov03
+\def\entry{%
+  \begingroup
+    %
+    % Start a new paragraph if necessary, so our assignments below can't
+    % affect previous text.
+    \par
+    %
+    % Do not fill out the last line with white space.
+    \parfillskip = 0in
+    %
+    % No extra space above this paragraph.
+    \parskip = 0in
+    %
+    % Do not prefer a separate line ending with a hyphen to fewer lines.
+    \finalhyphendemerits = 0
+    %
+    % \hangindent is only relevant when the entry text and page number
+    % don't both fit on one line.  In that case, bob suggests starting the
+    % dots pretty far over on the line.  Unfortunately, a large
+    % indentation looks wrong when the entry text itself is broken across
+    % lines.  So we use a small indentation and put up with long leaders.
+    %
+    % \hangafter is reset to 1 (which is the value we want) at the start
+    % of each paragraph, so we need not do anything with that.
+    \hangindent = 2em
+    %
+    % When the entry text needs to be broken, just fill out the first line
+    % with blank space.
+    \rightskip = 0pt plus1fil
+    %
+    % A bit of stretch before each entry for the benefit of balancing
+    % columns.
+    \vskip 0pt plus1pt
+    %
+    % Swallow the left brace of the text (first parameter):
+    \afterassignment\doentry
+    \let\temp =
+}
+\def\doentry{%
+    \bgroup % Instead of the swallowed brace.
+      \noindent
+      \aftergroup\finishentry
+      % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+    % #1 is the page number.
+    %
+    % The following is kludged to not output a line of dots in the index if
+    % there are no page numbers.  The next person who breaks this will be
+    % cursed by a Unix daemon.
+    \setbox\boxA = \hbox{#1}%
+    \ifdim\wd\boxA = 0pt
+      \ %
+    \else
+      %
+      % If we must, put the page number on a line of its own, and fill out
+      % this line with blank space.  (The \hfil is overwhelmed with the
+      % fill leaders glue in \indexdotfill if the page number does fit.)
+      \hfil\penalty50
+      \null\nobreak\indexdotfill % Have leaders before the page number.
+      %
+      % The `\ ' here is removed by the implicit \unskip that TeX does as
+      % part of (the primitive) \par.  Without it, a spurious underfull
+      % \hbox ensues.
+      \ifpdf
+	\pdfgettoks#1.%
+	\ \the\toksA
+      \else
+	\ #1%
+      \fi
+    \fi
+    \par
+  \endgroup
+}
+
+% Like plain.tex's \dotfill, except uses up at least 1 em.
+\def\indexdotfill{\cleaders
+  \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+  \parfillskip=0in
+  \parskip=0in
+  \hangindent=1in
+  \hangafter=1
+  \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+  \ifpdf
+    \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+  \else
+    #2
+  \fi
+  \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+  % Grab any single-column material above us.
+  \output = {%
+    %
+    % Here is a possibility not foreseen in manmac: if we accumulate a
+    % whole lot of material, we might end up calling this \output
+    % routine twice in a row (see the doublecol-lose test, which is
+    % essentially a couple of indexes with @setchapternewpage off).  In
+    % that case we just ship out what is in \partialpage with the normal
+    % output routine.  Generally, \partialpage will be empty when this
+    % runs and this will be a no-op.  See the indexspread.tex test case.
+    \ifvoid\partialpage \else
+      \onepageout{\pagecontents\partialpage}%
+    \fi
+    %
+    \global\setbox\partialpage = \vbox{%
+      % Unvbox the main output page.
+      \unvbox\PAGE
+      \kern-\topskip \kern\baselineskip
+    }%
+  }%
+  \eject % run that output routine to set \partialpage
+  %
+  % Use the double-column output routine for subsequent pages.
+  \output = {\doublecolumnout}%
+  %
+  % Change the page size parameters.  We could do this once outside this
+  % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+  % format, but then we repeat the same computation.  Repeating a couple
+  % of assignments once per index is clearly meaningless for the
+  % execution time, so we may as well do it in one place.
+  %
+  % First we halve the line length, less a little for the gutter between
+  % the columns.  We compute the gutter based on the line length, so it
+  % changes automatically with the paper format.  The magic constant
+  % below is chosen so that the gutter has the same value (well, +-<1pt)
+  % as it did when we hard-coded it.
+  %
+  % We put the result in a separate register, \doublecolumhsize, so we
+  % can restore it in \pagesofar, after \hsize itself has (potentially)
+  % been clobbered.
+  %
+  \doublecolumnhsize = \hsize
+    \advance\doublecolumnhsize by -.04154\hsize
+    \divide\doublecolumnhsize by 2
+  \hsize = \doublecolumnhsize
+  %
+  % Double the \vsize as well.  (We don't need a separate register here,
+  % since nobody clobbers \vsize.)
+  \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+  \splittopskip=\topskip \splitmaxdepth=\maxdepth
+  % Get the available space for the double columns -- the normal
+  % (undoubled) page height minus any material left over from the
+  % previous page.
+  \dimen@ = \vsize
+  \divide\dimen@ by 2
+  \advance\dimen@ by -\ht\partialpage
+  %
+  % box0 will be the left-hand column, box2 the right.
+  \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+  \onepageout\pagesofar
+  \unvbox255
+  \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+  \unvbox\partialpage
+  %
+  \hsize = \doublecolumnhsize
+  \wd0=\hsize \wd2=\hsize
+  \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+  % The following penalty ensures that the page builder is exercised
+  % _before_ we change the output routine.  This is necessary in the
+  % following situation:
+  %
+  % The last section of the index consists only of a single entry.
+  % Before this section, \pagetotal is less than \pagegoal, so no
+  % break occurs before the last section starts.  However, the last
+  % section, consisting of \initial and the single \entry, does not
+  % fit on the page and has to be broken off.  Without the following
+  % penalty the page builder will not be exercised until \eject
+  % below, and by that time we'll already have changed the output
+  % routine to the \balancecolumns version, so the next-to-last
+  % double-column page will be processed with \balancecolumns, which
+  % is wrong:  The two columns will go to the main vertical list, with
+  % the broken-off section in the recent contributions.  As soon as
+  % the output routine finishes, TeX starts reconsidering the page
+  % break.  The two columns and the broken-off section both fit on the
+  % page, because the two columns now take up only half of the page
+  % goal.  When TeX sees \eject from below which follows the final
+  % section, it invokes the new output routine that we've set after
+  % \balancecolumns below; \onepageout will try to fit the two columns
+  % and the final section into the vbox of \pageheight (see
+  % \pagebody), causing an overfull box.
+  %
+  % Note that glue won't work here, because glue does not exercise the
+  % page builder, unlike penalties (see The TeXbook, pp. 280-281).
+  \penalty0
+  %
+  \output = {%
+    % Split the last of the double-column material.  Leave it on the
+    % current page, no automatic page break.
+    \balancecolumns
+    %
+    % If we end up splitting too much material for the current page,
+    % though, there will be another page break right after this \output
+    % invocation ends.  Having called \balancecolumns once, we do not
+    % want to call it again.  Therefore, reset \output to its normal
+    % definition right away.  (We hope \balancecolumns will never be
+    % called on to balance too much material, but if it is, this makes
+    % the output somewhat more palatable.)
+    \global\output = {\onepageout{\pagecontents\PAGE}}%
+  }%
+  \eject
+  \endgroup % started in \begindoublecolumns
+  %
+  % \pagegoal was set to the doubled \vsize above, since we restarted
+  % the current page.  We're now back to normal single-column
+  % typesetting, so reset \pagegoal to the normal \vsize (after the
+  % \endgroup where \vsize got restored).
+  \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+  \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+  \dimen@ = \ht0
+  \advance\dimen@ by \topskip
+  \advance\dimen@ by-\baselineskip
+  \divide\dimen@ by 2 % target to split to
+  %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
+  \splittopskip = \topskip
+  % Loop until we get a decent breakpoint.
+  {%
+    \vbadness = 10000
+    \loop
+      \global\setbox3 = \copy0
+      \global\setbox1 = \vsplit3 to \dimen@
+    \ifdim\ht3>\dimen@
+      \global\advance\dimen@ by 1pt
+    \repeat
+  }%
+  %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+  \setbox0=\vbox to\dimen@{\unvbox1}%
+  \setbox2=\vbox to\dimen@{\unvbox3}%
+  %
+  \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% \unnumberedno is an oxymoron, of course.  But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number".  We avoid collisions with chapter
+% numbers by starting them at 10000.  (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno        \secno=0
+\newcount\subsecno     \subsecno=0
+\newcount\subsubsecno  \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno  \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+  \ifnum\appendixno=`A A%
+  \else\ifnum\appendixno=`B B%
+  \else\ifnum\appendixno=`C C%
+  \else\ifnum\appendixno=`D D%
+  \else\ifnum\appendixno=`E E%
+  \else\ifnum\appendixno=`F F%
+  \else\ifnum\appendixno=`G G%
+  \else\ifnum\appendixno=`H H%
+  \else\ifnum\appendixno=`I I%
+  \else\ifnum\appendixno=`J J%
+  \else\ifnum\appendixno=`K K%
+  \else\ifnum\appendixno=`L L%
+  \else\ifnum\appendixno=`M M%
+  \else\ifnum\appendixno=`N N%
+  \else\ifnum\appendixno=`O O%
+  \else\ifnum\appendixno=`P P%
+  \else\ifnum\appendixno=`Q Q%
+  \else\ifnum\appendixno=`R R%
+  \else\ifnum\appendixno=`S S%
+  \else\ifnum\appendixno=`T T%
+  \else\ifnum\appendixno=`U U%
+  \else\ifnum\appendixno=`V V%
+  \else\ifnum\appendixno=`W W%
+  \else\ifnum\appendixno=`X X%
+  \else\ifnum\appendixno=`Y Y%
+  \else\ifnum\appendixno=`Z Z%
+  % The \the is necessary, despite appearances, because \appendixletter is
+  % expanded while writing the .toc file.  \char\appendixno is not
+  % expandable, thus it is written literally, thus all appendixes come out
+  % with the same letter (or @) in the toc without it.
+  \else\char\the\appendixno
+  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines these (using marks) as the number+name, number
+% and name of the chapter.  Page headings and footings can use
+% these.  @section does likewise.
+\def\thischapter{}
+\def\thischapternum{}
+\def\thischaptername{}
+\def\thissection{}
+\def\thissectionnum{}
+\def\thissectionname{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achive this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unmlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+  % Compute the abs. sec. level:
+  \absseclevel=#2
+  \advance\absseclevel by \secbase
+  % Make sure \absseclevel doesn't fall outside the range:
+  \ifnum \absseclevel < 0
+    \absseclevel = 0
+  \else
+    \ifnum \absseclevel > 3
+      \absseclevel = 3
+    \fi
+  \fi
+  % The heading type:
+  \def\headtype{#1}%
+  \if \headtype U%
+    \ifnum \absseclevel < \unmlevel
+      \chardef\unmlevel = \absseclevel
+    \fi
+  \else
+    % Check for appendix sections:
+    \ifnum \absseclevel = 0
+      \edef\chapheadtype{\headtype}%
+    \else
+      \if \headtype A\if \chapheadtype N%
+	\errmessage{@appendix... within a non-appendix chapter}%
+      \fi\fi
+    \fi
+    % Check for numbered within unnumbered:
+    \ifnum \absseclevel > \unmlevel
+      \def\headtype{U}%
+    \else
+      \chardef\unmlevel = 3
+    \fi
+  \fi
+  % Now print the heading:
+  \if \headtype U%
+    \ifcase\absseclevel
+	\unnumberedzzz{#3}%
+    \or \unnumberedseczzz{#3}%
+    \or \unnumberedsubseczzz{#3}%
+    \or \unnumberedsubsubseczzz{#3}%
+    \fi
+  \else
+    \if \headtype A%
+      \ifcase\absseclevel
+	  \appendixzzz{#3}%
+      \or \appendixsectionzzz{#3}%
+      \or \appendixsubseczzz{#3}%
+      \or \appendixsubsubseczzz{#3}%
+      \fi
+    \else
+      \ifcase\absseclevel
+	  \chapterzzz{#3}%
+      \or \seczzz{#3}%
+      \or \numberedsubseczzz{#3}%
+      \or \numberedsubsubseczzz{#3}%
+      \fi
+    \fi
+  \fi
+  \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered.  Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v.  By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+  % section resetting is \global in case the chapter is in a group, such
+  % as an @include file.
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\chapno by 1
+  %
+  % Used for \float.
+  \gdef\chaplevelprefix{\the\chapno.}%
+  \resetallfloatnos
+  %
+  \message{\putwordChapter\space \the\chapno}%
+  %
+  % Write the actual heading.
+  \chapmacro{#1}{Ynumbered}{\the\chapno}%
+  %
+  % So @section and the like are numbered underneath this chapter.
+  \global\let\section = \numberedsec
+  \global\let\subsection = \numberedsubsec
+  \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz#1{%
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\appendixno by 1
+  \gdef\chaplevelprefix{\appendixletter.}%
+  \resetallfloatnos
+  %
+  \def\appendixnum{\putwordAppendix\space \appendixletter}%
+  \message{\appendixnum}%
+  %
+  \chapmacro{#1}{Yappendix}{\appendixletter}%
+  %
+  \global\let\section = \appendixsec
+  \global\let\subsection = \appendixsubsec
+  \global\let\subsubsection = \appendixsubsubsec
+}
+
+\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz#1{%
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\unnumberedno by 1
+  %
+  % Since an unnumbered has no number, no prefix for figures.
+  \global\let\chaplevelprefix = \empty
+  \resetallfloatnos
+  %
+  % This used to be simply \message{#1}, but TeX fully expands the
+  % argument to \message.  Therefore, if #1 contained @-commands, TeX
+  % expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
+  % expanded @cite (which turns out to cause errors because \cite is meant
+  % to be executed, not expanded).
+  %
+  % Anyway, we don't want the fully-expanded definition of @cite to appear
+  % as a result of the \message, we just want `@cite' itself.  We use
+  % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+  % simply yielding the contents of <toks register>.  (We also do this for
+  % the toc entries.)
+  \toks0 = {#1}%
+  \message{(\the\toks0)}%
+  %
+  \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+  %
+  \global\let\section = \unnumberedsec
+  \global\let\subsection = \unnumberedsubsec
+  \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+  % Well, we could do the following in a group, but that would break
+  % an assumption that \chapmacro is called at the outermost level.
+  % Thus we are safer this way:		--kasal, 24feb04
+  \let\centerparametersmaybe = \centerparameters
+  \unnmhead0{#1}%
+  \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Yappendix}%
+                 {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Ynothing}%
+                 {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Ynumbered}%
+                 {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Yappendix}%
+                 {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Ynothing}%
+                 {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and such:
+%       1) We use \vbox rather than the earlier \line to permit
+%          overlong headings to fold.
+%       2) \hyphenpenalty is set to 10000 because hyphenation in a
+%          heading is obnoxious; this forbids it.
+%       3) Likewise, headings look best if no \parindent is used, and
+%          if justification is not attempted.  Hence \raggedright.
+
+
+\def\majorheading{%
+  {\advance\chapheadingskip by 10pt \chapbreak }%
+  \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+  {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                    \parindent=0pt\raggedright
+                    \rm #1\hfill}}%
+  \bigskip \par\penalty 200\relax
+  \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip\chapheadingskip
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+% Because \domark is called before \chapoddpage, the filler page will
+% get the headings for the next chapter, which is wrong.  But we don't
+% care -- we just disable all headings on the filler page.
+\def\chapoddpage{%
+  \chappager
+  \ifodd\pageno \else
+    \begingroup
+      \evenheadline={\hfil}\evenfootline={\hfil}%
+      \oddheadline={\hfil}\oddfootline={\hfil}%
+      \hbox to 0pt{}%
+      \chappager
+    \endgroup
+  \fi
+}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+  % Insert the first mark before the heading break (see notes for \domark).
+  \let\prevchapterdefs=\lastchapterdefs
+  \let\prevsectiondefs=\lastsectiondefs
+  \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}%
+                        \gdef\thissection{}}%
+  %
+  \def\temptype{#2}%
+  \ifx\temptype\Ynothingkeyword
+    \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+                          \gdef\thischapter{\thischaptername}}%
+  \else\ifx\temptype\Yomitfromtockeyword
+    \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+                          \gdef\thischapter{}}%
+  \else\ifx\temptype\Yappendixkeyword
+    \toks0={#1}%
+    \xdef\lastchapterdefs{%
+      \gdef\noexpand\thischaptername{\the\toks0}%
+      \gdef\noexpand\thischapternum{\appendixletter}%
+      \gdef\noexpand\thischapter{\putwordAppendix{} \noexpand\thischapternum:
+                                 \noexpand\thischaptername}%
+    }%
+  \else
+    \toks0={#1}%
+    \xdef\lastchapterdefs{%
+      \gdef\noexpand\thischaptername{\the\toks0}%
+      \gdef\noexpand\thischapternum{\the\chapno}%
+      \gdef\noexpand\thischapter{\putwordChapter{} \noexpand\thischapternum:
+                                 \noexpand\thischaptername}%
+    }%
+  \fi\fi\fi
+  %
+  % Output the mark.  Pass it through \safewhatsit, to take care of
+  % the preceding space.
+  \safewhatsit\domark
+  %
+  % Insert the chapter heading break.
+  \pchapsepmacro
+  %
+  % Now the second mark, after the heading break.  No break points
+  % between here and the heading.
+  \let\prevchapterdefs=\lastchapterdefs
+  \let\prevsectiondefs=\lastsectiondefs
+  \domark
+  %
+  {%
+    \chapfonts \rm
+    %
+    % Have to define \lastsection before calling \donoderef, because the
+    % xref code eventually uses it.  On the other hand, it has to be called
+    % after \pchapsepmacro, or the headline will change too soon.
+    \gdef\lastsection{#1}%
+    %
+    % Only insert the separating space if we have a chapter/appendix
+    % number, and don't print the unnumbered ``number''.
+    \ifx\temptype\Ynothingkeyword
+      \setbox0 = \hbox{}%
+      \def\toctype{unnchap}%
+    \else\ifx\temptype\Yomitfromtockeyword
+      \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+      \def\toctype{omit}%
+    \else\ifx\temptype\Yappendixkeyword
+      \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+      \def\toctype{app}%
+    \else
+      \setbox0 = \hbox{#3\enspace}%
+      \def\toctype{numchap}%
+    \fi\fi\fi
+    %
+    % Write the toc entry for this chapter.  Must come before the
+    % \donoderef, because we include the current node name in the toc
+    % entry, and \donoderef resets it to empty.
+    \writetocentry{\toctype}{#1}{#3}%
+    %
+    % For pdftex, we have to write out the node definition (aka, make
+    % the pdfdest) after any page break, but before the actual text has
+    % been typeset.  If the destination for the pdf outline is after the
+    % text, then jumping from the outline may wind up with the text not
+    % being visible, for instance under high magnification.
+    \donoderef{#2}%
+    %
+    % Typeset the actual heading.
+    \nobreak % Avoid page breaks at the interline glue.
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+          \hangindent=\wd0 \centerparametersmaybe
+          \unhbox0 #1\par}%
+  }%
+  \nobreak\bigskip % no page break after a chapter title
+  \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+  \advance\rightskip by 3\rightskip
+  \leftskip = \rightskip
+  \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff.  We'll see.  --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt\raggedright
+                       \rm #1\hfill}}\bigskip \par\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt
+                       \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
+}
+\def\CHAPFopen{%
+  \global\let\chapmacro=\chfopen
+  \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles.  These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\seckeyword{sec}
+%
+\def\sectionheading#1#2#3#4{%
+  {%
+    % Switch to the right set of fonts.
+    \csname #2fonts\endcsname \rm
+    %
+    \def\sectionlevel{#2}%
+    \def\temptype{#3}%
+    %
+    % Insert first mark before the heading break (see notes for \domark).
+    \let\prevsectiondefs=\lastsectiondefs
+    \ifx\temptype\Ynothingkeyword
+      \ifx\sectionlevel\seckeyword
+        \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}%
+                              \gdef\thissection{\thissectionname}}%
+      \fi
+    \else\ifx\temptype\Yomitfromtockeyword
+      % Don't redefine \thissection.
+    \else\ifx\temptype\Yappendixkeyword
+      \ifx\sectionlevel\seckeyword
+        \toks0={#1}%
+        \xdef\lastsectiondefs{%
+          \gdef\noexpand\thissectionname{\the\toks0}%
+          \gdef\noexpand\thissectionnum{#4}%
+          \gdef\noexpand\thissection{\putwordSection{} \noexpand\thissectionnum:
+                                     \noexpand\thissectionname}%
+        }%
+      \fi
+    \else
+      \ifx\sectionlevel\seckeyword
+        \toks0={#1}%
+        \xdef\lastsectiondefs{%
+          \gdef\noexpand\thissectionname{\the\toks0}%
+          \gdef\noexpand\thissectionnum{#4}%
+          \gdef\noexpand\thissection{\putwordSection{} \noexpand\thissectionnum:
+                                     \noexpand\thissectionname}%
+        }%
+      \fi
+    \fi\fi\fi
+    %
+    % Output the mark.  Pass it through \safewhatsit, to take care of
+    % the preceding space.
+    \safewhatsit\domark
+    %
+    % Insert space above the heading.
+    \csname #2headingbreak\endcsname
+    %
+    % Now the second mark, after the heading break.  No break points
+    % between here and the heading.
+    \let\prevsectiondefs=\lastsectiondefs
+    \domark
+    %
+    % Only insert the space after the number if we have a section number.
+    \ifx\temptype\Ynothingkeyword
+      \setbox0 = \hbox{}%
+      \def\toctype{unn}%
+      \gdef\lastsection{#1}%
+    \else\ifx\temptype\Yomitfromtockeyword
+      % for @headings -- no section number, don't include in toc,
+      % and don't redefine \lastsection.
+      \setbox0 = \hbox{}%
+      \def\toctype{omit}%
+      \let\sectionlevel=\empty
+    \else\ifx\temptype\Yappendixkeyword
+      \setbox0 = \hbox{#4\enspace}%
+      \def\toctype{app}%
+      \gdef\lastsection{#1}%
+    \else
+      \setbox0 = \hbox{#4\enspace}%
+      \def\toctype{num}%
+      \gdef\lastsection{#1}%
+    \fi\fi\fi
+    %
+    % Write the toc entry (before \donoderef).  See comments in \chapmacro.
+    \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+    %
+    % Write the node reference (= pdf destination for pdftex).
+    % Again, see comments in \chapmacro.
+    \donoderef{#3}%
+    %
+    % Interline glue will be inserted when the vbox is completed.
+    % That glue will be a valid breakpoint for the page, since it'll be
+    % preceded by a whatsit (usually from the \donoderef, or from the
+    % \writetocentry if there was no node).  We don't want to allow that
+    % break, since then the whatsits could end up on page n while the
+    % section is on page n+1, thus toc/etc. are wrong.  Debian bug 276000.
+    \nobreak
+    %
+    % Output the actual section heading.
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+          \hangindent=\wd0  % zero if no section number
+          \unhbox0 #1}%
+  }%
+  % Add extra space after the heading -- half of whatever came above it.
+  % Don't allow stretch, though.
+  \kern .5 \csname #2headingskip\endcsname
+  %
+  % Do not let the kern be a potential breakpoint, as it would be if it
+  % was followed by glue.
+  \nobreak
+  %
+  % We'll almost certainly start a paragraph next, so don't let that
+  % glue accumulate.  (Not a breakpoint because it's preceded by a
+  % discardable item.)
+  \vskip-\parskip
+  %
+  % This is purely so the last item on the list is a known \penalty >
+  % 10000.  This is so \startdefun can avoid allowing breakpoints after
+  % section headings.  Otherwise, it would insert a valid breakpoint between:
+  %
+  %   @section sec-whatever
+  %   @deffn def-whatever
+  \penalty 10001
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this.  The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything.  This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+  \edef\writetoctype{#1}%
+  \ifx\writetoctype\omitkeyword \else
+    \iftocfileopened\else
+      \immediate\openout\tocfile = \jobname.toc
+      \global\tocfileopenedtrue
+    \fi
+    %
+    \iflinks
+      {\atdummies
+       \edef\temp{%
+         \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
+       \temp
+      }%
+    \fi
+  \fi
+  %
+  % Tell \shipout to create a pdf destination on each page, if we're
+  % writing pdf.  These are used in the table of contents.  We can't
+  % just write one on every page because the title pages are numbered
+  % 1 and 2 (the page numbers aren't printed), and so are the first
+  % two pages of the document.  Thus, we'd have two destinations named
+  % `1', and two named `2'.
+  \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+
+% These characters do not print properly in the Computer Modern roman
+% fonts, so we must take special care.  This is more or less redundant
+% with the Texinfo input format setup at the end of this file.
+%
+\def\activecatcodes{%
+  \catcode`\"=\active
+  \catcode`\$=\active
+  \catcode`\<=\active
+  \catcode`\>=\active
+  \catcode`\\=\active
+  \catcode`\^=\active
+  \catcode`\_=\active
+  \catcode`\|=\active
+  \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+  \setupdatafile
+  \activecatcodes
+  \input \tocreadfilename
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+  % If @setchapternewpage on, and @headings double, the contents should
+  % start on an odd page, unlike chapters.  Thus, we maintain
+  % \contentsalignmacro in parallel with \pagealignmacro.
+  % From: Torbjorn Granlund <tege@matematik.su.se>
+  \contentsalignmacro
+  \immediate\closeout\tocfile
+  %
+  % Don't need to put `Contents' or `Short Contents' in the headline.
+  % It is abundantly clear what they are.
+  \chapmacro{#1}{Yomitfromtoc}{}%
+  %
+  \savepageno = \pageno
+  \begingroup                  % Set up to handle contents files properly.
+    \raggedbottom              % Worry more about breakpoints than the bottom.
+    \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+    %
+    % Roman numerals for page numbers.
+    \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+% redefined for the two-volume lispref.  We always output on
+% \jobname.toc even if this is redefined.
+%
+\def\tocreadfilename{\jobname.toc}
+
+% Normal (long) toc.
+%
+\def\contents{%
+  \startcontents{\putwordTOC}%
+    \openin 1 \tocreadfilename\space
+    \ifeof 1 \else
+      \readtocfile
+    \fi
+    \vfill \eject
+    \contentsalignmacro % in case @setchapternewpage odd is in effect
+    \ifeof 1 \else
+      \pdfmakeoutlines
+    \fi
+    \closein 1
+  \endgroup
+  \lastnegativepageno = \pageno
+  \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+  \startcontents{\putwordShortTOC}%
+    %
+    \let\numchapentry = \shortchapentry
+    \let\appentry = \shortchapentry
+    \let\unnchapentry = \shortunnchapentry
+    % We want a true roman here for the page numbers.
+    \secfonts
+    \let\rm=\shortcontrm \let\bf=\shortcontbf
+    \let\sl=\shortcontsl \let\tt=\shortconttt
+    \rm
+    \hyphenpenalty = 10000
+    \advance\baselineskip by 1pt % Open it up a little.
+    \def\numsecentry##1##2##3##4{}
+    \let\appsecentry = \numsecentry
+    \let\unnsecentry = \numsecentry
+    \let\numsubsecentry = \numsecentry
+    \let\appsubsecentry = \numsecentry
+    \let\unnsubsecentry = \numsecentry
+    \let\numsubsubsecentry = \numsecentry
+    \let\appsubsubsecentry = \numsecentry
+    \let\unnsubsubsecentry = \numsecentry
+    \openin 1 \tocreadfilename\space
+    \ifeof 1 \else
+      \readtocfile
+    \fi
+    \closein 1
+    \vfill \eject
+    \contentsalignmacro % in case @setchapternewpage odd is in effect
+  \endgroup
+  \lastnegativepageno = \pageno
+  \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+  % This space should be enough, since a single number is .5em, and the
+  % widest letter (M) is 1em, at least in the Computer Modern fonts.
+  % But use \hss just in case.
+  % (This space doesn't include the extra space that gets added after
+  % the label; that gets put in by \shortchapentry above.)
+  %
+  % We'd like to right-justify chapter numbers, but that looks strange
+  % with appendix letters.  And right-justifying numbers and
+  % left-justifying letters looks strange when there is less than 10
+  % chapters.  Have to read the whole toc once to know how many chapters
+  % there are before deciding ...
+  \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+  \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+  % We use M since it's probably the widest letter.
+  \setbox0 = \hbox{\putwordAppendix{} M}%
+  \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+   \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+   \begingroup
+     \chapentryfonts
+     \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+   \endgroup
+   \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+  \secentryfonts \leftskip=\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+  \subsecentryfonts \leftskip=2\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+  \subsubsecentryfonts \leftskip=3\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, it should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \reducedsf error\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+   \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+   \advance\hsize by -2\dimen2 % Rules.
+   \vbox{%
+      \hrule height\dimen2
+      \hbox{\vrule width\dimen2 \kern3pt          % Space to left of text.
+         \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+         \kern3pt\vrule width\dimen2}% Space to right.
+      \hrule height\dimen2}
+    \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex    escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\envdef\tex{%
+  \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+  \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+  \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+  \catcode `\%=14
+  \catcode `\+=\other
+  \catcode `\"=\other
+  \catcode `\|=\other
+  \catcode `\<=\other
+  \catcode `\>=\other
+  \escapechar=`\\
+  %
+  \let\b=\ptexb
+  \let\bullet=\ptexbullet
+  \let\c=\ptexc
+  \let\,=\ptexcomma
+  \let\.=\ptexdot
+  \let\dots=\ptexdots
+  \let\equiv=\ptexequiv
+  \let\!=\ptexexclam
+  \let\i=\ptexi
+  \let\indent=\ptexindent
+  \let\noindent=\ptexnoindent
+  \let\{=\ptexlbrace
+  \let\+=\tabalign
+  \let\}=\ptexrbrace
+  \let\/=\ptexslash
+  \let\*=\ptexstar
+  \let\t=\ptext
+  \let\frenchspacing=\plainfrenchspacing
+  %
+  \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+  \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+  \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments.  \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical.  We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+  % =10000 instead of <10000 because of a special case in \itemzzz and
+  % \sectionheading, q.v.
+  \ifnum \lastpenalty=10000 \else
+    \advance\envskipamount by \parskip
+    \endgraf
+    \ifdim\lastskip<\envskipamount
+      \removelastskip
+      % it's not a good place to break if the last penalty was \nobreak
+      % or better ...
+      \ifnum\lastpenalty<10000 \penalty-50 \fi
+      \vskip\envskipamount
+    \fi
+  \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag.  If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+        \ctl\leaders\hrule height\circthick\hfil\ctr
+        \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+        \cbl\leaders\hrule height\circthick\hfil\cbr
+        \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+  \ifhmode\par\fi  % can't be in the midst of a paragraph.
+  \startsavinginserts
+  \lskip=\leftskip \rskip=\rightskip
+  \leftskip=0pt\rightskip=0pt % we want these *outside*.
+  \cartinner=\hsize \advance\cartinner by-\lskip
+  \advance\cartinner by-\rskip
+  \cartouter=\hsize
+  \advance\cartouter by 18.4pt	% allow for 3pt kerns on either
+				% side, and for 6pt waste from
+				% each corner char, and rule thickness
+  \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+  % Flag to tell @lisp, etc., not to narrow margin.
+  \let\nonarrowing = t%
+  \vbox\bgroup
+      \baselineskip=0pt\parskip=0pt\lineskip=0pt
+      \carttop
+      \hbox\bgroup
+	  \hskip\lskip
+	  \vrule\kern3pt
+	  \vbox\bgroup
+	      \kern3pt
+	      \hsize=\cartinner
+	      \baselineskip=\normbskip
+	      \lineskip=\normlskip
+	      \parskip=\normpskip
+	      \vskip -\parskip
+	      \comment % For explanation, see the end of \def\group.
+}
+\def\Ecartouche{%
+              \ifhmode\par\fi
+	      \kern3pt
+	  \egroup
+	  \kern3pt\vrule
+	  \hskip\rskip
+      \egroup
+      \cartbot
+  \egroup
+  \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+  \aboveenvbreak
+  \hfuzz = 12pt % Don't be fussy
+  \sepspaces % Make spaces be word-separators rather than space tokens.
+  \let\par = \lisppar % don't ignore blank lines
+  \obeylines % each line of input is a line of output
+  \parskip = 0pt
+  \parindent = 0pt
+  \emergencystretch = 0pt % don't try to avoid overfull boxes
+  \ifx\nonarrowing\relax
+    \advance \leftskip by \lispnarrowing
+    \exdentamount=\lispnarrowing
+  \else
+    \let\nonarrowing = \relax
+  \fi
+  \let\exdent=\nofillexdent
+}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+%    @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+  \ifx\SETdispenvsize\smallword
+    % end paragraph for sake of leading, in case document has no blank
+    % line.  This is redundant with what happens in \aboveenvbreak, but
+    % we need to do it before changing the fonts, and it's inconvenient
+    % to change the fonts afterward.
+    \ifnum \lastpenalty=10000 \else \endgraf \fi
+    \smallexamplefonts \rm
+  \fi
+}
+\def\setsmalldispenv{%
+  \ifx\SETdispenvsize\nosmallword
+  \else
+    \ifnum \lastpenalty=10000 \else \endgraf \fi
+    \smallexamplefonts \rm
+  \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it by one command:
+\def\makedispenv #1#2{
+  \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
+  \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
+  \expandafter\let\csname E#1\endcsname \afterenvbreak
+  \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two synonyms:
+\def\maketwodispenvs #1#2#3{
+  \makedispenv{#1}{#3}
+  \makedispenv{#2}{#3}
+}
+
+% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+%
+\maketwodispenvs {lisp}{example}{%
+  \nonfillstart
+  \tt\quoteexpand
+  \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+  \gobble       % eat return
+}
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenv {display}{%
+  \nonfillstart
+  \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenv{format}{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \advance\leftskip by 0pt plus 1fill
+  \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins.  We keep \parskip nonzero in general, since
+% we're doing normal filling.  So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\envdef\quotation{%
+  {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+  \parindent=0pt
+  %
+  % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+  \ifx\nonarrowing\relax
+    \advance\leftskip by \lispnarrowing
+    \advance\rightskip by \lispnarrowing
+    \exdentamount = \lispnarrowing
+  \else
+    \let\nonarrowing = \relax
+  \fi
+  \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+  \par
+  \ifx\quotationauthor\undefined\else
+    % indent a bit.
+    \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+  \fi
+  {\parskip=0pt \afterenvbreak}%
+}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+  \def\temp{#1}%
+  \ifx\temp\empty \else
+    {\bf #1: }%
+  \fi
+}
+
+
+% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command.  --janneke@gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996.  The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too.  Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+  \do\ \do\\\do\{\do\}\do\$\do\&%
+  \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+  \do\<\do\>\do\|\do\@\do+\do\"%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+  \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% [Knuth] pp. 380,381,391
+% Disable Spanish ligatures ?` and !` of \tt font
+\begingroup
+  \catcode`\`=\active\gdef`{\relax\lq}
+\endgroup
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+  \catcode`\^^I=\active
+  \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+  \tt  % easiest (and conventionally used) font for verbatim
+  \def\par{\leavevmode\endgraf}%
+  \catcode`\`=\active
+  \tabeightspaces
+  % Respect line breaks,
+  % print special symbols as themselves, and
+  % make each space count
+  % must do in this order:
+  \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+\def\starttabbox{\setbox0=\hbox\bgroup}
+
+% Allow an option to not replace quotes with a regular directed right
+% quote/apostrophe (char 0x27), but instead use the undirected quote
+% from cmtt (char 0x0d).  The undirected quote is ugly, so don't make it
+% the default, but it works for pasting with more pdf viewers (at least
+% evince), the lilypond developers report.  xpdf does work with the
+% regular 0x27.
+%
+\def\codequoteright{%
+  \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
+    \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+      '%
+    \else \char'15 \fi
+  \else \char'15 \fi
+}
+%
+% and a similar option for the left quote char vs. a grave accent.
+% Modern fonts display ASCII 0x60 as a grave accent, so some people like
+% the code environments to do likewise.
+%
+\def\codequoteleft{%
+  \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
+    \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+      `%
+    \else \char'22 \fi
+  \else \char'22 \fi
+}
+%
+\begingroup
+  \catcode`\^^I=\active
+  \gdef\tabexpand{%
+    \catcode`\^^I=\active
+    \def^^I{\leavevmode\egroup
+      \dimen0=\wd0 % the width so far, or since the previous tab
+      \divide\dimen0 by\tabw
+      \multiply\dimen0 by\tabw % compute previous multiple of \tabw
+      \advance\dimen0 by\tabw  % advance to next multiple of \tabw
+      \wd0=\dimen0 \box0 \starttabbox
+    }%
+  }
+  \catcode`\'=\active
+  \gdef\rquoteexpand{\catcode\rquoteChar=\active \def'{\codequoteright}}%
+  %
+  \catcode`\`=\active
+  \gdef\lquoteexpand{\catcode\lquoteChar=\active \def`{\codequoteleft}}%
+  %
+  \gdef\quoteexpand{\rquoteexpand \lquoteexpand}%
+\endgroup
+
+% start the verbatim environment.
+\def\setupverbatim{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  % Easiest (and conventionally used) font for verbatim
+  \tt
+  \def\par{\leavevmode\egroup\box0\endgraf}%
+  \catcode`\`=\active
+  \tabexpand
+  \quoteexpand
+  % Respect line breaks,
+  % print special symbols as themselves, and
+  % make each space count
+  % must do in this order:
+  \obeylines \uncatcodespecials \sepspaces
+  \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters.  Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+%    \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+  \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+  \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+%     \def\doverbatim#1@end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+  \catcode`\ =\active
+  \obeylines %
+  % ignore everything up to the first ^^M, that's the newline at the end
+  % of the @verbatim input line itself.  Otherwise we get an extra blank
+  % line in the output.
+  \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+  % We really want {...\end verbatim} in the body of the macro, but
+  % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+    \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+  {%
+    \makevalueexpandable
+    \setupverbatim
+    \input #1
+    \afterenvbreak
+  }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+  \begingroup
+    \parindent = 0pt  % paragraph indentation looks wrong on title page
+    \scanexp\copyingtext
+  \endgroup
+}
+
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+\newcount\defunpenalty
+
+% Start the processing of @deffn:
+\def\startdefun{%
+  \ifnum\lastpenalty<10000
+    \medbreak
+    \defunpenalty=10003 % Will keep this @deffn together with the
+                        % following @def command, see below.
+  \else
+    % If there are two @def commands in a row, we'll have a \nobreak,
+    % which is there to keep the function description together with its
+    % header.  But if there's nothing but headers, we need to allow a
+    % break somewhere.  Check specifically for penalty 10002, inserted
+    % by \printdefunline, instead of 10000, since the sectioning
+    % commands also insert a nobreak penalty, and we don't want to allow
+    % a break between a section heading and a defun.
+    %
+    % As a minor refinement, we avoid "club" headers by signalling
+    % with penalty of 10003 after the very first @deffn in the
+    % sequence (see above), and penalty of 10002 after any following
+    % @def command.
+    \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi
+    %
+    % Similarly, after a section heading, do not allow a break.
+    % But do insert the glue.
+    \medskip  % preceded by discardable penalty, so not a breakpoint
+  \fi
+  %
+  \parindent=0in
+  \advance\leftskip by \defbodyindent
+  \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+  % First, check whether we are in the right environment:
+  \checkenv#1%
+  %
+  % As above, allow line break if we have multiple x headers in a row.
+  % It's not a great place, though.
+  \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi
+  %
+  % And now, it's time to reuse the body of the original defun:
+  \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+  \begingroup
+    % call \deffnheader:
+    #1#2 \endheader
+    % common ending:
+    \interlinepenalty = 10000
+    \advance\rightskip by 0pt plus 1fil
+    \endgraf
+    \nobreak\vskip -\parskip
+    \penalty\defunpenalty  % signal to \startdefun and \dodefunx
+    % Some of the @defun-type tags do not enable magic parentheses,
+    % rendering the following check redundant.  But we don't optimize.
+    \checkparencounts
+  \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remainnig is to define \deffnheader.
+%
+\def\makedefun#1{%
+  \expandafter\let\csname E#1\endcsname = \Edefun
+  \edef\temp{\noexpand\domakedefun
+    \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+  \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+  \envdef#1{%
+    \startdefun
+    \parseargusing\activeparens{\printdefunline#3}%
+  }%
+  \def#2{\dodefunx#1}%
+  \def#3%
+}
+
+%%% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+  % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+  \dosubind{fn}{\code{#3}}{#1}%
+  \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+%%% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+  \dosubind{fn}{\code{#4}}{#1}%
+  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+  \dosubind{vr}{\code{#4}}{#1}%
+  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+%%% Type:
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+  \doind{tp}{\code{#2}}%
+  \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+  % Get the values of \leftskip and \rightskip as they were outside the @def...
+  \advance\leftskip by -\defbodyindent
+  %
+  % How we'll format the type name.  Putting it in brackets helps
+  % distinguish it from the body text that may end up on the next line
+  % just below it.
+  \def\temp{#1}%
+  \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+  %
+  % Figure out line sizes for the paragraph shape.
+  % The first line needs space for \box0; but if \rightskip is nonzero,
+  % we need only space for the part of \box0 which exceeds it:
+  \dimen0=\hsize  \advance\dimen0 by -\wd0  \advance\dimen0 by \rightskip
+  % The continuations:
+  \dimen2=\hsize  \advance\dimen2 by -\defargsindent
+  % (plain.tex says that \dimen1 should be used only as global.)
+  \parshape 2 0in \dimen0 \defargsindent \dimen2
+  %
+  % Put the type name to the right margin.
+  \noindent
+  \hbox to 0pt{%
+    \hfil\box0 \kern-\hsize
+    % \hsize has to be shortened this way:
+    \kern\leftskip
+    % Intentionally do not respect \rightskip, since we need the space.
+  }%
+  %
+  % Allow all lines to be underfull without complaint:
+  \tolerance=10000 \hbadness=10000
+  \exdentamount=\defbodyindent
+  {%
+    % defun fonts. We use typewriter by default (used to be bold) because:
+    % . we're printing identifiers, they should be in tt in principle.
+    % . in languages with many accents, such as Czech or French, it's
+    %   common to leave accents off identifiers.  The result looks ok in
+    %   tt, but exceedingly strange in rm.
+    % . we don't want -- and --- to be treated as ligatures.
+    % . this still does not fix the ?` and !` ligatures, but so far no
+    %   one has made identifiers using them :).
+    \df \tt
+    \def\temp{#2}% return value type
+    \ifx\temp\empty\else \tclose{\temp} \fi
+    #3% output function name
+  }%
+  {\rm\enskip}% hskip 0.5 em of \tenrm
+  %
+  \boldbrax
+  % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name.  This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable.  Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+  % use sl by default (not ttsl),
+  % tt for the names.
+  \df \sl \hyphenchar\font=0
+  %
+  % On the other hand, if an argument has two dashes (for instance), we
+  % want a way to get ttsl.  Let's try @var for that.
+  \let\var=\ttslanted
+  #1%
+  \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+  \catcode`\(=\active \catcode`\)=\active
+  \catcode`\[=\active \catcode`\]=\active
+  \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc.  For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+  \activeparens
+  \global\let(=\lparen \global\let)=\rparen
+  \global\let[=\lbrack \global\let]=\rbrack
+  \global\let& = \&
+
+  \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+  \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+  \ifampseen
+    % At the first level, print parens in roman,
+    % otherwise use the default font.
+    \ifnum \parencount=1 \rm \fi
+  \else
+    % The \sf parens (in \boldbrax) actually are a little bolder than
+    % the contained text.  This is especially needed for [ and ] .
+    \sf
+  \fi
+}
+\def\infirstlevel#1{%
+  \ifampseen
+    \ifnum\parencount=1
+      #1%
+    \fi
+  \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+  \global\advance\parencount by 1
+  {\parenfont(}%
+  \infirstlevel \bfafterword
+}
+\def\clnr{%
+  {\parenfont)}%
+  \infirstlevel \sl
+  \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+  \global\advance\brackcount by 1
+  {\bf[}%
+}
+\def\rbrb{%
+  {\bf]}%
+  \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+  \ifnum\parencount=0 \else \badparencount \fi
+  \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+% these should not use \errmessage; the glibc manual, at least, actually
+% has such constructs (when documenting function pointers).
+\def\badparencount{%
+  \message{Warning: unbalanced parentheses in @def...}%
+  \global\parencount=0
+}
+\def\badbrackcount{%
+  \message{Warning: unbalanced square brackets in @def...}%
+  \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\undefined
+  \newwrite\macscribble
+  \def\scantokens#1{%
+    \toks0={#1}%
+    \immediate\openout\macscribble=\jobname.tmp
+    \immediate\write\macscribble{\the\toks0}%
+    \immediate\closeout\macscribble
+    \input \jobname.tmp
+  }
+\fi
+
+\def\scanmacro#1{%
+  \begingroup
+    \newlinechar`\^^M
+    \let\xeatspaces\eatspaces
+    % Undo catcode changes of \startcontents and \doprintindex
+    % When called from @insertcopying or (short)caption, we need active
+    % backslash to get it printed correctly.  Previously, we had
+    % \catcode`\\=\other instead.  We'll see whether a problem appears
+    % with macro expansion.				--kasal, 19aug04
+    \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+    % ... and \example
+    \spaceisspace
+    %
+    % Append \endinput to make sure that TeX does not see the ending newline.
+    % I've verified that it is necessary both for e-TeX and for ordinary TeX
+    %							--kasal, 29nov03
+    \scantokens{#1\endinput}%
+  \endgroup
+}
+
+\def\scanexp#1{%
+  \edef\temp{\noexpand\scanmacro{#1}}%
+  \temp
+}
+
+\newcount\paramno   % Count of parameters
+\newtoks\macname    % Macro name
+\newif\ifrecursive  % Is it recursive?
+
+% List of all defined macros in the form
+%    \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+     \toks0 = \expandafter{\macrolist\definedummyword#1}%
+     \xdef\macrolist{\the\toks0}%
+}
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+%   \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+%
+\def\cslet#1#2{%
+  \expandafter\let
+  \csname#1\expandafter\endcsname
+  \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \.
+
+% Non-ASCII encodings make 8-bit characters active, so un-activate
+% them to avoid their expansion.  Must do this non-globally, to
+% confine the change to the current group.
+
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by  making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+
+\def\scanctxt{%
+  \catcode`\"=\other
+  \catcode`\+=\other
+  \catcode`\<=\other
+  \catcode`\>=\other
+  \catcode`\@=\other
+  \catcode`\^=\other
+  \catcode`\_=\other
+  \catcode`\|=\other
+  \catcode`\~=\other
+  \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi
+}
+
+\def\scanargctxt{%
+  \scanctxt
+  \catcode`\\=\other
+  \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{%
+  \scanctxt
+  \catcode`\{=\other
+  \catcode`\}=\other
+  \catcode`\^^M=\other
+  \usembodybackslash
+}
+
+\def\macroargctxt{%
+  \scanctxt
+  \catcode`\\=\other
+}
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+
+{\catcode`@=0 @catcode`@\=@active
+ @gdef@usembodybackslash{@let\=@mbodybackslash}
+ @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+  \getargs{#1}%           now \macname is the macname and \argl the arglist
+  \ifx\argl\empty       % no arguments
+     \paramno=0%
+  \else
+     \expandafter\parsemargdef \argl;%
+  \fi
+  \if1\csname ismacro.\the\macname\endcsname
+     \message{Warning: redefining \the\macname}%
+  \else
+     \expandafter\ifx\csname \the\macname\endcsname \relax
+     \else \errmessage{Macro name \the\macname\space already defined}\fi
+     \global\cslet{macsave.\the\macname}{\the\macname}%
+     \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+     \addtomacrolist{\the\macname}%
+  \fi
+  \begingroup \macrobodyctxt
+  \ifrecursive \expandafter\parsermacbody
+  \else \expandafter\parsemacbody
+  \fi}
+
+\parseargdef\unmacro{%
+  \if1\csname ismacro.#1\endcsname
+    \global\cslet{#1}{macsave.#1}%
+    \global\expandafter\let \csname ismacro.#1\endcsname=0%
+    % Remove the macro name from \macrolist:
+    \begingroup
+      \expandafter\let\csname#1\endcsname \relax
+      \let\definedummyword\unmacrodo
+      \xdef\macrolist{\macrolist}%
+    \endgroup
+  \else
+    \errmessage{Macro #1 not defined}%
+  \fi
+}
+
+% Called by \do from \dounmacro on each macro.  The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+  \ifx #1\relax
+    % remove this
+  \else
+    \noexpand\definedummyword \noexpand#1%
+  \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname #1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% Parse the optional {params} list.  Set up \paramno and \paramlist
+% so \defmacro knows what to do.  Define \macarg.blah for each blah
+% in the params list, to be ##N where N is the position in that list.
+% That gets used by \mbodybackslash (above).
+
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX:  let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+
+\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
+        \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+\def\parsemargdefxxx#1,{%
+  \if#1;\let\next=\relax
+  \else \let\next=\parsemargdefxxx
+    \advance\paramno by 1%
+    \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+        {\xeatspaces{\hash\the\paramno}}%
+    \edef\paramlist{\paramlist\hash\the\paramno,}%
+  \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+
+\long\def\parsemacbody#1@end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1@end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+
+% This defines the macro itself. There are six cases: recursive and
+% nonrecursive macros of zero, one, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+\def\defmacro{%
+  \let\hash=##% convert placeholders to macro parameter chars
+  \ifrecursive
+    \ifcase\paramno
+    % 0
+      \expandafter\xdef\csname\the\macname\endcsname{%
+        \noexpand\scanmacro{\temp}}%
+    \or % 1
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\braceorline
+         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+         \egroup\noexpand\scanmacro{\temp}}%
+    \else % many
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\csname\the\macname xx\endcsname}%
+      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+      \expandafter\expandafter
+      \expandafter\xdef
+      \expandafter\expandafter
+        \csname\the\macname xxx\endcsname
+          \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+    \fi
+  \else
+    \ifcase\paramno
+    % 0
+      \expandafter\xdef\csname\the\macname\endcsname{%
+        \noexpand\norecurse{\the\macname}%
+        \noexpand\scanmacro{\temp}\egroup}%
+    \or % 1
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\braceorline
+         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+        \egroup
+        \noexpand\norecurse{\the\macname}%
+        \noexpand\scanmacro{\temp}\egroup}%
+    \else % many
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \expandafter\noexpand\csname\the\macname xx\endcsname}%
+      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+      \expandafter\expandafter
+      \expandafter\xdef
+      \expandafter\expandafter
+      \csname\the\macname xxx\endcsname
+      \paramlist{%
+          \egroup
+          \noexpand\norecurse{\the\macname}%
+          \noexpand\scanmacro{\temp}\egroup}%
+    \fi
+  \fi}
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {.  If so it reads up to the closing }, if not, it reads the whole
+% line.  Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg)
+\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+  \ifx\nchar\bgroup\else
+    \expandafter\parsearg
+  \fi \macnamexxx}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign.  Just make them active and then expand them all to nothing.
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+  {%
+    \expandafter\let\obeyedspace=\empty
+    \addtomacrolist{#1}%
+    \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+  }%
+  \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+\newif\ifhavexrefs    % True if xref values are known.
+\newif\ifwarnedxrefs  % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+  node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references.  The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross,  ,  , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node.  #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+  \ifx\lastnode\empty\else
+    \setref{\lastnode}{#1}%
+    \global\let\lastnode=\empty
+  \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \lastsection,
+%                 or the anchor name.
+% 2) NAME-snt   - section number and type, passed as the SNT arg, or
+%                 empty for anchors.
+% 3) NAME-pg    - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat.  In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof   - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+  \pdfmkdest{#1}%
+  \iflinks
+    {%
+      \atdummies  % preserve commands, but don't expand them
+      \edef\writexrdef##1##2{%
+	\write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+	  ##1}{##2}}% these are parameters of \writexrdef
+      }%
+      \toks0 = \expandafter{\lastsection}%
+      \immediate \writexrdef{title}{\the\toks0 }%
+      \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+      \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during \shipout
+    }%
+  \fi
+}
+
+% @xref, @pxref, and @ref generate cross-references.  For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual.  All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+  \unsepspaces
+  \def\printedmanual{\ignorespaces #5}%
+  \def\printedrefname{\ignorespaces #3}%
+  \setbox1=\hbox{\printedmanual\unskip}%
+  \setbox0=\hbox{\printedrefname\unskip}%
+  \ifdim \wd0 = 0pt
+    % No printed node name was explicitly given.
+    \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+      % Use the node name inside the square brackets.
+      \def\printedrefname{\ignorespaces #1}%
+    \else
+      % Use the actual chapter/section title appear inside
+      % the square brackets.  Use the real section title if we have it.
+      \ifdim \wd1 > 0pt
+        % It is in another manual, so we don't have it.
+        \def\printedrefname{\ignorespaces #1}%
+      \else
+        \ifhavexrefs
+          % We know the real title if we have the xref values.
+          \def\printedrefname{\refx{#1-title}{}}%
+        \else
+          % Otherwise just copy the Info node name.
+          \def\printedrefname{\ignorespaces #1}%
+        \fi%
+      \fi
+    \fi
+  \fi
+  %
+  % Make link in pdf output.
+  \ifpdf
+    \leavevmode
+    \getfilename{#4}%
+    {\indexnofonts
+     \turnoffactive
+     % See comments at \activebackslashdouble.
+     {\activebackslashdouble \xdef\pdfxrefdest{#1}%
+      \backslashparens\pdfxrefdest}%
+     %
+     \ifnum\filenamelength>0
+       \startlink attr{/Border [0 0 0]}%
+         goto file{\the\filename.pdf} name{\pdfxrefdest}%
+     \else
+       \startlink attr{/Border [0 0 0]}%
+         goto name{\pdfmkpgn{\pdfxrefdest}}%
+     \fi
+    }%
+    \setcolor{\linkcolor}%
+  \fi
+  %
+  % Float references are printed completely differently: "Figure 1.2"
+  % instead of "[somenode], p.3".  We distinguish them by the
+  % LABEL-title being set to a magic string.
+  {%
+    % Have to otherify everything special to allow the \csname to
+    % include an _ in the xref name, etc.
+    \indexnofonts
+    \turnoffactive
+    \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+      \csname XR#1-title\endcsname
+  }%
+  \iffloat\Xthisreftitle
+    % If the user specified the print name (third arg) to the ref,
+    % print it instead of our usual "Figure 1.2".
+    \ifdim\wd0 = 0pt
+      \refx{#1-snt}{}%
+    \else
+      \printedrefname
+    \fi
+    %
+    % if the user also gave the printed manual name (fifth arg), append
+    % "in MANUALNAME".
+    \ifdim \wd1 > 0pt
+      \space \putwordin{} \cite{\printedmanual}%
+    \fi
+  \else
+    % node/anchor (non-float) references.
+    %
+    % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+    % insert empty discretionaries after hyphens, which means that it will
+    % not find a line break at a hyphen in a node names.  Since some manuals
+    % are best written with fairly long node names, containing hyphens, this
+    % is a loss.  Therefore, we give the text of the node name again, so it
+    % is as if TeX is seeing it for the first time.
+    \ifdim \wd1 > 0pt
+      \putwordSection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
+    \else
+      % _ (for example) has to be the character _ for the purposes of the
+      % control sequence corresponding to the node, but it has to expand
+      % into the usual \leavevmode...\vrule stuff for purposes of
+      % printing. So we \turnoffactive for the \refx-snt, back on for the
+      % printing, back off for the \refx-pg.
+      {\turnoffactive
+       % Only output a following space if the -snt ref is nonempty; for
+       % @unnumbered and @anchor, it won't be.
+       \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+       \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+      }%
+      % output the `[mynode]' via a macro so it can be overridden.
+      \xrefprintnodename\printedrefname
+      %
+      % But we always want a comma and a space:
+      ,\space
+      %
+      % output the `page 3'.
+      \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+    \fi
+  \fi
+  \endlink
+\endgroup}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output.  It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents.  Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+  \ifnum\secno=0
+    \putwordChapter@tie \the\chapno
+  \else \ifnum\subsecno=0
+    \putwordSection@tie \the\chapno.\the\secno
+  \else \ifnum\subsubsecno=0
+    \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
+  \else
+    \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+  \fi\fi\fi
+}
+\def\Yappendix{%
+  \ifnum\secno=0
+     \putwordAppendix@tie @char\the\appendixno{}%
+  \else \ifnum\subsecno=0
+     \putwordSection@tie @char\the\appendixno.\the\secno
+  \else \ifnum\subsubsecno=0
+    \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
+  \else
+    \putwordSection@tie
+      @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+  \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+  {%
+    \indexnofonts
+    \otherbackslash
+    \expandafter\global\expandafter\let\expandafter\thisrefX
+      \csname XR#1\endcsname
+  }%
+  \ifx\thisrefX\relax
+    % If not defined, say something at least.
+    \angleleft un\-de\-fined\angleright
+    \iflinks
+      \ifhavexrefs
+        \message{\linenumber Undefined cross reference `#1'.}%
+      \else
+        \ifwarnedxrefs\else
+          \global\warnedxrefstrue
+          \message{Cross reference values unknown; you must run TeX again.}%
+        \fi
+      \fi
+    \fi
+  \else
+    % It's defined, so just use it.
+    \thisrefX
+  \fi
+  #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file.  Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions).  But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+  {% The node name might contain 8-bit characters, which in our current
+   % implementation are changed to commands like @'e.  Don't let these
+   % mess up the control sequence name.
+    \indexnofonts
+    \turnoffactive
+    \xdef\safexrefname{#1}%
+  }%
+  %
+  \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
+  %
+  % Was that xref control sequence that we just defined for a float?
+  \expandafter\iffloat\csname XR\safexrefname\endcsname
+    % it was a float, and we have the (safe) float type in \iffloattype.
+    \expandafter\let\expandafter\floatlist
+      \csname floatlist\iffloattype\endcsname
+    %
+    % Is this the first time we've seen this float type?
+    \expandafter\ifx\floatlist\relax
+      \toks0 = {\do}% yes, so just \do
+    \else
+      % had it before, so preserve previous elements in list.
+      \toks0 = \expandafter{\floatlist\do}%
+    \fi
+    %
+    % Remember this xref in the control sequence \floatlistFLOATTYPE,
+    % for later use in \listoffloats.
+    \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
+      {\safexrefname}}%
+  \fi
+}
+
+% Read the last existing aux file, if any.  No error if none exists.
+%
+\def\tryauxfile{%
+  \openin 1 \jobname.aux
+  \ifeof 1 \else
+    \readdatafile{aux}%
+    \global\havexrefstrue
+  \fi
+  \closein 1
+}
+
+\def\setupdatafile{%
+  \catcode`\^^@=\other
+  \catcode`\^^A=\other
+  \catcode`\^^B=\other
+  \catcode`\^^C=\other
+  \catcode`\^^D=\other
+  \catcode`\^^E=\other
+  \catcode`\^^F=\other
+  \catcode`\^^G=\other
+  \catcode`\^^H=\other
+  \catcode`\^^K=\other
+  \catcode`\^^L=\other
+  \catcode`\^^N=\other
+  \catcode`\^^P=\other
+  \catcode`\^^Q=\other
+  \catcode`\^^R=\other
+  \catcode`\^^S=\other
+  \catcode`\^^T=\other
+  \catcode`\^^U=\other
+  \catcode`\^^V=\other
+  \catcode`\^^W=\other
+  \catcode`\^^X=\other
+  \catcode`\^^Z=\other
+  \catcode`\^^[=\other
+  \catcode`\^^\=\other
+  \catcode`\^^]=\other
+  \catcode`\^^^=\other
+  \catcode`\^^_=\other
+  % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+  % in xref tags, i.e., node names.  But since ^^e4 notation isn't
+  % supported in the main text, it doesn't seem desirable.  Furthermore,
+  % that is not enough: for node names that actually contain a ^
+  % character, we would end up writing a line like this: 'xrdef {'hat
+  % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+  % argument, and \hat is not an expandable control sequence.  It could
+  % all be worked out, but why?  Either we support ^^ or we don't.
+  %
+  % The other change necessary for this was to define \auxhat:
+  % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+  % and then to call \auxhat in \setq.
+  %
+  \catcode`\^=\other
+  %
+  % Special characters.  Should be turned off anyway, but...
+  \catcode`\~=\other
+  \catcode`\[=\other
+  \catcode`\]=\other
+  \catcode`\"=\other
+  \catcode`\_=\other
+  \catcode`\|=\other
+  \catcode`\<=\other
+  \catcode`\>=\other
+  \catcode`\$=\other
+  \catcode`\#=\other
+  \catcode`\&=\other
+  \catcode`\%=\other
+  \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+  %
+  % This is to support \ in node names and titles, since the \
+  % characters end up in a \csname.  It's easier than
+  % leaving it active and making its active definition an actual \
+  % character.  What I don't understand is why it works in the *value*
+  % of the xrdef.  Seems like it should be a catcode12 \, and that
+  % should not typeset properly.  But it works, so I'm moving on for
+  % now.  --karl, 15jan04.
+  \catcode`\\=\other
+  %
+  % Make the characters 128-255 be printing characters.
+  {%
+    \count1=128
+    \def\loop{%
+      \catcode\count1=\other
+      \advance\count1 by 1
+      \ifnum \count1<256 \loop \fi
+    }%
+  }%
+  %
+  % @ is our escape character in .aux files, and we need braces.
+  \catcode`\{=1
+  \catcode`\}=2
+  \catcode`\@=0
+}
+
+\def\readdatafile#1{%
+\begingroup
+  \setupdatafile
+  \input\jobname.#1
+\endgroup}
+
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes.  Otherwise like plain.
+\gdef\footnote{%
+  \let\indent=\ptexindent
+  \let\noindent=\ptexnoindent
+  \global\advance\footnoteno by \@ne
+  \edef\thisfootno{$^{\the\footnoteno}$}%
+  %
+  % In case the footnote comes at the end of a sentence, preserve the
+  % extra spacing after we do the footnote number.
+  \let\@sf\empty
+  \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+  %
+  % Remove inadvertent blank space before typesetting the footnote number.
+  \unskip
+  \thisfootno\@sf
+  \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter.  Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read.  --karl, 16nov96.
+%
+\gdef\dofootnote{%
+  \insert\footins\bgroup
+  % We want to typeset this text as a normal paragraph, even if the
+  % footnote reference occurs in (for example) a display environment.
+  % So reset some parameters.
+  \hsize=\pagewidth
+  \interlinepenalty\interfootnotelinepenalty
+  \splittopskip\ht\strutbox % top baseline for broken footnotes
+  \splitmaxdepth\dp\strutbox
+  \floatingpenalty\@MM
+  \leftskip\z@skip
+  \rightskip\z@skip
+  \spaceskip\z@skip
+  \xspaceskip\z@skip
+  \parindent\defaultparindent
+  %
+  \smallfonts \rm
+  %
+  % Because we use hanging indentation in footnotes, a @noindent appears
+  % to exdent this text, so make it be a no-op.  makeinfo does not use
+  % hanging indentation so @noindent can still be needed within footnote
+  % text after an @example or the like (not that this is good style).
+  \let\noindent = \relax
+  %
+  % Hang the footnote text off the number.  Use \everypar in case the
+  % footnote extends for more than one paragraph.
+  \everypar = {\hang}%
+  \textindent{\thisfootno}%
+  %
+  % Don't crash into the line above the footnote text.  Since this
+  % expands into a box, it must come within the paragraph, lest it
+  % provide a place where TeX can split the footnote.
+  \footstrut
+  \futurelet\next\fo@t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished.  Otherwise, the insertion
+% would be lost.
+% Similarily, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes.  --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+  \ifx \insert\ptexinsert
+    \let\insert\saveinsert
+  \else
+    \let\checkinserts\relax
+  \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+  \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+  \afterassignment\next
+  % swallow the left brace
+  \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+  \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+    {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+  \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials  %  ;-)
+  \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+  \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+  \next
+}
+\def\newsaveinsX #1{%
+  \csname newbox\endcsname #1%
+  \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+    \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image.  We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front.  If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+  % Do not bother showing banner with epsf.tex v2.7k (available in
+  % doc/epsf.tex and on ctan).
+  \def\epsfannounce{\toks0 = }%
+  \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+  work.  It is also included in the Texinfo distribution, or you can get
+  it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+  \ifx\epsfbox\undefined
+    \ifwarnednoepsf \else
+      \errhelp = \noepsfhelp
+      \errmessage{epsf.tex not found, images will be ignored}%
+      \global\warnednoepsftrue
+    \fi
+  \else
+    \imagexxx #1,,,,,\finish
+  \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing this stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+  \catcode`\^^M = 5     % in case we're inside an example
+  \normalturnoffactive  % allow _ et al. in names
+  % If the image is by itself, center it.
+  \ifvmode
+    \imagevmodetrue
+    \nobreak\bigskip
+    % Usually we'll have text after the image which will insert
+    % \parskip glue, so insert it here too to equalize the space
+    % above and below.
+    \nobreak\vskip\parskip
+    \nobreak
+    \line\bgroup
+  \fi
+  %
+  % Output the image.
+  \ifpdf
+    \dopdfimage{#1}{#2}{#3}%
+  \else
+    % \epsfbox itself resets \epsf?size at each figure.
+    \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+    \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+    \epsfbox{#1.eps}%
+  \fi
+  %
+  \ifimagevmode \egroup \bigbreak \fi  % space after the image
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc.  We don't actually implement floating yet, we always include the
+% float "here".  But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc.  Can't contain commas.  If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label.  Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored.  It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+  \let\thiscaption=\empty
+  \let\thisshortcaption=\empty
+  %
+  % don't lose footnotes inside @float.
+  %
+  % BEWARE: when the floats start float, we have to issue warning whenever an
+  % insert appears inside a float which could possibly float. --kasal, 26may04
+  %
+  \startsavinginserts
+  %
+  % We can't be used inside a paragraph.
+  \par
+  %
+  \vtop\bgroup
+    \def\floattype{#1}%
+    \def\floatlabel{#2}%
+    \def\floatloc{#3}% we do nothing with this yet.
+    %
+    \ifx\floattype\empty
+      \let\safefloattype=\empty
+    \else
+      {%
+        % the floattype might have accents or other special characters,
+        % but we need to use it in a control sequence name.
+        \indexnofonts
+        \turnoffactive
+        \xdef\safefloattype{\floattype}%
+      }%
+    \fi
+    %
+    % If label is given but no type, we handle that as the empty type.
+    \ifx\floatlabel\empty \else
+      % We want each FLOATTYPE to be numbered separately (Figure 1,
+      % Table 1, Figure 2, ...).  (And if no label, no number.)
+      %
+      \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+      \global\advance\floatno by 1
+      %
+      {%
+        % This magic value for \lastsection is output by \setref as the
+        % XREFLABEL-title value.  \xrefX uses it to distinguish float
+        % labels (which have a completely different output format) from
+        % node and anchor labels.  And \xrdef uses it to construct the
+        % lists of floats.
+        %
+        \edef\lastsection{\floatmagic=\safefloattype}%
+        \setref{\floatlabel}{Yfloat}%
+      }%
+    \fi
+    %
+    % start with \parskip glue, I guess.
+    \vskip\parskip
+    %
+    % Don't suppress indentation if a float happens to start a section.
+    \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption:    Foo 1.1
+% @float Foo & @caption{Cap}:     Foo: Cap
+% @float Foo & no caption:        Foo
+% @float ,lbl & Caption{Cap}:     1.1: Cap
+% @float ,lbl & no caption:       1.1
+% @float & @caption{Cap}:         Cap
+% @float & no caption:
+%
+\def\Efloat{%
+    \let\floatident = \empty
+    %
+    % In all cases, if we have a float type, it comes first.
+    \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+    %
+    % If we have an xref label, the number comes next.
+    \ifx\floatlabel\empty \else
+      \ifx\floattype\empty \else % if also had float type, need tie first.
+        \appendtomacro\floatident{\tie}%
+      \fi
+      % the number.
+      \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+    \fi
+    %
+    % Start the printed caption with what we've constructed in
+    % \floatident, but keep it separate; we need \floatident again.
+    \let\captionline = \floatident
+    %
+    \ifx\thiscaption\empty \else
+      \ifx\floatident\empty \else
+	\appendtomacro\captionline{: }% had ident, so need a colon between
+      \fi
+      %
+      % caption text.
+      \appendtomacro\captionline{\scanexp\thiscaption}%
+    \fi
+    %
+    % If we have anything to print, print it, with space before.
+    % Eventually this needs to become an \insert.
+    \ifx\captionline\empty \else
+      \vskip.5\parskip
+      \captionline
+      %
+      % Space below caption.
+      \vskip\parskip
+    \fi
+    %
+    % If have an xref label, write the list of floats info.  Do this
+    % after the caption, to avoid chance of it being a breakpoint.
+    \ifx\floatlabel\empty \else
+      % Write the text that goes in the lof to the aux file as
+      % \floatlabel-lof.  Besides \floatident, we include the short
+      % caption if specified, else the full caption if specified, else nothing.
+      {%
+        \atdummies
+        %
+        % since we read the caption text in the macro world, where ^^M
+        % is turned into a normal character, we have to scan it back, so
+        % we don't write the literal three characters "^^M" into the aux file.
+	\scanexp{%
+	  \xdef\noexpand\gtemp{%
+	    \ifx\thisshortcaption\empty
+	      \thiscaption
+	    \else
+	      \thisshortcaption
+	    \fi
+	  }%
+	}%
+        \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+	  \ifx\gtemp\empty \else : \gtemp \fi}}%
+      }%
+    \fi
+  \egroup  % end of \vtop
+  %
+  % place the captured inserts
+  %
+  % BEWARE: when the floats start floating, we have to issue warning
+  % whenever an insert appears inside a float which could possibly
+  % float. --kasal, 26may04
+  %
+  \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+  \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use.  Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+  \ifx#1\relax
+      % Haven't seen this figure type before.
+      \csname newcount\endcsname #1%
+      %
+      % Remember to reset this floatno at the next chap.
+      \expandafter\gdef\expandafter\resetallfloatnos
+        \expandafter{\resetallfloatnos #1=0 }%
+  \fi
+  \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value.  We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1".  We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref.  That is, the magic
+% \lastsection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string.  If so, #2 will be the
+% (safe) float type for this float.  We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+  \def\temp{#1}%
+  \def\iffloattype{#2}%
+  \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+  \def\floattype{#1}% floattype
+  {%
+    % the floattype might have accents or other special characters,
+    % but we need to use it in a control sequence name.
+    \indexnofonts
+    \turnoffactive
+    \xdef\safefloattype{\floattype}%
+  }%
+  %
+  % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+  \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+    \ifhavexrefs
+      % if the user said @listoffloats foo but never @float foo.
+      \message{\linenumber No `\safefloattype' floats to list.}%
+    \fi
+  \else
+    \begingroup
+      \leftskip=\tocindent  % indent these entries like a toc
+      \let\do=\listoffloatsdo
+      \csname floatlist\safefloattype\endcsname
+    \endgroup
+  \fi
+}
+
+% This is called on each entry in a list of floats.  We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file.  We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+  % Can't fully expand XR#1-lof because it can contain anything.  Just
+  % pass the control sequence.  On the other hand, XR#1-pg is just the
+  % page number, and we want to fully expand that so we can get a link
+  % in pdf output.
+  \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+  %
+  % use the same \entry macro we use to generate the TOC and index.
+  \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+  \writeentry
+}}
+
+
+\message{localization,}
+
+% @documentlanguage is usually given very early, just after
+% @setfilename.  If done too late, it may not override everything
+% properly.  Single argument is the language (de) or locale (de_DE)
+% abbreviation.  It would be nice if we could set up a hyphenation file.
+%
+{
+  \catcode`\_ = \active
+  \globaldefs=1
+\parseargdef\documentlanguage{\begingroup
+  \let_=\normalunderscore  % normal _ character for filenames
+  \tex % read txi-??.tex file in plain TeX.
+    % Read the file by the name they passed if it exists.
+    \openin 1 txi-#1.tex
+    \ifeof 1
+      \documentlanguagetrywithoutunderscore{#1_\finish}%
+    \else
+      \input txi-#1.tex
+    \fi
+    \closein 1
+  \endgroup
+\endgroup}
+}
+%
+% If they passed de_DE, and txi-de_DE.tex doesn't exist,
+% try txi-de.tex.
+%
+\def\documentlanguagetrywithoutunderscore#1_#2\finish{%
+  \openin 1 txi-#1.tex
+  \ifeof 1
+    \errhelp = \nolanghelp
+    \errmessage{Cannot read language file txi-#1.tex}%
+  \else
+    \input txi-#1.tex
+  \fi
+  \closein 1
+}
+%
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty.  Maybe you need to install it?  In the current directory
+should work if nowhere else does.}
+
+% Set the catcode of characters 128 through 255 to the specified number.
+%
+\def\setnonasciicharscatcode#1{%
+   \count255=128
+   \loop\ifnum\count255<256
+      \global\catcode\count255=#1\relax
+      \advance\count255 by 1
+   \repeat
+}
+
+\def\setnonasciicharscatcodenonglobal#1{%
+   \count255=128
+   \loop\ifnum\count255<256
+      \catcode\count255=#1\relax
+      \advance\count255 by 1
+   \repeat
+}
+
+% @documentencoding sets the definition of non-ASCII characters
+% according to the specified encoding.
+%
+\parseargdef\documentencoding{%
+  % Encoding being declared for the document.
+  \def\declaredencoding{\csname #1.enc\endcsname}%
+  %
+  % Supported encodings: names converted to tokens in order to be able
+  % to compare them with \ifx.
+  \def\ascii{\csname US-ASCII.enc\endcsname}%
+  \def\latnine{\csname ISO-8859-15.enc\endcsname}%
+  \def\latone{\csname ISO-8859-1.enc\endcsname}%
+  \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
+  \def\utfeight{\csname UTF-8.enc\endcsname}%
+  %
+  \ifx \declaredencoding \ascii
+     \asciichardefs
+  %
+  \else \ifx \declaredencoding \lattwo
+     \setnonasciicharscatcode\active
+     \lattwochardefs
+  %
+  \else \ifx \declaredencoding \latone
+     \setnonasciicharscatcode\active
+     \latonechardefs
+  %
+  \else \ifx \declaredencoding \latnine
+     \setnonasciicharscatcode\active
+     \latninechardefs
+  %
+  \else \ifx \declaredencoding \utfeight
+     \setnonasciicharscatcode\active
+     \utfeightchardefs
+  %
+  \else
+    \message{Unknown document encoding #1, ignoring.}%
+  %
+  \fi % utfeight
+  \fi % latnine
+  \fi % latone
+  \fi % lattwo
+  \fi % ascii
+}
+
+% A message to be logged when using a character that isn't available
+% the default font encoding (OT1).
+%
+\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
+
+% Take account of \c (plain) vs. \, (Texinfo) difference.
+\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
+
+% First, make active non-ASCII characters in order for them to be
+% correctly categorized when TeX reads the replacement text of
+% macros containing the character definitions.
+\setnonasciicharscatcode\active
+%
+% Latin1 (ISO-8859-1) character definitions.
+\def\latonechardefs{%
+  \gdef^^a0{~}
+  \gdef^^a1{\exclamdown}
+  \gdef^^a2{\missingcharmsg{CENT SIGN}}
+  \gdef^^a3{{\pounds}}
+  \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+  \gdef^^a5{\missingcharmsg{YEN SIGN}}
+  \gdef^^a6{\missingcharmsg{BROKEN BAR}}
+  \gdef^^a7{\S}
+  \gdef^^a8{\"{}}
+  \gdef^^a9{\copyright}
+  \gdef^^aa{\ordf}
+  \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}}
+  \gdef^^ac{$\lnot$}
+  \gdef^^ad{\-}
+  \gdef^^ae{\registeredsymbol}
+  \gdef^^af{\={}}
+  %
+  \gdef^^b0{\textdegree}
+  \gdef^^b1{$\pm$}
+  \gdef^^b2{$^2$}
+  \gdef^^b3{$^3$}
+  \gdef^^b4{\'{}}
+  \gdef^^b5{$\mu$}
+  \gdef^^b6{\P}
+  %
+  \gdef^^b7{$^.$}
+  \gdef^^b8{\cedilla\ }
+  \gdef^^b9{$^1$}
+  \gdef^^ba{\ordm}
+  %
+  \gdef^^bb{\missingcharmsg{RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK}}
+  \gdef^^bc{$1\over4$}
+  \gdef^^bd{$1\over2$}
+  \gdef^^be{$3\over4$}
+  \gdef^^bf{\questiondown}
+  %
+  \gdef^^c0{\`A}
+  \gdef^^c1{\'A}
+  \gdef^^c2{\^A}
+  \gdef^^c3{\~A}
+  \gdef^^c4{\"A}
+  \gdef^^c5{\ringaccent A}
+  \gdef^^c6{\AE}
+  \gdef^^c7{\cedilla C}
+  \gdef^^c8{\`E}
+  \gdef^^c9{\'E}
+  \gdef^^ca{\^E}
+  \gdef^^cb{\"E}
+  \gdef^^cc{\`I}
+  \gdef^^cd{\'I}
+  \gdef^^ce{\^I}
+  \gdef^^cf{\"I}
+  %
+  \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER ETH}}
+  \gdef^^d1{\~N}
+  \gdef^^d2{\`O}
+  \gdef^^d3{\'O}
+  \gdef^^d4{\^O}
+  \gdef^^d5{\~O}
+  \gdef^^d6{\"O}
+  \gdef^^d7{$\times$}
+  \gdef^^d8{\O}
+  \gdef^^d9{\`U}
+  \gdef^^da{\'U}
+  \gdef^^db{\^U}
+  \gdef^^dc{\"U}
+  \gdef^^dd{\'Y}
+  \gdef^^de{\missingcharmsg{LATIN CAPITAL LETTER THORN}}
+  \gdef^^df{\ss}
+  %
+  \gdef^^e0{\`a}
+  \gdef^^e1{\'a}
+  \gdef^^e2{\^a}
+  \gdef^^e3{\~a}
+  \gdef^^e4{\"a}
+  \gdef^^e5{\ringaccent a}
+  \gdef^^e6{\ae}
+  \gdef^^e7{\cedilla c}
+  \gdef^^e8{\`e}
+  \gdef^^e9{\'e}
+  \gdef^^ea{\^e}
+  \gdef^^eb{\"e}
+  \gdef^^ec{\`{\dotless i}}
+  \gdef^^ed{\'{\dotless i}}
+  \gdef^^ee{\^{\dotless i}}
+  \gdef^^ef{\"{\dotless i}}
+  %
+  \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER ETH}}
+  \gdef^^f1{\~n}
+  \gdef^^f2{\`o}
+  \gdef^^f3{\'o}
+  \gdef^^f4{\^o}
+  \gdef^^f5{\~o}
+  \gdef^^f6{\"o}
+  \gdef^^f7{$\div$}
+  \gdef^^f8{\o}
+  \gdef^^f9{\`u}
+  \gdef^^fa{\'u}
+  \gdef^^fb{\^u}
+  \gdef^^fc{\"u}
+  \gdef^^fd{\'y}
+  \gdef^^fe{\missingcharmsg{LATIN SMALL LETTER THORN}}
+  \gdef^^ff{\"y}
+}
+
+% Latin9 (ISO-8859-15) encoding character definitions.
+\def\latninechardefs{%
+  % Encoding is almost identical to Latin1.
+  \latonechardefs
+  %
+  \gdef^^a4{\euro}
+  \gdef^^a6{\v S}
+  \gdef^^a8{\v s}
+  \gdef^^b4{\v Z}
+  \gdef^^b8{\v z}
+  \gdef^^bc{\OE}
+  \gdef^^bd{\oe}
+  \gdef^^be{\"Y}
+}
+
+% Latin2 (ISO-8859-2) character definitions.
+\def\lattwochardefs{%
+  \gdef^^a0{~}
+  \gdef^^a1{\missingcharmsg{LATIN CAPITAL LETTER A WITH OGONEK}}
+  \gdef^^a2{\u{}}
+  \gdef^^a3{\L}
+  \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+  \gdef^^a5{\v L}
+  \gdef^^a6{\'S}
+  \gdef^^a7{\S}
+  \gdef^^a8{\"{}}
+  \gdef^^a9{\v S}
+  \gdef^^aa{\cedilla S}
+  \gdef^^ab{\v T}
+  \gdef^^ac{\'Z}
+  \gdef^^ad{\-}
+  \gdef^^ae{\v Z}
+  \gdef^^af{\dotaccent Z}
+  %
+  \gdef^^b0{\textdegree}
+  \gdef^^b1{\missingcharmsg{LATIN SMALL LETTER A WITH OGONEK}}
+  \gdef^^b2{\missingcharmsg{OGONEK}}
+  \gdef^^b3{\l}
+  \gdef^^b4{\'{}}
+  \gdef^^b5{\v l}
+  \gdef^^b6{\'s}
+  \gdef^^b7{\v{}}
+  \gdef^^b8{\cedilla\ }
+  \gdef^^b9{\v s}
+  \gdef^^ba{\cedilla s}
+  \gdef^^bb{\v t}
+  \gdef^^bc{\'z}
+  \gdef^^bd{\H{}}
+  \gdef^^be{\v z}
+  \gdef^^bf{\dotaccent z}
+  %
+  \gdef^^c0{\'R}
+  \gdef^^c1{\'A}
+  \gdef^^c2{\^A}
+  \gdef^^c3{\u A}
+  \gdef^^c4{\"A}
+  \gdef^^c5{\'L}
+  \gdef^^c6{\'C}
+  \gdef^^c7{\cedilla C}
+  \gdef^^c8{\v C}
+  \gdef^^c9{\'E}
+  \gdef^^ca{\missingcharmsg{LATIN CAPITAL LETTER E WITH OGONEK}}
+  \gdef^^cb{\"E}
+  \gdef^^cc{\v E}
+  \gdef^^cd{\'I}
+  \gdef^^ce{\^I}
+  \gdef^^cf{\v D}
+  %
+  \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER D WITH STROKE}}
+  \gdef^^d1{\'N}
+  \gdef^^d2{\v N}
+  \gdef^^d3{\'O}
+  \gdef^^d4{\^O}
+  \gdef^^d5{\H O}
+  \gdef^^d6{\"O}
+  \gdef^^d7{$\times$}
+  \gdef^^d8{\v R}
+  \gdef^^d9{\ringaccent U}
+  \gdef^^da{\'U}
+  \gdef^^db{\H U}
+  \gdef^^dc{\"U}
+  \gdef^^dd{\'Y}
+  \gdef^^de{\cedilla T}
+  \gdef^^df{\ss}
+  %
+  \gdef^^e0{\'r}
+  \gdef^^e1{\'a}
+  \gdef^^e2{\^a}
+  \gdef^^e3{\u a}
+  \gdef^^e4{\"a}
+  \gdef^^e5{\'l}
+  \gdef^^e6{\'c}
+  \gdef^^e7{\cedilla c}
+  \gdef^^e8{\v c}
+  \gdef^^e9{\'e}
+  \gdef^^ea{\missingcharmsg{LATIN SMALL LETTER E WITH OGONEK}}
+  \gdef^^eb{\"e}
+  \gdef^^ec{\v e}
+  \gdef^^ed{\'\i}
+  \gdef^^ee{\^\i}
+  \gdef^^ef{\v d}
+  %
+  \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER D WITH STROKE}}
+  \gdef^^f1{\'n}
+  \gdef^^f2{\v n}
+  \gdef^^f3{\'o}
+  \gdef^^f4{\^o}
+  \gdef^^f5{\H o}
+  \gdef^^f6{\"o}
+  \gdef^^f7{$\div$}
+  \gdef^^f8{\v r}
+  \gdef^^f9{\ringaccent u}
+  \gdef^^fa{\'u}
+  \gdef^^fb{\H u}
+  \gdef^^fc{\"u}
+  \gdef^^fd{\'y}
+  \gdef^^fe{\cedilla t}
+  \gdef^^ff{\dotaccent{}}
+}
+
+% UTF-8 character definitions.
+%
+% This code to support UTF-8 is based on LaTeX's utf8.def, with some
+% changes for Texinfo conventions.  It is included here under the GPL by
+% permission from Frank Mittelbach and the LaTeX team.
+%
+\newcount\countUTFx
+\newcount\countUTFy
+\newcount\countUTFz
+
+\gdef\UTFviiiTwoOctets#1#2{\expandafter
+   \UTFviiiDefined\csname u8:#1\string #2\endcsname}
+%
+\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
+   \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
+%
+\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
+   \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
+
+\gdef\UTFviiiDefined#1{%
+  \ifx #1\relax
+    \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
+  \else
+    \expandafter #1%
+  \fi
+}
+
+\begingroup
+  \catcode`\~13
+  \catcode`\"12
+
+  \def\UTFviiiLoop{%
+    \global\catcode\countUTFx\active
+    \uccode`\~\countUTFx
+    \uppercase\expandafter{\UTFviiiTmp}%
+    \advance\countUTFx by 1
+    \ifnum\countUTFx < \countUTFy
+      \expandafter\UTFviiiLoop
+    \fi}
+
+  \countUTFx = "C2
+  \countUTFy = "E0
+  \def\UTFviiiTmp{%
+    \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
+  \UTFviiiLoop
+
+  \countUTFx = "E0
+  \countUTFy = "F0
+  \def\UTFviiiTmp{%
+    \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
+  \UTFviiiLoop
+
+  \countUTFx = "F0
+  \countUTFy = "F4
+  \def\UTFviiiTmp{%
+    \xdef~{\noexpand\UTFviiiFourOctets\string~}}
+  \UTFviiiLoop
+\endgroup
+
+\begingroup
+  \catcode`\"=12
+  \catcode`\<=12
+  \catcode`\.=12
+  \catcode`\,=12
+  \catcode`\;=12
+  \catcode`\!=12
+  \catcode`\~=13
+
+  \gdef\DeclareUnicodeCharacter#1#2{%
+    \countUTFz = "#1\relax
+    \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+    \begingroup
+      \parseXMLCharref
+      \def\UTFviiiTwoOctets##1##2{%
+        \csname u8:##1\string ##2\endcsname}%
+      \def\UTFviiiThreeOctets##1##2##3{%
+        \csname u8:##1\string ##2\string ##3\endcsname}%
+      \def\UTFviiiFourOctets##1##2##3##4{%
+        \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
+      \expandafter\expandafter\expandafter\expandafter
+       \expandafter\expandafter\expandafter
+       \gdef\UTFviiiTmp{#2}%
+    \endgroup}
+
+  \gdef\parseXMLCharref{%
+    \ifnum\countUTFz < "A0\relax
+      \errhelp = \EMsimple
+      \errmessage{Cannot define Unicode char value < 00A0}%
+    \else\ifnum\countUTFz < "800\relax
+      \parseUTFviiiA,%
+      \parseUTFviiiB C\UTFviiiTwoOctets.,%
+    \else\ifnum\countUTFz < "10000\relax
+      \parseUTFviiiA;%
+      \parseUTFviiiA,%
+      \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
+    \else
+      \parseUTFviiiA;%
+      \parseUTFviiiA,%
+      \parseUTFviiiA!%
+      \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
+    \fi\fi\fi
+  }
+
+  \gdef\parseUTFviiiA#1{%
+    \countUTFx = \countUTFz
+    \divide\countUTFz by 64
+    \countUTFy = \countUTFz
+    \multiply\countUTFz by 64
+    \advance\countUTFx by -\countUTFz
+    \advance\countUTFx by 128
+    \uccode `#1\countUTFx
+    \countUTFz = \countUTFy}
+
+  \gdef\parseUTFviiiB#1#2#3#4{%
+    \advance\countUTFz by "#10\relax
+    \uccode `#3\countUTFz
+    \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
+\endgroup
+
+\def\utfeightchardefs{%
+  \DeclareUnicodeCharacter{00A0}{\tie}
+  \DeclareUnicodeCharacter{00A1}{\exclamdown}
+  \DeclareUnicodeCharacter{00A3}{\pounds}
+  \DeclareUnicodeCharacter{00A8}{\"{ }}
+  \DeclareUnicodeCharacter{00A9}{\copyright}
+  \DeclareUnicodeCharacter{00AA}{\ordf}
+  \DeclareUnicodeCharacter{00AB}{\guillemetleft}
+  \DeclareUnicodeCharacter{00AD}{\-}
+  \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
+  \DeclareUnicodeCharacter{00AF}{\={ }}
+
+  \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
+  \DeclareUnicodeCharacter{00B4}{\'{ }}
+  \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
+  \DeclareUnicodeCharacter{00BA}{\ordm}
+  \DeclareUnicodeCharacter{00BB}{\guillemetright}
+  \DeclareUnicodeCharacter{00BF}{\questiondown}
+
+  \DeclareUnicodeCharacter{00C0}{\`A}
+  \DeclareUnicodeCharacter{00C1}{\'A}
+  \DeclareUnicodeCharacter{00C2}{\^A}
+  \DeclareUnicodeCharacter{00C3}{\~A}
+  \DeclareUnicodeCharacter{00C4}{\"A}
+  \DeclareUnicodeCharacter{00C5}{\AA}
+  \DeclareUnicodeCharacter{00C6}{\AE}
+  \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
+  \DeclareUnicodeCharacter{00C8}{\`E}
+  \DeclareUnicodeCharacter{00C9}{\'E}
+  \DeclareUnicodeCharacter{00CA}{\^E}
+  \DeclareUnicodeCharacter{00CB}{\"E}
+  \DeclareUnicodeCharacter{00CC}{\`I}
+  \DeclareUnicodeCharacter{00CD}{\'I}
+  \DeclareUnicodeCharacter{00CE}{\^I}
+  \DeclareUnicodeCharacter{00CF}{\"I}
+
+  \DeclareUnicodeCharacter{00D1}{\~N}
+  \DeclareUnicodeCharacter{00D2}{\`O}
+  \DeclareUnicodeCharacter{00D3}{\'O}
+  \DeclareUnicodeCharacter{00D4}{\^O}
+  \DeclareUnicodeCharacter{00D5}{\~O}
+  \DeclareUnicodeCharacter{00D6}{\"O}
+  \DeclareUnicodeCharacter{00D8}{\O}
+  \DeclareUnicodeCharacter{00D9}{\`U}
+  \DeclareUnicodeCharacter{00DA}{\'U}
+  \DeclareUnicodeCharacter{00DB}{\^U}
+  \DeclareUnicodeCharacter{00DC}{\"U}
+  \DeclareUnicodeCharacter{00DD}{\'Y}
+  \DeclareUnicodeCharacter{00DF}{\ss}
+
+  \DeclareUnicodeCharacter{00E0}{\`a}
+  \DeclareUnicodeCharacter{00E1}{\'a}
+  \DeclareUnicodeCharacter{00E2}{\^a}
+  \DeclareUnicodeCharacter{00E3}{\~a}
+  \DeclareUnicodeCharacter{00E4}{\"a}
+  \DeclareUnicodeCharacter{00E5}{\aa}
+  \DeclareUnicodeCharacter{00E6}{\ae}
+  \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
+  \DeclareUnicodeCharacter{00E8}{\`e}
+  \DeclareUnicodeCharacter{00E9}{\'e}
+  \DeclareUnicodeCharacter{00EA}{\^e}
+  \DeclareUnicodeCharacter{00EB}{\"e}
+  \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
+  \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
+  \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
+  \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
+
+  \DeclareUnicodeCharacter{00F1}{\~n}
+  \DeclareUnicodeCharacter{00F2}{\`o}
+  \DeclareUnicodeCharacter{00F3}{\'o}
+  \DeclareUnicodeCharacter{00F4}{\^o}
+  \DeclareUnicodeCharacter{00F5}{\~o}
+  \DeclareUnicodeCharacter{00F6}{\"o}
+  \DeclareUnicodeCharacter{00F8}{\o}
+  \DeclareUnicodeCharacter{00F9}{\`u}
+  \DeclareUnicodeCharacter{00FA}{\'u}
+  \DeclareUnicodeCharacter{00FB}{\^u}
+  \DeclareUnicodeCharacter{00FC}{\"u}
+  \DeclareUnicodeCharacter{00FD}{\'y}
+  \DeclareUnicodeCharacter{00FF}{\"y}
+
+  \DeclareUnicodeCharacter{0100}{\=A}
+  \DeclareUnicodeCharacter{0101}{\=a}
+  \DeclareUnicodeCharacter{0102}{\u{A}}
+  \DeclareUnicodeCharacter{0103}{\u{a}}
+  \DeclareUnicodeCharacter{0106}{\'C}
+  \DeclareUnicodeCharacter{0107}{\'c}
+  \DeclareUnicodeCharacter{0108}{\^C}
+  \DeclareUnicodeCharacter{0109}{\^c}
+  \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
+  \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
+  \DeclareUnicodeCharacter{010C}{\v{C}}
+  \DeclareUnicodeCharacter{010D}{\v{c}}
+  \DeclareUnicodeCharacter{010E}{\v{D}}
+
+  \DeclareUnicodeCharacter{0112}{\=E}
+  \DeclareUnicodeCharacter{0113}{\=e}
+  \DeclareUnicodeCharacter{0114}{\u{E}}
+  \DeclareUnicodeCharacter{0115}{\u{e}}
+  \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
+  \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
+  \DeclareUnicodeCharacter{011A}{\v{E}}
+  \DeclareUnicodeCharacter{011B}{\v{e}}
+  \DeclareUnicodeCharacter{011C}{\^G}
+  \DeclareUnicodeCharacter{011D}{\^g}
+  \DeclareUnicodeCharacter{011E}{\u{G}}
+  \DeclareUnicodeCharacter{011F}{\u{g}}
+
+  \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
+  \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
+  \DeclareUnicodeCharacter{0124}{\^H}
+  \DeclareUnicodeCharacter{0125}{\^h}
+  \DeclareUnicodeCharacter{0128}{\~I}
+  \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
+  \DeclareUnicodeCharacter{012A}{\=I}
+  \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
+  \DeclareUnicodeCharacter{012C}{\u{I}}
+  \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
+
+  \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
+  \DeclareUnicodeCharacter{0131}{\dotless{i}}
+  \DeclareUnicodeCharacter{0132}{IJ}
+  \DeclareUnicodeCharacter{0133}{ij}
+  \DeclareUnicodeCharacter{0134}{\^J}
+  \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
+  \DeclareUnicodeCharacter{0139}{\'L}
+  \DeclareUnicodeCharacter{013A}{\'l}
+
+  \DeclareUnicodeCharacter{0141}{\L}
+  \DeclareUnicodeCharacter{0142}{\l}
+  \DeclareUnicodeCharacter{0143}{\'N}
+  \DeclareUnicodeCharacter{0144}{\'n}
+  \DeclareUnicodeCharacter{0147}{\v{N}}
+  \DeclareUnicodeCharacter{0148}{\v{n}}
+  \DeclareUnicodeCharacter{014C}{\=O}
+  \DeclareUnicodeCharacter{014D}{\=o}
+  \DeclareUnicodeCharacter{014E}{\u{O}}
+  \DeclareUnicodeCharacter{014F}{\u{o}}
+
+  \DeclareUnicodeCharacter{0150}{\H{O}}
+  \DeclareUnicodeCharacter{0151}{\H{o}}
+  \DeclareUnicodeCharacter{0152}{\OE}
+  \DeclareUnicodeCharacter{0153}{\oe}
+  \DeclareUnicodeCharacter{0154}{\'R}
+  \DeclareUnicodeCharacter{0155}{\'r}
+  \DeclareUnicodeCharacter{0158}{\v{R}}
+  \DeclareUnicodeCharacter{0159}{\v{r}}
+  \DeclareUnicodeCharacter{015A}{\'S}
+  \DeclareUnicodeCharacter{015B}{\'s}
+  \DeclareUnicodeCharacter{015C}{\^S}
+  \DeclareUnicodeCharacter{015D}{\^s}
+  \DeclareUnicodeCharacter{015E}{\cedilla{S}}
+  \DeclareUnicodeCharacter{015F}{\cedilla{s}}
+
+  \DeclareUnicodeCharacter{0160}{\v{S}}
+  \DeclareUnicodeCharacter{0161}{\v{s}}
+  \DeclareUnicodeCharacter{0162}{\cedilla{t}}
+  \DeclareUnicodeCharacter{0163}{\cedilla{T}}
+  \DeclareUnicodeCharacter{0164}{\v{T}}
+
+  \DeclareUnicodeCharacter{0168}{\~U}
+  \DeclareUnicodeCharacter{0169}{\~u}
+  \DeclareUnicodeCharacter{016A}{\=U}
+  \DeclareUnicodeCharacter{016B}{\=u}
+  \DeclareUnicodeCharacter{016C}{\u{U}}
+  \DeclareUnicodeCharacter{016D}{\u{u}}
+  \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
+  \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
+
+  \DeclareUnicodeCharacter{0170}{\H{U}}
+  \DeclareUnicodeCharacter{0171}{\H{u}}
+  \DeclareUnicodeCharacter{0174}{\^W}
+  \DeclareUnicodeCharacter{0175}{\^w}
+  \DeclareUnicodeCharacter{0176}{\^Y}
+  \DeclareUnicodeCharacter{0177}{\^y}
+  \DeclareUnicodeCharacter{0178}{\"Y}
+  \DeclareUnicodeCharacter{0179}{\'Z}
+  \DeclareUnicodeCharacter{017A}{\'z}
+  \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
+  \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
+  \DeclareUnicodeCharacter{017D}{\v{Z}}
+  \DeclareUnicodeCharacter{017E}{\v{z}}
+
+  \DeclareUnicodeCharacter{01C4}{D\v{Z}}
+  \DeclareUnicodeCharacter{01C5}{D\v{z}}
+  \DeclareUnicodeCharacter{01C6}{d\v{z}}
+  \DeclareUnicodeCharacter{01C7}{LJ}
+  \DeclareUnicodeCharacter{01C8}{Lj}
+  \DeclareUnicodeCharacter{01C9}{lj}
+  \DeclareUnicodeCharacter{01CA}{NJ}
+  \DeclareUnicodeCharacter{01CB}{Nj}
+  \DeclareUnicodeCharacter{01CC}{nj}
+  \DeclareUnicodeCharacter{01CD}{\v{A}}
+  \DeclareUnicodeCharacter{01CE}{\v{a}}
+  \DeclareUnicodeCharacter{01CF}{\v{I}}
+
+  \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
+  \DeclareUnicodeCharacter{01D1}{\v{O}}
+  \DeclareUnicodeCharacter{01D2}{\v{o}}
+  \DeclareUnicodeCharacter{01D3}{\v{U}}
+  \DeclareUnicodeCharacter{01D4}{\v{u}}
+
+  \DeclareUnicodeCharacter{01E2}{\={\AE}}
+  \DeclareUnicodeCharacter{01E3}{\={\ae}}
+  \DeclareUnicodeCharacter{01E6}{\v{G}}
+  \DeclareUnicodeCharacter{01E7}{\v{g}}
+  \DeclareUnicodeCharacter{01E8}{\v{K}}
+  \DeclareUnicodeCharacter{01E9}{\v{k}}
+
+  \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
+  \DeclareUnicodeCharacter{01F1}{DZ}
+  \DeclareUnicodeCharacter{01F2}{Dz}
+  \DeclareUnicodeCharacter{01F3}{dz}
+  \DeclareUnicodeCharacter{01F4}{\'G}
+  \DeclareUnicodeCharacter{01F5}{\'g}
+  \DeclareUnicodeCharacter{01F8}{\`N}
+  \DeclareUnicodeCharacter{01F9}{\`n}
+  \DeclareUnicodeCharacter{01FC}{\'{\AE}}
+  \DeclareUnicodeCharacter{01FD}{\'{\ae}}
+  \DeclareUnicodeCharacter{01FE}{\'{\O}}
+  \DeclareUnicodeCharacter{01FF}{\'{\o}}
+
+  \DeclareUnicodeCharacter{021E}{\v{H}}
+  \DeclareUnicodeCharacter{021F}{\v{h}}
+
+  \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
+  \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
+  \DeclareUnicodeCharacter{0228}{\cedilla{E}}
+  \DeclareUnicodeCharacter{0229}{\cedilla{e}}
+  \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
+  \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
+
+  \DeclareUnicodeCharacter{0232}{\=Y}
+  \DeclareUnicodeCharacter{0233}{\=y}
+  \DeclareUnicodeCharacter{0237}{\dotless{j}}
+
+  \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
+  \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
+  \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
+  \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
+  \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
+  \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
+  \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
+  \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
+  \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
+  \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
+  \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
+  \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
+
+  \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
+  \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
+
+  \DeclareUnicodeCharacter{1E20}{\=G}
+  \DeclareUnicodeCharacter{1E21}{\=g}
+  \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
+  \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
+  \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
+  \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
+  \DeclareUnicodeCharacter{1E26}{\"H}
+  \DeclareUnicodeCharacter{1E27}{\"h}
+
+  \DeclareUnicodeCharacter{1E30}{\'K}
+  \DeclareUnicodeCharacter{1E31}{\'k}
+  \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
+  \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
+  \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
+  \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
+  \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
+  \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
+  \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
+  \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
+  \DeclareUnicodeCharacter{1E3E}{\'M}
+  \DeclareUnicodeCharacter{1E3F}{\'m}
+
+  \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
+  \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
+  \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
+  \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
+  \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
+  \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
+  \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
+  \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
+  \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
+  \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
+
+  \DeclareUnicodeCharacter{1E54}{\'P}
+  \DeclareUnicodeCharacter{1E55}{\'p}
+  \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
+  \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
+  \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
+  \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
+  \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
+  \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
+  \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
+  \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
+
+  \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
+  \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
+  \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
+  \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
+  \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
+  \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
+  \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
+  \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
+  \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
+  \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
+
+  \DeclareUnicodeCharacter{1E7C}{\~V}
+  \DeclareUnicodeCharacter{1E7D}{\~v}
+  \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
+  \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
+
+  \DeclareUnicodeCharacter{1E80}{\`W}
+  \DeclareUnicodeCharacter{1E81}{\`w}
+  \DeclareUnicodeCharacter{1E82}{\'W}
+  \DeclareUnicodeCharacter{1E83}{\'w}
+  \DeclareUnicodeCharacter{1E84}{\"W}
+  \DeclareUnicodeCharacter{1E85}{\"w}
+  \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
+  \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
+  \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
+  \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
+  \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
+  \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
+  \DeclareUnicodeCharacter{1E8C}{\"X}
+  \DeclareUnicodeCharacter{1E8D}{\"x}
+  \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
+  \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
+
+  \DeclareUnicodeCharacter{1E90}{\^Z}
+  \DeclareUnicodeCharacter{1E91}{\^z}
+  \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
+  \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
+  \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
+  \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
+  \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
+  \DeclareUnicodeCharacter{1E97}{\"t}
+  \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
+  \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
+
+  \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
+  \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
+
+  \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
+  \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
+  \DeclareUnicodeCharacter{1EBC}{\~E}
+  \DeclareUnicodeCharacter{1EBD}{\~e}
+
+  \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
+  \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
+  \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
+  \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
+
+  \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
+  \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
+
+  \DeclareUnicodeCharacter{1EF2}{\`Y}
+  \DeclareUnicodeCharacter{1EF3}{\`y}
+  \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
+
+  \DeclareUnicodeCharacter{1EF8}{\~Y}
+  \DeclareUnicodeCharacter{1EF9}{\~y}
+
+  \DeclareUnicodeCharacter{2013}{--}
+  \DeclareUnicodeCharacter{2014}{---}
+  \DeclareUnicodeCharacter{2018}{\quoteleft}
+  \DeclareUnicodeCharacter{2019}{\quoteright}
+  \DeclareUnicodeCharacter{201A}{\quotesinglbase}
+  \DeclareUnicodeCharacter{201C}{\quotedblleft}
+  \DeclareUnicodeCharacter{201D}{\quotedblright}
+  \DeclareUnicodeCharacter{201E}{\quotedblbase}
+  \DeclareUnicodeCharacter{2022}{\bullet}
+  \DeclareUnicodeCharacter{2026}{\dots}
+  \DeclareUnicodeCharacter{2039}{\guilsinglleft}
+  \DeclareUnicodeCharacter{203A}{\guilsinglright}
+  \DeclareUnicodeCharacter{20AC}{\euro}
+
+  \DeclareUnicodeCharacter{2192}{\expansion}
+  \DeclareUnicodeCharacter{21D2}{\result}
+
+  \DeclareUnicodeCharacter{2212}{\minus}
+  \DeclareUnicodeCharacter{2217}{\point}
+  \DeclareUnicodeCharacter{2261}{\equiv}
+}% end of \utfeightchardefs
+
+
+% US-ASCII character definitions.
+\def\asciichardefs{% nothing need be done
+   \relax
+}
+
+% Make non-ASCII characters printable again for compatibility with
+% existing Texinfo documents that may use them, even without declaring a
+% document encoding.
+%
+\setnonasciicharscatcode \other
+
+
+\message{formatting,}
+
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be so finicky about underfull hboxes, either.
+\hbadness = 2000
+
+% Following George Bush, get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything.  We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize.  We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+  \ifx\emergencystretch\thisisundefined
+    % Allow us to assign to \emergencystretch anyway.
+    \def\emergencystretch{\dimen0}%
+  \else
+    \emergencystretch = .15\hsize
+  \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth;
+% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
+% 7) physical page height; 8) physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading.  The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+  \voffset = #3\relax
+  \topskip = #6\relax
+  \splittopskip = \topskip
+  %
+  \vsize = #1\relax
+  \advance\vsize by \topskip
+  \outervsize = \vsize
+  \advance\outervsize by 2\topandbottommargin
+  \pageheight = \vsize
+  %
+  \hsize = #2\relax
+  \outerhsize = \hsize
+  \advance\outerhsize by 0.5in
+  \pagewidth = \hsize
+  %
+  \normaloffset = #4\relax
+  \bindingoffset = #5\relax
+  %
+  \ifpdf
+    \pdfpageheight #7\relax
+    \pdfpagewidth #8\relax
+    % if we don't reset these, they will remain at "1 true in" of
+    % whatever layout pdftex was dumped with.
+    \pdfhorigin = 1 true in
+    \pdfvorigin = 1 true in
+  \fi
+  %
+  \setleading{\textleading}
+  %
+  \parindent = \defaultparindent
+  \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+  \parskip = 3pt plus 2pt minus 1pt
+  \textleading = 13.2pt
+  %
+  % If page is nothing but text, make it come out even.
+  \internalpagesizes{607.2pt}{6in}% that's 46 lines
+                    {\voffset}{.25in}%
+                    {\bindingoffset}{36pt}%
+                    {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.25 trim size.
+\def\smallbook{{\globaldefs = 1
+  \parskip = 2pt plus 1pt
+  \textleading = 12pt
+  %
+  \internalpagesizes{7.5in}{5in}%
+                    {-.2in}{0in}%
+                    {\bindingoffset}{16pt}%
+                    {9.25in}{7in}%
+  %
+  \lispnarrowing = 0.3in
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = .5cm
+}}
+
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+  \parskip = 1.5pt plus 1pt
+  \textleading = 12pt
+  %
+  \internalpagesizes{7.4in}{4.8in}%
+                    {-.2in}{-.4in}%
+                    {0pt}{14pt}%
+                    {9in}{6in}%
+  %
+  \lispnarrowing = 0.25in
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = .4cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+  \parskip = 3pt plus 2pt minus 1pt
+  \textleading = 13.2pt
+  %
+  % Double-side printing via postscript on Laserjet 4050
+  % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+  % To change the settings for a different printer or situation, adjust
+  % \normaloffset until the front-side and back-side texts align.  Then
+  % do the same for \bindingoffset.  You can set these for testing in
+  % your texinfo source file like this:
+  % @tex
+  % \global\normaloffset = -6mm
+  % \global\bindingoffset = 10mm
+  % @end tex
+  \internalpagesizes{673.2pt}{160mm}% that's 51 lines
+                    {\voffset}{\hoffset}%
+                    {\bindingoffset}{44pt}%
+                    {297mm}{210mm}%
+  %
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo@urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+  \parskip = 2pt plus 1pt minus 0.1pt
+  \textleading = 12.5pt
+  %
+  \internalpagesizes{160mm}{120mm}%
+                    {\voffset}{\hoffset}%
+                    {\bindingoffset}{8pt}%
+                    {210mm}{148mm}%
+  %
+  \lispnarrowing = 0.2in
+  \tolerance = 800
+  \hfuzz = 1.2pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = 2mm
+  \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+  \afourpaper
+  \internalpagesizes{237mm}{150mm}%
+                    {\voffset}{4.6mm}%
+                    {\bindingoffset}{7mm}%
+                    {297mm}{210mm}%
+  %
+  % Must explicitly reset to 0 because we call \afourpaper.
+  \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+  \afourpaper
+  \internalpagesizes{241mm}{165mm}%
+                    {\voffset}{-2.95mm}%
+                    {\bindingoffset}{7mm}%
+                    {297mm}{210mm}%
+  \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+  \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+  \globaldefs = 1
+  %
+  \parskip = 3pt plus 2pt minus 1pt
+  \setleading{\textleading}%
+  %
+  \dimen0 = #1\relax
+  \advance\dimen0 by \voffset
+  %
+  \dimen2 = \hsize
+  \advance\dimen2 by \normaloffset
+  %
+  \internalpagesizes{#1}{\hsize}%
+                    {\voffset}{\normaloffset}%
+                    {\bindingoffset}{44pt}%
+                    {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\catcode`\$=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+\def\normaldollar{$}%$ font-lock fix
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise.  Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font.  Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts.  But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+\let\realunder=_
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+% Used sometimes to turn off (effectively) the active characters even after
+% parsing them.
+\def\turnoffactive{%
+  \normalturnoffactive
+  \otherbackslash
+}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont  % let existing .??s files work
+
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}}
+
+% In texinfo, backslash is an active character; it prints the backslash
+% in fixed width font.
+\catcode`\\=\active
+@def@normalbackslash{{@tt@backslashcurfont}}
+% On startup, @fixbackslash assigns:
+%  @let \ = @normalbackslash
+
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other.
+@gdef@rawbackslash{@let\=@backslashcurfont}
+@gdef@otherbackslash{@let\=@realbackslash}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'.
+%
+@def@normalturnoffactive{%
+  @let\=@normalbackslash
+  @let"=@normaldoublequote
+  @let~=@normaltilde
+  @let^=@normalcaret
+  @let_=@normalunderscore
+  @let|=@normalverticalbar
+  @let<=@normalless
+  @let>=@normalgreater
+  @let+=@normalplus
+  @let$=@normaldollar %$ font-lock fix
+  @unsepspaces
+}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\' in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also turn back on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{%
+  @ifx\@eatinput @let\ = @normalbackslash @fi
+  @catcode`+=@active
+  @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+@escapechar = `@@
+
+% These look ok in all fonts, so just make them not special.
+@catcode`@& = @other
+@catcode`@# = @other
+@catcode`@% = @other
+
+
+@c Local variables:
+@c eval: (add-hook 'write-file-hooks 'time-stamp)
+@c page-delimiter: "^\\\\message"
+@c time-stamp-start: "def\\\\texinfoversion{"
+@c time-stamp-format: "%:y-%02m-%02d.%02H"
+@c time-stamp-end: "}"
+@c End:
+
+@c vim:sw=2:
+
+@ignore
+   arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
diff --git a/efiemu/i386/coredetect.c b/efiemu/i386/coredetect.c
new file mode 100644
index 0000000..828508d
--- /dev/null
+++ b/efiemu/i386/coredetect.c
@@ -0,0 +1,60 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/efiemu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/command.h>
+
+#define cpuid(num,a,b,c,d) \
+  asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
+		: "=a" (a), "=r" (b), "=c" (c), "=d" (d)  \
+		: "0" (num))
+
+#define bit_LM (1 << 29)
+
+char *
+grub_efiemu_get_default_core_name (void)
+{
+
+  unsigned int eax, ebx, ecx, edx;
+  unsigned int max_level;
+  unsigned int ext_level;
+
+  /* See if we can use cpuid.  */
+  asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
+		"pushl %0; popfl; pushfl; popl %0; popfl"
+		: "=&r" (eax), "=&r" (ebx)
+		: "i" (0x00200000));
+  if (((eax ^ ebx) & 0x00200000) == 0)
+    return "efiemu32.o";
+
+  /* Check the highest input value for eax.  */
+  cpuid (0, eax, ebx, ecx, edx);
+  /* We only look at the first four characters.  */
+  max_level = eax;
+  if (max_level == 0)
+    return "efiemu32.o";
+
+  cpuid (0x80000000, eax, ebx, ecx, edx);
+  ext_level = eax;
+  if (ext_level < 0x80000000)
+    return "efiemu32.o";
+
+  cpuid (0x80000001, eax, ebx, ecx, edx);
+  return (edx & bit_LM) ? "efiemu64.o" : "efiemu32.o";
+}
diff --git a/efiemu/i386/loadcore32.c b/efiemu/i386/loadcore32.c
new file mode 100644
index 0000000..24b63ec
--- /dev/null
+++ b/efiemu/i386/loadcore32.c
@@ -0,0 +1,114 @@
+/* i386 CPU-specific part of loadcore.c for 32-bit mode */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+#include <grub/elf.h>
+
+/* Check if EHDR is a valid ELF header.  */
+int
+grub_arch_efiemu_check_header32 (void *ehdr)
+{
+  Elf32_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+  return (e->e_ident[EI_CLASS] == ELFCLASS32
+	  && e->e_ident[EI_DATA] == ELFDATA2LSB
+	  && e->e_machine == EM_386);
+}
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_efiemu_relocate_symbols32 (grub_efiemu_segment_t segs,
+				     struct grub_efiemu_elf_sym *elfsyms,
+				     void *ehdr)
+{
+  unsigned i;
+  Elf32_Ehdr *e = ehdr;
+  Elf32_Shdr *s;
+  grub_err_t err;
+
+  grub_dprintf ("efiemu", "relocating symbols %d %d\n",
+		e->e_shoff, e->e_shnum);
+
+  for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_REL)
+      {
+	grub_efiemu_segment_t seg;
+	grub_dprintf ("efiemu", "shtrel\n");
+
+	/* Find the target segment.  */
+	for (seg = segs; seg; seg = seg->next)
+	  if (seg->section == s->sh_info)
+	    break;
+
+	if (seg)
+	  {
+	    Elf32_Rel *rel, *max;
+
+	    for (rel = (Elf32_Rel *) ((char *) e + s->sh_offset),
+		   max = rel + s->sh_size / s->sh_entsize;
+		 rel < max;
+		 rel++)
+	      {
+		Elf32_Word *addr;
+		struct grub_efiemu_elf_sym sym;
+		if (seg->size < rel->r_offset)
+		  return grub_error (GRUB_ERR_BAD_MODULE,
+				     "reloc offset is out of the segment");
+
+		addr = (Elf32_Word *)
+		  ((char *) grub_efiemu_mm_obtain_request (seg->handle)
+		   + seg->off + rel->r_offset);
+		sym = elfsyms[ELF32_R_SYM (rel->r_info)];
+
+		switch (ELF32_R_TYPE (rel->r_info))
+		  {
+		  case R_386_32:
+		    if ((err = grub_efiemu_write_value
+			 (addr, sym.off + *addr, sym.handle, 0,
+			  seg->ptv_rel_needed, sizeof (grub_uint32_t))))
+		      return err;
+
+		    break;
+
+		  case R_386_PC32:
+		    if ((err = grub_efiemu_write_value
+			 (addr, sym.off + *addr - rel->r_offset
+			  - seg->off, sym.handle, seg->handle,
+			  seg->ptv_rel_needed, sizeof (grub_uint32_t))))
+		      return err;
+		    break;
+		  default:
+		    return grub_error (GRUB_ERR_BAD_OS,
+				       "unrecognised relocation");
+		  }
+	      }
+	  }
+      }
+
+  return GRUB_ERR_NONE;
+}
+
+
diff --git a/efiemu/i386/loadcore64.c b/efiemu/i386/loadcore64.c
new file mode 100644
index 0000000..a692790
--- /dev/null
+++ b/efiemu/i386/loadcore64.c
@@ -0,0 +1,120 @@
+/* i386 CPU-specific part of loadcore.c for 32-bit mode */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+#include <grub/elf.h>
+
+/* Check if EHDR is a valid ELF header.  */
+int
+grub_arch_efiemu_check_header64 (void *ehdr)
+{
+  Elf64_Ehdr *e = ehdr;
+
+  return (e->e_ident[EI_CLASS] == ELFCLASS64
+	  && e->e_ident[EI_DATA] == ELFDATA2LSB
+	  && e->e_machine == EM_X86_64);
+}
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
+				     struct grub_efiemu_elf_sym *elfsyms,
+				     void *ehdr)
+{
+  unsigned i;
+  Elf64_Ehdr *e = ehdr;
+  Elf64_Shdr *s;
+  grub_err_t err;
+
+  for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_RELA)
+      {
+	grub_efiemu_segment_t seg;
+	grub_dprintf ("efiemu", "shtrel\n");
+
+	/* Find the target segment.  */
+	for (seg = segs; seg; seg = seg->next)
+	  if (seg->section == s->sh_info)
+	    break;
+
+	if (seg)
+	  {
+	    Elf64_Rela *rel, *max;
+
+	    for (rel = (Elf64_Rela *) ((char *) e + s->sh_offset),
+		   max = rel + (unsigned long) s->sh_size
+		   / (unsigned long)s->sh_entsize;
+		 rel < max;
+		 rel++)
+	      {
+		void *addr;
+		grub_uint32_t *addr32;
+		grub_uint64_t *addr64;
+		struct grub_efiemu_elf_sym sym;
+		if (seg->size < rel->r_offset)
+		  return grub_error (GRUB_ERR_BAD_MODULE,
+				     "reloc offset is out of the segment");
+
+		addr =
+		  ((char *) grub_efiemu_mm_obtain_request (seg->handle)
+		   + seg->off + rel->r_offset);
+		addr32 = (grub_uint32_t *) addr;
+		addr64 = (grub_uint64_t *) addr;
+		sym = elfsyms[ELF64_R_SYM (rel->r_info)];
+
+		switch (ELF64_R_TYPE (rel->r_info))
+		  {
+		  case R_X86_64_64:
+		    if ((err = grub_efiemu_write_value
+			 (addr, *addr64 + rel->r_addend + sym.off, sym.handle,
+			  0, seg->ptv_rel_needed, sizeof (grub_uint64_t))))
+		      return err;
+		    break;
+
+		  case R_X86_64_PC32:
+		    if ((err = grub_efiemu_write_value
+			 (addr, *addr32 + rel->r_addend + sym.off
+			  - rel->r_offset - seg->off, sym.handle, seg->handle,
+			  seg->ptv_rel_needed, sizeof (grub_uint32_t))))
+		      return err;
+		    break;
+
+                  case R_X86_64_32:
+                  case R_X86_64_32S:
+		    if ((err = grub_efiemu_write_value
+			 (addr, *addr32 + rel->r_addend + sym.off, sym.handle,
+			  0, seg->ptv_rel_needed, sizeof (grub_uint32_t))))
+		      return err;
+                    break;
+		  default:
+		    return grub_error (GRUB_ERR_BAD_OS,
+				       "unrecognised relocation");
+		  }
+	      }
+	  }
+      }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/efiemu/i386/pc/cfgtables.c b/efiemu/i386/pc/cfgtables.c
new file mode 100644
index 0000000..9c6b4e5
--- /dev/null
+++ b/efiemu/i386/pc/cfgtables.c
@@ -0,0 +1,76 @@
+/* Register SMBIOS and ACPI tables. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/acpi.h>
+
+grub_err_t
+grub_machine_efiemu_init_tables ()
+{
+  grub_uint8_t *ptr;
+  void *table;
+  grub_err_t err;
+  grub_efi_guid_t smbios = GRUB_EFI_SMBIOS_TABLE_GUID;
+  grub_efi_guid_t acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
+  grub_efi_guid_t acpi = GRUB_EFI_ACPI_TABLE_GUID;
+
+  err = grub_efiemu_unregister_configuration_table (smbios);
+  if (err)
+    return err;
+  err = grub_efiemu_unregister_configuration_table (acpi);
+  if (err)
+    return err;
+  err = grub_efiemu_unregister_configuration_table (acpi20);
+  if (err)
+    return err;
+
+  table = grub_acpi_get_rsdpv1 ();
+  if (table)
+    {
+      err = grub_efiemu_register_configuration_table (acpi, 0, 0, table);
+      if (err)
+	return err;
+    }
+  table = grub_acpi_get_rsdpv2 ();
+  if (table)
+    {
+      err = grub_efiemu_register_configuration_table (acpi20, 0, 0, table);
+      if (err)
+	return err;
+    }
+
+  for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000;
+       ptr += 16)
+    if (grub_memcmp (ptr, "_SM_", 4) == 0
+	&& grub_byte_checksum (ptr, *(ptr + 5)) == 0)
+      break;
+
+  if (ptr < (grub_uint8_t *) 0x100000)
+    {
+      grub_dprintf ("efiemu", "Registering SMBIOS\n");
+      if ((err = grub_efiemu_register_configuration_table (smbios, 0, 0, ptr)))
+	return err;
+    }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/efiemu/loadcore.c b/efiemu/loadcore.c
new file mode 100644
index 0000000..4bf26ee
--- /dev/null
+++ b/efiemu/loadcore.c
@@ -0,0 +1,370 @@
+/* Load runtime image of EFIemu. Functions specific to 32/64-bit mode */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/elf.h>
+
+/* ELF symbols and their values */
+static struct grub_efiemu_elf_sym *grub_efiemu_elfsyms = 0;
+static int grub_efiemu_nelfsyms = 0;
+
+/* Return the address of a section whose index is N.  */
+static grub_err_t
+grub_efiemu_get_section_addr (grub_efiemu_segment_t segs, unsigned n,
+			      int *handle, grub_off_t *off)
+{
+  grub_efiemu_segment_t seg;
+
+  for (seg = segs; seg; seg = seg->next)
+    if (seg->section == n)
+      {
+	*handle = seg->handle;
+	*off = seg->off;
+	return GRUB_ERR_NONE;
+      }
+
+  return grub_error (GRUB_ERR_BAD_OS, "section %d not found", n);
+}
+
+grub_err_t
+SUFFIX (grub_efiemu_loadcore_unload) (void)
+{
+  grub_free (grub_efiemu_elfsyms);
+  grub_efiemu_elfsyms = 0;
+  return GRUB_ERR_NONE;
+}
+
+/* Check if EHDR is a valid ELF header.  */
+int
+SUFFIX (grub_efiemu_check_header) (void *ehdr, grub_size_t size)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the header size.  */
+  if (size < sizeof (Elf_Ehdr))
+    return 0;
+
+  /* Check the magic numbers.  */
+  if (!SUFFIX (grub_arch_efiemu_check_header) (ehdr)
+      || 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_VERSION] != EV_CURRENT
+      || e->e_version != EV_CURRENT)
+    return 0;
+
+  return 1;
+}
+
+/* Load all segments from memory specified by E.  */
+static grub_err_t
+grub_efiemu_load_segments (grub_efiemu_segment_t segs, const Elf_Ehdr *e)
+{
+  Elf_Shdr *s;
+  grub_efiemu_segment_t cur;
+
+  grub_dprintf ("efiemu", "loading segments\n");
+
+  for (cur=segs; cur; cur = cur->next)
+    {
+      s = (Elf_Shdr *)cur->srcptr;
+
+      if ((s->sh_flags & SHF_ALLOC) && s->sh_size)
+	{
+	  void *addr;
+
+	  addr = (grub_uint8_t *) grub_efiemu_mm_obtain_request (cur->handle)
+	    + cur->off;
+
+	  switch (s->sh_type)
+	    {
+	    case SHT_PROGBITS:
+	      grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
+	      break;
+	    case SHT_NOBITS:
+	      grub_memset (addr, 0, s->sh_size);
+	      break;
+	    }
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Get a string at offset OFFSET from strtab */
+static char *
+grub_efiemu_get_string (unsigned offset, const Elf_Ehdr *e)
+{
+  unsigned i;
+  Elf_Shdr *s;
+
+  for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_STRTAB && offset < s->sh_size)
+      return (char *) e + s->sh_offset + offset;
+  return 0;
+}
+
+/* Request memory for segments and fill segments info */
+static grub_err_t
+grub_efiemu_init_segments (grub_efiemu_segment_t *segs, const Elf_Ehdr *e)
+{
+  unsigned i;
+  Elf_Shdr *s;
+
+  for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
+    {
+      if (s->sh_flags & SHF_ALLOC)
+	{
+	  grub_efiemu_segment_t seg;
+	  seg = (grub_efiemu_segment_t) grub_malloc (sizeof (*seg));
+	  if (! seg)
+	    return grub_errno;
+
+	  if (s->sh_size)
+	    {
+	      seg->handle
+		= grub_efiemu_request_memalign
+		(s->sh_addralign, s->sh_size,
+		 s->sh_flags & SHF_EXECINSTR ? GRUB_EFI_RUNTIME_SERVICES_CODE
+		 : GRUB_EFI_RUNTIME_SERVICES_DATA);
+	      if (seg->handle < 0)
+		return grub_errno;
+	      seg->off = 0;
+	    }
+
+	  /*
+	     .text-physical doesn't need to be relocated when switching to
+	     virtual mode
+	   */
+	  if (!grub_strcmp (grub_efiemu_get_string (s->sh_name, e),
+			    ".text-physical"))
+	    seg->ptv_rel_needed = 0;
+	  else
+	    seg->ptv_rel_needed = 1;
+	  seg->size = s->sh_size;
+	  seg->section = i;
+	  seg->next = *segs;
+	  seg->srcptr = s;
+	  *segs = seg;
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Count symbols and relocators and allocate/request memory for them */
+static grub_err_t
+grub_efiemu_count_symbols (const Elf_Ehdr *e)
+{
+  unsigned i;
+  Elf_Shdr *s;
+  int num = 0;
+
+  /* Symbols */
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
+
+  grub_efiemu_nelfsyms = (unsigned) s->sh_size / (unsigned) s->sh_entsize;
+  grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *)
+    grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms);
+
+  /* Relocators */
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA)
+      num += ((unsigned) s->sh_size) / ((unsigned) s->sh_entsize);
+
+  grub_efiemu_request_symbols (num);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Fill grub_efiemu_elfsyms with symbol values */
+static grub_err_t
+grub_efiemu_resolve_symbols (grub_efiemu_segment_t segs, Elf_Ehdr *e)
+{
+  unsigned i;
+  Elf_Shdr *s;
+  Elf_Sym *sym;
+  const char *str;
+  Elf_Word size, entsize;
+
+  grub_dprintf ("efiemu", "resolving symbols\n");
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
+
+  sym = (Elf_Sym *) ((char *) e + s->sh_offset);
+  size = s->sh_size;
+  entsize = s->sh_entsize;
+
+  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
+  str = (char *) e + s->sh_offset;
+
+  for (i = 0;
+       i < size / entsize;
+       i++, sym = (Elf_Sym *) ((char *) sym + entsize))
+    {
+      unsigned char type = ELF_ST_TYPE (sym->st_info);
+      unsigned char bind = ELF_ST_BIND (sym->st_info);
+      int handle;
+      grub_off_t off;
+      grub_err_t err;
+      const char *name = str + sym->st_name;
+      grub_efiemu_elfsyms[i].section = sym->st_shndx;
+      switch (type)
+	{
+	case STT_NOTYPE:
+	  /* Resolve a global symbol.  */
+	  if (sym->st_name != 0 && sym->st_shndx == 0)
+	    {
+	      if ((err = grub_efiemu_resolve_symbol (name, &handle, &off)))
+		return err;
+	      grub_efiemu_elfsyms[i].handle = handle;
+	      grub_efiemu_elfsyms[i].off = off;
+	    }
+	  else
+	    sym->st_value = 0;
+	  break;
+
+	case STT_OBJECT:
+	  if ((err = grub_efiemu_get_section_addr
+	       (segs, sym->st_shndx, &handle, &off)))
+	    return err;
+
+	  off += sym->st_value;
+	  if (bind != STB_LOCAL)
+	    if ((err = grub_efiemu_register_symbol (name, handle, off)))
+	      return err;
+	  grub_efiemu_elfsyms[i].handle = handle;
+	  grub_efiemu_elfsyms[i].off = off;
+	  break;
+
+	case STT_FUNC:
+	  if ((err = grub_efiemu_get_section_addr
+	       (segs, sym->st_shndx, &handle, &off)))
+	    return err;
+
+	  off += sym->st_value;
+	  if (bind != STB_LOCAL)
+	    if ((err = grub_efiemu_register_symbol (name, handle, off)))
+	      return err;
+	  grub_efiemu_elfsyms[i].handle = handle;
+	  grub_efiemu_elfsyms[i].off = off;
+	  break;
+
+	case STT_SECTION:
+	  if ((err = grub_efiemu_get_section_addr
+	       (segs, sym->st_shndx, &handle, &off)))
+	    {
+	      grub_efiemu_elfsyms[i].handle = 0;
+	      grub_efiemu_elfsyms[i].off = 0;
+	      grub_errno = GRUB_ERR_NONE;
+	      break;
+	    }
+
+	  grub_efiemu_elfsyms[i].handle = handle;
+	  grub_efiemu_elfsyms[i].off = off;
+	  break;
+
+	case STT_FILE:
+	  grub_efiemu_elfsyms[i].handle = 0;
+	  grub_efiemu_elfsyms[i].off = 0;
+	  break;
+
+	default:
+	  return grub_error (GRUB_ERR_BAD_MODULE,
+			     "unknown symbol type `%d'", (int) type);
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Load runtime to the memory and request memory for definitive location*/
+grub_err_t
+SUFFIX (grub_efiemu_loadcore_init) (void *core, grub_size_t core_size,
+				    grub_efiemu_segment_t *segments)
+{
+  Elf_Ehdr *e = (Elf_Ehdr *) core;
+  grub_err_t err;
+
+  if (e->e_type != ET_REL)
+    return grub_error (GRUB_ERR_BAD_MODULE, "invalid ELF file type");
+
+  /* Make sure that every section is within the core.  */
+  if ((grub_size_t) core_size < e->e_shoff + e->e_shentsize * e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_OS, "ELF sections outside core");
+
+  if ((err = grub_efiemu_init_segments (segments, core)))
+    return err;
+  if ((err = grub_efiemu_count_symbols (core)))
+    return err;
+
+  grub_efiemu_request_symbols (1);
+  return GRUB_ERR_NONE;
+}
+
+/* Load runtime definitively */
+grub_err_t
+SUFFIX (grub_efiemu_loadcore_load) (void *core,
+				    grub_size_t core_size
+				    __attribute__ ((unused)),
+				    grub_efiemu_segment_t segments)
+{
+  grub_err_t err;
+  err = grub_efiemu_load_segments (segments, core);
+  if (err)
+    return err;
+
+  err = grub_efiemu_resolve_symbols (segments, core);
+  if (err)
+    return err;
+
+  err = SUFFIX (grub_arch_efiemu_relocate_symbols) (segments,
+						    grub_efiemu_elfsyms,
+						    core);
+  if (err)
+    return err;
+
+  return GRUB_ERR_NONE;
+}
diff --git a/efiemu/loadcore32.c b/efiemu/loadcore32.c
new file mode 100644
index 0000000..c1e033b
--- /dev/null
+++ b/efiemu/loadcore32.c
@@ -0,0 +1,22 @@
+/* This file contains definitions so that loadcore.c compiles for 32-bit */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define SUFFIX(x) x ## 32
+#define GRUB_TARGET_WORDSIZE 32
+#include "loadcore.c"
diff --git a/efiemu/loadcore64.c b/efiemu/loadcore64.c
new file mode 100644
index 0000000..ce7284f
--- /dev/null
+++ b/efiemu/loadcore64.c
@@ -0,0 +1,22 @@
+/* This file contains definitions so that loadcore.c compiles for 64-bit */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define SUFFIX(x) x ## 64
+#define GRUB_TARGET_WORDSIZE 64
+#include "loadcore.c"
diff --git a/efiemu/loadcore_common.c b/efiemu/loadcore_common.c
new file mode 100644
index 0000000..a4db0ee
--- /dev/null
+++ b/efiemu/loadcore_common.c
@@ -0,0 +1,189 @@
+/* Load runtime image of EFIemu. Functions common to 32/64-bit mode */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+
+/* Are we in 32 or 64-bit mode?*/
+static grub_efiemu_mode_t grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
+/* Runtime ELF file */
+static grub_ssize_t efiemu_core_size;
+static void *efiemu_core = 0;
+/* Linked list of segments */
+static grub_efiemu_segment_t efiemu_segments = 0;
+
+/* equivalent to sizeof (grub_efi_uintn_t) but taking the mode into account*/
+int
+grub_efiemu_sizeof_uintn_t (void)
+{
+  if (grub_efiemu_mode == GRUB_EFIEMU32)
+    return 4;
+  if (grub_efiemu_mode == GRUB_EFIEMU64)
+    return 8;
+  return 0;
+}
+
+/* Check the header and set mode */
+static grub_err_t
+grub_efiemu_check_header (void *ehdr, grub_size_t size,
+			  grub_efiemu_mode_t *mode)
+{
+  /* Check the magic numbers.  */
+  if ((*mode == GRUB_EFIEMU_NOTLOADED || *mode == GRUB_EFIEMU32)
+      && grub_efiemu_check_header32 (ehdr,size))
+    {
+      *mode = GRUB_EFIEMU32;
+      return GRUB_ERR_NONE;
+    }
+  if ((*mode == GRUB_EFIEMU_NOTLOADED || *mode == GRUB_EFIEMU64)
+      && grub_efiemu_check_header64 (ehdr,size))
+    {
+      *mode = GRUB_EFIEMU64;
+      return GRUB_ERR_NONE;
+    }
+  return grub_error (GRUB_ERR_BAD_OS, "invalid ELF magic");
+}
+
+/* Unload segments */
+static int
+grub_efiemu_unload_segs (grub_efiemu_segment_t seg)
+{
+  grub_efiemu_segment_t segn;
+  for (; seg; seg = segn)
+    {
+      segn = seg->next;
+      grub_efiemu_mm_return_request (seg->handle);
+      grub_free (seg);
+    }
+  return 1;
+}
+
+
+grub_err_t
+grub_efiemu_loadcore_unload(void)
+{
+  switch (grub_efiemu_mode)
+    {
+    case GRUB_EFIEMU32:
+      grub_efiemu_loadcore_unload32 ();
+      break;
+
+    case GRUB_EFIEMU64:
+      grub_efiemu_loadcore_unload64 ();
+      break;
+
+    default:
+      break;
+    }
+
+  grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
+
+  grub_free (efiemu_core);
+  efiemu_core = 0;
+
+  grub_efiemu_unload_segs (efiemu_segments);
+  efiemu_segments = 0;
+
+  grub_efiemu_free_syms ();
+
+  return GRUB_ERR_NONE;
+}
+
+/* Load runtime file and do some initial preparations */
+grub_err_t
+grub_efiemu_loadcore_init (grub_file_t file)
+{
+  grub_err_t err;
+
+  efiemu_core_size = grub_file_size (file);
+  efiemu_core = 0;
+  efiemu_core = grub_malloc (efiemu_core_size);
+  if (! efiemu_core)
+    return grub_errno;
+
+  if (grub_file_read (file, efiemu_core, efiemu_core_size)
+      != (int) efiemu_core_size)
+    {
+      grub_free (efiemu_core);
+      efiemu_core = 0;
+      return grub_errno;
+    }
+
+  if (grub_efiemu_check_header (efiemu_core, efiemu_core_size,
+				&grub_efiemu_mode))
+    {
+      grub_free (efiemu_core);
+      efiemu_core = 0;
+      return GRUB_ERR_BAD_MODULE;
+    }
+
+  switch (grub_efiemu_mode)
+    {
+    case GRUB_EFIEMU32:
+      if ((err = grub_efiemu_loadcore_init32 (efiemu_core, efiemu_core_size,
+					      &efiemu_segments)))
+	{
+	  grub_free (efiemu_core);
+	  efiemu_core = 0;
+	  grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
+	  return err;
+	}
+      break;
+
+    case GRUB_EFIEMU64:
+      if ((err = grub_efiemu_loadcore_init64 (efiemu_core, efiemu_core_size,
+					      &efiemu_segments)))
+	{
+	  grub_free (efiemu_core);
+	  efiemu_core = 0;
+	  grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
+	  return err;
+	}
+      break;
+
+    default:
+      return grub_error (GRUB_ERR_BAD_OS, "unknown EFI runtime");
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_loadcore_load (void)
+{
+  grub_err_t err;
+  switch (grub_efiemu_mode)
+    {
+    case GRUB_EFIEMU32:
+      if ((err = grub_efiemu_loadcore_load32 (efiemu_core, efiemu_core_size,
+					      efiemu_segments)))
+	  grub_efiemu_loadcore_unload ();
+      return err;
+    case GRUB_EFIEMU64:
+      if ((err = grub_efiemu_loadcore_load64 (efiemu_core, efiemu_core_size,
+					      efiemu_segments)))
+	  grub_efiemu_loadcore_unload ();
+      return err;
+    default:
+      return grub_error (GRUB_ERR_BAD_OS, "unknown EFI runtime");
+    }
+}
diff --git a/efiemu/main.c b/efiemu/main.c
new file mode 100644
index 0000000..b5608e6
--- /dev/null
+++ b/efiemu/main.c
@@ -0,0 +1,344 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This is an emulation of EFI runtime services.
+   This allows a more uniform boot on i386 machines.
+   As it emulates only runtime service it isn't able
+   to chainload EFI bootloader on non-EFI system. */
+
+
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/command.h>
+
+/* System table. Two version depending on mode */
+grub_efi_system_table32_t *grub_efiemu_system_table32 = 0;
+grub_efi_system_table64_t *grub_efiemu_system_table64 = 0;
+/* Modules may need to execute some actions after memory allocation happens */
+static struct grub_efiemu_prepare_hook *efiemu_prepare_hooks = 0;
+/* Linked list of configuration tables */
+static struct grub_efiemu_configuration_table *efiemu_config_tables = 0;
+
+/* Free all allocated space */
+grub_err_t
+grub_efiemu_unload (void)
+{
+  struct grub_efiemu_configuration_table *cur, *d;
+  struct grub_efiemu_prepare_hook *curhook, *d2;
+  grub_efiemu_loadcore_unload ();
+
+  grub_efiemu_mm_unload ();
+
+  for (cur = efiemu_config_tables; cur;)
+    {
+      d = cur->next;
+      if (cur->unload)
+	cur->unload (cur->data);
+      grub_free (cur);
+      cur = d;
+    }
+  efiemu_config_tables = 0;
+
+  for (curhook = efiemu_prepare_hooks; curhook;)
+    {
+      d2 = curhook->next;
+      if (curhook->unload)
+	curhook->unload (curhook->data);
+      grub_free (curhook);
+      curhook = d2;
+    }
+  efiemu_prepare_hooks = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+/* Remove previously registered table from the list */
+grub_err_t
+grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid)
+{
+  struct grub_efiemu_configuration_table *cur, *prev;
+
+  /* Special treating if head is to remove */
+  while (efiemu_config_tables
+	 && !grub_memcmp (&(efiemu_config_tables->guid), &guid, sizeof (guid)))
+    {
+      if (efiemu_config_tables->unload)
+	  efiemu_config_tables->unload (efiemu_config_tables->data);
+	cur = efiemu_config_tables->next;
+	grub_free (efiemu_config_tables);
+	efiemu_config_tables = cur;
+    }
+  if (!efiemu_config_tables)
+    return GRUB_ERR_NONE;
+
+  /* Remove from chain */
+  for (prev = efiemu_config_tables, cur = prev->next; cur;)
+    if (grub_memcmp (&(cur->guid), &guid, sizeof (guid)) == 0)
+      {
+	if (cur->unload)
+	  cur->unload (cur->data);
+	prev->next = cur->next;
+	grub_free (cur);
+	cur = prev->next;
+      }
+    else
+      {
+	prev = cur;
+	cur = cur->next;
+      }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_register_prepare_hook (grub_err_t (*hook) (void *data),
+				   void (*unload) (void *data),
+				   void *data)
+{
+  struct grub_efiemu_prepare_hook *nhook;
+  if (! hook)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "you must supply the hook");
+  nhook = (struct grub_efiemu_prepare_hook *) grub_malloc (sizeof (*nhook));
+  if (! nhook)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't prepare hook");
+  nhook->hook = hook;
+  nhook->unload = unload;
+  nhook->data = data;
+  nhook->next = efiemu_prepare_hooks;
+  efiemu_prepare_hooks = nhook;
+  return GRUB_ERR_NONE;
+}
+
+/* Register a configuration table either supplying the address directly
+   or with a hook
+*/
+grub_err_t
+grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
+					  void * (*get_table) (void *data),
+					  void (*unload) (void *data),
+					  void *data)
+{
+  struct grub_efiemu_configuration_table *tbl;
+  grub_err_t err;
+
+ if (! get_table && ! data)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "you must set at least get_table or data");
+  if ((err = grub_efiemu_unregister_configuration_table (guid)))
+    return err;
+
+  tbl = (struct grub_efiemu_configuration_table *) grub_malloc (sizeof (*tbl));
+  if (! tbl)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't register table");
+
+  tbl->guid = guid;
+  tbl->get_table = get_table;
+  tbl->unload = unload;
+  tbl->data = data;
+  tbl->next = efiemu_config_tables;
+  efiemu_config_tables = tbl;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_efiemu_unload (grub_command_t cmd __attribute__ ((unused)),
+			int argc __attribute__ ((unused)),
+			char *args[] __attribute__ ((unused)))
+{
+  return grub_efiemu_unload ();
+}
+
+static grub_err_t
+grub_cmd_efiemu_prepare (grub_command_t cmd __attribute__ ((unused)),
+			 int argc __attribute__ ((unused)),
+			 char *args[] __attribute__ ((unused)))
+{
+  return grub_efiemu_prepare ();
+}
+
+
+
+
+int
+grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key
+				__attribute__ ((unused)))
+{
+  /* Nothing to do here yet */
+  return 1;
+}
+
+int
+grub_efiemu_finish_boot_services (void)
+{
+  /* Nothing to do here yet */
+  return 1;
+}
+
+/* Load the runtime from the file FILENAME.  */
+static grub_err_t
+grub_efiemu_load_file (const char *filename)
+{
+  grub_file_t file;
+  grub_err_t err;
+
+  file = grub_file_open (filename);
+  if (! file)
+    return 0;
+
+  err = grub_efiemu_mm_init ();
+  if (err)
+    {
+      grub_file_close (file);
+      grub_efiemu_unload ();
+      return grub_error (grub_errno, "Couldn't init memory management");
+    }
+
+  grub_dprintf ("efiemu", "mm initialized\n");
+
+  err = grub_efiemu_loadcore_init (file);
+  if (err)
+    {
+      grub_file_close (file);
+      grub_efiemu_unload ();
+      return err;
+    }
+
+  grub_file_close (file);
+
+  /* For configuration tables entry in system table. */
+  grub_efiemu_request_symbols (1);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_autocore (void)
+{
+  const char *prefix;
+  char *filename;
+  char *suffix;
+  grub_err_t err;
+
+  if (grub_efiemu_sizeof_uintn_t () != 0)
+    return GRUB_ERR_NONE;
+
+  prefix = grub_env_get ("prefix");
+
+  if (! prefix)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+		       "couldn't find efiemu core because prefix "
+		       "isn't set");
+
+  suffix = grub_efiemu_get_default_core_name ();
+
+  filename = grub_malloc (grub_strlen (prefix) + grub_strlen (suffix) + 2);
+  if (! filename)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		       "couldn't allocate temporary space");
+
+  grub_sprintf (filename, "%s/%s", prefix, suffix);
+
+  err = grub_efiemu_load_file (filename);
+  grub_free (filename);
+  if (err)
+    return err;
+#ifndef GRUB_UTIL
+  err = grub_machine_efiemu_init_tables ();
+  if (err)
+    return err;
+#endif
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_prepare (void)
+{
+  grub_err_t err;
+
+  grub_dprintf ("efiemu", "Preparing %d-bit efiemu\n",
+		8 * grub_efiemu_sizeof_uintn_t ());
+
+  err = grub_efiemu_autocore ();
+
+  /* Create NVRAM if not yet done. */
+  grub_efiemu_pnvram ();
+
+  if (grub_efiemu_sizeof_uintn_t () == 4)
+    return grub_efiemu_prepare32 (efiemu_prepare_hooks, efiemu_config_tables);
+  else
+    return grub_efiemu_prepare64 (efiemu_prepare_hooks, efiemu_config_tables);
+}
+
+
+static grub_err_t
+grub_cmd_efiemu_load (grub_command_t cmd __attribute__ ((unused)),
+		      int argc, char *args[])
+{
+  grub_err_t err;
+
+  grub_efiemu_unload ();
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename required");
+
+  err = grub_efiemu_load_file (args[0]);
+  if (err)
+    return err;
+#ifndef GRUB_UTIL
+  err = grub_machine_efiemu_init_tables ();
+  if (err)
+    return err;
+#endif
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd_loadcore, cmd_prepare, cmd_unload;
+
+void
+grub_efiemu_pnvram_cmd_register (void);
+
+GRUB_MOD_INIT(efiemu)
+{
+  cmd_loadcore = grub_register_command ("efiemu_loadcore",
+					grub_cmd_efiemu_load,
+				       "efiemu_loadcore FILE",
+				       "Load and initialize EFI emulator");
+  cmd_prepare = grub_register_command ("efiemu_prepare",
+				       grub_cmd_efiemu_prepare,
+				       "efiemu_prepare",
+				       "Finalize loading of EFI emulator");
+  cmd_unload = grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload,
+				      "efiemu_unload",
+				      "Unload  EFI emulator");
+  grub_efiemu_pnvram_cmd_register ();
+}
+
+GRUB_MOD_FINI(efiemu)
+{
+  grub_unregister_command (cmd_loadcore);
+  grub_unregister_command (cmd_prepare);
+  grub_unregister_command (cmd_unload);
+  grub_efiemu_pnvram_cmd_unregister ();
+}
diff --git a/efiemu/mm.c b/efiemu/mm.c
new file mode 100644
index 0000000..8b03229
--- /dev/null
+++ b/efiemu/mm.c
@@ -0,0 +1,633 @@
+/* Memory management for efiemu */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+/*
+  To keep efiemu runtime contiguous this mm is special.
+  It uses deferred allocation.
+  In the first stage you may request memory with grub_efiemu_request_memalign
+  It will give you a handle with which in the second phase you can access your
+  memory with grub_efiemu_mm_obtain_request (handle). It's guaranteed that
+  subsequent calls with the same handle return the same result. You can't request any additional memory once you're in the second phase
+*/
+
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/machine/memory.h>
+#include <grub/efiemu/efiemu.h>
+
+struct grub_efiemu_memrequest
+{
+  struct grub_efiemu_memrequest *next;
+  grub_efi_memory_type_t type;
+  grub_size_t size;
+  grub_size_t align_overhead;
+  int handle;
+  void *val;
+};
+/* Linked list of requested memory. */
+static struct grub_efiemu_memrequest *memrequests = 0;
+/* Memory map. */
+static grub_efi_memory_descriptor_t *efiemu_mmap = 0;
+/* Pointer to allocated memory */
+static void *resident_memory = 0;
+/* Size of requested memory per type */
+static grub_size_t requested_memory[GRUB_EFI_MAX_MEMORY_TYPE];
+/* How many slots is allocated for memory_map and how many are already used */
+static int mmap_reserved_size = 0, mmap_num = 0;
+
+/* Add a memory region to map*/
+static grub_err_t
+grub_efiemu_add_to_mmap (grub_uint64_t start, grub_uint64_t size,
+			 grub_efi_memory_type_t type)
+{
+  grub_uint64_t page_start, npages;
+
+  /* Extend map if necessary*/
+  if (mmap_num >= mmap_reserved_size)
+    {
+      efiemu_mmap = (grub_efi_memory_descriptor_t *)
+	grub_realloc (efiemu_mmap, (++mmap_reserved_size)
+		      * sizeof (grub_efi_memory_descriptor_t));
+      if (!efiemu_mmap)
+	return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			   "Not enough space for memory map");
+    }
+
+  /* Fill slot*/
+  page_start = start - (start % GRUB_EFIEMU_PAGESIZE);
+  npages = (size + (start % GRUB_EFIEMU_PAGESIZE) + GRUB_EFIEMU_PAGESIZE - 1)
+    / GRUB_EFIEMU_PAGESIZE;
+  efiemu_mmap[mmap_num].physical_start = page_start;
+  efiemu_mmap[mmap_num].virtual_start = page_start;
+  efiemu_mmap[mmap_num].num_pages = npages;
+  efiemu_mmap[mmap_num].type = type;
+  mmap_num++;
+
+  return GRUB_ERR_NONE;
+}
+
+/* Request a resident memory of type TYPE of size SIZE aligned at ALIGN
+   ALIGN must be a divisor of page size (if it's a divisor of 4096
+   it should be ok on all platforms)
+ */
+int
+grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
+			      grub_efi_memory_type_t type)
+{
+  grub_size_t align_overhead;
+  struct grub_efiemu_memrequest *ret, *cur, *prev;
+  /* Check that the request is correct */
+  if (type >= GRUB_EFI_MAX_MEMORY_TYPE || type <= GRUB_EFI_LOADER_CODE)
+    return -2;
+
+  /* Add new size to requested size */
+  align_overhead = align - (requested_memory[type]%align);
+  if (align_overhead == align)
+    align_overhead = 0;
+  requested_memory[type] += align_overhead + size;
+
+  /* Remember the request */
+  ret = grub_zalloc (sizeof (*ret));
+  if (!ret)
+    return -1;
+  ret->type = type;
+  ret->size = size;
+  ret->align_overhead = align_overhead;
+  prev = 0;
+
+  /* Add request to the end of the chain.
+     It should be at the end because otherwise alignment isn't guaranteed */
+  for (cur = memrequests; cur; prev = cur, cur = cur->next);
+  if (prev)
+    {
+      ret->handle = prev->handle + 1;
+      prev->next = ret;
+    }
+  else
+    {
+      ret->handle = 1; /* Avoid 0 handle*/
+      memrequests = ret;
+    }
+  return ret->handle;
+}
+
+/* Really allocate the memory */
+static grub_err_t
+efiemu_alloc_requests (void)
+{
+  grub_size_t align_overhead = 0;
+  grub_uint8_t *curptr, *typestart;
+  struct grub_efiemu_memrequest *cur;
+  grub_size_t total_alloc = 0;
+  unsigned i;
+  /* Order of memory regions */
+  grub_efi_memory_type_t reqorder[] =
+    {
+      /* First come regions usable by OS*/
+      GRUB_EFI_LOADER_CODE,
+      GRUB_EFI_LOADER_DATA,
+      GRUB_EFI_BOOT_SERVICES_CODE,
+      GRUB_EFI_BOOT_SERVICES_DATA,
+      GRUB_EFI_CONVENTIONAL_MEMORY,
+      GRUB_EFI_ACPI_RECLAIM_MEMORY,
+
+      /* Then memory used by runtime */
+      /* This way all our regions are in a single block */
+      GRUB_EFI_RUNTIME_SERVICES_CODE,
+      GRUB_EFI_RUNTIME_SERVICES_DATA,
+      GRUB_EFI_ACPI_MEMORY_NVS,
+
+      /* And then unavailable memory types. This is more for a completeness.
+	 You should double think before allocating memory of any of these types
+       */
+      GRUB_EFI_UNUSABLE_MEMORY,
+      GRUB_EFI_MEMORY_MAPPED_IO,
+      GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE,
+      GRUB_EFI_PAL_CODE
+    };
+
+  /* Compute total memory needed */
+  for (i = 0; i < sizeof (reqorder) / sizeof (reqorder[0]); i++)
+    {
+      align_overhead = GRUB_EFIEMU_PAGESIZE
+	- (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE);
+      if (align_overhead == GRUB_EFIEMU_PAGESIZE)
+	align_overhead = 0;
+      total_alloc += requested_memory[reqorder[i]] + align_overhead;
+    }
+
+  /* Allocate the whole memory in one block */
+  resident_memory = grub_memalign (GRUB_EFIEMU_PAGESIZE, total_alloc);
+  if (!resident_memory)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		       "couldn't allocate resident memory");
+
+  /* Split the memory into blocks by type */
+  curptr = resident_memory;
+  for (i = 0; i < sizeof (reqorder) / sizeof (reqorder[0]); i++)
+    {
+      if (!requested_memory[reqorder[i]])
+	continue;
+      typestart = curptr;
+
+      /* Write pointers to requests */
+      for (cur = memrequests; cur; cur = cur->next)
+	if (cur->type == reqorder[i])
+	  {
+	    curptr = ((grub_uint8_t *)curptr) + cur->align_overhead;
+	    cur->val = curptr;
+	    curptr = ((grub_uint8_t *)curptr) + cur->size;
+	  }
+
+      /* Ensure that the regions are page-aligned */
+      align_overhead = GRUB_EFIEMU_PAGESIZE
+	- (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE);
+      if (align_overhead == GRUB_EFIEMU_PAGESIZE)
+	align_overhead = 0;
+      curptr = ((grub_uint8_t *)curptr) + align_overhead;
+
+      /* Add the region to memory map */
+      grub_efiemu_add_to_mmap (PTR_TO_UINT64 (typestart),
+			       curptr - typestart, reqorder[i]);
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Get a pointer to requested memory from handle */
+void *
+grub_efiemu_mm_obtain_request (int handle)
+{
+  struct grub_efiemu_memrequest *cur;
+  for (cur = memrequests; cur; cur = cur->next)
+    if (cur->handle == handle)
+      return cur->val;
+  return 0;
+}
+
+/* Get type of requested memory by handle */
+grub_efi_memory_type_t
+grub_efiemu_mm_get_type (int handle)
+{
+  struct grub_efiemu_memrequest *cur;
+  for (cur = memrequests; cur; cur = cur->next)
+    if (cur->handle == handle)
+      return cur->type;
+  return 0;
+}
+
+/* Free a request */
+void
+grub_efiemu_mm_return_request (int handle)
+{
+  struct grub_efiemu_memrequest *cur, *prev;
+
+  /* Remove head if necessary */
+  while (memrequests && memrequests->handle == handle)
+    {
+      cur = memrequests->next;
+      grub_free (memrequests);
+      memrequests = cur;
+    }
+  if (!memrequests)
+    return;
+
+  /* Remove request from a middle of chain*/
+  for (prev = memrequests, cur = prev->next; cur;)
+    if (cur->handle == handle)
+      {
+	prev->next = cur->next;
+	grub_free (cur);
+	cur = prev->next;
+      }
+    else
+      {
+	prev = cur;
+	cur = prev->next;
+      }
+}
+
+/* Reserve space for memory map */
+static grub_err_t
+grub_efiemu_mmap_init (void)
+{
+  auto int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t, grub_uint64_t,
+					 grub_uint32_t);
+  int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t addr __attribute__ ((unused)),
+				    grub_uint64_t size __attribute__ ((unused)),
+				    grub_uint32_t type __attribute__ ((unused)))
+    {
+      mmap_reserved_size++;
+      return 0;
+    }
+
+  // the place for memory used by efiemu itself
+  mmap_reserved_size = GRUB_EFI_MAX_MEMORY_TYPE + 1;
+
+#ifndef GRUB_UTIL
+  grub_machine_mmap_iterate (bounds_hook);
+#endif
+
+  return GRUB_ERR_NONE;
+}
+
+/* This is a drop-in replacement of grub_efi_get_memory_map */
+/* Get the memory map as defined in the EFI spec. Return 1 if successful,
+   return 0 if partial, or return -1 if an error occurs.  */
+int
+grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
+			    grub_efi_memory_descriptor_t *memory_map,
+			    grub_efi_uintn_t *map_key,
+			    grub_efi_uintn_t *descriptor_size,
+			    grub_efi_uint32_t *descriptor_version)
+{
+  if (!efiemu_mmap)
+    {
+      grub_error (GRUB_ERR_INVALID_COMMAND,
+		  "you need to first launch efiemu_prepare");
+      return -1;
+    }
+
+  if (*memory_map_size < mmap_num * sizeof (grub_efi_memory_descriptor_t))
+    {
+      *memory_map_size = mmap_num * sizeof (grub_efi_memory_descriptor_t);
+      return 0;
+    }
+
+  *memory_map_size = mmap_num * sizeof (grub_efi_memory_descriptor_t);
+  grub_memcpy (memory_map, efiemu_mmap, *memory_map_size);
+  if (descriptor_size)
+    *descriptor_size = sizeof (grub_efi_memory_descriptor_t);
+  if (descriptor_version)
+    *descriptor_version = 1;
+  if (map_key)
+    *map_key = 0;
+
+  return 1;
+}
+
+/* Free everything */
+grub_err_t
+grub_efiemu_mm_unload (void)
+{
+  struct grub_efiemu_memrequest *cur, *d;
+  for (cur = memrequests; cur;)
+    {
+      d = cur->next;
+      grub_free (cur);
+      cur = d;
+    }
+  memrequests = 0;
+  grub_memset (&requested_memory, 0, sizeof (requested_memory));
+  grub_free (resident_memory);
+  resident_memory = 0;
+  grub_free (efiemu_mmap);
+  efiemu_mmap = 0;
+  mmap_reserved_size = mmap_num = 0;
+  return GRUB_ERR_NONE;
+}
+
+/* This function should be called before doing any requests */
+grub_err_t
+grub_efiemu_mm_init (void)
+{
+  grub_err_t err;
+
+  err = grub_efiemu_mm_unload ();
+  if (err)
+    return err;
+
+  grub_efiemu_mmap_init ();
+
+  return GRUB_ERR_NONE;
+}
+
+/* Copy host memory map */
+static grub_err_t
+grub_efiemu_mmap_fill (void)
+{
+  auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
+				  grub_uint64_t size,
+				  grub_uint32_t type)
+    {
+      switch (type)
+	{
+	case GRUB_MACHINE_MEMORY_AVAILABLE:
+	  return grub_efiemu_add_to_mmap (addr, size,
+					  GRUB_EFI_CONVENTIONAL_MEMORY);
+
+#ifdef GRUB_MACHINE_MEMORY_ACPI
+	case GRUB_MACHINE_MEMORY_ACPI:
+	  return grub_efiemu_add_to_mmap (addr, size,
+					  GRUB_EFI_ACPI_RECLAIM_MEMORY);
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_NVS
+	case GRUB_MACHINE_MEMORY_NVS:
+	  return grub_efiemu_add_to_mmap (addr, size,
+					  GRUB_EFI_ACPI_MEMORY_NVS);
+#endif
+
+	default:
+	  grub_printf ("Unknown memory type %d. Marking as unusable\n", type);
+	case GRUB_MACHINE_MEMORY_RESERVED:
+	  return grub_efiemu_add_to_mmap (addr, size,
+					  GRUB_EFI_UNUSABLE_MEMORY);
+	}
+    }
+
+#ifndef GRUB_UTIL
+  grub_machine_mmap_iterate (fill_hook);
+#endif
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+							grub_uint64_t,
+							grub_uint32_t))
+{
+  unsigned i;
+
+  for (i = 0; i < (unsigned) mmap_num; i++)
+    switch (efiemu_mmap[i].type)
+      {
+      case GRUB_EFI_RUNTIME_SERVICES_CODE:
+	hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+	      GRUB_EFIEMU_MEMORY_CODE);
+	break;
+
+      case GRUB_EFI_RESERVED_MEMORY_TYPE:
+      case GRUB_EFI_RUNTIME_SERVICES_DATA:
+      case GRUB_EFI_UNUSABLE_MEMORY:
+      case GRUB_EFI_MEMORY_MAPPED_IO:
+      case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+      case GRUB_EFI_PAL_CODE:
+      case GRUB_EFI_MAX_MEMORY_TYPE:
+	hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+	      GRUB_EFIEMU_MEMORY_RESERVED);
+	break;
+
+      case GRUB_EFI_LOADER_CODE:
+      case GRUB_EFI_LOADER_DATA:
+      case GRUB_EFI_BOOT_SERVICES_CODE:
+      case GRUB_EFI_BOOT_SERVICES_DATA:
+      case GRUB_EFI_CONVENTIONAL_MEMORY:
+	hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+	      GRUB_EFIEMU_MEMORY_AVAILABLE);
+	break;
+
+      case GRUB_EFI_ACPI_RECLAIM_MEMORY:
+	hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+	      GRUB_EFIEMU_MEMORY_ACPI);
+	break;
+
+      case GRUB_EFI_ACPI_MEMORY_NVS:
+	hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+	      GRUB_EFIEMU_MEMORY_NVS);
+	break;
+      }
+
+  return 0;
+}
+
+
+/* This function resolves overlapping regions and sorts the memory map
+   It uses scanline (sweeping) algorithm
+ */
+static grub_err_t
+grub_efiemu_mmap_sort_and_uniq (void)
+{
+  /* If same page is used by multiple types it's resolved
+     according to priority
+     0 - free memory
+     1 - memory immediately usable after ExitBootServices
+     2 - memory usable after loading ACPI tables
+     3 - efiemu memory
+     4 - unusable memory
+  */
+  int priority[GRUB_EFI_MAX_MEMORY_TYPE] =
+    {
+      [GRUB_EFI_RESERVED_MEMORY_TYPE] = 4,
+      [GRUB_EFI_LOADER_CODE] = 1,
+      [GRUB_EFI_LOADER_DATA] = 1,
+      [GRUB_EFI_BOOT_SERVICES_CODE] = 1,
+      [GRUB_EFI_BOOT_SERVICES_DATA] = 1,
+      [GRUB_EFI_RUNTIME_SERVICES_CODE] = 3,
+      [GRUB_EFI_RUNTIME_SERVICES_DATA] = 3,
+      [GRUB_EFI_CONVENTIONAL_MEMORY] = 0,
+      [GRUB_EFI_UNUSABLE_MEMORY] = 4,
+      [GRUB_EFI_ACPI_RECLAIM_MEMORY] = 2,
+      [GRUB_EFI_ACPI_MEMORY_NVS] = 3,
+      [GRUB_EFI_MEMORY_MAPPED_IO] = 4,
+      [GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE] = 4,
+      [GRUB_EFI_PAL_CODE] = 4
+    };
+
+  int i, j, k, done;
+
+  /* Scanline events */
+  struct grub_efiemu_mmap_scan
+  {
+    /* At which memory address*/
+    grub_uint64_t pos;
+    /* 0 = region starts, 1 = region ends */
+    int type;
+    /* Which type of memory region */
+    grub_efi_memory_type_t memtype;
+  };
+  struct grub_efiemu_mmap_scan *scanline_events;
+  struct grub_efiemu_mmap_scan t;
+
+  /* Previous scanline event */
+  grub_uint64_t lastaddr;
+  int lasttype;
+  /* Current scanline event */
+  int curtype;
+  /* how many regions of given type overlap at current location */
+  int present[GRUB_EFI_MAX_MEMORY_TYPE];
+  /* Here is stored the resulting memory map*/
+  grub_efi_memory_descriptor_t *result;
+
+  /* Initialize variables*/
+  grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE);
+  scanline_events = (struct grub_efiemu_mmap_scan *)
+    grub_malloc (sizeof (struct grub_efiemu_mmap_scan) * 2 * mmap_num);
+
+  /* Number of chunks can't increase more than by factor of 2 */
+  result = (grub_efi_memory_descriptor_t *)
+    grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num);
+  if (!result || !scanline_events)
+    {
+      grub_free (result);
+      grub_free (scanline_events);
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			 "couldn't allocate space for new memory map");
+    }
+
+  /* Register scanline events */
+  for (i = 0; i < mmap_num; i++)
+    {
+      scanline_events[2 * i].pos = efiemu_mmap[i].physical_start;
+      scanline_events[2 * i].type = 0;
+      scanline_events[2 * i].memtype = efiemu_mmap[i].type;
+      scanline_events[2 * i + 1].pos = efiemu_mmap[i].physical_start
+	+ efiemu_mmap[i].num_pages * GRUB_EFIEMU_PAGESIZE;
+      scanline_events[2 * i + 1].type = 1;
+      scanline_events[2 * i + 1].memtype = efiemu_mmap[i].type;
+    }
+
+  /* Primitive bubble sort. It has complexity O(n^2) but since we're
+     unlikely to have more than 100 chunks it's probably one of the
+     fastest for one purpose */
+  done = 1;
+  while (done)
+    {
+      done = 0;
+      for (i = 0; i < 2 * mmap_num - 1; i++)
+	if (scanline_events[i + 1].pos < scanline_events[i].pos)
+	  {
+	    t = scanline_events[i + 1];
+	    scanline_events[i + 1] = scanline_events[i];
+	    scanline_events[i] = t;
+	    done = 1;
+	  }
+    }
+
+  /* Pointer in resulting memory map */
+  j = 0;
+  lastaddr = scanline_events[0].pos;
+  lasttype = scanline_events[0].memtype;
+  for (i = 0; i < 2 * mmap_num; i++)
+    {
+      /* Process event */
+      if (scanline_events[i].type)
+	present[scanline_events[i].memtype]--;
+      else
+	present[scanline_events[i].memtype]++;
+
+      /* Determine current region type */
+      curtype = -1;
+      for (k = 0; k < GRUB_EFI_MAX_MEMORY_TYPE; k++)
+	if (present[k] && (curtype == -1 || priority[k] > priority[curtype]))
+	  curtype = k;
+
+      /* Add memory region to resulting map if necessary */
+      if ((curtype == -1 || curtype != lasttype)
+	  && lastaddr != scanline_events[i].pos
+	  && lasttype != -1)
+	{
+	  result[j].virtual_start = result[j].physical_start = lastaddr;
+	  result[j].num_pages = (scanline_events[i].pos - lastaddr)
+	    / GRUB_EFIEMU_PAGESIZE;
+	  result[j].type = lasttype;
+
+	  /* We set runtime attribute on pages we need to be mapped */
+	  result[j].attribute
+	    = (lasttype == GRUB_EFI_RUNTIME_SERVICES_CODE
+		   || lasttype == GRUB_EFI_RUNTIME_SERVICES_DATA)
+	    ? GRUB_EFI_MEMORY_RUNTIME : 0;
+	  grub_dprintf ("efiemu",
+			"mmap entry: type %d start 0x%llx 0x%llx pages\n",
+			result[j].type,
+			result[j].physical_start, result[j].num_pages);
+	  j++;
+	}
+
+      /* Update last values if necessary */
+      if (curtype == -1 || curtype != lasttype)
+	{
+	  lasttype = curtype;
+	  lastaddr = scanline_events[i].pos;
+	}
+    }
+
+  grub_free (scanline_events);
+
+  /* Shrink resulting memory map to really used size and replace efiemu_mmap
+     by new value */
+  grub_free (efiemu_mmap);
+  efiemu_mmap = grub_realloc (result, j * sizeof (*result));
+  return GRUB_ERR_NONE;
+}
+
+/* This function is called to switch from first to second phase */
+grub_err_t
+grub_efiemu_mm_do_alloc (void)
+{
+  grub_err_t err;
+
+  /* Preallocate mmap */
+  efiemu_mmap = (grub_efi_memory_descriptor_t *)
+    grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t));
+  if (!efiemu_mmap)
+    {
+      grub_efiemu_unload ();
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Couldn't initialize mmap");
+    }
+
+  if ((err = efiemu_alloc_requests ()))
+    return err;
+  if ((err = grub_efiemu_mmap_fill ()))
+    return err;
+  return grub_efiemu_mmap_sort_and_uniq ();
+}
diff --git a/efiemu/pnvram.c b/efiemu/pnvram.c
new file mode 100644
index 0000000..04ad6e2
--- /dev/null
+++ b/efiemu/pnvram.c
@@ -0,0 +1,400 @@
+/* Export pnvram and some variables for runtime */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/efiemu/runtime.h>
+#include <grub/extcmd.h>
+
+/* Place for final location of variables */
+static int nvram_handle = 0;
+static int nvramsize_handle = 0;
+static int high_monotonic_count_handle = 0;
+static int timezone_handle = 0;
+static int accuracy_handle = 0;
+static int daylight_handle = 0;
+
+/* Temporary place */
+static grub_uint8_t *nvram;
+static grub_size_t nvramsize;
+static grub_uint32_t high_monotonic_count;
+static grub_int16_t timezone;
+static grub_uint8_t daylight;
+static grub_uint32_t accuracy;
+
+static const struct grub_arg_option options[] = {
+  {"size", 's', 0, "number of bytes to reserve for pseudo NVRAM", 0,
+   ARG_TYPE_INT},
+  {"high-monotonic-count", 'm', 0,
+   "Initial value of high monotonic count", 0, ARG_TYPE_INT},
+  {"timezone", 't', 0,
+   "Timezone, offset in minutes from GMT", 0, ARG_TYPE_INT},
+  {"accuracy", 'a', 0,
+   "Accuracy of clock, in 1e-12 units", 0, ARG_TYPE_INT},
+  {"daylight", 'd', 0,
+   "Daylight value, as per EFI specifications", 0, ARG_TYPE_INT},
+  {0, 0, 0, 0, 0, 0}
+};
+
+/* Parse signed value */
+static int
+grub_strtosl (char *arg, char **end, int base)
+{
+  if (arg[0] == '-')
+    return -grub_strtoul (arg + 1, end, base);
+  return grub_strtoul (arg, end, base);
+}
+
+/* Export stuff for efiemu */
+static grub_err_t
+nvram_set (void * data __attribute__ ((unused)))
+{
+  /* Take definitive pointers */
+  grub_uint8_t *nvram_def = grub_efiemu_mm_obtain_request (nvram_handle);
+  grub_uint32_t *nvramsize_def
+    = grub_efiemu_mm_obtain_request (nvramsize_handle);
+  grub_uint32_t *high_monotonic_count_def
+    = grub_efiemu_mm_obtain_request (high_monotonic_count_handle);
+  grub_int16_t *timezone_def
+    = grub_efiemu_mm_obtain_request (timezone_handle);
+  grub_uint8_t *daylight_def
+    = grub_efiemu_mm_obtain_request (daylight_handle);
+  grub_uint32_t *accuracy_def
+    = grub_efiemu_mm_obtain_request (accuracy_handle);
+
+  /* Copy to definitive loaction */
+  grub_dprintf ("efiemu", "preparing pnvram\n");
+  grub_memcpy (nvram_def, nvram, nvramsize);
+  *nvramsize_def = nvramsize;
+  *high_monotonic_count_def = high_monotonic_count;
+  *timezone_def = timezone;
+  *daylight_def = daylight;
+  *accuracy_def = accuracy;
+
+  /* Register symbols */
+  grub_efiemu_register_symbol ("efiemu_variables", nvram_handle, 0);
+  grub_efiemu_register_symbol ("efiemu_varsize", nvramsize_handle, 0);
+  grub_efiemu_register_symbol ("efiemu_high_monotonic_count",
+			       high_monotonic_count_handle, 0);
+  grub_efiemu_register_symbol ("efiemu_time_zone", timezone_handle, 0);
+  grub_efiemu_register_symbol ("efiemu_time_daylight", daylight_handle, 0);
+  grub_efiemu_register_symbol ("efiemu_time_accuracy",
+			       accuracy_handle, 0);
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+nvram_unload (void * data __attribute__ ((unused)))
+{
+  grub_efiemu_mm_return_request (nvram_handle);
+  grub_efiemu_mm_return_request (nvramsize_handle);
+  grub_efiemu_mm_return_request (high_monotonic_count_handle);
+  grub_efiemu_mm_return_request (timezone_handle);
+  grub_efiemu_mm_return_request (accuracy_handle);
+  grub_efiemu_mm_return_request (daylight_handle);
+
+  grub_free (nvram);
+  nvram = 0;
+}
+
+/* Load the variables file It's in format
+   guid1:attr1:name1:data1;
+   guid2:attr2:name2:data2;
+   ...
+   Where all fields are in hex
+*/
+static grub_err_t
+read_pnvram (char *filename)
+{
+  char *buf, *ptr, *ptr2;
+  grub_file_t file;
+  grub_size_t size;
+  grub_uint8_t *nvramptr = nvram;
+  struct efi_variable *efivar;
+  grub_size_t guidlen, datalen;
+  unsigned i, j;
+
+  file = grub_file_open (filename);
+  if (!file)
+    return grub_error (GRUB_ERR_BAD_OS, "couldn't read pnvram");
+  size = grub_file_size (file);
+  buf = grub_malloc (size + 1);
+  if (!buf)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't read pnvram");
+  if (grub_file_read (file, buf, size) != (grub_ssize_t) size)
+    return grub_error (GRUB_ERR_BAD_OS, "couldn't read pnvram");
+  buf[size] = 0;
+  grub_file_close (file);
+
+  for (ptr = buf; *ptr; )
+    {
+      if (grub_isspace (*ptr))
+	{
+	  ptr++;
+	  continue;
+	}
+
+      efivar = (struct efi_variable *) nvramptr;
+      if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize)
+	return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			   "file is too large for reserved variable space");
+
+      nvramptr += sizeof (struct efi_variable);
+
+      /* look ahow long guid field is*/
+      guidlen = 0;
+      for (ptr2 = ptr; (grub_isspace (*ptr2)
+			|| (*ptr2 >= '0' && *ptr2 <= '9')
+			|| (*ptr2 >= 'a' && *ptr2 <= 'f')
+			|| (*ptr2 >= 'A' && *ptr2 <= 'F'));
+	   ptr2++)
+	if (!grub_isspace (*ptr2))
+	  guidlen++;
+      guidlen /= 2;
+
+      /* Read guid */
+      if (guidlen != sizeof (efivar->guid))
+	{
+	  grub_free (buf);
+	  return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename);
+	}
+      for (i = 0; i < 2 * sizeof (efivar->guid); i++)
+	{
+	  int hex = 0;
+	  while (grub_isspace (*ptr))
+	    ptr++;
+	  if (*ptr >= '0' && *ptr <= '9')
+	    hex = *ptr - '0';
+	  if (*ptr >= 'a' && *ptr <= 'f')
+	    hex = *ptr - 'a' + 10;
+	  if (*ptr >= 'A' && *ptr <= 'F')
+	    hex = *ptr - 'A' + 10;
+
+	  if (i%2 == 0)
+	    ((grub_uint8_t *)&(efivar->guid))[i/2] = hex << 4;
+	  else
+	    ((grub_uint8_t *)&(efivar->guid))[i/2] |= hex;
+	  ptr++;
+	}
+
+      while (grub_isspace (*ptr))
+	ptr++;
+      if (*ptr != ':')
+	{
+	  grub_dprintf ("efiemu", "Not colon\n");
+	  grub_free (buf);
+	  return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename);
+	}
+      ptr++;
+      while (grub_isspace (*ptr))
+	ptr++;
+
+      /* Attributes can be just parsed by existing functions */
+      efivar->attributes = grub_strtoul (ptr, &ptr, 16);
+
+      while (grub_isspace (*ptr))
+	ptr++;
+      if (*ptr != ':')
+	{
+	  grub_dprintf ("efiemu", "Not colon\n");
+	  grub_free (buf);
+	  return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename);
+	}
+      ptr++;
+      while (grub_isspace (*ptr))
+	ptr++;
+
+      /* Read name and value */
+      for (j = 0; j < 2; j++)
+	{
+	  /* Look the length */
+	  datalen = 0;
+	  for (ptr2 = ptr; *ptr2 && (grub_isspace (*ptr2)
+				     || (*ptr2 >= '0' && *ptr2 <= '9')
+				     || (*ptr2 >= 'a' && *ptr2 <= 'f')
+				     || (*ptr2 >= 'A' && *ptr2 <= 'F'));
+	       ptr2++)
+	    if (!grub_isspace (*ptr2))
+	      datalen++;
+	  datalen /= 2;
+
+	  if (nvramptr - nvram + datalen > nvramsize)
+	    {
+	      grub_free (buf);
+	      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+				 "file is too large for reserved "
+				 " variable space");
+	    }
+
+	  for (i = 0; i < 2 * datalen; i++)
+	    {
+	      int hex = 0;
+	      while (grub_isspace (*ptr))
+		ptr++;
+	      if (*ptr >= '0' && *ptr <= '9')
+		hex = *ptr - '0';
+	      if (*ptr >= 'a' && *ptr <= 'f')
+		hex = *ptr - 'a' + 10;
+	      if (*ptr >= 'A' && *ptr <= 'F')
+		hex = *ptr - 'A' + 10;
+
+	      if (i%2 == 0)
+		nvramptr[i/2] = hex << 4;
+	      else
+		nvramptr[i/2] |= hex;
+	      ptr++;
+	    }
+	  nvramptr += datalen;
+	  while (grub_isspace (*ptr))
+	    ptr++;
+	  if (*ptr != (j ? ';' : ':'))
+	    {
+	      grub_free (buf);
+	      grub_dprintf ("efiemu", j?"Not semicolon\n":"Not colon\n");
+	      return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename);
+	    }
+	  if (j)
+	    efivar->size = datalen;
+	  else
+	    efivar->namelen = datalen;
+
+	  ptr++;
+	}
+    }
+  grub_free (buf);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_efiemu_make_nvram (void)
+{
+  grub_err_t err;
+
+  err = grub_efiemu_autocore ();
+  if (err)
+    {
+      grub_free (nvram);
+      return err;
+    }
+
+  err = grub_efiemu_register_prepare_hook (nvram_set, nvram_unload, 0);
+  if (err)
+    {
+      grub_free (nvram);
+      return err;
+    }
+  nvram_handle
+    = grub_efiemu_request_memalign (1, nvramsize,
+				    GRUB_EFI_RUNTIME_SERVICES_DATA);
+  nvramsize_handle
+    = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
+				    GRUB_EFI_RUNTIME_SERVICES_DATA);
+  high_monotonic_count_handle
+    = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
+				    GRUB_EFI_RUNTIME_SERVICES_DATA);
+  timezone_handle
+    = grub_efiemu_request_memalign (1, sizeof (grub_uint16_t),
+				    GRUB_EFI_RUNTIME_SERVICES_DATA);
+  daylight_handle
+    = grub_efiemu_request_memalign (1, sizeof (grub_uint8_t),
+				    GRUB_EFI_RUNTIME_SERVICES_DATA);
+  accuracy_handle
+    = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
+				    GRUB_EFI_RUNTIME_SERVICES_DATA);
+
+  grub_efiemu_request_symbols (6);
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_pnvram (void)
+{
+  if (nvram)
+    return GRUB_ERR_NONE;
+
+  nvramsize = 2048;
+  high_monotonic_count = 1;
+  timezone = GRUB_EFI_UNSPECIFIED_TIMEZONE;
+  accuracy = 50000000;
+  daylight = 0;
+
+  nvram = grub_zalloc (nvramsize);
+  if (!nvram)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		       "Couldn't allocate space for temporary pnvram storage");
+
+  return grub_efiemu_make_nvram ();
+}
+
+static grub_err_t
+grub_cmd_efiemu_pnvram (struct grub_extcmd *cmd,
+			int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  grub_err_t err;
+
+  if (argc > 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one argument expected");
+
+  nvramsize = state[0].set ? grub_strtoul (state[0].arg, 0, 0) : 2048;
+  high_monotonic_count = state[1].set ? grub_strtoul (state[1].arg, 0, 0) : 1;
+  timezone = state[2].set ? grub_strtosl (state[2].arg, 0, 0)
+    : GRUB_EFI_UNSPECIFIED_TIMEZONE;
+  accuracy = state[3].set ? grub_strtoul (state[3].arg, 0, 0) : 50000000;
+  daylight = state[4].set ? grub_strtoul (state[4].arg, 0, 0) : 0;
+
+  nvram = grub_zalloc (nvramsize);
+  if (!nvram)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		       "Couldn't allocate space for temporary pnvram storage");
+
+  if (argc == 1 && (err = read_pnvram (args[0])))
+    {
+      grub_free (nvram);
+      return err;
+    }
+  return grub_efiemu_make_nvram ();
+}
+
+static grub_extcmd_t cmd;
+
+void grub_efiemu_pnvram_cmd_register (void);
+void grub_efiemu_pnvram_cmd_unregister (void);
+
+void
+grub_efiemu_pnvram_cmd_register (void)
+{
+  cmd = grub_register_extcmd ("efiemu_pnvram", grub_cmd_efiemu_pnvram,
+			      GRUB_COMMAND_FLAG_BOTH,
+			      "efiemu_pnvram [FILENAME]",
+			      "Initialise pseudo-NVRAM and load variables "
+			      "from FILE",
+			      options);
+}
+
+void
+grub_efiemu_pnvram_cmd_unregister (void)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/efiemu/prepare.c b/efiemu/prepare.c
new file mode 100644
index 0000000..9e6d46f
--- /dev/null
+++ b/efiemu/prepare.c
@@ -0,0 +1,128 @@
+/* Prepare efiemu. E.g. allocate memory, load the runtime
+   to appropriate place, etc */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/lib/crc.h>
+
+grub_err_t
+SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks,
+			      struct grub_efiemu_configuration_table
+			      *config_tables)
+{
+  grub_err_t err;
+  int conftable_handle;
+  struct grub_efiemu_configuration_table *cur;
+  struct grub_efiemu_prepare_hook *curhook;
+
+  int cntconftables = 0;
+  struct SUFFIX (grub_efiemu_configuration_table) *conftables = 0;
+  struct SUFFIX (grub_efiemu_runtime_services) *runtime_services;
+  int i;
+  int handle;
+  grub_off_t off;
+
+  grub_dprintf ("efiemu", "Preparing EfiEmu\n");
+
+  /* Request space for the list of configuration tables */
+  for (cur = config_tables; cur; cur = cur->next)
+    cntconftables++;
+  conftable_handle
+    = grub_efiemu_request_memalign (GRUB_EFIEMU_PAGESIZE,
+				    cntconftables * sizeof (*conftables),
+				    GRUB_EFI_RUNTIME_SERVICES_DATA);
+
+  /* Switch from phase 1 (counting) to phase 2 (real job) */
+  grub_efiemu_alloc_syms ();
+  grub_efiemu_mm_do_alloc ();
+
+  grub_efiemu_system_table32 = 0;
+  grub_efiemu_system_table64 = 0;
+
+  /* Execute hooks */
+  for (curhook = prepare_hooks; curhook; curhook = curhook->next)
+    curhook->hook (curhook->data);
+
+  /* Move runtime to its due place */
+  err = grub_efiemu_loadcore_load ();
+  if (err)
+    {
+      grub_efiemu_unload ();
+      return err;
+    }
+
+  err = grub_efiemu_resolve_symbol ("efiemu_system_table", &handle, &off);
+  if (err)
+    {
+      grub_efiemu_unload ();
+      return err;
+    }
+
+  SUFFIX (grub_efiemu_system_table)
+    = (struct SUFFIX (grub_efi_system_table) *)
+    ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off);
+
+  /* compute CRC32 of runtime_services */
+  if ((err = grub_efiemu_resolve_symbol ("efiemu_runtime_services",
+					 &handle, &off)))
+    return err;
+  runtime_services = (struct SUFFIX (grub_efiemu_runtime_services) *)
+	((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off);
+  runtime_services->hdr.crc32 = 0;
+  runtime_services->hdr.crc32 = grub_getcrc32
+    (0, runtime_services, runtime_services->hdr.header_size);
+
+  /* Put pointer to the list of configuration tables in system table */
+  grub_efiemu_write_value
+    (&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0,
+     conftable_handle, 0, 1,
+     sizeof (SUFFIX (grub_efiemu_system_table)->configuration_table));
+  SUFFIX(grub_efiemu_system_table)->num_table_entries = cntconftables;
+
+  /* Fill the list of configuration tables */
+  conftables = (struct SUFFIX (grub_efiemu_configuration_table) *)
+    grub_efiemu_mm_obtain_request (conftable_handle);
+  i = 0;
+  for (cur = config_tables; cur; cur = cur->next, i++)
+    {
+      grub_memcpy (&(conftables[i].vendor_guid), &(cur->guid),
+		       sizeof (cur->guid));
+      if (cur->get_table)
+	conftables[i].vendor_table
+	  = PTR_TO_UINT64 (cur->get_table (cur->data));
+      else
+	conftables[i].vendor_table = PTR_TO_UINT64 (cur->data);
+    }
+
+  /* compute CRC32 of system table */
+  SUFFIX (grub_efiemu_system_table)->hdr.crc32 = 0;
+  SUFFIX (grub_efiemu_system_table)->hdr.crc32
+    = grub_getcrc32 (0, SUFFIX (grub_efiemu_system_table),
+		     SUFFIX (grub_efiemu_system_table)->hdr.header_size);
+
+  grub_dprintf ("efiemu","system_table = %p, runtime_services = %p,"
+		" conftables = %p (%d entries)\n",
+		SUFFIX (grub_efiemu_system_table), runtime_services,
+		conftables, cntconftables);
+
+  return GRUB_ERR_NONE;
+}
diff --git a/efiemu/prepare32.c b/efiemu/prepare32.c
new file mode 100644
index 0000000..fd6109e
--- /dev/null
+++ b/efiemu/prepare32.c
@@ -0,0 +1,22 @@
+/* This file contains definitions so that prepare.c compiles for 32-bit */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define SUFFIX(x) x ## 32
+
+#include "prepare.c"
diff --git a/efiemu/prepare64.c b/efiemu/prepare64.c
new file mode 100644
index 0000000..811f558
--- /dev/null
+++ b/efiemu/prepare64.c
@@ -0,0 +1,22 @@
+/* This file contains definitions so that prepare.c compiles for 64-bit */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define SUFFIX(x) x ## 64
+
+#include "prepare.c"
diff --git a/efiemu/runtime/config.h b/efiemu/runtime/config.h
new file mode 100644
index 0000000..26fb2ff
--- /dev/null
+++ b/efiemu/runtime/config.h
@@ -0,0 +1,34 @@
+/* This is a pseudo config.h so that types.h compiles nicely */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define GRUB_TYPES_CPU_HEADER	1
+
+#ifdef ELF32
+# define SIZEOF_VOID_P	4
+# define SIZEOF_LONG	4
+# define GRUB_TARGET_SIZEOF_VOID_P	4
+# define GRUB_TARGET_SIZEOF_LONG	4
+# define EFI_FUNC(x) x
+#else
+# define SIZEOF_VOID_P	8
+# define SIZEOF_LONG	8
+# define GRUB_TARGET_SIZEOF_VOID_P	8
+# define GRUB_TARGET_SIZEOF_LONG	8
+# define EFI_FUNC(x) x ## _real
+#endif
diff --git a/efiemu/runtime/efiemu.S b/efiemu/runtime/efiemu.S
new file mode 100644
index 0000000..b502314
--- /dev/null
+++ b/efiemu/runtime/efiemu.S
@@ -0,0 +1,159 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+/*
+ * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use
+ * different call conversion, so we need to do some conversion.
+ *
+ * gcc:
+ *   %rdi,  %rsi,  %rdx,  %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ...
+ *
+ * efi:
+ *   %rcx,  %rdx,  %r8,  %r9,  32(%rsp), 40(%rsp), 48(%rsp), ...
+ *
+ */
+
+        .file   "efiemu.S"
+	.text
+
+FUNCTION (efiemu_get_time)
+	push %rdi
+	push %rsi
+	mov %rcx, %rdi
+	mov %rdx, %rsi
+	call efiemu_get_time_real
+	pop %rsi
+	pop %rdi
+	ret
+
+FUNCTION (efiemu_set_time)
+	push %rdi
+	push %rsi
+	mov %rcx, %rdi
+	call efiemu_set_time_real
+	pop %rsi
+	pop %rdi
+	ret
+
+
+FUNCTION (efiemu_get_wakeup_time)
+	push %rdi
+	push %rsi
+	mov %rcx, %rdi
+	mov %rdx, %rsi
+	mov %r8, %rdx
+	call efiemu_get_wakeup_time_real
+	pop %rsi
+	pop %rdi
+	ret
+
+FUNCTION (efiemu_set_wakeup_time)
+	push %rdi
+	push %rsi
+	mov %rcx, %rdi
+	mov %rdx, %rsi
+	call efiemu_set_wakeup_time_real
+	pop %rsi
+	pop %rdi
+	ret
+
+FUNCTION (efiemu_get_variable)
+	push %rdi
+	push %rsi
+	mov %rcx, %rdi
+	mov %rdx, %rsi
+	mov %r8, %rdx
+	mov %r9, %rcx
+	mov 56(%rsp), %r8
+	call efiemu_get_variable_real
+	pop %rsi
+	pop %rdi
+	ret
+
+FUNCTION (efiemu_get_next_variable_name)
+	push %rdi
+	push %rsi
+	mov %rcx, %rdi
+	mov %rdx, %rsi
+	mov %r8, %rdx
+	call efiemu_get_next_variable_name_real
+	pop %rsi
+	pop %rdi
+	ret
+
+FUNCTION (efiemu_set_variable)
+	push %rdi
+	push %rsi
+	mov %rcx, %rdi
+	mov %rdx, %rsi
+	mov %r8, %rdx
+	mov %r9, %rcx
+	mov 56(%rsp), %r8
+	call efiemu_set_variable_real
+	pop %rsi
+	pop %rdi
+	ret
+
+FUNCTION (efiemu_get_next_high_monotonic_count)
+	push %rdi
+	push %rsi
+	mov %rcx, %rdi
+	call efiemu_get_next_high_monotonic_count_real
+	pop %rsi
+	pop %rdi
+	ret
+
+FUNCTION (efiemu_reset_system)
+	push %rdi
+	push %rsi
+	mov %rcx, %rdi
+	mov %rdx, %rsi
+	mov %r8, %rdx
+	mov %r9, %rcx
+	call efiemu_reset_system_real
+	pop %rsi
+	pop %rdi
+	ret
+
+	/* The following functions are always called in physical mode */
+	.section ".text-physical", "ax"
+
+FUNCTION (efiemu_set_virtual_address_map)
+	push %rdi
+	push %rsi
+	mov %rcx, %rdi
+	mov %rdx, %rsi
+	mov %r8, %rdx
+	mov %r9, %rcx
+	call efiemu_set_virtual_address_map_real
+	pop %rsi
+	pop %rdi
+	ret
+
+FUNCTION (efiemu_convert_pointer)
+	push %rdi
+	push %rsi
+	mov %rcx, %rdi
+	mov %rdx, %rsi
+	call efiemu_convert_pointer_real
+	pop %rsi
+	pop %rdi
+	ret
+
diff --git a/efiemu/runtime/efiemu.c b/efiemu/runtime/efiemu.c
new file mode 100644
index 0000000..085e75d
--- /dev/null
+++ b/efiemu/runtime/efiemu.c
@@ -0,0 +1,631 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This is an emulation of EFI runtime services.
+   This allows a more uniform boot on i386 machines.
+   As it emulates only runtime serviceit isn't able
+   to chainload EFI bootloader on non-EFI system (TODO) */
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/efi/api.h>
+#include <grub/efiemu/runtime.h>
+
+grub_efi_status_t
+efiemu_get_time (grub_efi_time_t *time,
+		 grub_efi_time_capabilities_t *capabilities);
+grub_efi_status_t
+efiemu_set_time (grub_efi_time_t *time);
+
+grub_efi_status_t
+efiemu_get_wakeup_time (grub_efi_boolean_t *enabled,
+			grub_efi_boolean_t *pending,
+			grub_efi_time_t *time);
+grub_efi_status_t
+efiemu_set_wakeup_time (grub_efi_boolean_t enabled,
+			grub_efi_time_t *time);
+
+#ifdef APPLE_CC
+#define PHYSICAL_ATTRIBUTE __attribute__ ((section("_text-physical, _text-physical")));
+#else
+#define PHYSICAL_ATTRIBUTE __attribute__ ((section(".text-physical")));
+#endif
+
+grub_efi_status_t
+efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
+				grub_efi_uintn_t descriptor_size,
+				grub_efi_uint32_t descriptor_version,
+				grub_efi_memory_descriptor_t *virtual_map)
+  PHYSICAL_ATTRIBUTE;
+
+grub_efi_status_t
+efiemu_convert_pointer (grub_efi_uintn_t debug_disposition,
+			void **address)
+  PHYSICAL_ATTRIBUTE;
+
+grub_efi_status_t
+efiemu_get_variable (grub_efi_char16_t *variable_name,
+		     grub_efi_guid_t *vendor_guid,
+		     grub_efi_uint32_t *attributes,
+		     grub_efi_uintn_t *data_size,
+		     void *data);
+
+grub_efi_status_t
+efiemu_get_next_variable_name (grub_efi_uintn_t *variable_name_size,
+			       grub_efi_char16_t *variable_name,
+			       grub_efi_guid_t *vendor_guid);
+
+grub_efi_status_t
+efiemu_set_variable (grub_efi_char16_t *variable_name,
+		     grub_efi_guid_t *vendor_guid,
+		     grub_efi_uint32_t attributes,
+		     grub_efi_uintn_t data_size,
+		     void *data);
+grub_efi_status_t
+efiemu_get_next_high_monotonic_count (grub_efi_uint32_t *high_count);
+void
+efiemu_reset_system (grub_efi_reset_type_t reset_type,
+		     grub_efi_status_t reset_status,
+		     grub_efi_uintn_t data_size,
+		     grub_efi_char16_t *reset_data);
+
+grub_efi_status_t
+EFI_FUNC (efiemu_set_virtual_address_map) (grub_efi_uintn_t,
+					      grub_efi_uintn_t,
+					      grub_efi_uint32_t,
+					      grub_efi_memory_descriptor_t *)
+     PHYSICAL_ATTRIBUTE;
+grub_efi_status_t
+EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
+				      void **address)
+     PHYSICAL_ATTRIBUTE;
+static grub_uint32_t
+efiemu_getcrc32 (grub_uint32_t crc, void *buf, int size)
+     PHYSICAL_ATTRIBUTE;
+static void
+init_crc32_table (void)
+     PHYSICAL_ATTRIBUTE;
+static grub_uint32_t
+reflect (grub_uint32_t ref, int len)
+     PHYSICAL_ATTRIBUTE;
+
+/*
+  The log. It's used when examining memory dump
+*/
+static grub_uint8_t loge[1000] = "EFIEMULOG";
+static int logn = 9;
+#define LOG(x)   { if (logn<900) loge[logn++]=x; }
+
+static int ptv_relocated = 0;
+
+/* Interface with grub */
+struct grub_efi_runtime_services efiemu_runtime_services;
+struct grub_efi_system_table efiemu_system_table;
+extern struct grub_efiemu_ptv_rel efiemu_ptv_relloc[];
+extern grub_uint8_t efiemu_variables[];
+extern grub_uint32_t efiemu_varsize;
+extern grub_uint32_t efiemu_high_monotonic_count;
+extern grub_int16_t efiemu_time_zone;
+extern grub_uint8_t efiemu_time_daylight;
+extern grub_uint32_t efiemu_time_accuracy;
+
+/* Some standard functions because we need to be standalone */
+static void
+efiemu_memcpy (void *to, void *from, int count)
+{
+  int i;
+  for (i = 0; i < count; i++)
+    ((grub_uint8_t *) to)[i] = ((grub_uint8_t *) from)[i];
+}
+
+static int
+efiemu_str16equal (grub_uint16_t *a, grub_uint16_t *b)
+{
+  grub_uint16_t *ptr1, *ptr2;
+  for (ptr1=a,ptr2=b; *ptr1 && *ptr2 == *ptr1; ptr1++, ptr2++);
+  return *ptr2 == *ptr1;
+}
+
+static grub_size_t
+efiemu_str16len (grub_uint16_t *a)
+{
+  grub_uint16_t *ptr1;
+  for (ptr1 = a; *ptr1; ptr1++);
+  return ptr1 - a;
+}
+
+static int
+efiemu_memequal (void *a, void *b, grub_size_t n)
+{
+  grub_uint8_t *ptr1, *ptr2;
+  for (ptr1 = (grub_uint8_t *) a, ptr2 = (grub_uint8_t *)b;
+       ptr1 < (grub_uint8_t *)a + n && *ptr2 == *ptr1; ptr1++, ptr2++);
+  return ptr1 == a + n;
+}
+
+static void
+efiemu_memset (grub_uint8_t *a, grub_uint8_t b, grub_size_t n)
+{
+  grub_uint8_t *ptr1;
+  for (ptr1=a; ptr1 < a + n; ptr1++)
+    *ptr1 = b;
+}
+
+static inline void
+write_cmos (grub_uint8_t addr, grub_uint8_t val)
+{
+  __asm__ __volatile__ ("outb %%al,$0x70\n"
+			"mov %%cl, %%al\n"
+			"outb %%al,$0x71": :"a" (addr), "c" (val));
+}
+
+static inline grub_uint8_t
+read_cmos (grub_uint8_t addr)
+{
+  grub_uint8_t ret;
+  __asm__ __volatile__ ("outb %%al, $0x70\n"
+			"inb $0x71, %%al": "=a"(ret) :"a" (addr));
+  return ret;
+}
+
+/* Needed by some gcc versions */
+int __stack_chk_fail ()
+{
+  return 0;
+}
+
+/* The function that implement runtime services as specified in
+   EFI specification */
+static inline grub_uint8_t
+bcd_to_hex (grub_uint8_t in)
+{
+  return 10 * ((in & 0xf0) >> 4) + (in & 0x0f);
+}
+
+grub_efi_status_t
+EFI_FUNC (efiemu_get_time) (grub_efi_time_t *time,
+			       grub_efi_time_capabilities_t *capabilities)
+{
+  LOG ('a');
+  grub_uint8_t state;
+  state = read_cmos (0xb);
+  if (!(state & (1 << 2)))
+    {
+      time->year = 2000 + bcd_to_hex (read_cmos (0x9));
+      time->month = bcd_to_hex (read_cmos (0x8));
+      time->day = bcd_to_hex (read_cmos (0x7));
+      time->hour = bcd_to_hex (read_cmos (0x4));
+      if (time->hour >= 81)
+	time->hour -= 80 - 12;
+      if (time->hour == 24)
+	time->hour = 0;
+      time->minute = bcd_to_hex (read_cmos (0x2));
+      time->second = bcd_to_hex (read_cmos (0x0));
+    }
+  else
+    {
+      time->year = 2000 + read_cmos (0x9);
+      time->month = read_cmos (0x8);
+      time->day = read_cmos (0x7);
+      time->hour = read_cmos (0x4);
+      if (time->hour >= 0x81)
+	time->hour -= 0x80 - 12;
+      if (time->hour == 24)
+	time->hour = 0;
+      time->minute = read_cmos (0x2);
+      time->second = read_cmos (0x0);
+    }
+  time->nanosecond = 0;
+  time->pad1 = 0;
+  time->pad2 = 0;
+  time->time_zone = efiemu_time_zone;
+  time->daylight = efiemu_time_daylight;
+  capabilities->resolution = 1;
+  capabilities->accuracy = efiemu_time_accuracy;
+  capabilities->sets_to_zero = 0;
+  return GRUB_EFI_SUCCESS;
+}
+
+grub_efi_status_t
+EFI_FUNC (efiemu_set_time) (grub_efi_time_t *time)
+{
+  LOG ('b');
+  grub_uint8_t state;
+  state = read_cmos (0xb);
+  write_cmos (0xb, state | 0x6);
+  write_cmos (0x9, time->year - 2000);
+  write_cmos (0x8, time->month);
+  write_cmos (0x7, time->day);
+  write_cmos (0x4, time->hour);
+  write_cmos (0x2, time->minute);
+  write_cmos (0x0, time->second);
+  efiemu_time_zone = time->time_zone;
+  efiemu_time_daylight = time->daylight;
+  return GRUB_EFI_SUCCESS;
+}
+
+/* Following 2 functions are vendor specific. So announce it as unsupported */
+grub_efi_status_t
+EFI_FUNC (efiemu_get_wakeup_time) (grub_efi_boolean_t *enabled,
+				      grub_efi_boolean_t *pending,
+				      grub_efi_time_t *time)
+{
+  LOG ('c');
+  return GRUB_EFI_UNSUPPORTED;
+}
+
+grub_efi_status_t
+EFI_FUNC (efiemu_set_wakeup_time) (grub_efi_boolean_t enabled,
+				      grub_efi_time_t *time)
+{
+  LOG ('d');
+  return GRUB_EFI_UNSUPPORTED;
+}
+
+static grub_uint32_t crc32_table [256];
+
+static grub_uint32_t
+reflect (grub_uint32_t ref, int len)
+{
+  grub_uint32_t result = 0;
+  int i;
+
+  for (i = 1; i <= len; i++)
+    {
+      if (ref & 1)
+	result |= 1 << (len - i);
+      ref >>= 1;
+    }
+
+  return result;
+}
+
+static void
+init_crc32_table (void)
+{
+  grub_uint32_t polynomial = 0x04c11db7;
+  int i, j;
+
+  for(i = 0; i < 256; i++)
+    {
+      crc32_table[i] = reflect(i, 8) << 24;
+      for (j = 0; j < 8; j++)
+        crc32_table[i] = (crc32_table[i] << 1) ^
+            (crc32_table[i] & (1 << 31) ? polynomial : 0);
+      crc32_table[i] = reflect(crc32_table[i], 32);
+    }
+}
+
+static grub_uint32_t
+efiemu_getcrc32 (grub_uint32_t crc, void *buf, int size)
+{
+  int i;
+  grub_uint8_t *data = buf;
+
+  if (! crc32_table[1])
+    init_crc32_table ();
+
+  crc^= 0xffffffff;
+
+  for (i = 0; i < size; i++)
+    {
+      crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *data];
+      data++;
+    }
+
+  return crc ^ 0xffffffff;
+}
+
+
+grub_efi_status_t EFI_FUNC
+(efiemu_set_virtual_address_map) (grub_efi_uintn_t memory_map_size,
+				  grub_efi_uintn_t descriptor_size,
+				  grub_efi_uint32_t descriptor_version,
+				  grub_efi_memory_descriptor_t *virtual_map)
+{
+  struct grub_efiemu_ptv_rel *cur_relloc;
+
+  LOG ('e');
+
+  /* Ensure that we are called only once */
+  if (ptv_relocated)
+    return GRUB_EFI_UNSUPPORTED;
+  ptv_relocated = 1;
+
+  /* Correct addresses using information supplied by grub */
+  for (cur_relloc = efiemu_ptv_relloc; cur_relloc->size;cur_relloc++)
+    {
+      grub_int64_t corr = 0;
+      grub_efi_memory_descriptor_t *descptr;
+
+      /* Compute correction */
+      for (descptr = virtual_map;
+	   ((grub_uint8_t *) descptr - (grub_uint8_t *) virtual_map)
+	     < memory_map_size;
+	   descptr = (grub_efi_memory_descriptor_t *)
+	     ((grub_uint8_t *) descptr + descriptor_size))
+	{
+	  if (descptr->type == cur_relloc->plustype)
+	    corr += descptr->virtual_start - descptr->physical_start;
+	  if (descptr->type == cur_relloc->minustype)
+	    corr -= descptr->virtual_start - descptr->physical_start;
+	}
+
+      /* Apply correction */
+      switch (cur_relloc->size)
+	{
+	case 8:
+	  *((grub_uint64_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
+	  break;
+	case 4:
+	  *((grub_uint32_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
+	  break;
+	case 2:
+	  *((grub_uint16_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
+	  break;
+	case 1:
+	  *((grub_uint8_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
+	  break;
+	}
+    }
+
+  /* Recompute crc32 of system table and runtime services */
+  efiemu_system_table.hdr.crc32 = 0;
+  efiemu_system_table.hdr.crc32 = efiemu_getcrc32
+    (0, &efiemu_system_table, sizeof (efiemu_system_table));
+
+  efiemu_runtime_services.hdr.crc32 = 0;
+  efiemu_runtime_services.hdr.crc32 = efiemu_getcrc32
+    (0, &efiemu_runtime_services, sizeof (efiemu_runtime_services));
+
+  return GRUB_EFI_SUCCESS;
+}
+
+/* since efiemu_set_virtual_address_map corrects all the pointers
+   we don't need efiemu_convert_pointer */
+grub_efi_status_t
+EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
+				      void **address)
+{
+  LOG ('f');
+  return GRUB_EFI_UNSUPPORTED;
+}
+
+/* Next comes variable services. Because we have no vendor-independent
+   way to store these variables we have no non-volatility */
+
+/* Find variable by name and GUID. */
+static struct efi_variable *
+find_variable (grub_efi_guid_t *vendor_guid,
+	       grub_efi_char16_t *variable_name)
+{
+  grub_uint8_t *ptr;
+  struct efi_variable *efivar;
+
+  for (ptr = efiemu_variables; ptr < efiemu_variables + efiemu_varsize; )
+    {
+      efivar = (struct efi_variable *) ptr;
+      if (!efivar->namelen)
+	return 0;
+      if (efiemu_str16equal((grub_efi_char16_t *)(efivar + 1), variable_name)
+	  && efiemu_memequal (&(efivar->guid), vendor_guid,
+			      sizeof (efivar->guid)))
+	return efivar;
+      ptr += efivar->namelen + efivar->size + sizeof (*efivar);
+    }
+  return 0;
+}
+
+grub_efi_status_t
+EFI_FUNC (efiemu_get_variable) (grub_efi_char16_t *variable_name,
+				   grub_efi_guid_t *vendor_guid,
+				   grub_efi_uint32_t *attributes,
+				   grub_efi_uintn_t *data_size,
+				   void *data)
+{
+  struct efi_variable *efivar;
+  LOG ('g');
+  efivar = find_variable (vendor_guid, variable_name);
+  if (!efivar)
+    return GRUB_EFI_NOT_FOUND;
+  if (*data_size < efivar->size)
+    {
+      *data_size = efivar->size;
+      return GRUB_EFI_BUFFER_TOO_SMALL;
+    }
+  *data_size = efivar->size;
+  efiemu_memcpy (data, (grub_uint8_t *)(efivar + 1) + efivar->namelen,
+		 efivar->size);
+  *attributes = efivar->attributes;
+
+  return GRUB_EFI_SUCCESS;
+}
+
+grub_efi_status_t EFI_FUNC
+(efiemu_get_next_variable_name) (grub_efi_uintn_t *variable_name_size,
+				 grub_efi_char16_t *variable_name,
+				 grub_efi_guid_t *vendor_guid)
+{
+  struct efi_variable *efivar;
+  LOG ('l');
+
+  if (!variable_name_size || !variable_name || !vendor_guid)
+    return GRUB_EFI_INVALID_PARAMETER;
+  if (variable_name[0])
+    {
+      efivar = find_variable (vendor_guid, variable_name);
+      if (!efivar)
+	return GRUB_EFI_NOT_FOUND;
+      efivar = (struct efi_variable *)((grub_uint8_t *)efivar
+				       + efivar->namelen
+				       + efivar->size + sizeof (*efivar));
+    }
+  else
+    efivar = (struct efi_variable *) (efiemu_variables);
+
+  LOG ('m');
+  if ((grub_uint8_t *)efivar >= efiemu_variables + efiemu_varsize
+      || !efivar->namelen)
+    return GRUB_EFI_NOT_FOUND;
+  if (*variable_name_size < efivar->namelen)
+    {
+      *variable_name_size = efivar->namelen;
+      return GRUB_EFI_BUFFER_TOO_SMALL;
+    }
+
+  efiemu_memcpy (variable_name, efivar + 1, efivar->namelen);
+  efiemu_memcpy (vendor_guid, &(efivar->guid),
+		 sizeof (efivar->guid));
+
+  LOG('h');
+  return GRUB_EFI_SUCCESS;
+}
+
+grub_efi_status_t
+EFI_FUNC (efiemu_set_variable) (grub_efi_char16_t *variable_name,
+				   grub_efi_guid_t *vendor_guid,
+				   grub_efi_uint32_t attributes,
+				   grub_efi_uintn_t data_size,
+				   void *data)
+{
+  struct efi_variable *efivar;
+  grub_uint8_t *ptr;
+  LOG('i');
+  if (!variable_name[0])
+    return GRUB_EFI_INVALID_PARAMETER;
+  efivar = find_variable (vendor_guid, variable_name);
+
+  /* Delete variable if any */
+  if (efivar)
+    {
+      efiemu_memcpy (efivar, (grub_uint8_t *)(efivar + 1)
+		     + efivar->namelen + efivar->size,
+		     (efiemu_variables + efiemu_varsize)
+		     - ((grub_uint8_t *)(efivar + 1)
+			+ efivar->namelen + efivar->size));
+      efiemu_memset (efiemu_variables + efiemu_varsize
+		     - (sizeof (*efivar) + efivar->namelen + efivar->size),
+		     0, (sizeof (*efivar) + efivar->namelen + efivar->size));
+    }
+
+  if (!data_size)
+    return GRUB_EFI_SUCCESS;
+
+  for (ptr = efiemu_variables; ptr < efiemu_variables + efiemu_varsize; )
+    {
+      efivar = (struct efi_variable *) ptr;
+      ptr += efivar->namelen + efivar->size + sizeof (*efivar);
+      if (!efivar->namelen)
+	break;
+    }
+  if ((grub_uint8_t *)(efivar + 1) + data_size
+      + 2 * (efiemu_str16len (variable_name) + 1)
+      >= efiemu_variables + efiemu_varsize)
+    return GRUB_EFI_OUT_OF_RESOURCES;
+
+  efiemu_memcpy (&(efivar->guid), vendor_guid, sizeof (efivar->guid));
+  efivar->namelen = 2 * (efiemu_str16len (variable_name) + 1);
+  efivar->size = data_size;
+  efivar->attributes = attributes;
+  efiemu_memcpy (efivar + 1, variable_name,
+		 2 * (efiemu_str16len (variable_name) + 1));
+  efiemu_memcpy ((grub_uint8_t *)(efivar + 1)
+		 + 2 * (efiemu_str16len (variable_name) + 1),
+		 data, data_size);
+
+  return GRUB_EFI_SUCCESS;
+}
+
+grub_efi_status_t EFI_FUNC
+(efiemu_get_next_high_monotonic_count) (grub_efi_uint32_t *high_count)
+{
+  LOG ('j');
+  if (!high_count)
+    return GRUB_EFI_INVALID_PARAMETER;
+  *high_count = ++efiemu_high_monotonic_count;
+  return GRUB_EFI_SUCCESS;
+}
+
+/* To implement it with APM we need to go to real mode. It's too much hassle
+   Besides EFI specification says that this function shouldn't be used
+   on systems supporting ACPI
+ */
+void
+EFI_FUNC (efiemu_reset_system) (grub_efi_reset_type_t reset_type,
+				   grub_efi_status_t reset_status,
+				   grub_efi_uintn_t data_size,
+				   grub_efi_char16_t *reset_data)
+{
+  LOG ('k');
+}
+
+struct grub_efi_runtime_services efiemu_runtime_services =
+{
+  .hdr =
+  {
+    .signature = GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE,
+    .revision = 0x0001000a,
+    .header_size = sizeof (struct grub_efi_runtime_services),
+    .crc32 = 0, /* filled later*/
+    .reserved = 0
+  },
+  .get_time = efiemu_get_time,
+  .set_time = efiemu_set_time,
+  .get_wakeup_time = efiemu_get_wakeup_time,
+  .set_wakeup_time = efiemu_set_wakeup_time,
+
+  .set_virtual_address_map = efiemu_set_virtual_address_map,
+  .convert_pointer = efiemu_convert_pointer,
+
+  .get_variable = efiemu_get_variable,
+  .get_next_variable_name = efiemu_get_next_variable_name,
+  .set_variable = efiemu_set_variable,
+  .get_next_high_monotonic_count = efiemu_get_next_high_monotonic_count,
+
+  .reset_system = efiemu_reset_system
+};
+
+
+static grub_uint16_t efiemu_vendor[] =
+  {'G', 'R', 'U', 'B', ' ', 'E', 'F', 'I', ' ',
+   'R', 'U', 'N', 'T', 'I', 'M', 'E', 0};
+
+struct grub_efi_system_table efiemu_system_table =
+{
+  .hdr =
+  {
+    .signature = GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE,
+    .revision = 0x0001000a,
+    .header_size = sizeof (struct grub_efi_system_table),
+    .crc32 = 0, /* filled later*/
+    .reserved = 0
+  },
+  .firmware_vendor = efiemu_vendor,
+  .firmware_revision = 0x0001000a,
+  .console_in_handler = 0,
+  .con_in = 0,
+  .console_out_handler = 0,
+  .con_out = 0,
+  .standard_error_handle = 0,
+  .std_err = 0,
+  .runtime_services = &efiemu_runtime_services,
+  .boot_services = 0,
+  .num_table_entries = 0,
+  .configuration_table = 0
+};
+
diff --git a/efiemu/runtime/efiemu.sh b/efiemu/runtime/efiemu.sh
new file mode 100644
index 0000000..5a492dc
--- /dev/null
+++ b/efiemu/runtime/efiemu.sh
@@ -0,0 +1,4 @@
+gcc -c -m32 -DELF32 -o efiemu32.o ./efiemu.c -Wall -Werror -nostdlib -O2 -I. -I../../include
+gcc -c -m64 -DELF64 -o efiemu64_c.o ./efiemu.c -Wall -Werror -mcmodel=large -O2 -I. -I../../include
+gcc -c -m64 -DELF64 -o efiemu64_s.o ./efiemu.S -Wall -Werror -mcmodel=large -O2 -I. -I../../include
+ld -o efiemu64.o -r efiemu64_s.o efiemu64_c.o -nostdlib
diff --git a/efiemu/symbols.c b/efiemu/symbols.c
new file mode 100644
index 0000000..ec508d9
--- /dev/null
+++ b/efiemu/symbols.c
@@ -0,0 +1,188 @@
+/* Code for managing symbols and pointers in efiemu */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/efiemu/runtime.h>
+
+static int ptv_written = 0;
+static int ptv_alloc = 0;
+static int ptv_handle = 0;
+static int ptv_requested = 0;
+static struct grub_efiemu_sym *efiemu_syms = 0;
+
+struct grub_efiemu_sym
+{
+  struct grub_efiemu_sym *next;
+  char *name;
+  int handle;
+  grub_off_t off;
+};
+
+void
+grub_efiemu_free_syms (void)
+{
+  struct grub_efiemu_sym *cur, *d;
+  for (cur = efiemu_syms; cur;)
+    {
+      d = cur->next;
+      grub_free (cur->name);
+      grub_free (cur);
+      cur = d;
+    }
+  efiemu_syms = 0;
+  ptv_written = 0;
+  ptv_alloc = 0;
+  ptv_requested = 0;
+  grub_efiemu_mm_return_request (ptv_handle);
+  ptv_handle = 0;
+}
+
+/* Announce that the module will need NUM allocators */
+/* Because of deferred memory allocation all the relocators have to be
+   announced during phase 1*/
+grub_err_t
+grub_efiemu_request_symbols (int num)
+{
+  if (ptv_alloc)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "symbols have already been allocated");
+  if (num < 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "can't request negative symbols");
+  ptv_requested += num;
+  return GRUB_ERR_NONE;
+}
+
+/* Resolve the symbol name NAME and set HANDLE and OFF accordingly  */
+grub_err_t
+grub_efiemu_resolve_symbol (const char *name, int *handle, grub_off_t *off)
+{
+  struct grub_efiemu_sym *cur;
+  for (cur = efiemu_syms; cur; cur = cur->next)
+    if (!grub_strcmp (name, cur->name))
+      {
+	*handle = cur->handle;
+	*off = cur->off;
+	return GRUB_ERR_NONE;
+      }
+  grub_dprintf ("efiemu", "%s not found\n", name);
+  return grub_error (GRUB_ERR_BAD_OS, "symbol %s isn't found", name);
+}
+
+/* Register symbol named NAME in memory handle HANDLE at offset OFF */
+grub_err_t
+grub_efiemu_register_symbol (const char *name, int handle, grub_off_t off)
+{
+  struct grub_efiemu_sym *cur;
+  cur = (struct grub_efiemu_sym *) grub_malloc (sizeof (*cur));
+  grub_dprintf ("efiemu", "registering symbol '%s'\n", name);
+  if (!cur)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't register symbol");
+  cur->name = grub_strdup (name);
+  cur->next = efiemu_syms;
+  cur->handle = handle;
+  cur->off = off;
+  efiemu_syms = cur;
+
+  return 0;
+}
+
+/* Go from phase 1 to phase 2. Must be called before similar function in mm.c */
+grub_err_t
+grub_efiemu_alloc_syms (void)
+{
+  ptv_alloc = ptv_requested;
+  ptv_handle = grub_efiemu_request_memalign
+    (1, (ptv_requested + 1) * sizeof (struct grub_efiemu_ptv_rel),
+     GRUB_EFI_RUNTIME_SERVICES_DATA);
+  grub_efiemu_register_symbol ("efiemu_ptv_relloc", ptv_handle, 0);
+  return grub_errno;
+}
+
+/* Write value (pointer to memory PLUS_HANDLE)
+   - (pointer to memory MINUS_HANDLE) + VALUE to ADDR assuming that the
+   size SIZE bytes. If PTV_NEEDED is 1 then announce it to runtime that this
+   value needs to be recomputed before going to virtual mode
+*/
+grub_err_t
+grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle,
+			 int minus_handle, int ptv_needed, int size)
+{
+  /* Announce relocator to runtime */
+  if (ptv_needed)
+    {
+      struct grub_efiemu_ptv_rel *ptv_rels
+	= grub_efiemu_mm_obtain_request (ptv_handle);
+
+      if (ptv_needed && ptv_written >= ptv_alloc)
+	return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			   "your module didn't declare efiemu "
+			   " relocators correctly");
+
+      if (minus_handle)
+	ptv_rels[ptv_written].minustype
+	  = grub_efiemu_mm_get_type (minus_handle);
+      else
+	ptv_rels[ptv_written].minustype = 0;
+
+      if (plus_handle)
+	ptv_rels[ptv_written].plustype
+	  = grub_efiemu_mm_get_type (plus_handle);
+      else
+	ptv_rels[ptv_written].plustype = 0;
+
+      ptv_rels[ptv_written].addr = PTR_TO_UINT64 (addr);
+      ptv_rels[ptv_written].size = size;
+      ptv_written++;
+
+      /* memset next value to zero to mark the end */
+      grub_memset (&ptv_rels[ptv_written], 0, sizeof (ptv_rels[ptv_written]));
+    }
+
+  /* Compute the value */
+  if (minus_handle)
+    value -= PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (minus_handle));
+
+  if (plus_handle)
+    value += PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (plus_handle));
+
+  /* Write the value */
+  switch (size)
+    {
+    case 8:
+      *((grub_uint64_t *) addr) = value;
+      break;
+    case 4:
+      *((grub_uint32_t *) addr) = value;
+      break;
+    case 2:
+      *((grub_uint16_t *) addr) = value;
+      break;
+    case 1:
+      *((grub_uint8_t *) addr) = value;
+      break;
+    default:
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "wrong symbol size");
+    }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/font/font.c b/font/font.c
new file mode 100644
index 0000000..a812919
--- /dev/null
+++ b/font/font.c
@@ -0,0 +1,1053 @@
+/* font.c - Font API and font file loader.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/bufio.h>
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/font.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/video.h>
+#include <grub/bitmap.h>
+
+#ifndef FONT_DEBUG
+#define FONT_DEBUG 0
+#endif
+
+struct char_index_entry
+{
+  grub_uint32_t code;
+  grub_uint8_t storage_flags;
+  grub_uint32_t offset;
+
+  /* Glyph if loaded, or NULL otherwise.  */
+  struct grub_font_glyph *glyph;
+};
+
+#define FONT_WEIGHT_NORMAL 100
+#define FONT_WEIGHT_BOLD 200
+
+struct grub_font
+{
+  char *name;
+  grub_file_t file;
+  char *family;
+  short point_size;
+  short weight;
+  short max_char_width;
+  short max_char_height;
+  short ascent;
+  short descent;
+  short leading;
+  grub_uint32_t num_chars;
+  struct char_index_entry *char_index;
+};
+
+/* Definition of font registry.  */
+struct grub_font_node *grub_font_list;
+
+static int register_font (grub_font_t font);
+static void font_init (grub_font_t font);
+static void free_font (grub_font_t font);
+static void remove_font (grub_font_t font);
+
+struct font_file_section
+{
+  /* The file this section is in.  */
+  grub_file_t file;
+
+  /* FOURCC name of the section.  */
+  char name[4];
+
+  /* Length of the section contents.  */
+  grub_uint32_t length;
+
+  /* Set by open_section() on EOF.  */
+  int eof;
+};
+
+/* Font file format constants.  */
+static const char pff2_magic[4] = { 'P', 'F', 'F', '2' };
+static const char section_names_file[4] = { 'F', 'I', 'L', 'E' };
+static const char section_names_font_name[4] = { 'N', 'A', 'M', 'E' };
+static const char section_names_point_size[4] = { 'P', 'T', 'S', 'Z' };
+static const char section_names_weight[4] = { 'W', 'E', 'I', 'G' };
+static const char section_names_max_char_width[4] = { 'M', 'A', 'X', 'W' };
+static const char section_names_max_char_height[4] = { 'M', 'A', 'X', 'H' };
+static const char section_names_ascent[4] = { 'A', 'S', 'C', 'E' };
+static const char section_names_descent[4] = { 'D', 'E', 'S', 'C' };
+static const char section_names_char_index[4] = { 'C', 'H', 'I', 'X' };
+static const char section_names_data[4] = { 'D', 'A', 'T', 'A' };
+
+/* Replace unknown glyphs with a rounded question mark.  */
+static grub_uint8_t unknown_glyph_bitmap[] =
+{
+  /*       76543210 */
+  0x7C, /*  ooooo   */
+  0x82, /* o     o  */
+  0xBA, /* o ooo o  */
+  0xAA, /* o o o o  */
+  0xAA, /* o o o o  */
+  0x8A, /* o   o o  */
+  0x9A, /* o  oo o  */
+  0x92, /* o  o  o  */
+  0x92, /* o  o  o  */
+  0x92, /* o  o  o  */
+  0x92, /* o  o  o  */
+  0x82, /* o     o  */
+  0x92, /* o  o  o  */
+  0x82, /* o     o  */
+  0x7C, /*  ooooo   */
+  0x00  /*          */
+};
+
+/* The "unknown glyph" glyph, used as a last resort.  */
+static struct grub_font_glyph *unknown_glyph;
+
+/* The font structure used when no other font is loaded.  This functions
+   as a "Null Object" pattern, so that code everywhere does not have to
+   check for a NULL grub_font_t to avoid dereferencing a null pointer.  */
+static struct grub_font null_font;
+
+/* Flag to ensure module is initialized only once.  */
+static grub_uint8_t font_loader_initialized;
+
+void
+grub_font_loader_init (void)
+{
+  /* Only initialize font loader once.  */
+  if (font_loader_initialized)
+    return;
+
+  /* Make glyph for unknown glyph.  */
+  unknown_glyph = grub_malloc(sizeof(struct grub_font_glyph)
+                              + sizeof(unknown_glyph_bitmap));
+  if (! unknown_glyph)
+    return;
+
+  unknown_glyph->width = 8;
+  unknown_glyph->height = 16;
+  unknown_glyph->offset_x = 0;
+  unknown_glyph->offset_y = -3;
+  unknown_glyph->device_width = 8;
+  grub_memcpy(unknown_glyph->bitmap,
+              unknown_glyph_bitmap, sizeof(unknown_glyph_bitmap));
+
+  /* Initialize the null font.  */
+  font_init (&null_font);
+  null_font.name = "<No Font>";
+  null_font.ascent = unknown_glyph->height-3;
+  null_font.descent = 3;
+  null_font.max_char_width = unknown_glyph->width;
+  null_font.max_char_height = unknown_glyph->height;
+
+  font_loader_initialized = 1;
+}
+
+/* Initialize the font object with initial default values.  */
+static void
+font_init (grub_font_t font)
+{
+  font->name = 0;
+  font->file = 0;
+  font->family = 0;
+  font->point_size = 0;
+  font->weight = 0;
+
+  /* Default leading value, not in font file yet.  */
+  font->leading = 1;
+
+  font->max_char_width = 0;
+  font->max_char_height = 0;
+  font->ascent = 0;
+  font->descent = 0;
+  font->num_chars = 0;
+  font->char_index = 0;
+}
+
+/* Open the next section in the file.
+
+   On success, the section name is stored in section->name and the length in
+   section->length, and 0 is returned.  On failure, 1 is returned and
+   grub_errno is set appropriately with an error message.
+
+   If 1 is returned due to being at the end of the file, then section->eof is
+   set to 1; otherwise, section->eof is set to 0.  */
+static int
+open_section (grub_file_t file, struct font_file_section *section)
+{
+  grub_ssize_t retval;
+  grub_uint32_t raw_length;
+
+  section->file = file;
+  section->eof = 0;
+
+  /* Read the FOURCC section name.  */
+  retval = grub_file_read (file, section->name, 4);
+  if (retval >= 0 && retval < 4)
+    {
+      /* EOF encountered.  */
+      section->eof = 1;
+      return 1;
+    }
+  else if (retval < 0)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                  "Font format error: can't read section name");
+      return 1;
+    }
+
+  /* Read the big-endian 32-bit section length.  */
+  retval = grub_file_read (file, &raw_length, 4);
+  if (retval >= 0 && retval < 4)
+    {
+      /* EOF encountered.  */
+      section->eof = 1;
+      return 1;
+    }
+  else if (retval < 0)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                  "Font format error: can't read section length");
+      return 1;
+    }
+
+  /* Convert byte-order and store in *length.  */
+  section->length = grub_be_to_cpu32 (raw_length);
+
+  return 0;
+}
+
+/* Size in bytes of each character index (CHIX section)
+   entry in the font file.  */
+#define FONT_CHAR_INDEX_ENTRY_SIZE (4 + 1 + 4)
+
+/* Load the character index (CHIX) section contents from the font file.  This
+   presumes that the position of FILE is positioned immediately after the
+   section length for the CHIX section (i.e., at the start of the section
+   contents).  Returns 0 upon success, nonzero for failure (in which case
+   grub_errno is set appropriately).  */
+static int
+load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
+                 grub_font *font)
+{
+  unsigned i;
+  grub_uint32_t last_code;
+
+#if FONT_DEBUG >= 2
+  grub_printf("load_font_index(sect_length=%d)\n", sect_length);
+#endif
+
+  /* Sanity check: ensure section length is divisible by the entry size.  */
+  if ((sect_length % FONT_CHAR_INDEX_ENTRY_SIZE) != 0)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                  "Font file format error: character index length %d "
+                  "is not a multiple of the entry size %d",
+                  sect_length, FONT_CHAR_INDEX_ENTRY_SIZE);
+      return 1;
+    }
+
+  /* Calculate the number of characters.  */
+  font->num_chars = sect_length / FONT_CHAR_INDEX_ENTRY_SIZE;
+
+  /* Allocate the character index array.  */
+  font->char_index = grub_malloc (font->num_chars
+                                  * sizeof (struct char_index_entry));
+  if (! font->char_index)
+    return 1;
+
+#if FONT_DEBUG >= 2
+  grub_printf("num_chars=%d)\n", font->num_chars);
+#endif
+
+  last_code = 0;
+
+  /* Load the character index data from the file.  */
+  for (i = 0; i < font->num_chars; i++)
+    {
+      struct char_index_entry *entry = &font->char_index[i];
+
+      /* Read code point value; convert to native byte order.  */
+      if (grub_file_read (file, &entry->code, 4) != 4)
+        return 1;
+      entry->code = grub_be_to_cpu32 (entry->code);
+
+      /* Verify that characters are in ascending order.  */
+      if (i != 0 && entry->code <= last_code)
+        {
+          grub_error (GRUB_ERR_BAD_FONT,
+                      "Font characters not in ascending order: %u <= %u",
+                      entry->code, last_code);
+          return 1;
+        }
+
+      last_code = entry->code;
+
+      /* Read storage flags byte.  */
+      if (grub_file_read (file, &entry->storage_flags, 1) != 1)
+        return 1;
+
+      /* Read glyph data offset; convert to native byte order.  */
+      if (grub_file_read (file, &entry->offset, 4) != 4)
+        return 1;
+      entry->offset = grub_be_to_cpu32 (entry->offset);
+
+      /* No glyph loaded.  Will be loaded on demand and cached thereafter.  */
+      entry->glyph = 0;
+
+#if FONT_DEBUG >= 5
+      /* Print the 1st 10 characters.  */
+      if (i < 10)
+        grub_printf("c=%d o=%d\n", entry->code, entry->offset);
+#endif
+    }
+
+  return 0;
+}
+
+/* Read the contents of the specified section as a string, which is
+   allocated on the heap.  Returns 0 if there is an error.  */
+static char *
+read_section_as_string (struct font_file_section *section)
+{
+  char *str;
+  grub_ssize_t ret;
+
+  str = grub_malloc (section->length + 1);
+  if (! str)
+    return 0;
+
+  ret = grub_file_read (section->file, str, section->length);
+  if (ret < 0 || ret != (grub_ssize_t) section->length)
+    {
+      grub_free (str);
+      return 0;
+    }
+
+  str[section->length] = '\0';
+  return str;
+}
+
+/* Read the contents of the current section as a 16-bit integer value,
+   which is stored into *VALUE.
+   Returns 0 upon success, nonzero upon failure.  */
+static int
+read_section_as_short (struct font_file_section *section, grub_int16_t *value)
+{
+  grub_uint16_t raw_value;
+
+  if (section->length != 2)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                  "Font file format error: section %c%c%c%c length "
+                  "is %d but should be 2",
+                  section->name[0], section->name[1],
+                  section->name[2], section->name[3],
+                  section->length);
+      return 1;
+    }
+  if (grub_file_read (section->file, &raw_value, 2) != 2)
+    return 1;
+
+  *value = grub_be_to_cpu16 (raw_value);
+  return 0;
+}
+
+/* Load a font and add it to the beginning of the global font list.
+   Returns 0 upon success, nonzero upon failure.  */
+int
+grub_font_load (const char *filename)
+{
+  grub_file_t file = 0;
+  struct font_file_section section;
+  char magic[4];
+  grub_font_t font = 0;
+
+#if FONT_DEBUG >= 1
+  grub_printf("add_font(%s)\n", filename);
+#endif
+
+  file = grub_buffile_open (filename, 1024);
+  if (!file)
+    goto fail;
+
+#if FONT_DEBUG >= 3
+  grub_printf("file opened\n");
+#endif
+
+  /* Read the FILE section.  It indicates the file format.  */
+  if (open_section (file, &section) != 0)
+    goto fail;
+
+#if FONT_DEBUG >= 3
+  grub_printf("opened FILE section\n");
+#endif
+  if (grub_memcmp (section.name, section_names_file, 4) != 0)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                  "Font file format error: 1st section must be FILE");
+      goto fail;
+    }
+
+#if FONT_DEBUG >= 3
+  grub_printf("section name ok\n");
+#endif
+  if (section.length != 4)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                  "Font file format error (file type ID length is %d "
+                  "but should be 4)", section.length);
+      goto fail;
+    }
+
+#if FONT_DEBUG >= 3
+  grub_printf("section length ok\n");
+#endif
+  /* Check the file format type code.  */
+  if (grub_file_read (file, magic, 4) != 4)
+    goto fail;
+
+#if FONT_DEBUG >= 3
+  grub_printf("read magic ok\n");
+#endif
+
+  if (grub_memcmp (magic, pff2_magic, 4) != 0)
+    {
+      grub_error (GRUB_ERR_BAD_FONT, "Invalid font magic %x %x %x %x",
+                  magic[0], magic[1], magic[2], magic[3]);
+      goto fail;
+    }
+
+#if FONT_DEBUG >= 3
+  grub_printf("compare magic ok\n");
+#endif
+
+  /* Allocate the font object.  */
+  font = (grub_font_t) grub_malloc (sizeof (struct grub_font));
+  if (! font)
+    goto fail;
+
+  font_init (font);
+  font->file = file;
+
+#if FONT_DEBUG >= 3
+  grub_printf("allocate font ok; loading font info\n");
+#endif
+
+  /* Load the font information.  */
+  while (1)
+    {
+      if (open_section (file, &section) != 0)
+        {
+          if (section.eof)
+            break;              /* Done reading the font file.  */
+          else
+            goto fail;
+        }
+
+#if FONT_DEBUG >= 2
+      grub_printf("opened section %c%c%c%c ok\n",
+                  section.name[0], section.name[1],
+                  section.name[2], section.name[3]);
+#endif
+
+      if (grub_memcmp (section.name, section_names_font_name, 4) == 0)
+        {
+          font->name = read_section_as_string (&section);
+          if (!font->name)
+            goto fail;
+        }
+      else if (grub_memcmp (section.name, section_names_point_size, 4) == 0)
+        {
+          if (read_section_as_short (&section, &font->point_size) != 0)
+            goto fail;
+        }
+      else if (grub_memcmp (section.name, section_names_weight, 4) == 0)
+        {
+          char *wt;
+          wt = read_section_as_string (&section);
+          if (!wt)
+            continue;
+          /* Convert the weight string 'normal' or 'bold' into a number.  */
+          if (grub_strcmp (wt, "normal") == 0)
+            font->weight = FONT_WEIGHT_NORMAL;
+          else if (grub_strcmp (wt, "bold") == 0)
+            font->weight = FONT_WEIGHT_BOLD;
+          grub_free (wt);
+        }
+      else if (grub_memcmp (section.name, section_names_max_char_width, 4) == 0)
+        {
+          if (read_section_as_short (&section, &font->max_char_width) != 0)
+            goto fail;
+        }
+      else if (grub_memcmp (section.name, section_names_max_char_height, 4) == 0)
+        {
+          if (read_section_as_short (&section, &font->max_char_height) != 0)
+            goto fail;
+        }
+      else if (grub_memcmp (section.name, section_names_ascent, 4) == 0)
+        {
+          if (read_section_as_short (&section, &font->ascent) != 0)
+            goto fail;
+        }
+      else if (grub_memcmp (section.name, section_names_descent, 4) == 0)
+        {
+          if (read_section_as_short (&section, &font->descent) != 0)
+            goto fail;
+        }
+      else if (grub_memcmp (section.name, section_names_char_index, 4) == 0)
+        {
+          if (load_font_index (file, section.length, font) != 0)
+            goto fail;
+        }
+      else if (grub_memcmp (section.name, section_names_data, 4) == 0)
+        {
+          /* When the DATA section marker is reached, we stop reading.  */
+          break;
+        }
+      else
+        {
+          /* Unhandled section type, simply skip past it.  */
+#if FONT_DEBUG >= 3
+          grub_printf("Unhandled section type, skipping.\n");
+#endif
+          grub_off_t section_end = grub_file_tell (file) + section.length;
+          if ((int) grub_file_seek (file, section_end) == -1)
+            goto fail;
+        }
+    }
+
+  if (! font->name)
+    {
+      grub_printf ("Note: Font has no name.\n");
+      font->name = grub_strdup ("Unknown");
+    }
+
+#if FONT_DEBUG >= 1
+  grub_printf ("Loaded font `%s'.\n"
+               "Ascent=%d Descent=%d MaxW=%d MaxH=%d Number of characters=%d.\n",
+               font->name,
+               font->ascent, font->descent,
+               font->max_char_width, font->max_char_height,
+               font->num_chars);
+#endif
+
+  if (font->max_char_width == 0
+      || font->max_char_height == 0
+      || font->num_chars == 0
+      || font->char_index == 0
+      || font->ascent == 0
+      || font->descent == 0)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                  "Invalid font file: missing some required data.");
+      goto fail;
+    }
+
+  /* Add the font to the global font registry.  */
+  if (register_font (font) != 0)
+    goto fail;
+
+  return 0;
+
+fail:
+  free_font (font);
+  return 1;
+}
+
+/* Read a 16-bit big-endian integer from FILE, convert it to native byte
+   order, and store it in *VALUE.
+   Returns 0 on success, 1 on failure.  */
+static int
+read_be_uint16 (grub_file_t file, grub_uint16_t * value)
+{
+  if (grub_file_read (file, value, 2) != 2)
+    return 1;
+  *value = grub_be_to_cpu16 (*value);
+  return 0;
+}
+
+static int
+read_be_int16 (grub_file_t file, grub_int16_t * value)
+{
+  /* For the signed integer version, use the same code as for unsigned.  */
+  return read_be_uint16 (file, (grub_uint16_t *) value);
+}
+
+/* Return a pointer to the character index entry for the glyph corresponding to
+   the codepoint CODE in the font FONT.  If not found, return zero.  */
+static struct char_index_entry *
+find_glyph (const grub_font_t font, grub_uint32_t code)
+{
+  struct char_index_entry *table;
+  grub_size_t lo;
+  grub_size_t hi;
+  grub_size_t mid;
+
+  /* Do a binary search in `char_index', which is ordered by code point.  */
+  table = font->char_index;
+  lo = 0;
+  hi = font->num_chars - 1;
+
+  if (! table)
+    return 0;
+
+  while (lo <= hi)
+    {
+      mid = lo + (hi - lo) / 2;
+      if (code < table[mid].code)
+        hi = mid - 1;
+      else if (code > table[mid].code)
+        lo = mid + 1;
+      else
+        return &table[mid];
+    }
+
+  return 0;
+}
+
+/* Get a glyph for the Unicode character CODE in FONT.  The glyph is loaded
+   from the font file if has not been loaded yet.
+   Returns a pointer to the glyph if found, or 0 if it is not found.  */
+static struct grub_font_glyph *
+grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
+{
+  struct char_index_entry *index_entry;
+
+  index_entry = find_glyph (font, code);
+  if (index_entry)
+    {
+      struct grub_font_glyph *glyph = 0;
+      grub_uint16_t width;
+      grub_uint16_t height;
+      grub_int16_t xoff;
+      grub_int16_t yoff;
+      grub_int16_t dwidth;
+      int len;
+
+      if (index_entry->glyph)
+        /* Return cached glyph.  */
+        return index_entry->glyph;
+
+      if (! font->file)
+        /* No open file, can't load any glyphs.  */
+        return 0;
+
+      /* Make sure we can find glyphs for error messages.  Push active
+         error message to error stack and reset error message.  */
+      grub_error_push ();
+
+      grub_file_seek (font->file, index_entry->offset);
+
+      /* Read the glyph width, height, and baseline.  */
+      if (read_be_uint16(font->file, &width) != 0
+          || read_be_uint16(font->file, &height) != 0
+          || read_be_int16(font->file, &xoff) != 0
+          || read_be_int16(font->file, &yoff) != 0
+          || read_be_int16(font->file, &dwidth) != 0)
+        {
+          remove_font (font);
+          return 0;
+        }
+
+      len = (width * height + 7) / 8;
+      glyph = grub_malloc (sizeof (struct grub_font_glyph) + len);
+      if (! glyph)
+        {
+          remove_font (font);
+          return 0;
+        }
+
+      glyph->font = font;
+      glyph->width = width;
+      glyph->height = height;
+      glyph->offset_x = xoff;
+      glyph->offset_y = yoff;
+      glyph->device_width = dwidth;
+
+      /* Don't try to read empty bitmaps (e.g., space characters).  */
+      if (len != 0)
+        {
+          if (grub_file_read (font->file, glyph->bitmap, len) != len)
+            {
+              remove_font (font);
+              return 0;
+            }
+        }
+
+      /* Restore old error message.  */
+      grub_error_pop ();
+
+      /* Cache the glyph.  */
+      index_entry->glyph = glyph;
+
+      return glyph;
+    }
+
+  return 0;
+}
+
+/* Free the memory used by FONT.
+   This should not be called if the font has been made available to
+   users (once it is added to the global font list), since there would
+   be the possibility of a dangling pointer.  */
+static void
+free_font (grub_font_t font)
+{
+  if (font)
+    {
+      if (font->file)
+        grub_file_close (font->file);
+      grub_free (font->name);
+      grub_free (font->family);
+      grub_free (font->char_index);
+      grub_free (font);
+    }
+}
+
+/* Add FONT to the global font registry.
+   Returns 0 upon success, nonzero on failure
+   (the font was not registered).  */
+static int
+register_font (grub_font_t font)
+{
+  struct grub_font_node *node = 0;
+
+  node = grub_malloc (sizeof (struct grub_font_node));
+  if (! node)
+    return 1;
+
+  node->value = font;
+  node->next = grub_font_list;
+  grub_font_list = node;
+
+  return 0;
+}
+
+/* Remove the font from the global font list.  We don't actually free the
+   font's memory since users could be holding references to the font.  */
+static void
+remove_font (grub_font_t font)
+{
+  struct grub_font_node **nextp, *cur;
+
+  for (nextp = &grub_font_list, cur = *nextp;
+       cur;
+       nextp = &cur->next, cur = cur->next)
+    {
+      if (cur->value == font)
+        {
+          *nextp = cur->next;
+
+          /* Free the node, but not the font itself.  */
+          grub_free (cur);
+
+          return;
+        }
+    }
+}
+
+/* Get a font from the list of loaded fonts.  This function will return
+   another font if the requested font is not available.  If no fonts are
+   loaded, then a special 'null font' is returned, which contains no glyphs,
+   but is not a null pointer so the caller may omit checks for NULL.  */
+grub_font_t
+grub_font_get (const char *font_name)
+{
+  struct grub_font_node *node;
+
+  for (node = grub_font_list; node; node = node->next)
+    {
+      grub_font_t font = node->value;
+      if (grub_strcmp (font->name, font_name) == 0)
+        return font;
+    }
+
+  /* If no font by that name is found, return the first font in the list
+     as a fallback.  */
+  if (grub_font_list && grub_font_list->value)
+    return grub_font_list->value;
+  else
+    /* The null_font is a last resort.  */
+    return &null_font;
+}
+
+/* Get the full name of the font.  For instance, "Helvetica Bold 12".  */
+const char *
+grub_font_get_name (grub_font_t font)
+{
+  return font->name;
+}
+
+/* Get the maximum width of any character in the font in pixels.  */
+int
+grub_font_get_max_char_width (grub_font_t font)
+{
+  return font->max_char_width;
+}
+
+/* Get the maximum height of any character in the font in pixels.  */
+int
+grub_font_get_max_char_height (grub_font_t font)
+{
+  return font->max_char_height;
+}
+
+/* Get the distance in pixels from the top of characters to the baseline.  */
+int
+grub_font_get_ascent (grub_font_t font)
+{
+  return font->ascent;
+}
+
+/* Get the distance in pixels from the baseline to the lowest descenders
+   (for instance, in a lowercase 'y', 'g', etc.).  */
+int
+grub_font_get_descent (grub_font_t font)
+{
+  return font->descent;
+}
+
+/* Get the *standard leading* of the font in pixel, which is the spacing
+   between two lines of text.  Specifically, it is the space between the
+   descent of one line and the ascent of the next line.  This is included
+   in the *height* metric.  */
+int
+grub_font_get_leading (grub_font_t font)
+{
+  return font->leading;
+}
+
+/* Get the distance in pixels between baselines of adjacent lines of text.  */
+int
+grub_font_get_height (grub_font_t font)
+{
+  return font->ascent + font->descent + font->leading;
+}
+
+/* Get the width in pixels of the specified UTF-8 string, when rendered in
+   in the specified font (but falling back on other fonts for glyphs that
+   are missing).  */
+int
+grub_font_get_string_width (grub_font_t font, const char *str)
+{
+  int width;
+  struct grub_font_glyph *glyph;
+  grub_uint32_t code;
+  const grub_uint8_t *ptr;
+
+  for (ptr = (const grub_uint8_t *) str, width = 0;
+       grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0; )
+    {
+      glyph = grub_font_get_glyph_with_fallback (font, code);
+      width += glyph->device_width;
+    }
+
+  return width;
+}
+
+/* Get the glyph for FONT corresponding to the Unicode code point CODE.
+   Returns a pointer to an glyph indicating there is no glyph available
+   if CODE does not exist in the font.  The glyphs are cached once loaded.  */
+struct grub_font_glyph *
+grub_font_get_glyph (grub_font_t font, grub_uint32_t code)
+{
+  struct grub_font_glyph *glyph;
+  glyph = grub_font_get_glyph_internal (font, code);
+  if (glyph == 0)
+    glyph = unknown_glyph;
+  return glyph;
+}
+
+
+/* Calculate a subject value representing "how similar" two fonts are.
+   This is used to prioritize the order that fonts are scanned for missing
+   glyphs.  The object is to select glyphs from the most similar font
+   possible, for the best appearance.
+   The heuristic is crude, but it helps greatly when fonts of similar
+   sizes are used so that tiny 8 point glyphs are not mixed into a string
+   of 24 point text unless there is no other choice.  */
+static int
+get_font_diversity(grub_font_t a, grub_font_t b)
+{
+  int d;
+
+  d = 0;
+
+  if (a->ascent && b->ascent)
+    d += grub_abs (a->ascent - b->ascent) * 8;
+  else
+    /* Penalty for missing attributes.  */
+    d += 50;
+
+  if (a->max_char_height && b->max_char_height)
+    d += grub_abs (a->max_char_height - b->max_char_height) * 8;
+  else
+    /* Penalty for missing attributes.  */
+    d += 50;
+
+  /* Weight is a minor factor. */
+  d += (a->weight != b->weight) ? 5 : 0;
+
+  return d;
+}
+
+/* Get a glyph corresponding to the codepoint CODE.  If FONT contains the
+   specified glyph, then it is returned.  Otherwise, all other loaded fonts
+   are searched until one is found that contains a glyph for CODE.
+   If no glyph is available for CODE in the loaded fonts, then a glyph
+   representing an unknown character is returned.
+   This function never returns NULL.
+   The returned glyph is owned by the font manager and should not be freed
+   by the caller.  The glyphs are cached.  */
+struct grub_font_glyph *
+grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
+{
+  struct grub_font_glyph *glyph;
+  struct grub_font_node *node;
+  /* Keep track of next node, in case there's an I/O error in
+     grub_font_get_glyph_internal() and the font is removed from the list.  */
+  struct grub_font_node *next;
+  /* Information on the best glyph found so far, to help find the glyph in
+     the best matching to the requested one.  */
+  int best_diversity;
+  struct grub_font_glyph *best_glyph;
+
+  if (font)
+    {
+      /* First try to get the glyph from the specified font.  */
+      glyph = grub_font_get_glyph_internal (font, code);
+      if (glyph)
+        return glyph;
+    }
+
+  /* Otherwise, search all loaded fonts for the glyph and use the one from
+     the font that best matches the requested font.  */
+  best_diversity = 10000;
+  best_glyph = 0;
+
+  for (node = grub_font_list; node; node = next)
+    {
+      grub_font_t curfont;
+
+      curfont = node->value;
+      next = node->next;
+
+      glyph = grub_font_get_glyph_internal (curfont, code);
+      if (glyph)
+        {
+          int d;
+
+          d = get_font_diversity (curfont, font);
+          if (d < best_diversity)
+            {
+              best_diversity = d;
+              best_glyph = glyph;
+            }
+        }
+    }
+
+  if (best_glyph)
+    return best_glyph;
+  else
+    /* Glyph not available in any font.  Return unknown glyph.  */
+    return unknown_glyph;
+}
+
+
+/* Draw the specified glyph at (x, y).  The y coordinate designates the
+   baseline of the character, while the x coordinate designates the left
+   side location of the character.  */
+grub_err_t
+grub_font_draw_glyph (struct grub_font_glyph *glyph,
+                      grub_video_color_t color,
+                      int left_x, int baseline_y)
+{
+  struct grub_video_bitmap glyph_bitmap;
+
+  /* Don't try to draw empty glyphs (U+0020, etc.).  */
+  if (glyph->width == 0 || glyph->height == 0)
+    return GRUB_ERR_NONE;
+
+  glyph_bitmap.mode_info.width = glyph->width;
+  glyph_bitmap.mode_info.height = glyph->height;
+  glyph_bitmap.mode_info.mode_type =
+    (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
+    | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP;
+  glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED;
+  glyph_bitmap.mode_info.bpp = 1;
+
+  /* Really 1 bit per pixel.  */
+  glyph_bitmap.mode_info.bytes_per_pixel = 0;
+
+  /* Packed densely as bits.  */
+  glyph_bitmap.mode_info.pitch = glyph->width;
+
+  glyph_bitmap.mode_info.number_of_colors = 2;
+  glyph_bitmap.mode_info.bg_red = 0;
+  glyph_bitmap.mode_info.bg_green = 0;
+  glyph_bitmap.mode_info.bg_blue = 0;
+  glyph_bitmap.mode_info.bg_alpha = 0;
+  grub_video_unmap_color(color,
+                         &glyph_bitmap.mode_info.fg_red,
+                         &glyph_bitmap.mode_info.fg_green,
+                         &glyph_bitmap.mode_info.fg_blue,
+                         &glyph_bitmap.mode_info.fg_alpha);
+  glyph_bitmap.data = glyph->bitmap;
+
+  int bitmap_left = left_x + glyph->offset_x;
+  int bitmap_bottom = baseline_y - glyph->offset_y;
+  int bitmap_top = bitmap_bottom - glyph->height;
+
+  return grub_video_blit_bitmap (&glyph_bitmap, GRUB_VIDEO_BLIT_BLEND,
+                                 bitmap_left, bitmap_top,
+                                 0, 0,
+                                 glyph->width, glyph->height);
+}
+
+/* Draw a UTF-8 string of text on the current video render target.
+   The x coordinate specifies the starting x position for the first character,
+   while the y coordinate specifies the baseline position.
+   If the string contains a character that FONT does not contain, then
+   a glyph from another loaded font may be used instead.  */
+grub_err_t
+grub_font_draw_string (const char *str, grub_font_t font,
+                       grub_video_color_t color,
+                       int left_x, int baseline_y)
+{
+  int x;
+  struct grub_font_glyph *glyph;
+  grub_uint32_t code;
+  const grub_uint8_t *ptr;
+
+  for (ptr = (const grub_uint8_t *) str, x = left_x;
+       grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0; )
+    {
+      glyph = grub_font_get_glyph_with_fallback (font, code);
+      if (grub_font_draw_glyph (glyph, color, x, baseline_y)
+          != GRUB_ERR_NONE)
+        return grub_errno;
+      x += glyph->device_width;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
diff --git a/font/font_cmd.c b/font/font_cmd.c
new file mode 100644
index 0000000..0402b8d
--- /dev/null
+++ b/font/font_cmd.c
@@ -0,0 +1,79 @@
+/* font_cmd.c - Font command definition. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/font.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+
+static grub_err_t
+loadfont_command (grub_command_t cmd __attribute__ ((unused)),
+		  int argc,
+		  char **args)
+{
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no font specified");
+
+  while (argc--)
+    if (grub_font_load (*args++) != 0)
+      return GRUB_ERR_BAD_FONT;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+lsfonts_command (grub_command_t cmd __attribute__ ((unused)),
+                 int argc __attribute__ ((unused)),
+                 char **args __attribute__ ((unused)))
+{
+  struct grub_font_node *node;
+
+  grub_printf ("Loaded fonts:\n");
+  for (node = grub_font_list; node; node = node->next)
+    {
+      grub_font_t font = node->value;
+      grub_printf ("%s\n", grub_font_get_name (font));
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd_loadfont, cmd_lsfonts;
+
+GRUB_MOD_INIT(font_manager)
+{
+  grub_font_loader_init ();
+
+  cmd_loadfont =
+    grub_register_command ("loadfont", loadfont_command,
+			 "loadfont FILE...",
+			 "Specify one or more font files to load.");
+  cmd_lsfonts =
+    grub_register_command ("lsfonts", lsfonts_command,
+			   0, "List the loaded fonts.");
+}
+
+GRUB_MOD_FINI(font_manager)
+{
+  /* TODO: Determine way to free allocated resources.
+     Warning: possible pointer references could be in use.  */
+
+  grub_unregister_command (cmd_loadfont);
+  grub_unregister_command (cmd_lsfonts);
+}
diff --git a/fs/affs.c b/fs/affs.c
new file mode 100644
index 0000000..cfe7d57
--- /dev/null
+++ b/fs/affs.c
@@ -0,0 +1,550 @@
+/* affs.c - Amiga Fast FileSystem.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+/* The affs bootblock.  */
+struct grub_affs_bblock
+{
+  grub_uint8_t type[3];
+  grub_uint8_t flags;
+  grub_uint32_t checksum;
+  grub_uint32_t rootblock;
+} __attribute__ ((packed));
+
+/* Set if the filesystem is a AFFS filesystem.  Otherwise this is an
+   OFS filesystem.  */
+#define GRUB_AFFS_FLAG_FFS	1
+
+/* The affs rootblock.  */
+struct grub_affs_rblock
+{
+  grub_uint8_t type[4];
+  grub_uint8_t unused1[8];
+  grub_uint32_t htsize;
+  grub_uint32_t unused2;
+  grub_uint32_t checksum;
+  grub_uint32_t hashtable[1];
+} __attribute__ ((packed));
+
+/* The second part of a file header block.  */
+struct grub_affs_file
+{
+  grub_uint8_t unused1[12];
+  grub_uint32_t size;
+  grub_uint8_t unused2[104];
+  grub_uint8_t namelen;
+  grub_uint8_t name[30];
+  grub_uint8_t unused3[33];
+  grub_uint32_t next;
+  grub_uint32_t parent;
+  grub_uint32_t extension;
+  grub_int32_t type;
+} __attribute__ ((packed));
+
+/* The location of `struct grub_affs_file' relative to the end of a
+   file header block.  */
+#define	GRUB_AFFS_FILE_LOCATION		200
+
+/* The offset in both the rootblock and the file header block for the
+   hashtable, symlink and block pointers (all synonyms).  */
+#define GRUB_AFFS_HASHTABLE_OFFSET	24
+#define GRUB_AFFS_BLOCKPTR_OFFSET	24
+#define GRUB_AFFS_SYMLINK_OFFSET	24
+
+#define GRUB_AFFS_SYMLINK_SIZE(blocksize) ((blocksize) - 225)
+
+#define GRUB_AFFS_FILETYPE_DIR		-3
+#define GRUB_AFFS_FILETYPE_REG		2
+#define GRUB_AFFS_FILETYPE_SYMLINK	3
+
+
+struct grub_fshelp_node
+{
+  struct grub_affs_data *data;
+  int block;
+  int size;
+  int parent;
+};
+
+/* Information about a "mounted" affs filesystem.  */
+struct grub_affs_data
+{
+  struct grub_affs_bblock bblock;
+  struct grub_fshelp_node diropen;
+  grub_disk_t disk;
+
+  /* Blocksize in sectors.  */
+  int blocksize;
+
+  /* The number of entries in the hashtable.  */
+  int htsize;
+};
+
+static grub_dl_t my_mod;
+
+
+static grub_disk_addr_t
+grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  int links;
+  grub_uint32_t pos;
+  int block = node->block;
+  struct grub_affs_file file;
+  struct grub_affs_data *data = node->data;
+  grub_uint32_t mod;
+
+  /* Find the block that points to the fileblock we are looking up by
+     following the chain until the right table is reached.  */
+  for (links = grub_divmod64 (fileblock, data->htsize, &mod); links; links--)
+    {
+      grub_disk_read (data->disk, block + data->blocksize - 1,
+		      data->blocksize * (GRUB_DISK_SECTOR_SIZE
+					 - GRUB_AFFS_FILE_LOCATION),
+		      sizeof (file), &file);
+      if (grub_errno)
+	return 0;
+
+      block = grub_be_to_cpu32 (file.extension);
+    }
+
+  /* Translate the fileblock to the block within the right table.  */
+  fileblock = mod;
+  grub_disk_read (data->disk, block,
+		  GRUB_AFFS_BLOCKPTR_OFFSET
+		  + (data->htsize - fileblock - 1) * sizeof (pos),
+		  sizeof (pos), &pos);
+  if (grub_errno)
+    return 0;
+
+  return grub_be_to_cpu32 (pos);
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_affs_read_file (grub_fshelp_node_t node,
+		     void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+					unsigned offset, unsigned length),
+		     int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+				pos, len, buf, grub_affs_read_block,
+				node->size, 0);
+}
+
+
+static struct grub_affs_data *
+grub_affs_mount (grub_disk_t disk)
+{
+  struct grub_affs_data *data;
+  grub_uint32_t *rootblock = 0;
+  struct grub_affs_rblock *rblock;
+
+  int checksum = 0;
+  int checksumr = 0;
+  int blocksize = 0;
+
+  data = grub_malloc (sizeof (struct grub_affs_data));
+  if (!data)
+    return 0;
+
+  /* Read the bootblock.  */
+  grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
+		  &data->bblock);
+  if (grub_errno)
+    goto fail;
+
+  /* Make sure this is an affs filesystem.  */
+  if (grub_strncmp ((char *) (data->bblock.type), "DOS", 3))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not an affs filesystem");
+      goto fail;
+    }
+
+  /* Test if the filesystem is a OFS filesystem.  */
+  if (! (data->bblock.flags & GRUB_AFFS_FLAG_FFS))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "ofs not yet supported");
+      goto fail;
+    }
+
+  /* Read the bootblock.  */
+  grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
+		  &data->bblock);
+  if (grub_errno)
+    goto fail;
+
+  /* No sane person uses more than 8KB for a block.  At least I hope
+     for that person because in that case this won't work.  */
+  rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE * 16);
+  if (!rootblock)
+    goto fail;
+
+  rblock = (struct grub_affs_rblock *) rootblock;
+
+  /* Read the rootblock.  */
+  grub_disk_read (disk, (disk->total_sectors >> 1) + blocksize, 0,
+		  GRUB_DISK_SECTOR_SIZE * 16, rootblock);
+  if (grub_errno)
+    goto fail;
+
+  /* The filesystem blocksize is not stored anywhere in the filesystem
+     itself.  One way to determine it is reading blocks for the
+     rootblock until the checksum is correct.  */
+  checksumr = grub_be_to_cpu32 (rblock->checksum);
+  rblock->checksum = 0;
+  for (blocksize = 0; blocksize < 8; blocksize++)
+    {
+      grub_uint32_t *currblock = rootblock + GRUB_DISK_SECTOR_SIZE * blocksize;
+      unsigned int i;
+
+      for (i = 0; i < GRUB_DISK_SECTOR_SIZE / sizeof (*currblock); i++)
+	checksum += grub_be_to_cpu32 (currblock[i]);
+
+      if (checksumr == -checksum)
+	break;
+    }
+  if (-checksum != checksumr)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "affs blocksize could not be determined");
+      goto fail;
+    }
+  blocksize++;
+
+  data->blocksize = blocksize;
+  data->disk = disk;
+  data->htsize = grub_be_to_cpu32 (rblock->htsize);
+  data->diropen.data = data;
+  data->diropen.block = (disk->total_sectors >> 1);
+
+  grub_free (rootblock);
+
+  return data;
+
+ fail:
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not an affs filesystem");
+
+  grub_free (data);
+  grub_free (rootblock);
+  return 0;
+}
+
+
+static char *
+grub_affs_read_symlink (grub_fshelp_node_t node)
+{
+  struct grub_affs_data *data = node->data;
+  char *symlink;
+
+  symlink = grub_malloc (GRUB_AFFS_SYMLINK_SIZE (data->blocksize));
+  if (!symlink)
+    return 0;
+
+  grub_disk_read (data->disk, node->block, GRUB_AFFS_SYMLINK_OFFSET,
+		  GRUB_AFFS_SYMLINK_SIZE (data->blocksize), symlink);
+  if (grub_errno)
+    {
+      grub_free (symlink);
+      return 0;
+    }
+  grub_dprintf ("affs", "Symlink: `%s'\n", symlink);
+  return symlink;
+}
+
+
+static int
+grub_affs_iterate_dir (grub_fshelp_node_t dir,
+		       int NESTED_FUNC_ATTR
+		       (*hook) (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node))
+{
+  int i;
+  struct grub_affs_file file;
+  struct grub_fshelp_node *node = 0;
+  struct grub_affs_data *data = dir->data;
+  grub_uint32_t *hashtable;
+
+  auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
+						   int size, int type);
+
+  int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
+					      int size, int type)
+    {
+      node = grub_malloc (sizeof (*node));
+      if (!node)
+	{
+	  grub_free (hashtable);
+	  return 1;
+	}
+
+      node->data = data;
+      node->size = size;
+      node->block = block;
+      node->parent = grub_be_to_cpu32 (file.parent);
+
+      if (hook (name, type, node))
+	{
+	  grub_free (hashtable);
+	  return 1;
+	}
+      return 0;
+    }
+
+  hashtable = grub_malloc (data->htsize * sizeof (*hashtable));
+  if (!hashtable)
+    return 1;
+
+  grub_disk_read (data->disk, dir->block, GRUB_AFFS_HASHTABLE_OFFSET,
+		  data->htsize * sizeof (*hashtable), (char *) hashtable);
+  if (grub_errno)
+    goto fail;
+
+  /* Create the directory entries for `.' and `..'.  */
+  if (grub_affs_create_node (".", dir->block, dir->size, GRUB_FSHELP_DIR))
+    return 1;
+  if (grub_affs_create_node ("..", dir->parent ? dir->parent : dir->block,
+			     dir->size, GRUB_FSHELP_DIR))
+    return 1;
+
+  for (i = 0; i < data->htsize; i++)
+    {
+      enum grub_fshelp_filetype type;
+      grub_uint64_t next;
+
+      if (!hashtable[i])
+	continue;
+
+      /* Every entry in the hashtable can be chained.  Read the entire
+	 chain.  */
+      next = grub_be_to_cpu32 (hashtable[i]);
+
+      while (next)
+	{
+	  grub_disk_read (data->disk, next + data->blocksize - 1,
+			  data->blocksize * GRUB_DISK_SECTOR_SIZE
+			  - GRUB_AFFS_FILE_LOCATION,
+			  sizeof (file), (char *) &file);
+	  if (grub_errno)
+	    goto fail;
+
+	  file.name[file.namelen] = '\0';
+
+	  if ((int) grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_DIR)
+	    type = GRUB_FSHELP_REG;
+	  else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_REG)
+	    type = GRUB_FSHELP_DIR;
+	  else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_SYMLINK)
+	    type = GRUB_FSHELP_SYMLINK;
+	  else
+	    type = GRUB_FSHELP_UNKNOWN;
+
+	  if (grub_affs_create_node ((char *) (file.name), next,
+				     grub_be_to_cpu32 (file.size), type))
+	    return 1;
+
+	  next = grub_be_to_cpu32 (file.next);
+	}
+    }
+
+  grub_free (hashtable);
+  return 0;
+
+ fail:
+  grub_free (node);
+  grub_free (hashtable);
+  return 0;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_affs_open (struct grub_file *file, const char *name)
+{
+  struct grub_affs_data *data;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_affs_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_affs_iterate_dir,
+			 grub_affs_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  file->size = fdiro->size;
+  data->diropen = *fdiro;
+  grub_free (fdiro);
+
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+ fail:
+  if (data && fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_affs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+
+/* Read LEN bytes data from FILE into BUF.  */
+static grub_ssize_t
+grub_affs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_affs_data *data =
+    (struct grub_affs_data *) file->data;
+
+  int size = grub_affs_read_file (&data->diropen, file->read_hook,
+			      file->offset, len, buf);
+
+  return size;
+}
+
+
+static grub_err_t
+grub_affs_dir (grub_device_t device, const char *path,
+	       int (*hook) (const char *filename,
+			    const struct grub_dirhook_info *info))
+{
+  struct grub_affs_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+				     enum grub_fshelp_filetype filetype,
+				     grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_affs_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_affs_iterate_dir,
+			 grub_affs_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  grub_affs_iterate_dir (fdiro, iterate);
+
+ fail:
+  if (data && fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_affs_label (grub_device_t device, char **label)
+{
+  struct grub_affs_data *data;
+  struct grub_affs_file file;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_affs_mount (disk);
+  if (data)
+    {
+      /* The rootblock maps quite well on a file header block, it's
+	 something we can use here.  */
+      grub_disk_read (data->disk, disk->total_sectors >> 1,
+		      data->blocksize * (GRUB_DISK_SECTOR_SIZE
+					 - GRUB_AFFS_FILE_LOCATION),
+		      sizeof (file), &file);
+      if (grub_errno)
+	return 0;
+
+      *label = grub_strndup ((char *) (file.name), file.namelen);
+    }
+  else
+    *label = 0;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+static struct grub_fs grub_affs_fs =
+  {
+    .name = "affs",
+    .dir = grub_affs_dir,
+    .open = grub_affs_open,
+    .read = grub_affs_read,
+    .close = grub_affs_close,
+    .label = grub_affs_label,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(affs)
+{
+  grub_fs_register (&grub_affs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(affs)
+{
+  grub_fs_unregister (&grub_affs_fs);
+}
diff --git a/fs/afs.c b/fs/afs.c
new file mode 100644
index 0000000..cd61f4d
--- /dev/null
+++ b/fs/afs.c
@@ -0,0 +1,718 @@
+/* afs.c - The native AtheOS file-system.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+#ifdef MODE_BIGENDIAN
+#define GRUB_AFS_FSNAME_SUFFIX "_be"
+#else
+#define GRUB_AFS_FSNAME_SUFFIX ""
+#endif
+
+#ifdef MODE_BFS
+#define GRUB_AFS_FSNAME "befs" GRUB_AFS_FSNAME_SUFFIX
+#else
+#define GRUB_AFS_FSNAME "afs" GRUB_AFS_FSNAME_SUFFIX
+#endif
+
+#define	GRUB_AFS_DIRECT_BLOCK_COUNT	12
+#define	GRUB_AFS_BLOCKS_PER_DI_RUN	4
+
+#ifdef MODE_BFS
+#define GRUB_AFS_SBLOCK_SECTOR 1
+#define	GRUB_AFS_SBLOCK_MAGIC1	0x42465331 /* BFS1.  */
+#else
+#define GRUB_AFS_SBLOCK_SECTOR 2
+#define	GRUB_AFS_SBLOCK_MAGIC1	0x41465331 /* AFS1.  */
+#endif
+
+#define	GRUB_AFS_SBLOCK_MAGIC2	0xdd121031
+#define	GRUB_AFS_SBLOCK_MAGIC3	0x15b6830e
+
+#define	GRUB_AFS_INODE_MAGIC	0x64358428
+
+#ifdef MODE_BFS
+#define GRUB_AFS_BTREE_MAGIC	0x69f6c2e8
+#else
+#define GRUB_AFS_BTREE_MAGIC	0x65768995
+#endif
+
+#define GRUB_AFS_BNODE_SIZE	1024
+
+#define GRUB_AFS_S_IFMT		00170000
+#define GRUB_AFS_S_IFLNK	0120000
+
+#define GRUB_AFS_S_IFREG	0100000
+#define GRUB_AFS_S_IFDIR	0040000
+#define GRUB_AFS_S_IFIFO	0010000
+
+#define GRUB_AFS_NULL_VAL	((grub_afs_bvalue_t)-1)
+
+#ifdef MODE_BIGENDIAN
+#define grub_afs_to_cpu16(x) grub_be_to_cpu16 (x)
+#define grub_afs_to_cpu32(x) grub_be_to_cpu32 (x)
+#define grub_afs_to_cpu64(x) grub_be_to_cpu64 (x)
+#else
+#define grub_afs_to_cpu16(x) grub_le_to_cpu16 (x)
+#define grub_afs_to_cpu32(x) grub_le_to_cpu32 (x)
+#define grub_afs_to_cpu64(x) grub_le_to_cpu64 (x)
+#endif
+
+#ifdef MODE_BFS
+#define B_KEY_INDEX_ALIGN 8
+#else
+#define B_KEY_INDEX_ALIGN 4
+#endif
+
+#define B_KEY_INDEX_OFFSET(node) ((grub_uint16_t *) \
+				  ((char *) (node) \
+				   + ALIGN_UP (sizeof (struct grub_afs_bnode) \
+					       + node->key_size, \
+					       B_KEY_INDEX_ALIGN)))
+
+#define B_KEY_VALUE_OFFSET(node) ((grub_afs_bvalue_t *) \
+                                   ((char *) B_KEY_INDEX_OFFSET (node) + \
+                                    node->key_count * 2))
+
+typedef grub_uint64_t grub_afs_off_t;
+typedef grub_uint64_t grub_afs_bigtime;
+typedef grub_uint64_t grub_afs_bvalue_t;
+
+struct grub_afs_blockrun
+{
+  grub_uint32_t group;
+  grub_uint16_t start;
+  grub_uint16_t len;
+} __attribute__ ((packed));
+
+struct grub_afs_datastream
+{
+  struct grub_afs_blockrun direct[GRUB_AFS_DIRECT_BLOCK_COUNT];
+  grub_afs_off_t max_direct_range;
+  struct grub_afs_blockrun indirect;
+  grub_afs_off_t max_indirect_range;
+  struct grub_afs_blockrun double_indirect;
+  grub_afs_off_t max_double_indirect_range;
+  grub_afs_off_t size;
+} __attribute__ ((packed));
+
+struct grub_afs_bnode
+{
+  grub_afs_bvalue_t left;
+  grub_afs_bvalue_t right;
+  grub_afs_bvalue_t overflow;
+#ifdef MODE_BFS
+  grub_uint16_t key_count;
+  grub_uint16_t key_size;
+#else
+  grub_uint32_t key_count;
+  grub_uint32_t key_size;
+#endif
+  char key_data[0];
+} __attribute__ ((packed));
+
+#ifdef MODE_BFS
+struct grub_afs_btree
+{
+  grub_uint32_t magic;
+  grub_uint32_t unused1;
+  grub_uint32_t tree_depth;
+  grub_uint32_t unused2;
+  grub_afs_bvalue_t root;
+  grub_uint32_t unused3[4];
+} __attribute__ ((packed));
+#else
+struct grub_afs_btree
+{
+  grub_uint32_t magic;
+  grub_afs_bvalue_t root;
+  grub_uint32_t tree_depth;
+  grub_afs_bvalue_t last_node;
+  grub_afs_bvalue_t first_free;
+} __attribute__ ((packed));
+#endif
+
+/* Beware that following structure describes AtheFS and if you write code
+   which uses currently unused fields check it with both AtheFS and BeFS.
+ */
+struct grub_afs_sblock
+{
+  char name[32];
+  grub_uint32_t magic1;
+  grub_uint32_t byte_order;
+  grub_uint32_t	block_size;
+  grub_uint32_t block_shift;
+  grub_afs_off_t num_blocks;
+  grub_afs_off_t used_blocks;
+  grub_uint32_t	inode_size;
+  grub_uint32_t	magic2;
+  grub_uint32_t	block_per_group; /* Number of blocks per allocation
+				    group. (Max 65536)  */
+  grub_uint32_t	alloc_group_shift; /* Number of bits to shift a group
+				      number to get a byte address.  */
+  grub_uint32_t	alloc_group_count;
+  grub_uint32_t	flags;
+  struct grub_afs_blockrun log_block;
+  grub_afs_off_t log_start;
+  grub_uint32_t valid_log_blocks;
+  grub_uint32_t log_size;
+  grub_uint32_t	magic3;
+  struct grub_afs_blockrun root_dir; /* Root dir inode.  */
+  struct grub_afs_blockrun deleted_files; /* Directory containing files
+					     scheduled for deletion.  */
+  struct grub_afs_blockrun index_dir; /* Directory of index files.  */
+  grub_uint32_t boot_loader_size;
+  grub_uint32_t	pad[7];
+}  __attribute__ ((packed));
+
+struct grub_afs_inode
+{
+  grub_uint32_t magic1;
+  struct grub_afs_blockrun inode_num;
+  grub_uint32_t uid;
+  grub_uint32_t gid;
+  grub_uint32_t mode;
+  grub_uint32_t flags;
+#ifndef MODE_BFS
+  grub_uint32_t link_count;
+#endif
+  grub_afs_bigtime create_time;
+  grub_afs_bigtime modified_time;
+  struct grub_afs_blockrun parent;
+  struct grub_afs_blockrun attrib_dir;
+  grub_uint32_t index_type; /* Key data-key only used for index files. */
+  grub_uint32_t inode_size;
+  grub_uint32_t unused;
+  struct grub_afs_datastream stream;
+  grub_uint32_t	pad[4];
+  grub_uint32_t small_data[1];
+} __attribute__ ((packed));
+
+struct grub_fshelp_node
+{
+  struct grub_afs_data *data;
+  struct grub_afs_inode inode;
+};
+
+struct grub_afs_data
+{
+  grub_disk_t disk;
+  struct grub_afs_sblock sblock;
+  struct grub_afs_inode *inode;
+  struct grub_fshelp_node diropen;
+};
+
+static grub_dl_t my_mod;
+
+static grub_afs_off_t
+grub_afs_run_to_num (struct grub_afs_sblock *sb,
+                     struct grub_afs_blockrun *run)
+{
+  return ((grub_afs_off_t) grub_afs_to_cpu32 (run->group)
+	  * sb->block_per_group + grub_afs_to_cpu16 (run->start));
+}
+
+static grub_err_t
+grub_afs_read_inode (struct grub_afs_data *data,
+                     grub_uint32_t ino, struct grub_afs_inode *inode)
+{
+  return grub_disk_read (data->disk,
+                         ino *
+                         (data->sblock.block_size >> GRUB_DISK_SECTOR_BITS),
+                         0, sizeof (struct grub_afs_inode),
+                         inode);
+}
+
+static grub_disk_addr_t
+grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  struct grub_afs_sblock *sb = &node->data->sblock;
+  struct grub_afs_datastream *ds = &node->inode.stream;
+
+  if (fileblock < grub_afs_to_cpu64 (ds->max_direct_range))
+    {
+      int i;
+
+      for (i = 0; i < GRUB_AFS_DIRECT_BLOCK_COUNT; i++)
+        {
+          if (fileblock < grub_afs_to_cpu16 (ds->direct[i].len))
+            return grub_afs_run_to_num (sb, &ds->direct[i]) + fileblock;
+          fileblock -= grub_afs_to_cpu16 (ds->direct[i].len);
+        }
+    }
+  else if (fileblock < grub_afs_to_cpu64 (ds->max_indirect_range))
+    {
+      int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun);
+      struct grub_afs_blockrun indir[ptrs_per_blk];
+      grub_afs_off_t blk = grub_afs_run_to_num (sb, &ds->indirect);
+      int i;
+
+      fileblock -= grub_afs_to_cpu64 (ds->max_direct_range);
+      for (i = 0; i < ds->indirect.len; i++, blk++)
+        {
+          int j;
+
+          if (grub_disk_read (node->data->disk,
+                              blk * (sb->block_size >> GRUB_DISK_SECTOR_BITS),
+                              0, sizeof (indir),
+                              indir))
+            return 0;
+
+          for (j = 0; j < ptrs_per_blk; j++)
+            {
+              if (fileblock < grub_afs_to_cpu16 (indir[j].len))
+                return grub_afs_run_to_num (sb, &indir[j]) + fileblock;
+
+              fileblock -= grub_afs_to_cpu16 (indir[j].len);
+            }
+        }
+    }
+  else
+    {
+      int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun);
+      struct grub_afs_blockrun indir[ptrs_per_blk];
+
+      /* ([idblk][idptr]) ([dblk][dptr]) [blk]  */
+      int cur_pos = fileblock - grub_afs_to_cpu64 (ds->max_indirect_range);
+
+      int dptr_size = GRUB_AFS_BLOCKS_PER_DI_RUN;
+      int dblk_size = dptr_size * ptrs_per_blk;
+      int idptr_size = dblk_size * GRUB_AFS_BLOCKS_PER_DI_RUN;
+      int idblk_size = idptr_size * ptrs_per_blk;
+
+      int off = cur_pos % GRUB_AFS_BLOCKS_PER_DI_RUN;
+      int dptr = (cur_pos / dptr_size) % ptrs_per_blk;
+      int dblk = (cur_pos / dblk_size) % GRUB_AFS_BLOCKS_PER_DI_RUN;
+      int idptr = (cur_pos / idptr_size) % ptrs_per_blk;
+      int idblk = (cur_pos / idblk_size);
+
+      if (grub_disk_read (node->data->disk,
+                          (grub_afs_run_to_num (sb, &ds->double_indirect)
+                           + idblk) *
+                          (sb->block_size >> GRUB_DISK_SECTOR_BITS),
+                          0, sizeof (indir),
+                          indir))
+        return 0;
+
+      if (grub_disk_read (node->data->disk,
+                          (grub_afs_run_to_num (sb, &indir[idptr]) + dblk) *
+                          (sb->block_size >> GRUB_DISK_SECTOR_BITS),
+                          0, sizeof (indir),
+                          indir))
+        return 0;
+
+      return grub_afs_run_to_num (sb, &indir[dptr]) + off;
+    }
+
+  return 0;
+}
+
+static grub_ssize_t
+grub_afs_read_file (grub_fshelp_node_t node,
+                    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                                        unsigned offset, unsigned length),
+                    int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+				pos, len, buf, grub_afs_read_block,
+                                grub_afs_to_cpu64 (node->inode.stream.size),
+				node->data->sblock.block_shift
+                                - GRUB_DISK_SECTOR_BITS);
+}
+
+static char *
+grub_afs_read_symlink (grub_fshelp_node_t node)
+{
+  char *ret;
+  grub_afs_off_t size = grub_afs_to_cpu64 (node->inode.stream.size);
+
+  if (size == 0)
+    {
+      size = sizeof (node->inode.stream);
+      ret = grub_zalloc (size + 1);
+      if (! ret)
+	return 0;
+      grub_memcpy (ret, (char *) &(node->inode.stream),
+		   sizeof (node->inode.stream));
+      return ret;
+    }
+  ret = grub_zalloc (size + 1);
+  if (! ret)
+    return 0;
+  grub_afs_read_file (node, 0, 0, size, ret);
+  return ret;
+}
+
+static int
+grub_afs_iterate_dir (grub_fshelp_node_t dir,
+                      int NESTED_FUNC_ATTR
+                      (*hook) (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node))
+{
+  struct grub_afs_btree head;
+  char node_data [GRUB_AFS_BNODE_SIZE];
+  struct grub_afs_bnode *node = (struct grub_afs_bnode *) node_data;
+  int i;
+
+  if ((dir->inode.stream.size == 0)
+      || ((grub_afs_to_cpu32 (dir->inode.mode) & GRUB_AFS_S_IFMT)
+	  != GRUB_AFS_S_IFDIR))
+    return 0;
+
+  grub_afs_read_file (dir, 0, 0, sizeof (head), (char *) &head);
+  if (grub_errno)
+    return 0;
+
+  grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (head.root),
+                      GRUB_AFS_BNODE_SIZE, (char *) node);
+  if (grub_errno)
+    return 0;
+
+  for (i = 0; i < (int) grub_afs_to_cpu32 (head.tree_depth) - 1; i++)
+    {
+      grub_afs_bvalue_t blk;
+
+      blk = grub_afs_to_cpu64(B_KEY_VALUE_OFFSET (node) [0]);
+      grub_afs_read_file (dir, 0, blk, GRUB_AFS_BNODE_SIZE, (char *) node);
+      if (grub_errno)
+        return 0;
+    }
+
+  if (node->key_count)
+    {
+      grub_uint32_t cur_key = 0;
+
+      while (1)
+        {
+          int key_start, key_size;
+          grub_uint16_t *index;
+
+          index = B_KEY_INDEX_OFFSET (node);
+
+	  key_start = (cur_key > 0)
+	    ? grub_afs_to_cpu16 (index[cur_key - 1]) : 0;
+          key_size = grub_afs_to_cpu16 (index[cur_key]) - key_start;
+          if (key_size > 0)
+            {
+              char filename [key_size + 1];
+              struct grub_fshelp_node *fdiro;
+              int mode, type;
+
+              fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
+              if (! fdiro)
+                return 0;
+
+              fdiro->data = dir->data;
+              if (grub_afs_read_inode (dir->data,
+                                       grub_afs_to_cpu64
+				       (B_KEY_VALUE_OFFSET (node) [cur_key]),
+                                       &fdiro->inode))
+                return 0;
+
+              grub_memcpy (filename, &node->key_data[key_start], key_size);
+              filename [key_size] = 0;
+
+              mode = (grub_afs_to_cpu32 (fdiro->inode.mode) & GRUB_AFS_S_IFMT);
+              if (mode == GRUB_AFS_S_IFDIR)
+                type = GRUB_FSHELP_DIR;
+              else if (mode == GRUB_AFS_S_IFREG)
+                type = GRUB_FSHELP_REG;
+	      else if (mode == GRUB_AFS_S_IFLNK)
+		type = GRUB_FSHELP_SYMLINK;
+              else
+                type = GRUB_FSHELP_UNKNOWN;
+
+              if (hook (filename, type, fdiro))
+                return 1;
+            }
+
+          cur_key++;
+          if (cur_key >= grub_afs_to_cpu32 (node->key_count))
+            {
+              if (node->right == GRUB_AFS_NULL_VAL)
+                break;
+
+              grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (node->right),
+                                  GRUB_AFS_BNODE_SIZE, (char *) node);
+              if (grub_errno)
+                return 0;
+
+              cur_key = 0;
+            }
+        }
+    }
+
+  return 0;
+}
+
+static int
+grub_afs_validate_sblock (struct grub_afs_sblock *sb)
+{
+  if (grub_afs_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1)
+    {
+      sb->magic2 = grub_afs_to_cpu32 (sb->magic2);
+      sb->magic3 = grub_afs_to_cpu32 (sb->magic3);
+      sb->block_shift = grub_afs_to_cpu32 (sb->block_shift);
+      sb->block_size = grub_afs_to_cpu32 (sb->block_size);
+      sb->used_blocks = grub_afs_to_cpu64 (sb->used_blocks);
+      sb->num_blocks = grub_afs_to_cpu64 (sb->num_blocks);
+      sb->inode_size = grub_afs_to_cpu32 (sb->inode_size);
+      sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count);
+      sb->alloc_group_shift = grub_afs_to_cpu32 (sb->alloc_group_shift);
+      sb->block_per_group = grub_afs_to_cpu32 (sb->block_per_group);
+      sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count);
+      sb->log_size = grub_afs_to_cpu32 (sb->log_size);
+    }
+  else
+    return 0;
+
+  if ((sb->magic2 != GRUB_AFS_SBLOCK_MAGIC2) ||
+      (sb->magic3 != GRUB_AFS_SBLOCK_MAGIC3))
+    return 0;
+
+#ifdef MODE_BFS
+  sb->block_per_group = 1 << (sb->alloc_group_shift);
+#endif
+
+  if (((grub_uint32_t) (1 << sb->block_shift) != sb->block_size)
+      || (sb->used_blocks > sb->num_blocks )
+      || (sb->inode_size != sb->block_size)
+      || (0 == sb->block_size)
+#ifndef MODE_BFS
+      || ((grub_uint32_t) (1 << sb->alloc_group_shift) !=
+	  sb->block_per_group * sb->block_size)
+      || (sb->alloc_group_count * sb->block_per_group < sb->num_blocks)
+      || (grub_afs_to_cpu16 (sb->log_block.len) != sb->log_size)
+      || (grub_afs_to_cpu32 (sb->valid_log_blocks) > sb->log_size)
+#endif
+      )
+    return 0;
+
+  return 1;
+}
+
+static struct grub_afs_data *
+grub_afs_mount (grub_disk_t disk)
+{
+  struct grub_afs_data *data = 0;
+
+  data = grub_malloc (sizeof (struct grub_afs_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  if (grub_disk_read (disk, GRUB_AFS_SBLOCK_SECTOR, 0,
+		      sizeof (struct grub_afs_sblock), &data->sblock))
+    goto fail;
+
+  if (! grub_afs_validate_sblock (&data->sblock))
+    goto fail;
+
+  data->diropen.data = data;
+  data->inode = &data->diropen.inode;
+  data->disk = disk;
+
+  if (grub_afs_read_inode (data,
+                           grub_afs_run_to_num (&data->sblock,
+                                                &data->sblock.root_dir),
+                           data->inode))
+    goto fail;
+
+  return data;
+
+fail:
+  grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem");
+
+  grub_free (data);
+  return 0;
+}
+
+static grub_err_t
+grub_afs_open (struct grub_file *file, const char *name)
+{
+  struct grub_afs_data *data;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_afs_mount (file->device->disk);
+  if (! data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_afs_iterate_dir,
+			 grub_afs_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_afs_inode));
+  grub_free (fdiro);
+
+  file->size = grub_afs_to_cpu64 (data->inode->stream.size);
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+fail:
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_afs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_afs_data *data = (struct grub_afs_data *) file->data;
+
+  return grub_afs_read_file (&data->diropen, file->read_hook,
+                             file->offset, len, buf);
+}
+
+static grub_err_t
+grub_afs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_afs_dir (grub_device_t device, const char *path,
+              int (*hook) (const char *filename,
+			   const struct grub_dirhook_info *info))
+{
+  struct grub_afs_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+				     enum grub_fshelp_filetype filetype,
+				     grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      info.mtimeset = 1;
+#ifdef MODE_BFS
+      info.mtime = grub_afs_to_cpu64 (node->inode.modified_time) >> 16;
+#else
+      info.mtime = grub_divmod64 (grub_afs_to_cpu64 (node->inode.modified_time),
+				  1000000, 0);
+#endif
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_afs_mount (device->disk);
+  if (! data)
+    goto fail;
+
+  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_afs_iterate_dir,
+			 grub_afs_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  grub_afs_iterate_dir (fdiro, iterate);
+
+  if (fdiro != &data->diropen)
+    grub_free (fdiro);
+
+ fail:
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_afs_label (grub_device_t device, char **label)
+{
+  struct grub_afs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_afs_mount (disk);
+  if (data)
+    *label = grub_strndup (data->sblock.name, sizeof (data->sblock.name));
+  else
+    *label = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+static struct grub_fs grub_afs_fs = {
+  .name = GRUB_AFS_FSNAME,
+  .dir = grub_afs_dir,
+  .open = grub_afs_open,
+  .read = grub_afs_read,
+  .close = grub_afs_close,
+  .label = grub_afs_label,
+  .next = 0
+};
+
+#if defined (MODE_BIGENDIAN) && defined (MODE_BFS)
+GRUB_MOD_INIT (befs_be)
+#elif defined (MODE_BFS)
+GRUB_MOD_INIT (befs)
+#elif defined (MODE_BIGENDIAN)
+GRUB_MOD_INIT (afs_be)
+#else
+GRUB_MOD_INIT (afs)
+#endif
+{
+  grub_fs_register (&grub_afs_fs);
+  my_mod = mod;
+}
+
+#if defined (MODE_BIGENDIAN) && defined (MODE_BFS)
+GRUB_MOD_FINI (befs_be)
+#elif defined (MODE_BFS)
+GRUB_MOD_FINI (befs)
+#elif defined (MODE_BIGENDIAN)
+GRUB_MOD_FINI (afs_be)
+#else
+GRUB_MOD_FINI (afs)
+#endif
+{
+  grub_fs_unregister (&grub_afs_fs);
+}
diff --git a/fs/afs_be.c b/fs/afs_be.c
new file mode 100644
index 0000000..1f1f48f
--- /dev/null
+++ b/fs/afs_be.c
@@ -0,0 +1,2 @@
+#define MODE_BIGENDIAN 1
+#include "afs.c"
diff --git a/fs/befs.c b/fs/befs.c
new file mode 100644
index 0000000..c54d8e1
--- /dev/null
+++ b/fs/befs.c
@@ -0,0 +1,3 @@
+/* befs.c - The native BeOS/Haiku file-system.  */
+#define MODE_BFS 1
+#include "afs.c"
diff --git a/fs/befs_be.c b/fs/befs_be.c
new file mode 100644
index 0000000..f6e8179
--- /dev/null
+++ b/fs/befs_be.c
@@ -0,0 +1,4 @@
+/* befs.c - The native BeOS/Haiku file-system.  */
+#define MODE_BFS 1
+#define MODE_BIGENDIAN 1
+#include "afs.c"
diff --git a/fs/cpio.c b/fs/cpio.c
new file mode 100644
index 0000000..3f3a3d1
--- /dev/null
+++ b/fs/cpio.c
@@ -0,0 +1,371 @@
+/* cpio.c - cpio and tar filesystem.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+
+#ifndef MODE_USTAR
+/* cpio support */
+#define	MAGIC_BCPIO	070707
+struct head
+{
+  grub_uint16_t magic;
+  grub_uint16_t dev;
+  grub_uint16_t ino;
+  grub_uint16_t mode;
+  grub_uint16_t uid;
+  grub_uint16_t gid;
+  grub_uint16_t nlink;
+  grub_uint16_t rdev;
+  grub_uint16_t mtime_1;
+  grub_uint16_t mtime_2;
+  grub_uint16_t namesize;
+  grub_uint16_t filesize_1;
+  grub_uint16_t filesize_2;
+} __attribute__ ((packed));
+#else
+/* tar support */
+#define MAGIC_USTAR	"ustar"
+struct head
+{
+  char name[100];
+  char mode[8];
+  char uid[8];
+  char gid[8];
+  char size[12];
+  char mtime[12];
+  char chksum[8];
+  char typeflag;
+  char linkname[100];
+  char magic[6];
+  char version[2];
+  char uname[32];
+  char gname[32];
+  char devmajor[8];
+  char devminor[8];
+  char prefix[155];
+} __attribute__ ((packed));
+#endif
+
+struct grub_cpio_data
+{
+  grub_disk_t disk;
+  grub_uint32_t hofs;
+  grub_uint32_t dofs;
+  grub_uint32_t size;
+};
+
+static grub_dl_t my_mod;
+
+static grub_err_t
+grub_cpio_find_file (struct grub_cpio_data *data, char **name,
+		     grub_uint32_t * ofs)
+{
+#ifndef MODE_USTAR
+      struct head hd;
+
+      if (grub_disk_read
+	  (data->disk, 0, data->hofs, sizeof (hd), &hd))
+	return grub_errno;
+
+      if (hd.magic != MAGIC_BCPIO)
+	return grub_error (GRUB_ERR_BAD_FS, "Invalid cpio archive");
+
+      data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2;
+
+      if (hd.namesize & 1)
+	hd.namesize++;
+
+      if ((*name = grub_malloc (hd.namesize)) == NULL)
+	return grub_errno;
+
+      if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd),
+			  hd.namesize, *name))
+	{
+	  grub_free (*name);
+	  return grub_errno;
+	}
+
+      if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1
+	  && ! grub_memcmp(*name, "TRAILER!!!", 11))
+	{
+	  *ofs = 0;
+	  return GRUB_ERR_NONE;
+	}
+
+      data->dofs = data->hofs + sizeof (hd) + hd.namesize;
+      *ofs = data->dofs + data->size;
+      if (data->size & 1)
+	(*ofs)++;
+#else
+      struct head hd;
+
+      if (grub_disk_read
+	  (data->disk, 0, data->hofs, sizeof (hd), &hd))
+	return grub_errno;
+
+      if (!hd.name[0])
+	{
+	  *ofs = 0;
+	  return GRUB_ERR_NONE;
+	}
+
+      if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1))
+	return grub_error (GRUB_ERR_BAD_FS, "Invalid tar archive");
+
+      if ((*name = grub_strdup (hd.name)) == NULL)
+	return grub_errno;
+
+      data->size = grub_strtoul (hd.size, NULL, 8);
+      data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
+      *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
+			   ~(GRUB_DISK_SECTOR_SIZE - 1));
+#endif
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_cpio_data *
+grub_cpio_mount (grub_disk_t disk)
+{
+  struct head hd;
+  struct grub_cpio_data *data;
+
+  if (grub_disk_read (disk, 0, 0, sizeof (hd), &hd))
+    goto fail;
+
+#ifndef MODE_USTAR
+  if (hd.magic != MAGIC_BCPIO)
+#else
+  if (grub_memcmp (hd.magic, MAGIC_USTAR,
+		   sizeof (MAGIC_USTAR) - 1))
+#endif
+    goto fail;
+
+  data = (struct grub_cpio_data *) grub_malloc (sizeof (*data));
+  if (!data)
+    goto fail;
+
+  data->disk = disk;
+
+  return data;
+
+fail:
+  grub_error (GRUB_ERR_BAD_FS, "not a "
+#ifdef MODE_USTAR
+	      "tar"
+#else
+	      "cpio"
+#endif
+	      " filesystem");
+  return 0;
+}
+
+static grub_err_t
+grub_cpio_dir (grub_device_t device, const char *path,
+	       int (*hook) (const char *filename,
+			    const struct grub_dirhook_info *info))
+{
+  struct grub_cpio_data *data;
+  grub_uint32_t ofs;
+  char *prev, *name;
+  const char *np;
+  int len;
+
+  grub_dl_ref (my_mod);
+
+  prev = 0;
+
+  data = grub_cpio_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  np = path + 1;
+  len = grub_strlen (path) - 1;
+
+  data->hofs = 0;
+  while (1)
+    {
+      if (grub_cpio_find_file (data, &name, &ofs))
+	goto fail;
+
+      if (!ofs)
+	break;
+
+      if (grub_memcmp (np, name, len) == 0)
+	{
+	  char *p, *n;
+
+	  n = name + len;
+	  if (*n == '/')
+	    n++;
+
+	  p = grub_strchr (name + len, '/');
+	  if (p)
+	    *p = 0;
+
+	  if ((!prev) || (grub_strcmp (prev, name) != 0))
+	    {
+	      struct grub_dirhook_info info;
+	      grub_memset (&info, 0, sizeof (info));
+	      info.dir = (p != NULL);
+
+	      hook (name + len, &info);
+	      if (prev)
+		grub_free (prev);
+	      prev = name;
+	    }
+	  else
+	    grub_free (name);
+	}
+      data->hofs = ofs;
+    }
+
+fail:
+
+  if (prev)
+    grub_free (prev);
+
+  if (data)
+    grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cpio_open (grub_file_t file, const char *name)
+{
+  struct grub_cpio_data *data;
+  grub_uint32_t ofs;
+  char *fn;
+  int i, j;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_cpio_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  data->hofs = 0;
+  while (1)
+    {
+      if (grub_cpio_find_file (data, &fn, &ofs))
+	goto fail;
+
+      if (!ofs)
+	{
+	  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+	  break;
+	}
+
+      /* Compare NAME and FN by hand in order to cope with duplicate
+	 slashes.  */
+      i = 1;
+      j = 0;
+      while (1)
+	{
+	  if (name[i] != fn[j])
+	    goto no_match;
+
+	  if (name[i] == '\0')
+	    break;
+
+	  if (name[i] == '/' && name[i+1] == '/')
+	    i++;
+
+	  i++;
+	  j++;
+	}
+
+      file->data = data;
+      file->size = data->size;
+      grub_free (fn);
+
+      return GRUB_ERR_NONE;
+
+    no_match:
+
+      grub_free (fn);
+      data->hofs = ofs;
+    }
+
+fail:
+
+  if (data)
+    grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_cpio_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_cpio_data *data;
+
+  data = file->data;
+  return (grub_disk_read (data->disk, 0, data->dofs + file->offset,
+			  len, buf)) ? -1 : (grub_ssize_t) len;
+}
+
+static grub_err_t
+grub_cpio_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_cpio_fs = {
+#ifdef MODE_USTAR
+  .name = "tarfs",
+#else
+  .name = "cpiofs",
+#endif
+  .dir = grub_cpio_dir,
+  .open = grub_cpio_open,
+  .read = grub_cpio_read,
+  .close = grub_cpio_close,
+};
+
+#ifdef MODE_USTAR
+GRUB_MOD_INIT (tar)
+#else
+GRUB_MOD_INIT (cpio)
+#endif
+{
+  grub_fs_register (&grub_cpio_fs);
+  my_mod = mod;
+}
+
+#ifdef MODE_USTAR
+GRUB_MOD_FINI (tar)
+#else
+GRUB_MOD_FINI (cpio)
+#endif
+{
+  grub_fs_unregister (&grub_cpio_fs);
+}
diff --git a/fs/ext2.c b/fs/ext2.c
new file mode 100644
index 0000000..e7a20a4
--- /dev/null
+++ b/fs/ext2.c
@@ -0,0 +1,945 @@
+/* ext2.c - Second Extended filesystem */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Magic value used to identify an ext2 filesystem.  */
+#define	EXT2_MAGIC		0xEF53
+/* Amount of indirect blocks in an inode.  */
+#define INDIRECT_BLOCKS		12
+/* Maximum length of a pathname.  */
+#define EXT2_PATH_MAX		4096
+/* Maximum nesting of symlinks, used to prevent a loop.  */
+#define	EXT2_MAX_SYMLINKCNT	8
+
+/* The good old revision and the default inode size.  */
+#define EXT2_GOOD_OLD_REVISION		0
+#define EXT2_GOOD_OLD_INODE_SIZE	128
+
+/* Filetype used in directory entry.  */
+#define	FILETYPE_UNKNOWN	0
+#define	FILETYPE_REG		1
+#define	FILETYPE_DIRECTORY	2
+#define	FILETYPE_SYMLINK	7
+
+/* Filetype information as used in inodes.  */
+#define FILETYPE_INO_MASK	0170000
+#define FILETYPE_INO_REG	0100000
+#define FILETYPE_INO_DIRECTORY	0040000
+#define FILETYPE_INO_SYMLINK	0120000
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+/* Log2 size of ext2 block in 512 blocks.  */
+#define LOG2_EXT2_BLOCK_SIZE(data)			\
+	(grub_le_to_cpu32 (data->sblock.log2_block_size) + 1)
+
+/* Log2 size of ext2 block in bytes.  */
+#define LOG2_BLOCK_SIZE(data)					\
+	(grub_le_to_cpu32 (data->sblock.log2_block_size) + 10)
+
+/* The size of an ext2 block in bytes.  */
+#define EXT2_BLOCK_SIZE(data)		(1 << LOG2_BLOCK_SIZE (data))
+
+/* The revision level.  */
+#define EXT2_REVISION(data)	grub_le_to_cpu32 (data->sblock.revision_level)
+
+/* The inode size.  */
+#define EXT2_INODE_SIZE(data)	\
+        (EXT2_REVISION (data) == EXT2_GOOD_OLD_REVISION \
+         ? EXT2_GOOD_OLD_INODE_SIZE \
+         : grub_le_to_cpu16 (data->sblock.inode_size))
+
+/* Superblock filesystem feature flags (RW compatible)
+ * A filesystem with any of these enabled can be read and written by a driver
+ * that does not understand them without causing metadata/data corruption.  */
+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC	0x0001
+#define EXT2_FEATURE_COMPAT_IMAGIC_INODES	0x0002
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL		0x0004
+#define EXT2_FEATURE_COMPAT_EXT_ATTR		0x0008
+#define EXT2_FEATURE_COMPAT_RESIZE_INODE	0x0010
+#define EXT2_FEATURE_COMPAT_DIR_INDEX		0x0020
+/* Superblock filesystem feature flags (RO compatible)
+ * A filesystem with any of these enabled can be safely read by a driver that
+ * does not understand them, but should not be written to, usually because
+ * additional metadata is required.  */
+#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 EXT4_FEATURE_RO_COMPAT_GDT_CSUM		0x0010
+#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK	0x0020
+#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE	0x0040
+/* Superblock filesystem feature flags (back-incompatible)
+ * A filesystem with any of these enabled should not be attempted to be read
+ * by a driver that does not understand them, since they usually indicate
+ * metadata format changes that might confuse the reader.  */
+#define EXT2_FEATURE_INCOMPAT_COMPRESSION	0x0001
+#define EXT2_FEATURE_INCOMPAT_FILETYPE		0x0002
+#define EXT3_FEATURE_INCOMPAT_RECOVER		0x0004 /* Needs recovery */
+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV	0x0008 /* Volume is journal device */
+#define EXT2_FEATURE_INCOMPAT_META_BG		0x0010
+#define EXT4_FEATURE_INCOMPAT_EXTENTS		0x0040 /* Extents used */
+#define EXT4_FEATURE_INCOMPAT_64BIT		0x0080
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG		0x0200
+
+/* The set of back-incompatible features this driver DOES support. Add (OR)
+ * flags here as the related features are implemented into the driver.  */
+#define EXT2_DRIVER_SUPPORTED_INCOMPAT ( EXT2_FEATURE_INCOMPAT_FILETYPE \
+                                       | EXT4_FEATURE_INCOMPAT_EXTENTS  \
+                                       | EXT4_FEATURE_INCOMPAT_FLEX_BG )
+/* List of rationales for the ignored "incompatible" features:
+ * needs_recovery: Not really back-incompatible - was added as such to forbid
+ *                 ext2 drivers from mounting an ext3 volume with a dirty
+ *                 journal because they will ignore the journal, but the next
+ *                 ext3 driver to mount the volume will find the journal and
+ *                 replay it, potentially corrupting the metadata written by
+ *                 the ext2 drivers. Safe to ignore for this RO driver.  */
+#define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER )
+
+
+#define EXT3_JOURNAL_MAGIC_NUMBER	0xc03b3998U
+
+#define EXT3_JOURNAL_DESCRIPTOR_BLOCK	1
+#define EXT3_JOURNAL_COMMIT_BLOCK	2
+#define EXT3_JOURNAL_SUPERBLOCK_V1	3
+#define EXT3_JOURNAL_SUPERBLOCK_V2	4
+#define EXT3_JOURNAL_REVOKE_BLOCK	5
+
+#define EXT3_JOURNAL_FLAG_ESCAPE	1
+#define EXT3_JOURNAL_FLAG_SAME_UUID	2
+#define EXT3_JOURNAL_FLAG_DELETED	4
+#define EXT3_JOURNAL_FLAG_LAST_TAG	8
+
+#define EXT4_EXTENTS_FLAG		0x80000
+
+/* The ext2 superblock.  */
+struct grub_ext2_sblock
+{
+  grub_uint32_t total_inodes;
+  grub_uint32_t total_blocks;
+  grub_uint32_t reserved_blocks;
+  grub_uint32_t free_blocks;
+  grub_uint32_t free_inodes;
+  grub_uint32_t first_data_block;
+  grub_uint32_t log2_block_size;
+  grub_uint32_t log2_fragment_size;
+  grub_uint32_t blocks_per_group;
+  grub_uint32_t fragments_per_group;
+  grub_uint32_t inodes_per_group;
+  grub_uint32_t mtime;
+  grub_uint32_t utime;
+  grub_uint16_t mnt_count;
+  grub_uint16_t max_mnt_count;
+  grub_uint16_t magic;
+  grub_uint16_t fs_state;
+  grub_uint16_t error_handling;
+  grub_uint16_t minor_revision_level;
+  grub_uint32_t lastcheck;
+  grub_uint32_t checkinterval;
+  grub_uint32_t creator_os;
+  grub_uint32_t revision_level;
+  grub_uint16_t uid_reserved;
+  grub_uint16_t gid_reserved;
+  grub_uint32_t first_inode;
+  grub_uint16_t inode_size;
+  grub_uint16_t block_group_number;
+  grub_uint32_t feature_compatibility;
+  grub_uint32_t feature_incompat;
+  grub_uint32_t feature_ro_compat;
+  grub_uint16_t uuid[8];
+  char volume_name[16];
+  char last_mounted_on[64];
+  grub_uint32_t compression_info;
+  grub_uint8_t prealloc_blocks;
+  grub_uint8_t prealloc_dir_blocks;
+  grub_uint16_t reserved_gdt_blocks;
+  grub_uint8_t journal_uuid[16];
+  grub_uint32_t journal_inum;
+  grub_uint32_t journal_dev;
+  grub_uint32_t last_orphan;
+  grub_uint32_t hash_seed[4];
+  grub_uint8_t def_hash_version;
+  grub_uint8_t jnl_backup_type;
+  grub_uint16_t reserved_word_pad;
+  grub_uint32_t default_mount_opts;
+  grub_uint32_t first_meta_bg;
+  grub_uint32_t mkfs_time;
+  grub_uint32_t jnl_blocks[17];
+};
+
+/* The ext2 blockgroup.  */
+struct grub_ext2_block_group
+{
+  grub_uint32_t block_id;
+  grub_uint32_t inode_id;
+  grub_uint32_t inode_table_id;
+  grub_uint16_t free_blocks;
+  grub_uint16_t free_inodes;
+  grub_uint16_t used_dirs;
+  grub_uint16_t pad;
+  grub_uint32_t reserved[3];
+};
+
+/* The ext2 inode.  */
+struct grub_ext2_inode
+{
+  grub_uint16_t mode;
+  grub_uint16_t uid;
+  grub_uint32_t size;
+  grub_uint32_t atime;
+  grub_uint32_t ctime;
+  grub_uint32_t mtime;
+  grub_uint32_t dtime;
+  grub_uint16_t gid;
+  grub_uint16_t nlinks;
+  grub_uint32_t blockcnt;  /* Blocks of 512 bytes!! */
+  grub_uint32_t flags;
+  grub_uint32_t osd1;
+  union
+  {
+    struct datablocks
+    {
+      grub_uint32_t dir_blocks[INDIRECT_BLOCKS];
+      grub_uint32_t indir_block;
+      grub_uint32_t double_indir_block;
+      grub_uint32_t triple_indir_block;
+    } blocks;
+    char symlink[60];
+  };
+  grub_uint32_t version;
+  grub_uint32_t acl;
+  grub_uint32_t dir_acl;
+  grub_uint32_t fragment_addr;
+  grub_uint32_t osd2[3];
+};
+
+/* The header of an ext2 directory entry.  */
+struct ext2_dirent
+{
+  grub_uint32_t inode;
+  grub_uint16_t direntlen;
+  grub_uint8_t namelen;
+  grub_uint8_t filetype;
+};
+
+struct grub_ext3_journal_header
+{
+  grub_uint32_t magic;
+  grub_uint32_t block_type;
+  grub_uint32_t sequence;
+};
+
+struct grub_ext3_journal_revoke_header
+{
+  struct grub_ext3_journal_header header;
+  grub_uint32_t count;
+  grub_uint32_t data[0];
+};
+
+struct grub_ext3_journal_block_tag
+{
+  grub_uint32_t block;
+  grub_uint32_t flags;
+};
+
+struct grub_ext3_journal_sblock
+{
+  struct grub_ext3_journal_header header;
+  grub_uint32_t block_size;
+  grub_uint32_t maxlen;
+  grub_uint32_t first;
+  grub_uint32_t sequence;
+  grub_uint32_t start;
+};
+
+#define EXT4_EXT_MAGIC		0xf30a
+
+struct grub_ext4_extent_header
+{
+  grub_uint16_t magic;
+  grub_uint16_t entries;
+  grub_uint16_t max;
+  grub_uint16_t depth;
+  grub_uint32_t generation;
+};
+
+struct grub_ext4_extent
+{
+  grub_uint32_t block;
+  grub_uint16_t len;
+  grub_uint16_t start_hi;
+  grub_uint32_t start;
+};
+
+struct grub_ext4_extent_idx
+{
+  grub_uint32_t block;
+  grub_uint32_t leaf;
+  grub_uint16_t leaf_hi;
+  grub_uint16_t unused;
+};
+
+struct grub_fshelp_node
+{
+  struct grub_ext2_data *data;
+  struct grub_ext2_inode inode;
+  int ino;
+  int inode_read;
+};
+
+/* Information about a "mounted" ext2 filesystem.  */
+struct grub_ext2_data
+{
+  struct grub_ext2_sblock sblock;
+  grub_disk_t disk;
+  struct grub_ext2_inode *inode;
+  struct grub_fshelp_node diropen;
+};
+
+static grub_dl_t my_mod;
+
+
+
+/* Read into BLKGRP the blockgroup descriptor of blockgroup GROUP of
+   the mounted filesystem DATA.  */
+inline static grub_err_t
+grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
+		      struct grub_ext2_block_group *blkgrp)
+{
+  return grub_disk_read (data->disk,
+                         ((grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
+                          << LOG2_EXT2_BLOCK_SIZE (data)),
+			 group * sizeof (struct grub_ext2_block_group),
+			 sizeof (struct grub_ext2_block_group), blkgrp);
+}
+
+static struct grub_ext4_extent_header *
+grub_ext4_find_leaf (struct grub_ext2_data *data, char *buf,
+                     struct grub_ext4_extent_header *ext_block,
+                     grub_uint32_t fileblock)
+{
+  struct grub_ext4_extent_idx *index;
+
+  while (1)
+    {
+      int i;
+      grub_disk_addr_t block;
+
+      index = (struct grub_ext4_extent_idx *) (ext_block + 1);
+
+      if (grub_le_to_cpu16(ext_block->magic) != EXT4_EXT_MAGIC)
+        return 0;
+
+      if (ext_block->depth == 0)
+        return ext_block;
+
+      for (i = 0; i < grub_le_to_cpu16 (ext_block->entries); i++)
+        {
+          if (fileblock < grub_le_to_cpu32(index[i].block))
+            break;
+        }
+
+      if (--i < 0)
+        return 0;
+
+      block = grub_le_to_cpu16 (index[i].leaf_hi);
+      block = (block << 32) + grub_le_to_cpu32 (index[i].leaf);
+      if (grub_disk_read (data->disk,
+                          block << LOG2_EXT2_BLOCK_SIZE (data),
+                          0, EXT2_BLOCK_SIZE(data), buf))
+        return 0;
+
+      ext_block = (struct grub_ext4_extent_header *) buf;
+    }
+}
+
+static grub_disk_addr_t
+grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  struct grub_ext2_data *data = node->data;
+  struct grub_ext2_inode *inode = &node->inode;
+  int blknr = -1;
+  unsigned int blksz = EXT2_BLOCK_SIZE (data);
+  int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
+
+  if (grub_le_to_cpu32(inode->flags) & EXT4_EXTENTS_FLAG)
+    {
+      char buf[EXT2_BLOCK_SIZE(data)];
+      struct grub_ext4_extent_header *leaf;
+      struct grub_ext4_extent *ext;
+      int i;
+
+      leaf = grub_ext4_find_leaf (data, buf,
+                                  (struct grub_ext4_extent_header *) inode->blocks.dir_blocks,
+                                  fileblock);
+      if (! leaf)
+        {
+          grub_error (GRUB_ERR_BAD_FS, "invalid extent");
+          return -1;
+        }
+
+      ext = (struct grub_ext4_extent *) (leaf + 1);
+      for (i = 0; i < grub_le_to_cpu16 (leaf->entries); i++)
+        {
+          if (fileblock < grub_le_to_cpu32 (ext[i].block))
+            break;
+        }
+
+      if (--i >= 0)
+        {
+          fileblock -= grub_le_to_cpu32 (ext[i].block);
+          if (fileblock >= grub_le_to_cpu16 (ext[i].len))
+            return 0;
+          else
+            {
+              grub_disk_addr_t start;
+
+              start = grub_le_to_cpu16 (ext[i].start_hi);
+              start = (start << 32) + grub_le_to_cpu32 (ext[i].start);
+
+              return fileblock + start;
+            }
+        }
+      else
+        {
+          grub_error (GRUB_ERR_BAD_FS, "something wrong with extent");
+          return -1;
+        }
+    }
+  /* Direct blocks.  */
+  if (fileblock < INDIRECT_BLOCKS)
+    blknr = grub_le_to_cpu32 (inode->blocks.dir_blocks[fileblock]);
+  /* Indirect.  */
+  else if (fileblock < INDIRECT_BLOCKS + blksz / 4)
+    {
+      grub_uint32_t indir[blksz / 4];
+
+      if (grub_disk_read (data->disk,
+			  grub_le_to_cpu32 (inode->blocks.indir_block)
+			  << log2_blksz,
+			  0, blksz, indir))
+	return grub_errno;
+
+      blknr = grub_le_to_cpu32 (indir[fileblock - INDIRECT_BLOCKS]);
+    }
+  /* Double indirect.  */
+  else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1))
+    {
+      unsigned int perblock = blksz / 4;
+      unsigned int rblock = fileblock - (INDIRECT_BLOCKS
+					 + blksz / 4);
+      grub_uint32_t indir[blksz / 4];
+
+      if (grub_disk_read (data->disk,
+			  grub_le_to_cpu32 (inode->blocks.double_indir_block)
+			  << log2_blksz,
+			  0, blksz, indir))
+	return grub_errno;
+
+      if (grub_disk_read (data->disk,
+			  grub_le_to_cpu32 (indir[rblock / perblock])
+			  << log2_blksz,
+			  0, blksz, indir))
+	return grub_errno;
+
+
+      blknr = grub_le_to_cpu32 (indir[rblock % perblock]);
+    }
+  /* triple indirect.  */
+  else
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+		  "ext2fs doesn't support triple indirect blocks");
+    }
+
+  return blknr;
+}
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_ext2_read_file (grub_fshelp_node_t node,
+		     void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+					unsigned offset, unsigned length),
+		     int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+				pos, len, buf, grub_ext2_read_block,
+				node->inode.size,
+				LOG2_EXT2_BLOCK_SIZE (node->data));
+
+}
+
+
+/* Read the inode INO for the file described by DATA into INODE.  */
+static grub_err_t
+grub_ext2_read_inode (struct grub_ext2_data *data,
+		      int ino, struct grub_ext2_inode *inode)
+{
+  struct grub_ext2_block_group blkgrp;
+  struct grub_ext2_sblock *sblock = &data->sblock;
+  int inodes_per_block;
+  unsigned int blkno;
+  unsigned int blkoff;
+
+  /* It is easier to calculate if the first inode is 0.  */
+  ino--;
+
+  grub_ext2_blockgroup (data,
+                        ino / grub_le_to_cpu32 (sblock->inodes_per_group),
+			&blkgrp);
+  if (grub_errno)
+    return grub_errno;
+
+  inodes_per_block = EXT2_BLOCK_SIZE (data) / EXT2_INODE_SIZE (data);
+  blkno = (ino % grub_le_to_cpu32 (sblock->inodes_per_group))
+    / inodes_per_block;
+  blkoff = (ino % grub_le_to_cpu32 (sblock->inodes_per_group))
+    % inodes_per_block;
+
+  /* Read the inode.  */
+  if (grub_disk_read (data->disk,
+		      ((grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno)
+		        << LOG2_EXT2_BLOCK_SIZE (data)),
+		      EXT2_INODE_SIZE (data) * blkoff,
+		      sizeof (struct grub_ext2_inode), inode))
+    return grub_errno;
+
+  return 0;
+}
+
+static struct grub_ext2_data *
+grub_ext2_mount (grub_disk_t disk)
+{
+  struct grub_ext2_data *data;
+
+  data = grub_malloc (sizeof (struct grub_ext2_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_ext2_sblock),
+                  &data->sblock);
+  if (grub_errno)
+    goto fail;
+
+  /* Make sure this is an ext2 filesystem.  */
+  if (grub_le_to_cpu16 (data->sblock.magic) != EXT2_MAGIC)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem");
+      goto fail;
+    }
+
+  /* Check the FS doesn't have feature bits enabled that we don't support. */
+  if (grub_le_to_cpu32 (data->sblock.feature_incompat)
+        & ~(EXT2_DRIVER_SUPPORTED_INCOMPAT | EXT2_DRIVER_IGNORED_INCOMPAT))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "filesystem has unsupported incompatible features");
+      goto fail;
+    }
+
+
+  data->disk = disk;
+
+  data->diropen.data = data;
+  data->diropen.ino = 2;
+  data->diropen.inode_read = 1;
+
+  data->inode = &data->diropen.inode;
+
+  grub_ext2_read_inode (data, 2, data->inode);
+  if (grub_errno)
+    goto fail;
+
+  return data;
+
+ fail:
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem");
+
+  grub_free (data);
+  return 0;
+}
+
+static char *
+grub_ext2_read_symlink (grub_fshelp_node_t node)
+{
+  char *symlink;
+  struct grub_fshelp_node *diro = node;
+
+  if (! diro->inode_read)
+    {
+      grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
+      if (grub_errno)
+	return 0;
+    }
+
+  symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
+  if (! symlink)
+    return 0;
+
+  /* If the filesize of the symlink is bigger than
+     60 the symlink is stored in a separate block,
+     otherwise it is stored in the inode.  */
+  if (grub_le_to_cpu32 (diro->inode.size) <= 60)
+    grub_strncpy (symlink,
+		  diro->inode.symlink,
+		  grub_le_to_cpu32 (diro->inode.size));
+  else
+    {
+      grub_ext2_read_file (diro, 0, 0,
+			   grub_le_to_cpu32 (diro->inode.size),
+			   symlink);
+      if (grub_errno)
+	{
+	  grub_free (symlink);
+	  return 0;
+	}
+    }
+
+  symlink[grub_le_to_cpu32 (diro->inode.size)] = '\0';
+  return symlink;
+}
+
+static int
+grub_ext2_iterate_dir (grub_fshelp_node_t dir,
+		       int NESTED_FUNC_ATTR
+		       (*hook) (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node))
+{
+  unsigned int fpos = 0;
+  struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
+
+  if (! diro->inode_read)
+    {
+      grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
+      if (grub_errno)
+	return 0;
+    }
+
+  /* Search the file.  */
+  while (fpos < grub_le_to_cpu32 (diro->inode.size))
+    {
+      struct ext2_dirent dirent;
+
+      grub_ext2_read_file (diro, 0, fpos, sizeof (struct ext2_dirent),
+			   (char *) &dirent);
+      if (grub_errno)
+	return 0;
+
+      if (dirent.direntlen == 0)
+        return 0;
+
+      if (dirent.namelen != 0)
+	{
+	  char filename[dirent.namelen + 1];
+	  struct grub_fshelp_node *fdiro;
+	  enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN;
+
+	  grub_ext2_read_file (diro, 0, fpos + sizeof (struct ext2_dirent),
+			       dirent.namelen, filename);
+	  if (grub_errno)
+	    return 0;
+
+	  fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
+	  if (! fdiro)
+	    return 0;
+
+	  fdiro->data = diro->data;
+	  fdiro->ino = grub_le_to_cpu32 (dirent.inode);
+
+	  filename[dirent.namelen] = '\0';
+
+	  if (dirent.filetype != FILETYPE_UNKNOWN)
+	    {
+	      fdiro->inode_read = 0;
+
+	      if (dirent.filetype == FILETYPE_DIRECTORY)
+		type = GRUB_FSHELP_DIR;
+	      else if (dirent.filetype == FILETYPE_SYMLINK)
+		type = GRUB_FSHELP_SYMLINK;
+	      else if (dirent.filetype == FILETYPE_REG)
+		type = GRUB_FSHELP_REG;
+	    }
+	  else
+	    {
+	      /* The filetype can not be read from the dirent, read
+		 the inode to get more information.  */
+	      grub_ext2_read_inode (diro->data,
+                                    grub_le_to_cpu32 (dirent.inode),
+				    &fdiro->inode);
+	      if (grub_errno)
+		{
+		  grub_free (fdiro);
+		  return 0;
+		}
+
+	      fdiro->inode_read = 1;
+
+	      if ((grub_le_to_cpu16 (fdiro->inode.mode)
+		   & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY)
+		type = GRUB_FSHELP_DIR;
+	      else if ((grub_le_to_cpu16 (fdiro->inode.mode)
+			& FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK)
+		type = GRUB_FSHELP_SYMLINK;
+	      else if ((grub_le_to_cpu16 (fdiro->inode.mode)
+			& FILETYPE_INO_MASK) == FILETYPE_INO_REG)
+		type = GRUB_FSHELP_REG;
+	    }
+
+	  if (hook (filename, type, fdiro))
+	    return 1;
+	}
+
+      fpos += grub_le_to_cpu16 (dirent.direntlen);
+    }
+
+  return 0;
+}
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_ext2_open (struct grub_file *file, const char *name)
+{
+  struct grub_ext2_data *data;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ext2_mount (file->device->disk);
+  if (! data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_ext2_iterate_dir,
+			 grub_ext2_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  if (! fdiro->inode_read)
+    {
+      grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode);
+      if (grub_errno)
+	goto fail;
+    }
+
+  grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_ext2_inode));
+  grub_free (fdiro);
+
+  file->size = grub_le_to_cpu32 (data->inode->size);
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+ fail:
+  if (fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_ext2_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Read LEN bytes data from FILE into BUF.  */
+static grub_ssize_t
+grub_ext2_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_ext2_data *data = (struct grub_ext2_data *) file->data;
+
+  return grub_ext2_read_file (&data->diropen, file->read_hook,
+			      file->offset, len, buf);
+}
+
+
+static grub_err_t
+grub_ext2_dir (grub_device_t device, const char *path,
+	       int (*hook) (const char *filename,
+			    const struct grub_dirhook_info *info))
+{
+  struct grub_ext2_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+				     enum grub_fshelp_filetype filetype,
+				     grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      if (! node->inode_read)
+	{
+	  grub_ext2_read_inode (data, node->ino, &node->inode);
+	  if (!grub_errno)
+	    node->inode_read = 1;
+	  grub_errno = GRUB_ERR_NONE;
+	}
+      if (node->inode_read)
+	{
+	  info.mtimeset = 1;
+	  info.mtime = grub_le_to_cpu32 (node->inode.mtime);
+	}
+
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ext2_mount (device->disk);
+  if (! data)
+    goto fail;
+
+  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_ext2_iterate_dir,
+			 grub_ext2_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  grub_ext2_iterate_dir (fdiro, iterate);
+
+ fail:
+  if (fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_ext2_label (grub_device_t device, char **label)
+{
+  struct grub_ext2_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ext2_mount (disk);
+  if (data)
+    *label = grub_strndup (data->sblock.volume_name, 14);
+  else
+    *label = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_ext2_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_ext2_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ext2_mount (disk);
+  if (data)
+    {
+      *uuid = grub_malloc (40 + sizeof ('\0'));
+      grub_sprintf (*uuid, "%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
+		    grub_be_to_cpu16 (data->sblock.uuid[0]), grub_be_to_cpu16 (data->sblock.uuid[1]),
+		    grub_be_to_cpu16 (data->sblock.uuid[2]), grub_be_to_cpu16 (data->sblock.uuid[3]),
+		    grub_be_to_cpu16 (data->sblock.uuid[4]), grub_be_to_cpu16 (data->sblock.uuid[5]),
+		    grub_be_to_cpu16 (data->sblock.uuid[6]), grub_be_to_cpu16 (data->sblock.uuid[7]));
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+/* Get mtime.  */
+static grub_err_t
+grub_ext2_mtime (grub_device_t device, grub_int32_t *tm)
+{
+  struct grub_ext2_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ext2_mount (disk);
+  if (!data)
+    *tm = 0;
+  else
+    *tm = grub_le_to_cpu32 (data->sblock.utime);
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+
+}
+
+
+
+static struct grub_fs grub_ext2_fs =
+  {
+    .name = "ext2",
+    .dir = grub_ext2_dir,
+    .open = grub_ext2_open,
+    .read = grub_ext2_read,
+    .close = grub_ext2_close,
+    .label = grub_ext2_label,
+    .uuid = grub_ext2_uuid,
+    .mtime = grub_ext2_mtime,
+#ifdef GRUB_UTIL
+    .reserved_first_sector = 1,
+#endif
+    .next = 0
+  };
+
+GRUB_MOD_INIT(ext2)
+{
+  grub_fs_register (&grub_ext2_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(ext2)
+{
+  grub_fs_unregister (&grub_ext2_fs);
+}
diff --git a/fs/fat.c b/fs/fat.c
new file mode 100644
index 0000000..e7f0162
--- /dev/null
+++ b/fs/fat.c
@@ -0,0 +1,874 @@
+/* fat.c - FAT filesystem */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/fs.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+
+#define GRUB_FAT_DIR_ENTRY_SIZE	32
+
+#define GRUB_FAT_ATTR_READ_ONLY	0x01
+#define GRUB_FAT_ATTR_HIDDEN	0x02
+#define GRUB_FAT_ATTR_SYSTEM	0x04
+#define GRUB_FAT_ATTR_VOLUME_ID	0x08
+#define GRUB_FAT_ATTR_DIRECTORY	0x10
+#define GRUB_FAT_ATTR_ARCHIVE	0x20
+
+#define GRUB_FAT_MAXFILE	256
+
+#define GRUB_FAT_ATTR_LONG_NAME	(GRUB_FAT_ATTR_READ_ONLY \
+				 | GRUB_FAT_ATTR_HIDDEN \
+				 | GRUB_FAT_ATTR_SYSTEM \
+				 | GRUB_FAT_ATTR_VOLUME_ID)
+#define GRUB_FAT_ATTR_VALID	(GRUB_FAT_ATTR_READ_ONLY \
+				 | GRUB_FAT_ATTR_HIDDEN \
+				 | GRUB_FAT_ATTR_SYSTEM \
+				 | GRUB_FAT_ATTR_DIRECTORY \
+				 | GRUB_FAT_ATTR_ARCHIVE \
+				 | GRUB_FAT_ATTR_VOLUME_ID)
+
+struct grub_fat_bpb
+{
+  grub_uint8_t jmp_boot[3];
+  grub_uint8_t oem_name[8];
+  grub_uint16_t bytes_per_sector;
+  grub_uint8_t sectors_per_cluster;
+  grub_uint16_t num_reserved_sectors;
+  grub_uint8_t num_fats;
+  grub_uint16_t num_root_entries;
+  grub_uint16_t num_total_sectors_16;
+  grub_uint8_t media;
+  grub_uint16_t sectors_per_fat_16;
+  grub_uint16_t sectors_per_track;
+  grub_uint16_t num_heads;
+  grub_uint32_t num_hidden_sectors;
+  grub_uint32_t num_total_sectors_32;
+  union
+  {
+    struct
+    {
+      grub_uint8_t num_ph_drive;
+      grub_uint8_t reserved;
+      grub_uint8_t boot_sig;
+      grub_uint32_t num_serial;
+      grub_uint8_t label[11];
+      grub_uint8_t fstype[8];
+    } __attribute__ ((packed)) fat12_or_fat16;
+    struct
+    {
+      grub_uint32_t sectors_per_fat_32;
+      grub_uint16_t extended_flags;
+      grub_uint16_t fs_version;
+      grub_uint32_t root_cluster;
+      grub_uint16_t fs_info;
+      grub_uint16_t backup_boot_sector;
+      grub_uint8_t reserved[12];
+      grub_uint8_t num_ph_drive;
+      grub_uint8_t reserved1;
+      grub_uint8_t boot_sig;
+      grub_uint32_t num_serial;
+      grub_uint8_t label[11];
+      grub_uint8_t fstype[8];
+    } __attribute__ ((packed)) fat32;
+  } __attribute__ ((packed)) version_specific;
+} __attribute__ ((packed));
+
+struct grub_fat_dir_entry
+{
+  grub_uint8_t name[11];
+  grub_uint8_t attr;
+  grub_uint8_t nt_reserved;
+  grub_uint8_t c_time_tenth;
+  grub_uint16_t c_time;
+  grub_uint16_t c_date;
+  grub_uint16_t a_date;
+  grub_uint16_t first_cluster_high;
+  grub_uint16_t w_time;
+  grub_uint16_t w_date;
+  grub_uint16_t first_cluster_low;
+  grub_uint32_t file_size;
+} __attribute__ ((packed));
+
+struct grub_fat_long_name_entry
+{
+  grub_uint8_t id;
+  grub_uint16_t name1[5];
+  grub_uint8_t attr;
+  grub_uint8_t reserved;
+  grub_uint8_t checksum;
+  grub_uint16_t name2[6];
+  grub_uint16_t first_cluster;
+  grub_uint16_t name3[2];
+} __attribute__ ((packed));
+
+struct grub_fat_data
+{
+  int logical_sector_bits;
+  grub_uint32_t num_sectors;
+
+  grub_uint16_t fat_sector;
+  grub_uint32_t sectors_per_fat;
+  int fat_size;
+
+  grub_uint32_t root_cluster;
+  grub_uint32_t root_sector;
+  grub_uint32_t num_root_sectors;
+
+  int cluster_bits;
+  grub_uint32_t cluster_eof_mark;
+  grub_uint32_t cluster_sector;
+  grub_uint32_t num_clusters;
+
+  grub_uint8_t attr;
+  grub_ssize_t file_size;
+  grub_uint32_t file_cluster;
+  grub_uint32_t cur_cluster_num;
+  grub_uint32_t cur_cluster;
+
+  grub_uint32_t uuid;
+};
+
+static grub_dl_t my_mod;
+
+static int
+fat_log2 (unsigned x)
+{
+  int i;
+
+  if (x == 0)
+    return -1;
+
+  for (i = 0; (x & 1) == 0; i++)
+    x >>= 1;
+
+  if (x != 1)
+    return -1;
+
+  return i;
+}
+
+static struct grub_fat_data *
+grub_fat_mount (grub_disk_t disk)
+{
+  struct grub_fat_bpb bpb;
+  struct grub_fat_data *data = 0;
+  grub_uint32_t first_fat, magic;
+
+  if (! disk)
+    goto fail;
+
+  data = (struct grub_fat_data *) grub_malloc (sizeof (*data));
+  if (! data)
+    goto fail;
+
+  /* Read the BPB.  */
+  if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
+    goto fail;
+
+  if (grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT12", 5)
+      && grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT16", 5)
+      && grub_strncmp((const char *) bpb.version_specific.fat32.fstype, "FAT32", 5))
+    goto fail;
+
+  /* Get the sizes of logical sectors and clusters.  */
+  data->logical_sector_bits =
+    fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector));
+  if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS)
+    goto fail;
+  data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS;
+
+  data->cluster_bits = fat_log2 (bpb.sectors_per_cluster);
+  if (data->cluster_bits < 0)
+    goto fail;
+  data->cluster_bits += data->logical_sector_bits;
+
+  /* Get information about FATs.  */
+  data->fat_sector = (grub_le_to_cpu16 (bpb.num_reserved_sectors)
+		      << data->logical_sector_bits);
+  if (data->fat_sector == 0)
+    goto fail;
+
+  data->sectors_per_fat = ((bpb.sectors_per_fat_16
+			    ? grub_le_to_cpu16 (bpb.sectors_per_fat_16)
+			    : grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32))
+			   << data->logical_sector_bits);
+  if (data->sectors_per_fat == 0)
+    goto fail;
+
+  /* Get the number of sectors in this volume.  */
+  data->num_sectors = ((bpb.num_total_sectors_16
+			? grub_le_to_cpu16 (bpb.num_total_sectors_16)
+			: grub_le_to_cpu32 (bpb.num_total_sectors_32))
+		       << data->logical_sector_bits);
+  if (data->num_sectors == 0)
+    goto fail;
+
+  /* Get information about the root directory.  */
+  if (bpb.num_fats == 0)
+    goto fail;
+
+  data->root_sector = data->fat_sector + bpb.num_fats * data->sectors_per_fat;
+  data->num_root_sectors
+    = ((((grub_uint32_t) grub_le_to_cpu16 (bpb.num_root_entries)
+	 * GRUB_FAT_DIR_ENTRY_SIZE
+	 + grub_le_to_cpu16 (bpb.bytes_per_sector) - 1)
+	>> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS))
+       << (data->logical_sector_bits));
+
+  data->cluster_sector = data->root_sector + data->num_root_sectors;
+  data->num_clusters = (((data->num_sectors - data->cluster_sector)
+			 >> (data->cluster_bits + data->logical_sector_bits))
+			+ 2);
+
+  if (data->num_clusters <= 2)
+    goto fail;
+
+  if (! bpb.sectors_per_fat_16)
+    {
+      /* FAT32.  */
+      grub_uint16_t flags = grub_le_to_cpu16 (bpb.version_specific.fat32.extended_flags);
+
+      data->root_cluster = grub_le_to_cpu32 (bpb.version_specific.fat32.root_cluster);
+      data->fat_size = 32;
+      data->cluster_eof_mark = 0x0ffffff8;
+
+      if (flags & 0x80)
+	{
+	  /* Get an active FAT.  */
+	  unsigned active_fat = flags & 0xf;
+
+	  if (active_fat > bpb.num_fats)
+	    goto fail;
+
+	  data->fat_sector += active_fat * data->sectors_per_fat;
+	}
+
+      if (bpb.num_root_entries != 0 || bpb.version_specific.fat32.fs_version != 0)
+	goto fail;
+    }
+  else
+    {
+      /* FAT12 or FAT16.  */
+      data->root_cluster = ~0U;
+
+      if (data->num_clusters <= 4085 + 2)
+	{
+	  /* FAT12.  */
+	  data->fat_size = 12;
+	  data->cluster_eof_mark = 0x0ff8;
+	}
+      else
+	{
+	  /* FAT16.  */
+	  data->fat_size = 16;
+	  data->cluster_eof_mark = 0xfff8;
+	}
+    }
+
+  /* More sanity checks.  */
+  if (data->num_sectors <= data->fat_sector)
+    goto fail;
+
+  if (grub_disk_read (disk,
+		      data->fat_sector,
+		      0,
+		      sizeof (first_fat),
+		      &first_fat))
+    goto fail;
+
+  first_fat = grub_le_to_cpu32 (first_fat);
+
+  if (data->fat_size == 32)
+    {
+      first_fat &= 0x0fffffff;
+      magic = 0x0fffff00;
+    }
+  else if (data->fat_size == 16)
+    {
+      first_fat &= 0x0000ffff;
+      magic = 0xff00;
+    }
+  else
+    {
+      first_fat &= 0x00000fff;
+      magic = 0x0f00;
+    }
+
+  /* Serial number.  */
+  if (bpb.sectors_per_fat_16)
+    data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial);
+  else
+    data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial);
+
+  /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
+     descriptor, even if it is a so-called superfloppy (e.g. an USB key).
+     The check may be too strict for this kind of stupid BIOSes, as
+     they overwrite the media descriptor.  */
+  if ((first_fat | 0x8) != (magic | bpb.media | 0x8))
+    goto fail;
+
+  /* Start from the root directory.  */
+  data->file_cluster = data->root_cluster;
+  data->cur_cluster_num = ~0U;
+  data->attr = GRUB_FAT_ATTR_DIRECTORY;
+  return data;
+
+ fail:
+
+  grub_free (data);
+  grub_error (GRUB_ERR_BAD_FS, "not a fat filesystem");
+  return 0;
+}
+
+static grub_ssize_t
+grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
+		    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+				       unsigned offset, unsigned length),
+		    grub_off_t offset, grub_size_t len, char *buf)
+{
+  grub_size_t size;
+  grub_uint32_t logical_cluster;
+  unsigned logical_cluster_bits;
+  grub_ssize_t ret = 0;
+  unsigned long sector;
+
+  /* This is a special case. FAT12 and FAT16 doesn't have the root directory
+     in clusters.  */
+  if (data->file_cluster == ~0U)
+    {
+      size = (data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset;
+      if (size > len)
+	size = len;
+
+      if (grub_disk_read (disk, data->root_sector, offset, size, buf))
+	return -1;
+
+      return size;
+    }
+
+  /* Calculate the logical cluster number and offset.  */
+  logical_cluster_bits = (data->cluster_bits
+			  + data->logical_sector_bits
+			  + GRUB_DISK_SECTOR_BITS);
+  logical_cluster = offset >> logical_cluster_bits;
+  offset &= (1 << logical_cluster_bits) - 1;
+
+  if (logical_cluster < data->cur_cluster_num)
+    {
+      data->cur_cluster_num = 0;
+      data->cur_cluster = data->file_cluster;
+    }
+
+  while (len)
+    {
+      while (logical_cluster > data->cur_cluster_num)
+	{
+	  /* Find next cluster.  */
+	  grub_uint32_t next_cluster;
+	  unsigned long fat_offset;
+
+	  switch (data->fat_size)
+	    {
+	    case 32:
+	      fat_offset = data->cur_cluster << 2;
+	      break;
+	    case 16:
+	      fat_offset = data->cur_cluster << 1;
+	      break;
+	    default:
+	      /* case 12: */
+	      fat_offset = data->cur_cluster + (data->cur_cluster >> 1);
+	      break;
+	    }
+
+	  /* Read the FAT.  */
+	  if (grub_disk_read (disk, data->fat_sector, fat_offset,
+			      (data->fat_size + 7) >> 3,
+			      (char *) &next_cluster))
+	    return -1;
+
+	  next_cluster = grub_le_to_cpu32 (next_cluster);
+	  switch (data->fat_size)
+	    {
+	    case 16:
+	      next_cluster &= 0xFFFF;
+	      break;
+	    case 12:
+	      if (data->cur_cluster & 1)
+		next_cluster >>= 4;
+
+	      next_cluster &= 0x0FFF;
+	      break;
+	    }
+
+	  grub_dprintf ("fat", "fat_size=%d, next_cluster=%u\n",
+			data->fat_size, next_cluster);
+
+	  /* Check the end.  */
+	  if (next_cluster >= data->cluster_eof_mark)
+	    return ret;
+
+	  if (next_cluster < 2 || next_cluster >= data->num_clusters)
+	    {
+	      grub_error (GRUB_ERR_BAD_FS, "invalid cluster %u",
+			  next_cluster);
+	      return -1;
+	    }
+
+	  data->cur_cluster = next_cluster;
+	  data->cur_cluster_num++;
+	}
+
+      /* Read the data here.  */
+      sector = (data->cluster_sector
+		+ ((data->cur_cluster - 2)
+		   << (data->cluster_bits + data->logical_sector_bits)));
+      size = (1 << logical_cluster_bits) - offset;
+      if (size > len)
+	size = len;
+
+      disk->read_hook = read_hook;
+      grub_disk_read (disk, sector, offset, size, buf);
+      disk->read_hook = 0;
+      if (grub_errno)
+	return -1;
+
+      len -= size;
+      buf += size;
+      ret += size;
+      logical_cluster++;
+      offset = 0;
+    }
+
+  return ret;
+}
+
+static grub_err_t
+grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
+		      int (*hook) (const char *filename,
+				   struct grub_fat_dir_entry *dir))
+{
+  struct grub_fat_dir_entry dir;
+  char *filename, *filep = 0;
+  grub_uint16_t *unibuf;
+  int slot = -1, slots = -1;
+  int checksum = -1;
+  grub_ssize_t offset = -sizeof(dir);
+
+  if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+
+  /* Allocate space enough to hold a long name.  */
+  filename = grub_malloc (0x40 * 13 * 4 + 1);
+  unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2);
+  if (! filename || ! unibuf)
+    {
+      grub_free (filename);
+      grub_free (unibuf);
+      return 0;
+    }
+
+  while (1)
+    {
+      unsigned i;
+
+      /* Adjust the offset.  */
+      offset += sizeof (dir);
+
+      /* Read a directory entry.  */
+      if ((grub_fat_read_data (disk, data, 0,
+			       offset, sizeof (dir), (char *) &dir)
+	   != sizeof (dir) || dir.name[0] == 0))
+	break;
+      /* Handle long name entries.  */
+      if (dir.attr == GRUB_FAT_ATTR_LONG_NAME)
+	{
+	  struct grub_fat_long_name_entry *long_name
+	    = (struct grub_fat_long_name_entry *) &dir;
+	  grub_uint8_t id = long_name->id;
+
+	  if (id & 0x40)
+	    {
+	      id &= 0x3f;
+	      slots = slot = id;
+	      checksum = long_name->checksum;
+	    }
+
+	  if (id != slot || slot == 0 || checksum != long_name->checksum)
+	    {
+	      checksum = -1;
+	      continue;
+	    }
+
+	  slot--;
+	  grub_memcpy (unibuf + slot * 13, long_name->name1, 5 * 2);
+	  grub_memcpy (unibuf + slot * 13 + 5, long_name->name2, 6 * 2);
+	  grub_memcpy (unibuf + slot * 13 + 11, long_name->name3, 2 * 2);
+	  continue;
+	}
+
+      /* Check if this entry is valid.  */
+      if (dir.name[0] == 0xe5 || (dir.attr & ~GRUB_FAT_ATTR_VALID))
+	continue;
+
+      /* This is a workaround for Japanese.  */
+      if (dir.name[0] == 0x05)
+	dir.name[0] = 0xe5;
+
+      if (checksum != -1 && slot == 0)
+	{
+	  grub_uint8_t sum;
+
+	  for (sum = 0, i = 0; i < sizeof (dir.name); i++)
+	    sum = ((sum >> 1) | (sum << 7)) + dir.name[i];
+
+	  if (sum == checksum)
+	    {
+	      int u;
+
+	      for (u = 0; u < slots * 13; u++)
+		unibuf[u] = grub_le_to_cpu16 (unibuf[u]);
+
+	      *grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf,
+				   slots * 13) = '\0';
+
+	      if (hook (filename, &dir))
+		break;
+
+	      checksum = -1;
+	      continue;
+	    }
+
+	  checksum = -1;
+	}
+
+      /* Convert the 8.3 file name.  */
+      filep = filename;
+      if (dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
+	{
+	  for (i = 0; i < sizeof (dir.name) && dir.name[i]
+		 && ! grub_isspace (dir.name[i]); i++)
+	    *filep++ = dir.name[i];
+	}
+      else
+	{
+	  for (i = 0; i < 8 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
+	    *filep++ = grub_tolower (dir.name[i]);
+
+	  *filep = '.';
+
+	  for (i = 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
+	    *++filep = grub_tolower (dir.name[i]);
+
+	  if (*filep != '.')
+	    filep++;
+	}
+      *filep = '\0';
+
+      if (hook (filename, &dir))
+	break;
+    }
+
+  grub_free (filename);
+
+  return grub_errno;
+}
+
+
+/* Find the underlying directory or file in PATH and return the
+   next path. If there is no next path or an error occurs, return NULL.
+   If HOOK is specified, call it with each file name.  */
+static char *
+grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
+		   const char *path,
+		   int (*hook) (const char *filename,
+				const struct grub_dirhook_info *info))
+{
+  char *dirname, *dirp;
+  int call_hook;
+  int found = 0;
+
+  auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir);
+  int iter_hook (const char *filename, struct grub_fat_dir_entry *dir)
+  {
+    struct grub_dirhook_info info;
+    grub_memset (&info, 0, sizeof (info));
+
+    info.dir = !! (dir->attr & GRUB_FAT_ATTR_DIRECTORY);
+    info.case_insensitive = 1;
+
+    if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID)
+      return 0;
+    if (*dirname == '\0' && call_hook)
+      return hook (filename, &info);
+
+    if (grub_strcasecmp (dirname, filename) == 0)
+      {
+	found = 1;
+	data->attr = dir->attr;
+	data->file_size = grub_le_to_cpu32 (dir->file_size);
+	data->file_cluster = ((grub_le_to_cpu16 (dir->first_cluster_high) << 16)
+			      | grub_le_to_cpu16 (dir->first_cluster_low));
+	data->cur_cluster_num = ~0U;
+
+	if (call_hook)
+	  hook (filename, &info);
+
+	return 1;
+      }
+    return 0;
+  }
+
+  if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      return 0;
+    }
+
+  /* Extract a directory name.  */
+  while (*path == '/')
+    path++;
+
+  dirp = grub_strchr (path, '/');
+  if (dirp)
+    {
+      unsigned len = dirp - path;
+
+      dirname = grub_malloc (len + 1);
+      if (! dirname)
+	return 0;
+
+      grub_memcpy (dirname, path, len);
+      dirname[len] = '\0';
+    }
+  else
+    /* This is actually a file.  */
+    dirname = grub_strdup (path);
+
+  call_hook = (! dirp && hook);
+
+  grub_fat_iterate_dir (disk, data, iter_hook);
+  if (grub_errno == GRUB_ERR_NONE && ! found && !call_hook)
+    grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+
+  grub_free (dirname);
+
+  return found ? dirp : 0;
+}
+
+static grub_err_t
+grub_fat_dir (grub_device_t device, const char *path,
+	      int (*hook) (const char *filename,
+			   const struct grub_dirhook_info *info))
+{
+  struct grub_fat_data *data = 0;
+  grub_disk_t disk = device->disk;
+  grub_size_t len;
+  char *dirname = 0;
+  char *p;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_fat_mount (disk);
+  if (! data)
+    goto fail;
+
+  /* Make sure that DIRNAME terminates with '/'.  */
+  len = grub_strlen (path);
+  dirname = grub_malloc (len + 1 + 1);
+  if (! dirname)
+    goto fail;
+  grub_memcpy (dirname, path, len);
+  p = dirname + len;
+  if (path[len - 1] != '/')
+    *p++ = '/';
+  *p = '\0';
+  p = dirname;
+
+  do
+    {
+      p = grub_fat_find_dir (disk, data, p, hook);
+    }
+  while (p && grub_errno == GRUB_ERR_NONE);
+
+ fail:
+
+  grub_free (dirname);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_fat_open (grub_file_t file, const char *name)
+{
+  struct grub_fat_data *data = 0;
+  char *p = (char *) name;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_fat_mount (file->device->disk);
+  if (! data)
+    goto fail;
+
+  do
+    {
+      p = grub_fat_find_dir (file->device->disk, data, p, 0);
+      if (grub_errno != GRUB_ERR_NONE)
+	goto fail;
+    }
+  while (p);
+
+  if (data->attr & GRUB_FAT_ATTR_DIRECTORY)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a file");
+      goto fail;
+    }
+
+  file->data = data;
+  file->size = data->file_size;
+
+  return GRUB_ERR_NONE;
+
+ fail:
+
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_fat_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  return grub_fat_read_data (file->device->disk, file->data, file->read_hook,
+			     file->offset, len, buf);
+}
+
+static grub_err_t
+grub_fat_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_fat_label (grub_device_t device, char **label)
+{
+  struct grub_fat_data *data;
+  grub_disk_t disk = device->disk;
+
+  auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir);
+  int iter_hook (const char *filename, struct grub_fat_dir_entry *dir)
+  {
+    if (dir->attr == GRUB_FAT_ATTR_VOLUME_ID)
+      {
+	*label = grub_strdup (filename);
+	return 1;
+      }
+    return 0;
+  }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_fat_mount (disk);
+  if (! data)
+    goto fail;
+
+  if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      return 0;
+    }
+
+  *label = 0;
+
+  grub_fat_iterate_dir (disk, data, iter_hook);
+
+ fail:
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_fat_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_fat_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_fat_mount (disk);
+  if (data)
+    {
+      *uuid = grub_malloc (sizeof ("xxxx-xxxx"));
+      grub_sprintf (*uuid, "%04x-%04x", (grub_uint16_t) (data->uuid >> 16),
+		    (grub_uint16_t) data->uuid);
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_fat_fs =
+  {
+    .name = "fat",
+    .dir = grub_fat_dir,
+    .open = grub_fat_open,
+    .read = grub_fat_read,
+    .close = grub_fat_close,
+    .label = grub_fat_label,
+    .uuid = grub_fat_uuid,
+#ifdef GRUB_UTIL
+    .reserved_first_sector = 1,
+#endif
+    .next = 0
+  };
+
+GRUB_MOD_INIT(fat)
+{
+  grub_fs_register (&grub_fat_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(fat)
+{
+  grub_fs_unregister (&grub_fat_fs);
+}
+
diff --git a/fs/fshelp.c b/fs/fshelp.c
new file mode 100644
index 0000000..d0b1e49
--- /dev/null
+++ b/fs/fshelp.c
@@ -0,0 +1,315 @@
+/* fshelp.c -- Filesystem helper functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/fshelp.h>
+
+
+/* Lookup the node PATH.  The node ROOTNODE describes the root of the
+   directory tree.  The node found is returned in FOUNDNODE, which is
+   either a ROOTNODE or a new malloc'ed node.  ITERATE_DIR is used to
+   iterate over all directory entries in the current node.
+   READ_SYMLINK is used to read the symlink if a node is a symlink.
+   EXPECTTYPE is the type node that is expected by the called, an
+   error is generated if the node is not of the expected type.  Make
+   sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required
+   because GCC has a nasty bug when using regparm=3.  */
+grub_err_t
+grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
+		       grub_fshelp_node_t *foundnode,
+		       int (*iterate_dir) (grub_fshelp_node_t dir,
+					   int NESTED_FUNC_ATTR (*hook)
+					   (const char *filename,
+					    enum grub_fshelp_filetype filetype,
+					    grub_fshelp_node_t node)),
+		       char *(*read_symlink) (grub_fshelp_node_t node),
+		       enum grub_fshelp_filetype expecttype)
+{
+  grub_err_t err;
+  enum grub_fshelp_filetype foundtype = GRUB_FSHELP_DIR;
+  int symlinknest = 0;
+
+  auto grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath,
+					      grub_fshelp_node_t currroot,
+					      grub_fshelp_node_t *currfound);
+
+  grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath,
+					 grub_fshelp_node_t currroot,
+					 grub_fshelp_node_t *currfound)
+    {
+      char fpath[grub_strlen (currpath) + 1];
+      char *name = fpath;
+      char *next;
+      //  unsigned int pos = 0;
+      enum grub_fshelp_filetype type = GRUB_FSHELP_DIR;
+      grub_fshelp_node_t currnode = currroot;
+      grub_fshelp_node_t oldnode = currroot;
+
+      auto int NESTED_FUNC_ATTR iterate (const char *filename,
+					 enum grub_fshelp_filetype filetype,
+					 grub_fshelp_node_t node);
+
+      auto void free_node (grub_fshelp_node_t node);
+
+      void free_node (grub_fshelp_node_t node)
+	{
+          if (node != rootnode && node != currroot)
+	    grub_free (node);
+	}
+
+      int NESTED_FUNC_ATTR iterate (const char *filename,
+				    enum grub_fshelp_filetype filetype,
+				    grub_fshelp_node_t node)
+	{
+	  if (filetype == GRUB_FSHELP_UNKNOWN ||
+              (grub_strcmp (name, filename) &&
+               (! (filetype & GRUB_FSHELP_CASE_INSENSITIVE) ||
+                grub_strncasecmp (name, filename, GRUB_LONG_MAX))))
+	    {
+	      grub_free (node);
+	      return 0;
+	    }
+
+	  /* The node is found, stop iterating over the nodes.  */
+	  type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE;
+	  oldnode = currnode;
+	  currnode = node;
+
+	  return 1;
+	}
+
+      grub_strncpy (fpath, currpath, grub_strlen (currpath) + 1);
+
+      /* Remove all leading slashes.  */
+      while (*name == '/')
+	name++;
+
+      if (! *name)
+	{
+	  *currfound = currnode;
+	  return 0;
+	}
+
+      for (;;)
+	{
+	  int found;
+
+	  /* Extract the actual part from the pathname.  */
+	  next = grub_strchr (name, '/');
+	  if (next)
+	    {
+	      /* Remove all leading slashes.  */
+	      while (*next == '/')
+		*(next++) = '\0';
+	    }
+
+	  /* At this point it is expected that the current node is a
+	     directory, check if this is true.  */
+	  if (type != GRUB_FSHELP_DIR)
+	    {
+	      free_node (currnode);
+	      return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+	    }
+
+	  /* Iterate over the directory.  */
+	  found = iterate_dir (currnode, iterate);
+	  if (! found)
+	    {
+	      if (grub_errno)
+		return grub_errno;
+
+	      break;
+	    }
+
+	  /* Read in the symlink and follow it.  */
+	  if (type == GRUB_FSHELP_SYMLINK)
+	    {
+	      char *symlink;
+
+	      /* Test if the symlink does not loop.  */
+	      if (++symlinknest == 8)
+		{
+		  free_node (currnode);
+		  free_node (oldnode);
+		  return grub_error (GRUB_ERR_SYMLINK_LOOP,
+                                     "too deep nesting of symlinks");
+		}
+
+	      symlink = read_symlink (currnode);
+	      free_node (currnode);
+
+	      if (!symlink)
+		{
+		  free_node (oldnode);
+		  return grub_errno;
+		}
+
+	      /* The symlink is an absolute path, go back to the root inode.  */
+	      if (symlink[0] == '/')
+		{
+		  free_node (oldnode);
+		  oldnode = rootnode;
+		}
+
+	      /* Lookup the node the symlink points to.  */
+	      find_file (symlink, oldnode, &currnode);
+	      type = foundtype;
+	      grub_free (symlink);
+
+	      if (grub_errno)
+		{
+		  free_node (oldnode);
+		  return grub_errno;
+		}
+	    }
+
+	  free_node (oldnode);
+
+	  /* Found the node!  */
+	  if (! next || *next == '\0')
+	    {
+	      *currfound = currnode;
+	      foundtype = type;
+	      return 0;
+	    }
+
+	  name = next;
+	}
+
+      return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+    }
+
+  if (!path || path[0] != '/')
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
+      return grub_errno;
+    }
+
+  err = find_file (path, rootnode, foundnode);
+  if (err)
+    return err;
+
+  /* Check if the node that was found was of the expected type.  */
+  if (expecttype == GRUB_FSHELP_REG && foundtype != expecttype)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file");
+  else if (expecttype == GRUB_FSHELP_DIR && foundtype != expecttype)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+
+  return 0;
+}
+
+/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
+   beginning with the block POS.  READ_HOOK should be set before
+   reading a block from the file.  GET_BLOCK is used to translate file
+   blocks to disk blocks.  The file is FILESIZE bytes big and the
+   blocks have a size of LOG2BLOCKSIZE (in log2).  */
+grub_ssize_t
+grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
+		       void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                                           unsigned offset,
+                                                           unsigned length),
+		       grub_off_t pos, grub_size_t len, char *buf,
+		       grub_disk_addr_t (*get_block) (grub_fshelp_node_t node,
+                                                      grub_disk_addr_t block),
+		       grub_off_t filesize, int log2blocksize)
+{
+  grub_disk_addr_t i, blockcnt;
+  int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS);
+
+  /* Adjust LEN so it we can't read past the end of the file.  */
+  if (pos + len > filesize)
+    len = filesize - pos;
+
+  blockcnt = ((len + pos) + blocksize - 1) >> (log2blocksize + GRUB_DISK_SECTOR_BITS);
+
+  for (i = pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS); i < blockcnt; i++)
+    {
+      grub_disk_addr_t blknr;
+      int blockoff = pos & (blocksize - 1);
+      int blockend = blocksize;
+
+      int skipfirst = 0;
+
+      blknr = get_block (node, i);
+      if (grub_errno)
+	return -1;
+
+      blknr = blknr << log2blocksize;
+
+      /* Last block.  */
+      if (i == blockcnt - 1)
+	{
+	  blockend = (len + pos) & (blocksize - 1);
+
+	  /* The last portion is exactly blocksize.  */
+	  if (! blockend)
+	    blockend = blocksize;
+	}
+
+      /* First block.  */
+      if (i == (pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS)))
+	{
+	  skipfirst = blockoff;
+	  blockend -= skipfirst;
+	}
+
+      /* If the block number is 0 this block is not stored on disk but
+	 is zero filled instead.  */
+      if (blknr)
+	{
+	  disk->read_hook = read_hook;
+
+	  grub_disk_read (disk, blknr, skipfirst,
+			  blockend, buf);
+	  disk->read_hook = 0;
+	  if (grub_errno)
+	    return -1;
+	}
+      else
+	grub_memset (buf, 0, blockend);
+
+      buf += blocksize - skipfirst;
+    }
+
+  return len;
+}
+
+unsigned int
+grub_fshelp_log2blksize (unsigned int blksize, unsigned int *pow)
+{
+  int mod;
+
+  *pow = 0;
+  while (blksize > 1)
+    {
+      mod = blksize - ((blksize >> 1) << 1);
+      blksize >>= 1;
+
+      /* Check if it really is a power of two.  */
+      if (mod)
+	return grub_error (GRUB_ERR_BAD_NUMBER,
+			   "the blocksize is not a power of two");
+      (*pow)++;
+    }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/fs/hfs.c b/fs/hfs.c
new file mode 100644
index 0000000..5062b5f
--- /dev/null
+++ b/fs/hfs.c
@@ -0,0 +1,1097 @@
+/* hfs.c - HFS.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* HFS is documented at
+   http://developer.apple.com/documentation/mac/Files/Files-2.html */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/hfs.h>
+
+#define	GRUB_HFS_SBLOCK		2
+#define GRUB_HFS_EMBED_HFSPLUS_SIG 0x482B
+
+#define GRUB_HFS_BLKS		(data->blksz >> 9)
+
+#define GRUB_HFS_NODE_LEAF	0xFF
+
+/* The two supported filesystems a record can have.  */
+enum
+  {
+    GRUB_HFS_FILETYPE_DIR = 1,
+    GRUB_HFS_FILETYPE_FILE = 2
+  };
+
+/* Catalog node ID (CNID).  */
+enum grub_hfs_cnid_type
+  {
+    GRUB_HFS_CNID_ROOT_PARENT = 1,
+    GRUB_HFS_CNID_ROOT = 2,
+    GRUB_HFS_CNID_EXT = 3,
+    GRUB_HFS_CNID_CAT = 4,
+    GRUB_HFS_CNID_BAD = 5
+  };
+
+/* A node descriptor.  This is the header of every node.  */
+struct grub_hfs_node
+{
+  grub_uint32_t next;
+  grub_uint32_t prev;
+  grub_uint8_t type;
+  grub_uint8_t level;
+  grub_uint16_t reccnt;
+  grub_uint16_t unused;
+} __attribute__ ((packed));
+
+/* The head of the B*-Tree.  */
+struct grub_hfs_treeheader
+{
+  grub_uint16_t tree_depth;
+  /* The number of the first node.  */
+  grub_uint32_t root_node;
+  grub_uint32_t leaves;
+  grub_uint32_t first_leaf;
+  grub_uint32_t last_leaf;
+  grub_uint16_t node_size;
+  grub_uint16_t key_size;
+  grub_uint32_t nodes;
+  grub_uint32_t free_nodes;
+  grub_uint8_t unused[76];
+} __attribute__ ((packed));
+
+/* The state of a mounted HFS filesystem.  */
+struct grub_hfs_data
+{
+  struct grub_hfs_sblock sblock;
+  grub_disk_t disk;
+  grub_hfs_datarecord_t extents;
+  int fileid;
+  int size;
+  int ext_root;
+  int ext_size;
+  int cat_root;
+  int cat_size;
+  int blksz;
+  int log2_blksz;
+  int rootdir;
+};
+
+/* The key as used on disk in a catalog tree.  This is used to lookup
+   file/directory nodes by parent directory ID and filename.  */
+struct grub_hfs_catalog_key
+{
+  grub_uint8_t unused;
+  grub_uint32_t parent_dir;
+
+  /* Filename length.  */
+  grub_uint8_t strlen;
+
+  /* Filename.  */
+  grub_uint8_t str[31];
+} __attribute__ ((packed));
+
+/* The key as used on disk in a extent overflow tree.  Using this key
+   the extents can be looked up using a fileid and logical start block
+   as index.  */
+struct grub_hfs_extent_key
+{
+  /* The kind of fork.  This is used to store meta information like
+     icons, attributes, etc.  We will only use the datafork, which is
+     0.  */
+  grub_uint8_t forktype;
+  grub_uint32_t fileid;
+  grub_uint16_t first_block;
+} __attribute__ ((packed));
+
+/* A directory record.  This is used to find out the directory ID.  */
+struct grub_hfs_dirrec
+{
+  /* For a directory, type == 1.  */
+  grub_uint8_t type;
+  grub_uint8_t unused[5];
+  grub_uint32_t dirid;
+} __attribute__ ((packed));
+
+/* Information about a file.  */
+struct grub_hfs_filerec
+{
+  /* For a file, type == 2.  */
+  grub_uint8_t type;
+  grub_uint8_t unused[19];
+  grub_uint32_t fileid;
+  grub_uint8_t unused2[2];
+  grub_uint32_t size;
+  grub_uint8_t unused3[44];
+
+  /* The first 3 extents of the file.  The other extents can be found
+     in the extent overflow file.  */
+  grub_hfs_datarecord_t extents;
+} __attribute__ ((packed));
+
+/* A record descriptor, both key and data, used to pass to call back
+   functions.  */
+struct grub_hfs_record
+{
+  void *key;
+  int keylen;
+  void *data;
+  int datalen;
+};
+
+static grub_dl_t my_mod;
+
+static int grub_hfs_find_node (struct grub_hfs_data *, char *,
+			       grub_uint32_t, int, char *, int);
+
+/* Find block BLOCK of the file FILE in the mounted UFS filesystem
+   DATA.  The first 3 extents are described by DAT.  If cache is set,
+   using caching to improve non-random reads.  */
+static unsigned int
+grub_hfs_block (struct grub_hfs_data *data, grub_hfs_datarecord_t dat,
+		int file, int block, int cache)
+{
+  grub_hfs_datarecord_t dr;
+  int pos = 0;
+  struct grub_hfs_extent_key key;
+
+  int tree = 0;
+  static int cache_file = 0;
+  static int cache_pos = 0;
+  static grub_hfs_datarecord_t cache_dr;
+
+  grub_memcpy (dr, dat, sizeof (dr));
+
+  key.forktype = 0;
+  key.fileid = grub_cpu_to_be32 (file);
+
+  if (cache && cache_file == file  && block > cache_pos)
+    {
+      pos = cache_pos;
+      key.first_block = grub_cpu_to_be16 (pos);
+      grub_memcpy (dr, cache_dr, sizeof (cache_dr));
+    }
+
+  for (;;)
+    {
+      int i;
+
+      /* Try all 3 extents.  */
+      for (i = 0; i < 3; i++)
+	{
+	  /* Check if the block is stored in this extent.  */
+	  if (grub_be_to_cpu16 (dr[i].count) + pos > block)
+	    {
+	      int first = grub_be_to_cpu16 (dr[i].first_block);
+
+	      /* If the cache is enabled, store the current position
+		 in the tree.  */
+	      if (tree && cache)
+		{
+		  cache_file = file;
+		  cache_pos = pos;
+		  grub_memcpy (cache_dr, dr, sizeof (cache_dr));
+		}
+
+	      return (grub_be_to_cpu16 (data->sblock.first_block)
+		      + (first + block - pos) * GRUB_HFS_BLKS);
+	    }
+
+	  /* Try the next extent.  */
+	  pos += grub_be_to_cpu16 (dr[i].count);
+	}
+
+      /* Lookup the block in the extent overflow file.  */
+      key.first_block = grub_cpu_to_be16 (pos);
+      tree = 1;
+      grub_hfs_find_node (data, (char *) &key, data->ext_root,
+			  1, (char *) &dr, sizeof (dr));
+      if (grub_errno)
+	return 0;
+    }
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_hfs_read_file (struct grub_hfs_data *data,
+		    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+				       unsigned offset, unsigned length),
+		     int pos, grub_size_t len, char *buf)
+{
+  int i;
+  int blockcnt;
+
+  blockcnt = ((len + pos)
+	      + data->blksz - 1) / data->blksz;
+
+  for (i = pos / data->blksz; i < blockcnt; i++)
+    {
+      int blknr;
+      int blockoff = pos % data->blksz;
+      int blockend = data->blksz;
+
+      int skipfirst = 0;
+
+      blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1);
+      if (grub_errno)
+	return -1;
+
+      /* Last block.  */
+      if (i == blockcnt - 1)
+	{
+	  blockend = (len + pos) % data->blksz;
+
+	  /* The last portion is exactly EXT2_BLOCK_SIZE (data).  */
+	  if (! blockend)
+	    blockend = data->blksz;
+	}
+
+      /* First block.  */
+      if (i == pos / data->blksz)
+	{
+	  skipfirst = blockoff;
+	  blockend -= skipfirst;
+	}
+
+      /* If the block number is 0 this block is not stored on disk but
+	 is zero filled instead.  */
+      if (blknr)
+	{
+	  data->disk->read_hook = read_hook;
+	  grub_disk_read (data->disk, blknr, skipfirst,
+			  blockend, buf);
+	  data->disk->read_hook = 0;
+	  if (grub_errno)
+	    return -1;
+	}
+
+      buf += data->blksz - skipfirst;
+    }
+
+  return len;
+}
+
+
+/* Mount the filesystem on the disk DISK.  */
+static struct grub_hfs_data *
+grub_hfs_mount (grub_disk_t disk)
+{
+  struct grub_hfs_data *data;
+  struct grub_hfs_catalog_key key;
+  struct grub_hfs_dirrec dir;
+  int first_block;
+
+  struct
+  {
+    struct grub_hfs_node node;
+    struct grub_hfs_treeheader head;
+  } treehead;
+
+  data = grub_malloc (sizeof (struct grub_hfs_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  if (grub_disk_read (disk, GRUB_HFS_SBLOCK, 0,
+		      sizeof (struct grub_hfs_sblock), &data->sblock))
+    goto fail;
+
+  /* Check if this is a HFS filesystem.  */
+  if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not an HFS filesystem");
+      goto fail;
+    }
+
+  /* Check if this is an embedded HFS+ filesystem.  */
+  if (grub_be_to_cpu16 (data->sblock.embed_sig) == GRUB_HFS_EMBED_HFSPLUS_SIG)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "embedded HFS+ filesystem");
+      goto fail;
+    }
+
+  data->blksz = grub_be_to_cpu32 (data->sblock.blksz);
+  data->disk = disk;
+
+  /* Lookup the root node of the extent overflow tree.  */
+  first_block = ((grub_be_to_cpu16 (data->sblock.extent_recs[0].first_block)
+		  * GRUB_HFS_BLKS)
+		 + grub_be_to_cpu16 (data->sblock.first_block));
+
+  if (grub_disk_read (data->disk, first_block, 0,
+		      sizeof (treehead), &treehead))
+    goto fail;
+  data->ext_root = grub_be_to_cpu32 (treehead.head.root_node);
+  data->ext_size = grub_be_to_cpu16 (treehead.head.node_size);
+
+  /* Lookup the root node of the catalog tree.  */
+  first_block = ((grub_be_to_cpu16 (data->sblock.catalog_recs[0].first_block)
+		  * GRUB_HFS_BLKS)
+		 + grub_be_to_cpu16 (data->sblock.first_block));
+  if (grub_disk_read (data->disk, first_block, 0,
+		      sizeof (treehead), &treehead))
+    goto fail;
+  data->cat_root = grub_be_to_cpu32 (treehead.head.root_node);
+  data->cat_size = grub_be_to_cpu16 (treehead.head.node_size);
+
+  /* Lookup the root directory node in the catalog tree using the
+     volume name.  */
+  key.parent_dir = grub_cpu_to_be32 (1);
+  key.strlen = data->sblock.volname[0];
+  grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1));
+
+  if (grub_hfs_find_node (data, (char *) &key, data->cat_root,
+			  0, (char *) &dir, sizeof (dir)) == 0)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "can not find the hfs root directory");
+      goto fail;
+    }
+
+  if (grub_errno)
+    goto fail;
+
+  data->rootdir = grub_be_to_cpu32 (dir.dirid);
+
+  return data;
+ fail:
+  grub_free (data);
+
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not a hfs filesystem");
+
+  return 0;
+}
+
+/* Compare the K1 and K2 catalog file keys using HFS character ordering.  */
+static int
+grub_hfs_cmp_catkeys (struct grub_hfs_catalog_key *k1,
+		      struct grub_hfs_catalog_key *k2)
+{
+  /* Taken from hfsutils 3.2.6 and converted to a readable form */
+  static const unsigned char hfs_charorder[256] = {
+    [0x00] = 0,
+    [0x01] = 1,
+    [0x02] = 2,
+    [0x03] = 3,
+    [0x04] = 4,
+    [0x05] = 5,
+    [0x06] = 6,
+    [0x07] = 7,
+    [0x08] = 8,
+    [0x09] = 9,
+    [0x0A] = 10,
+    [0x0B] = 11,
+    [0x0C] = 12,
+    [0x0D] = 13,
+    [0x0E] = 14,
+    [0x0F] = 15,
+    [0x10] = 16,
+    [0x11] = 17,
+    [0x12] = 18,
+    [0x13] = 19,
+    [0x14] = 20,
+    [0x15] = 21,
+    [0x16] = 22,
+    [0x17] = 23,
+    [0x18] = 24,
+    [0x19] = 25,
+    [0x1A] = 26,
+    [0x1B] = 27,
+    [0x1C] = 28,
+    [0x1D] = 29,
+    [0x1E] = 30,
+    [0x1F] = 31,
+    [' '] = 32,		[0xCA] = 32,
+    ['!'] = 33,
+    ['"'] = 34,
+    [0xD2] = 35,
+    [0xD3] = 36,
+    [0xC7] = 37,
+    [0xC8] = 38,
+    ['#'] = 39,
+    ['$'] = 40,
+    ['%'] = 41,
+    ['&'] = 42,
+    ['\''] = 43,
+    [0xD4] = 44,
+    [0xD5] = 45,
+    ['('] = 46,
+    [')'] = 47,
+    ['*'] = 48,
+    ['+'] = 49,
+    [','] = 50,
+    ['-'] = 51,
+    ['.'] = 52,
+    ['/'] = 53,
+    ['0'] = 54,
+    ['1'] = 55,
+    ['2'] = 56,
+    ['3'] = 57,
+    ['4'] = 58,
+    ['5'] = 59,
+    ['6'] = 60,
+    ['7'] = 61,
+    ['8'] = 62,
+    ['9'] = 63,
+    [':'] = 64,
+    [';'] = 65,
+    ['<'] = 66,
+    ['='] = 67,
+    ['>'] = 68,
+    ['?'] = 69,
+    ['@'] = 70,
+    ['A'] = 71,		['a'] = 71,
+    [0x88] = 72,	[0xCB] = 72,
+    [0x80] = 73,	[0x8A] = 73,
+    [0x8B] = 74,	[0xCC] = 74,
+    [0x81] = 75,	[0x8C] = 75,
+    [0xAE] = 76,	[0xBE] = 76,
+    ['`'] = 77,
+    [0x87] = 78,
+    [0x89] = 79,
+    [0xBB] = 80,
+    ['B'] = 81,		['b'] = 81,
+    ['C'] = 82,		['c'] = 82,
+    [0x82] = 83,	[0x8D] = 83,
+    ['D'] = 84,		['d'] = 84,
+    ['E'] = 85,		['e'] = 85,
+    [0x83] = 86,	[0x8E] = 86,
+    [0x8F] = 87,
+    [0x90] = 88,
+    [0x91] = 89,
+    ['F'] = 90,		['f'] = 90,
+    ['G'] = 91,		['g'] = 91,
+    ['H'] = 92,		['h'] = 92,
+    ['I'] = 93,		['i'] = 93,
+    [0x92] = 94,
+    [0x93] = 95,
+    [0x94] = 96,
+    [0x95] = 97,
+    ['J'] = 98,		['j'] = 98,
+    ['K'] = 99,		['k'] = 99,
+    ['L'] = 100,	['l'] = 100,
+    ['M'] = 101,	['m'] = 101,
+    ['N'] = 102,	['n'] = 102,
+    [0x84] = 103,	[0x96] = 103,
+    ['O'] = 104,	['o'] = 104,
+    [0x85] = 105,	[0x9A] = 105,
+    [0x9B] = 106,	[0xCD] = 106,
+    [0xAF] = 107,	[0xBF] = 107,
+    [0xCE] = 108,	[0xCF] = 108,
+    [0x97] = 109,
+    [0x98] = 110,
+    [0x99] = 111,
+    [0xBC] = 112,
+    ['P'] = 113,	['p'] = 113,
+    ['Q'] = 114,	['q'] = 114,
+    ['R'] = 115,	['r'] = 115,
+    ['S'] = 116,	['s'] = 116,
+    [0xA7] = 117,
+    ['T'] = 118,	['t'] = 118,
+    ['U'] = 119,	['u'] = 119,
+    [0x86] = 120,	[0x9F] = 120,
+    [0x9C] = 121,
+    [0x9D] = 122,
+    [0x9E] = 123,
+    ['V'] = 124,	['v'] = 124,
+    ['W'] = 125,	['w'] = 125,
+    ['X'] = 126,	['x'] = 126,
+    ['Y'] = 127,	['y'] = 127,
+    [0xD8] = 128,
+    ['Z'] = 129,	['z'] = 129,
+    ['['] = 130,
+    ['\\'] = 131,
+    [']'] = 132,
+    ['^'] = 133,
+    ['_'] = 134,
+    ['{'] = 135,
+    ['|'] = 136,
+    ['}'] = 137,
+    ['~'] = 138,
+    [0x7F] = 139,
+    [0xA0] = 140,
+    [0xA1] = 141,
+    [0xA2] = 142,
+    [0xA3] = 143,
+    [0xA4] = 144,
+    [0xA5] = 145,
+    [0xA6] = 146,
+    [0xA8] = 147,
+    [0xA9] = 148,
+    [0xAA] = 149,
+    [0xAB] = 150,
+    [0xAC] = 151,
+    [0xAD] = 152,
+    [0xB0] = 153,
+    [0xB1] = 154,
+    [0xB2] = 155,
+    [0xB3] = 156,
+    [0xB4] = 157,
+    [0xB5] = 158,
+    [0xB6] = 159,
+    [0xB7] = 160,
+    [0xB8] = 161,
+    [0xB9] = 162,
+    [0xBA] = 163,
+    [0xBD] = 164,
+    [0xC0] = 165,
+    [0xC1] = 166,
+    [0xC2] = 167,
+    [0xC3] = 168,
+    [0xC4] = 169,
+    [0xC5] = 170,
+    [0xC6] = 171,
+    [0xC9] = 172,
+    [0xD0] = 173,
+    [0xD1] = 174,
+    [0xD6] = 175,
+    [0xD7] = 176,
+    [0xD9] = 177,
+    [0xDA] = 178,
+    [0xDB] = 179,
+    [0xDC] = 180,
+    [0xDD] = 181,
+    [0xDE] = 182,
+    [0xDF] = 183,
+    [0xE0] = 184,
+    [0xE1] = 185,
+    [0xE2] = 186,
+    [0xE3] = 187,
+    [0xE4] = 188,
+    [0xE5] = 189,
+    [0xE6] = 190,
+    [0xE7] = 191,
+    [0xE8] = 192,
+    [0xE9] = 193,
+    [0xEA] = 194,
+    [0xEB] = 195,
+    [0xEC] = 196,
+    [0xED] = 197,
+    [0xEE] = 198,
+    [0xEF] = 199,
+    [0xF0] = 200,
+    [0xF1] = 201,
+    [0xF2] = 202,
+    [0xF3] = 203,
+    [0xF4] = 204,
+    [0xF5] = 205,
+    [0xF6] = 206,
+    [0xF7] = 207,
+    [0xF8] = 208,
+    [0xF9] = 209,
+    [0xFA] = 210,
+    [0xFB] = 211,
+    [0xFC] = 212,
+    [0xFD] = 213,
+    [0xFE] = 214,
+    [0xFF] = 215,
+  };
+  int i;
+  int cmp;
+  int minlen = (k1->strlen < k2->strlen) ? k1->strlen : k2->strlen;
+
+  cmp = (grub_be_to_cpu32 (k1->parent_dir) - grub_be_to_cpu32 (k2->parent_dir));
+  if (cmp != 0)
+    return cmp;
+
+  for (i = 0; i < minlen; i++)
+    {
+      cmp = (hfs_charorder[k1->str[i]] - hfs_charorder[k2->str[i]]);
+      if (cmp != 0)
+	return cmp;
+    }
+
+  /* Shorter strings precede long ones.  */
+  return (k1->strlen - k2->strlen);
+}
+
+
+/* Compare the K1 and K2 extent overflow file keys.  */
+static int
+grub_hfs_cmp_extkeys (struct grub_hfs_extent_key *k1,
+		      struct grub_hfs_extent_key *k2)
+{
+  int cmp = k1->forktype - k2->forktype;
+  if (cmp == 0)
+    cmp = grub_be_to_cpu32 (k1->fileid) - grub_be_to_cpu32 (k2->fileid);
+  if (cmp == 0)
+    cmp = (grub_be_to_cpu16 (k1->first_block)
+	   - grub_be_to_cpu16 (k2->first_block));
+  return cmp;
+}
+
+
+/* Iterate the records in the node with index IDX in the mounted HFS
+   filesystem DATA.  This node holds data of the type TYPE (0 =
+   catalog node, 1 = extent overflow node).  If this is set, continue
+   iterating to the next node.  For every records, call NODE_HOOK.  */
+static grub_err_t
+grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx,
+			  int this, int (*node_hook) (struct grub_hfs_node *hnd,
+						      struct grub_hfs_record *))
+{
+  int nodesize = type == 0 ? data->cat_size : data->ext_size;
+
+  union
+  {
+    struct grub_hfs_node node;
+    char rawnode[nodesize];
+    grub_uint16_t offsets[nodesize / 2];
+  } node;
+
+  do
+    {
+      int i;
+      struct grub_hfs_extent *dat;
+      int blk;
+
+      dat = (struct grub_hfs_extent *) (type == 0
+					? (&data->sblock.catalog_recs)
+					: (&data->sblock.extent_recs));
+
+      /* Read the node into memory.  */
+      blk = grub_hfs_block (data, dat,
+                            (type == 0) ? GRUB_HFS_CNID_CAT : GRUB_HFS_CNID_EXT,
+			    idx / (data->blksz / nodesize), 0);
+      blk += (idx % (data->blksz / nodesize));
+      if (grub_errno)
+	return grub_errno;
+
+      if (grub_disk_read (data->disk, blk, 0,
+			  sizeof (node), &node))
+	return grub_errno;
+
+      /* Iterate over all records in this node.  */
+      for (i = 0; i < grub_be_to_cpu16 (node.node.reccnt); i++)
+	{
+	  int pos = (nodesize >> 1) - 1 - i;
+ 	  struct pointer
+	  {
+	    grub_uint8_t keylen;
+	    grub_uint8_t key;
+	  } __attribute__ ((packed)) *pnt;
+	  pnt = (struct pointer *) (grub_be_to_cpu16 (node.offsets[pos])
+				    + node.rawnode);
+
+	  struct grub_hfs_record rec =
+	    {
+	      &pnt->key,
+	      pnt->keylen,
+	      &pnt->key + pnt->keylen +(pnt->keylen + 1) % 2,
+	      nodesize - grub_be_to_cpu16 (node.offsets[pos])
+	      - pnt->keylen - 1
+	    };
+
+	  if (node_hook (&node.node, &rec))
+	    return 0;
+	}
+
+      idx = grub_be_to_cpu32 (node.node.next);
+    } while (idx && this);
+
+  return 0;
+}
+
+
+/* Lookup a record in the mounted filesystem DATA using the key KEY.
+   The index of the node on top of the tree is IDX.  The tree is of
+   the type TYPE (0 = catalog node, 1 = extent overflow node).  Return
+   the data in DATAR with a maximum length of DATALEN.  */
+static int
+grub_hfs_find_node (struct grub_hfs_data *data, char *key,
+		    grub_uint32_t idx, int type, char *datar, int datalen)
+{
+  int found = -1;
+  int isleaf = 0;
+  int done = 0;
+
+  auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *);
+
+  int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec)
+    {
+      int cmp = 1;
+
+      if (type == 0)
+	cmp = grub_hfs_cmp_catkeys (rec->key, (void *) key);
+      else
+	cmp = grub_hfs_cmp_extkeys (rec->key, (void *) key);
+
+      /* If the key is smaller or equal to the current node, mark the
+	 entry.  In case of a non-leaf mode it will be used to lookup
+	 the rest of the tree.  */
+      if (cmp <= 0)
+	{
+	  grub_uint32_t *node = (grub_uint32_t *) rec->data;
+	  found = grub_be_to_cpu32 (*node);
+	}
+      else /* The key can not be found in the tree. */
+	return 1;
+
+      /* Check if this node is a leaf node.  */
+      if (hnd->type == GRUB_HFS_NODE_LEAF)
+	{
+	  isleaf = 1;
+
+	  /* Found it!!!!  */
+	  if (cmp == 0)
+	    {
+              done = 1;
+
+	      grub_memcpy (datar, rec->data,
+			   rec->datalen < datalen ? rec->datalen : datalen);
+	      return 1;
+	    }
+	}
+
+      return 0;
+    }
+
+  do
+    {
+      found = -1;
+
+      if (grub_hfs_iterate_records (data, type, idx, 0, node_found))
+        return 0;
+
+      if (found == -1)
+        return 0;
+
+      idx = found;
+    } while (! isleaf);
+
+  return done;
+}
+
+
+/* Iterate over the directory with the id DIR.  The tree is searched
+   starting with the node ROOT_IDX.  For every entry in this directory
+   call HOOK.  */
+static grub_err_t
+grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx,
+		      unsigned int dir, int (*hook) (struct grub_hfs_record *))
+{
+  int found = -1;
+  int isleaf = 0;
+  int next = 0;
+
+  /* The lowest key possible with DIR as root directory.  */
+  struct grub_hfs_catalog_key key = {0, grub_cpu_to_be32 (dir), 0, ""};
+
+  auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *);
+  auto int it_dir (struct grub_hfs_node * __attribute ((unused)),
+		   struct grub_hfs_record *);
+
+
+  int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec)
+    {
+      struct grub_hfs_catalog_key *ckey = rec->key;
+
+      if (grub_hfs_cmp_catkeys (rec->key, (void *) &key) <= 0)
+	found = grub_be_to_cpu32 (*(grub_uint32_t *) rec->data);
+
+      if (hnd->type == 0xFF && ckey->strlen > 0)
+	{
+	  isleaf = 1;
+	  next = grub_be_to_cpu32 (hnd->next);
+
+	  /* An entry was found.  */
+	  if (grub_be_to_cpu32 (ckey->parent_dir) == dir)
+	    return hook (rec);
+	}
+
+      return 0;
+    }
+
+  int it_dir (struct grub_hfs_node *hnd __attribute ((unused)),
+	      struct grub_hfs_record *rec)
+    {
+      struct grub_hfs_catalog_key *ckey = rec->key;
+      struct grub_hfs_catalog_key *origkey = &key;
+
+      /* Stop when the entries do not match anymore.  */
+      if (grub_be_to_cpu32 (ckey->parent_dir)
+	  != grub_be_to_cpu32 ((origkey)->parent_dir))
+	return 1;
+
+      return hook (rec);
+    }
+
+  do
+    {
+      found = -1;
+
+      if (grub_hfs_iterate_records (data, 0, root_idx, 0, node_found))
+        return grub_errno;
+
+      if (found == -1)
+        return 0;
+
+      root_idx = found;
+    } while (! isleaf);
+
+  /* If there was a matching record in this leaf node, continue the
+     iteration until the last record was found.  */
+  grub_hfs_iterate_records (data, 0, next, 1, it_dir);
+  return grub_errno;
+}
+
+
+/* Find a file or directory with the pathname PATH in the filesystem
+   DATA.  Return the file record in RETDATA when it is non-zero.
+   Return the directory number in RETINODE when it is non-zero.  */
+static grub_err_t
+grub_hfs_find_dir (struct grub_hfs_data *data, const char *path,
+		   struct grub_hfs_filerec *retdata, int *retinode)
+{
+  int inode = data->rootdir;
+  char *next;
+  char *origpath;
+  union {
+    struct grub_hfs_filerec frec;
+    struct grub_hfs_dirrec dir;
+  } fdrec;
+
+  fdrec.frec.type = GRUB_HFS_FILETYPE_DIR;
+
+  if (path[0] != '/')
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
+      return 0;
+    }
+
+  origpath = grub_strdup (path);
+  if (!origpath)
+    return grub_errno;
+
+  path = origpath;
+  while (*path == '/')
+    path++;
+
+  while (path && grub_strlen (path))
+    {
+      if (fdrec.frec.type != GRUB_HFS_FILETYPE_DIR)
+	{
+	  grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+	  goto fail;
+	}
+
+      /* Isolate a part of the path.  */
+      next = grub_strchr (path, '/');
+      if (next)
+	{
+	  while (*next == '/')
+	    *(next++) = '\0';
+	}
+
+      struct grub_hfs_catalog_key key;
+
+      key.parent_dir = grub_cpu_to_be32 (inode);
+      key.strlen = grub_strlen (path);
+      grub_strcpy ((char *) (key.str), path);
+
+      /* Lookup this node.  */
+      if (! grub_hfs_find_node (data, (char *) &key, data->cat_root,
+				0, (char *) &fdrec.frec, sizeof (fdrec.frec)))
+	{
+	  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+	  goto fail;
+	}
+
+      if (grub_errno)
+	goto fail;
+
+      inode = grub_be_to_cpu32 (fdrec.dir.dirid);
+      path = next;
+    }
+
+  if (retdata)
+    grub_memcpy (retdata, &fdrec.frec, sizeof (fdrec.frec));
+
+  if (retinode)
+    *retinode = inode;
+
+ fail:
+  grub_free (origpath);
+  return grub_errno;
+}
+
+
+
+static grub_err_t
+grub_hfs_dir (grub_device_t device, const char *path,
+		  int (*hook) (const char *filename,
+			       const struct grub_dirhook_info *info))
+{
+  int inode;
+
+  auto int dir_hook (struct grub_hfs_record *rec);
+
+  int dir_hook (struct grub_hfs_record *rec)
+    {
+      char fname[32] = { 0 };
+      char *filetype = rec->data;
+      struct grub_hfs_catalog_key *ckey = rec->key;
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+
+      grub_strncpy (fname, (char *) (ckey->str), ckey->strlen);
+
+      if (*filetype == GRUB_HFS_FILETYPE_DIR
+	  || *filetype == GRUB_HFS_FILETYPE_FILE)
+	{
+	  info.dir = (*filetype == GRUB_HFS_FILETYPE_DIR);
+	  return hook (fname, &info);
+	}
+      return 0;
+    }
+
+  struct grub_hfs_data *data;
+  struct grub_hfs_filerec frec;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfs_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  /* First the directory ID for the directory.  */
+  if (grub_hfs_find_dir (data, path, &frec, &inode))
+    goto fail;
+
+  if (frec.type != GRUB_HFS_FILETYPE_DIR)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      goto fail;
+    }
+
+  grub_hfs_iterate_dir (data, data->cat_root, inode, dir_hook);
+
+ fail:
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_hfs_open (struct grub_file *file, const char *name)
+{
+  struct grub_hfs_data *data;
+  struct grub_hfs_filerec frec;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfs_mount (file->device->disk);
+
+  if (grub_hfs_find_dir (data, name, &frec, 0))
+    {
+      grub_free (data);
+      grub_dl_unref (my_mod);
+      return grub_errno;
+    }
+
+  if (frec.type != GRUB_HFS_FILETYPE_FILE)
+    {
+      grub_free (data);
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a file");
+      grub_dl_unref (my_mod);
+      return grub_errno;
+    }
+
+  grub_memcpy (data->extents, frec.extents, sizeof (grub_hfs_datarecord_t));
+  file->size = grub_be_to_cpu32 (frec.size);
+  data->size = grub_be_to_cpu32 (frec.size);
+  data->fileid = grub_be_to_cpu32 (frec.fileid);
+  file->offset = 0;
+
+  file->data = data;
+
+  return 0;
+}
+
+static grub_ssize_t
+grub_hfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_hfs_data *data =
+    (struct grub_hfs_data *) file->data;
+
+  return grub_hfs_read_file (data, file->read_hook, file->offset, len, buf);
+}
+
+
+static grub_err_t
+grub_hfs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return 0;
+}
+
+
+static grub_err_t
+grub_hfs_label (grub_device_t device, char **label)
+{
+  struct grub_hfs_data *data;
+
+  data = grub_hfs_mount (device->disk);
+
+  if (data)
+    *label = grub_strndup ((char *) (data->sblock.volname + 1),
+			   *data->sblock.volname);
+  else
+    *label = 0;
+
+  grub_free (data);
+  return grub_errno;
+}
+
+
+
+static struct grub_fs grub_hfs_fs =
+  {
+    .name = "hfs",
+    .dir = grub_hfs_dir,
+    .open = grub_hfs_open,
+    .read = grub_hfs_read,
+    .close = grub_hfs_close,
+    .label = grub_hfs_label,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(hfs)
+{
+  grub_fs_register (&grub_hfs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(hfs)
+{
+  grub_fs_unregister (&grub_hfs_fs);
+}
diff --git a/fs/hfsplus.c b/fs/hfsplus.c
new file mode 100644
index 0000000..b306e8d
--- /dev/null
+++ b/fs/hfsplus.c
@@ -0,0 +1,1039 @@
+/* hfsplus.c - HFS+ Filesystem.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* HFS+ is documented at http://developer.apple.com/technotes/tn/tn1150.html */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+#include <grub/hfs.h>
+
+#define GRUB_HFSPLUS_MAGIC 0x482B
+#define GRUB_HFSPLUSX_MAGIC 0x4858
+#define GRUB_HFSPLUS_SBLOCK 2
+
+/* A HFS+ extent.  */
+struct grub_hfsplus_extent
+{
+  /* The first block of a file on disk.  */
+  grub_uint32_t start;
+  /* The amount of blocks described by this extent.  */
+  grub_uint32_t count;
+} __attribute__ ((packed));
+
+/* The descriptor of a fork.  */
+struct grub_hfsplus_forkdata
+{
+  grub_uint64_t size;
+  grub_uint32_t clumpsize;
+  grub_uint32_t blocks;
+  struct grub_hfsplus_extent extents[8];
+} __attribute__ ((packed));
+
+/* The HFS+ Volume Header.  */
+struct grub_hfsplus_volheader
+{
+  grub_uint16_t magic;
+  grub_uint16_t version;
+  grub_uint32_t attributes;
+  grub_uint8_t unused1[12];
+  grub_uint32_t utime;
+  grub_uint8_t unused2[16];
+  grub_uint32_t blksize;
+  grub_uint8_t unused3[60];
+  grub_uint64_t num_serial;
+  struct grub_hfsplus_forkdata allocations_file;
+  struct grub_hfsplus_forkdata extents_file;
+  struct grub_hfsplus_forkdata catalog_file;
+  struct grub_hfsplus_forkdata attrib_file;
+  struct grub_hfsplus_forkdata startup_file;
+} __attribute__ ((packed));
+
+/* The type of node.  */
+enum grub_hfsplus_btnode_type
+  {
+    GRUB_HFSPLUS_BTNODE_TYPE_LEAF = -1,
+    GRUB_HFSPLUS_BTNODE_TYPE_INDEX = 0,
+    GRUB_HFSPLUS_BTNODE_TYPE_HEADER = 1,
+    GRUB_HFSPLUS_BTNODE_TYPE_MAP = 2,
+  };
+
+struct grub_hfsplus_btnode
+{
+  grub_uint32_t next;
+  grub_uint32_t prev;
+  grub_int8_t type;
+  grub_uint8_t height;
+  grub_uint16_t count;
+  grub_uint16_t unused;
+} __attribute__ ((packed));
+
+/* The header of a HFS+ B+ Tree.  */
+struct grub_hfsplus_btheader
+{
+  grub_uint16_t depth;
+  grub_uint32_t root;
+  grub_uint32_t leaf_records;
+  grub_uint32_t first_leaf_node;
+  grub_uint32_t last_leaf_node;
+  grub_uint16_t nodesize;
+  grub_uint16_t keysize;
+  grub_uint32_t total_nodes;
+  grub_uint32_t free_nodes;
+  grub_uint16_t reserved1;
+  grub_uint32_t clump_size;  /* ignored */
+  grub_uint8_t btree_type;
+  grub_uint8_t key_compare;
+  grub_uint32_t attributes;
+} __attribute__ ((packed));
+
+/* The on disk layout of a catalog key.  */
+struct grub_hfsplus_catkey
+{
+  grub_uint16_t keylen;
+  grub_uint32_t parent;
+  grub_uint16_t namelen;
+  grub_uint16_t name[30];
+} __attribute__ ((packed));
+
+/* The on disk layout of an extent overflow file key.  */
+struct grub_hfsplus_extkey
+{
+  grub_uint16_t keylen;
+  grub_uint8_t type;
+  grub_uint8_t unused;
+  grub_uint32_t fileid;
+  grub_uint32_t start;
+} __attribute__ ((packed));
+
+struct grub_hfsplus_key
+{
+  union
+  {
+    struct grub_hfsplus_extkey extkey;
+    struct grub_hfsplus_catkey catkey;
+    grub_uint16_t keylen;
+  };
+} __attribute__ ((packed));
+
+struct grub_hfsplus_catfile
+{
+  grub_uint16_t type;
+  grub_uint16_t flags;
+  grub_uint32_t reserved;
+  grub_uint32_t fileid;
+  grub_uint8_t unused1[4];
+  grub_uint32_t mtime;
+  grub_uint8_t unused2[22];
+  grub_uint16_t mode;
+  grub_uint8_t unused3[44];
+  struct grub_hfsplus_forkdata data;
+  struct grub_hfsplus_forkdata resource;
+} __attribute__ ((packed));
+
+/* Filetype information as used in inodes.  */
+#define GRUB_HFSPLUS_FILEMODE_MASK	0170000
+#define GRUB_HFSPLUS_FILEMODE_REG	0100000
+#define GRUB_HFSPLUS_FILEMODE_DIRECTORY	0040000
+#define GRUB_HFSPLUS_FILEMODE_SYMLINK	0120000
+
+/* Some pre-defined file IDs.  */
+#define GRUB_HFSPLUS_FILEID_ROOTDIR	2
+#define GRUB_HFSPLUS_FILEID_OVERFLOW	3
+#define GRUB_HFSPLUS_FILEID_CATALOG	4
+
+enum grub_hfsplus_filetype
+  {
+    GRUB_HFSPLUS_FILETYPE_DIR = 1,
+    GRUB_HFSPLUS_FILETYPE_REG = 2,
+    GRUB_HFSPLUS_FILETYPE_DIR_THREAD = 3,
+    GRUB_HFSPLUS_FILETYPE_REG_THREAD = 4
+  };
+
+#define GRUB_HFSPLUSX_BINARYCOMPARE	0xBC
+#define GRUB_HFSPLUSX_CASEFOLDING	0xCF
+
+/* Internal representation of a catalog key.  */
+struct grub_hfsplus_catkey_internal
+{
+  int parent;
+  char *name;
+};
+
+/* Internal representation of an extent overflow key.  */
+struct grub_hfsplus_extkey_internal
+{
+  grub_uint32_t fileid;
+  grub_uint32_t start;
+};
+
+struct grub_hfsplus_key_internal
+{
+  union
+  {
+    struct grub_hfsplus_extkey_internal extkey;
+    struct grub_hfsplus_catkey_internal catkey;
+  };
+};
+
+
+
+struct grub_fshelp_node
+{
+  struct grub_hfsplus_data *data;
+  struct grub_hfsplus_extent extents[8];
+  grub_uint64_t size;
+  grub_uint32_t fileid;
+  grub_int32_t mtime;
+};
+
+struct grub_hfsplus_btree
+{
+  grub_uint32_t root;
+  int nodesize;
+
+  /* Catalog file node.  */
+  struct grub_fshelp_node file;
+};
+
+/* Information about a "mounted" HFS+ filesystem.  */
+struct grub_hfsplus_data
+{
+  struct grub_hfsplus_volheader volheader;
+  grub_disk_t disk;
+
+  unsigned int log2blksize;
+
+  struct grub_hfsplus_btree catalog_tree;
+  struct grub_hfsplus_btree extoverflow_tree;
+
+  struct grub_fshelp_node dirroot;
+  struct grub_fshelp_node opened_file;
+
+  /* This is the offset into the physical disk for an embedded HFS+
+     filesystem (one inside a plain HFS wrapper).  */
+  int embedded_offset;
+  int case_sensitive;
+};
+
+static grub_dl_t my_mod;
+
+
+/* Return the offset of the record with the index INDEX, in the node
+   NODE which is part of the B+ tree BTREE.  */
+static inline unsigned int
+grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree,
+			   struct grub_hfsplus_btnode *node, int index)
+{
+  char *cnode = (char *) node;
+  grub_uint16_t *recptr;
+  recptr = (grub_uint16_t *) (&cnode[btree->nodesize
+				     - index * sizeof (grub_uint16_t) - 2]);
+  return grub_be_to_cpu16 (*recptr);
+}
+
+/* Return a pointer to the record with the index INDEX, in the node
+   NODE which is part of the B+ tree BTREE.  */
+static inline struct grub_hfsplus_key *
+grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree,
+			   struct grub_hfsplus_btnode *node, int index)
+{
+  char *cnode = (char *) node;
+  unsigned int offset;
+  offset = grub_hfsplus_btree_recoffset (btree, node, index);
+  return (struct grub_hfsplus_key *) &cnode[offset];
+}
+
+
+/* Find the extent that points to FILEBLOCK.  If it is not in one of
+   the 8 extents described by EXTENT, return -1.  In that case set
+   FILEBLOCK to the next block.  */
+static int
+grub_hfsplus_find_block (struct grub_hfsplus_extent *extent,
+			 int *fileblock)
+{
+  int i;
+  grub_size_t blksleft = *fileblock;
+
+  /* First lookup the file in the given extents.  */
+  for (i = 0; i < 8; i++)
+    {
+      if (blksleft < grub_be_to_cpu32 (extent[i].count))
+	return grub_be_to_cpu32 (extent[i].start) + blksleft;
+      blksleft -= grub_be_to_cpu32 (extent[i].count);
+    }
+
+  *fileblock = blksleft;
+  return -1;
+}
+
+static grub_err_t
+grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
+			   struct grub_hfsplus_key_internal *key,
+			   int (*compare_keys) (struct grub_hfsplus_key *keya,
+						struct grub_hfsplus_key_internal *keyb),
+			   struct grub_hfsplus_btnode **matchnode, int *keyoffset);
+
+static int grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
+				    struct grub_hfsplus_key_internal *keyb);
+
+/* Search for the block FILEBLOCK inside the file NODE.  Return the
+   blocknumber of this block on disk.  */
+static grub_disk_addr_t
+grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  struct grub_hfsplus_btnode *nnode = 0;
+  int blksleft = fileblock;
+  struct grub_hfsplus_extent *extents = &node->extents[0];
+
+  while (1)
+    {
+      struct grub_hfsplus_extkey *key;
+      struct grub_hfsplus_extkey_internal extoverflow;
+      int blk;
+      int ptr;
+
+      /* Try to find this block in the current set of extents.  */
+      blk = grub_hfsplus_find_block (extents, &blksleft);
+
+      /* The previous iteration of this loop allocated memory.  The
+	 code above used this memory, it can be freed now.  */
+      grub_free (nnode);
+      nnode = 0;
+
+      if (blk != -1)
+	return (blk
+		+ (node->data->embedded_offset >> (node->data->log2blksize
+						   - GRUB_DISK_SECTOR_BITS)));
+
+      /* For the extent overflow file, extra extents can't be found in
+	 the extent overflow file.  If this happens, you found a
+	 bug...  */
+      if (node->fileid == GRUB_HFSPLUS_FILEID_OVERFLOW)
+	{
+	  grub_error (GRUB_ERR_READ_ERROR,
+		      "extra extents found in an extend overflow file");
+	  break;
+	}
+
+      /* Set up the key to look for in the extent overflow file.  */
+      extoverflow.fileid = node->fileid;
+      extoverflow.start = fileblock - blksleft;
+
+      if (grub_hfsplus_btree_search (&node->data->extoverflow_tree,
+				     (struct grub_hfsplus_key_internal *) &extoverflow,
+				     grub_hfsplus_cmp_extkey, &nnode, &ptr))
+	{
+	  grub_error (GRUB_ERR_READ_ERROR,
+		      "no block found for the file id 0x%x and the block offset 0x%x",
+		      node->fileid, fileblock);
+	  break;
+	}
+
+      /* The extent overflow file has 8 extents right after the key.  */
+      key = (struct grub_hfsplus_extkey *)
+	grub_hfsplus_btree_recptr (&node->data->extoverflow_tree, nnode, ptr);
+      extents = (struct grub_hfsplus_extent *) (key + 1);
+
+      /* The block wasn't found.  Perhaps the next iteration will find
+	 it.  The last block we found is stored in BLKSLEFT now.  */
+    }
+
+  grub_free (nnode);
+
+  /* Too bad, you lose.  */
+  return -1;
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_hfsplus_read_file (grub_fshelp_node_t node,
+			void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+					   unsigned offset, unsigned length),
+			int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+				pos, len, buf, grub_hfsplus_read_block,
+				node->size,
+				node->data->log2blksize - GRUB_DISK_SECTOR_BITS);
+}
+
+static struct grub_hfsplus_data *
+grub_hfsplus_mount (grub_disk_t disk)
+{
+  struct grub_hfsplus_data *data;
+  struct grub_hfsplus_btheader header;
+  struct grub_hfsplus_btnode node;
+  grub_uint16_t magic;
+  union {
+    struct grub_hfs_sblock hfs;
+    struct grub_hfsplus_volheader hfsplus;
+  } volheader;
+
+  data = grub_malloc (sizeof (*data));
+  if (!data)
+    return 0;
+
+  data->disk = disk;
+
+  /* Read the bootblock.  */
+  grub_disk_read (disk, GRUB_HFSPLUS_SBLOCK, 0, sizeof (volheader),
+		  &volheader);
+  if (grub_errno)
+    goto fail;
+
+  data->embedded_offset = 0;
+  if (grub_be_to_cpu16 (volheader.hfs.magic) == GRUB_HFS_MAGIC)
+    {
+      int extent_start;
+      int ablk_size;
+      int ablk_start;
+
+      /* See if there's an embedded HFS+ filesystem.  */
+      if (grub_be_to_cpu16 (volheader.hfs.embed_sig) != GRUB_HFSPLUS_MAGIC)
+	{
+	  grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
+	  goto fail;
+	}
+
+      /* Calculate the offset needed to translate HFS+ sector numbers.  */
+      extent_start = grub_be_to_cpu16 (volheader.hfs.embed_extent.first_block);
+      ablk_size = grub_be_to_cpu32 (volheader.hfs.blksz);
+      ablk_start = grub_be_to_cpu16 (volheader.hfs.first_block);
+      data->embedded_offset = (ablk_start
+			       + extent_start
+			       * (ablk_size >> GRUB_DISK_SECTOR_BITS));
+
+      grub_disk_read (disk, data->embedded_offset + GRUB_HFSPLUS_SBLOCK, 0,
+		      sizeof (volheader), &volheader);
+      if (grub_errno)
+	goto fail;
+    }
+
+  /* Make sure this is an HFS+ filesystem.  XXX: Do we really support
+     HFX?  */
+  magic = grub_be_to_cpu16 (volheader.hfsplus.magic);
+  if ((magic != GRUB_HFSPLUS_MAGIC) && (magic != GRUB_HFSPLUSX_MAGIC))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
+      goto fail;
+    }
+
+  grub_memcpy (&data->volheader, &volheader.hfsplus,
+      sizeof (volheader.hfsplus));
+
+  if (grub_fshelp_log2blksize (grub_be_to_cpu32 (data->volheader.blksize),
+			       &data->log2blksize))
+    goto fail;
+
+  /* Make a new node for the catalog tree.  */
+  data->catalog_tree.file.data = data;
+  data->catalog_tree.file.fileid = GRUB_HFSPLUS_FILEID_CATALOG;
+  grub_memcpy (&data->catalog_tree.file.extents,
+	       data->volheader.catalog_file.extents,
+	       sizeof data->volheader.catalog_file.extents);
+  data->catalog_tree.file.size =
+    grub_be_to_cpu64 (data->volheader.catalog_file.size);
+
+  /* Make a new node for the extent overflow file.  */
+  data->extoverflow_tree.file.data = data;
+  data->extoverflow_tree.file.fileid = GRUB_HFSPLUS_FILEID_OVERFLOW;
+  grub_memcpy (&data->extoverflow_tree.file.extents,
+	       data->volheader.extents_file.extents,
+	       sizeof data->volheader.catalog_file.extents);
+
+  data->extoverflow_tree.file.size =
+    grub_be_to_cpu64 (data->volheader.extents_file.size);
+
+  /* Read the essential information about the trees.  */
+  if (grub_hfsplus_read_file (&data->catalog_tree.file, 0,
+			      sizeof (struct grub_hfsplus_btnode),
+			      sizeof (header), (char *) &header) <= 0)
+    goto fail;
+
+  data->catalog_tree.root = grub_be_to_cpu32 (header.root);
+  data->catalog_tree.nodesize = grub_be_to_cpu16 (header.nodesize);
+  data->case_sensitive = ((magic == GRUB_HFSPLUSX_MAGIC) &&
+			  (header.key_compare == GRUB_HFSPLUSX_BINARYCOMPARE));
+
+  if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0,
+			      sizeof (struct grub_hfsplus_btnode),
+			      sizeof (header), (char *) &header) <= 0)
+    goto fail;
+
+  data->extoverflow_tree.root = grub_be_to_cpu32 (header.root);
+
+  if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0,
+			      sizeof (node), (char *) &node) <= 0)
+    goto fail;
+
+  data->extoverflow_tree.root = grub_be_to_cpu32 (header.root);
+  data->extoverflow_tree.nodesize = grub_be_to_cpu16 (header.nodesize);
+
+  data->dirroot.data = data;
+  data->dirroot.fileid = GRUB_HFSPLUS_FILEID_ROOTDIR;
+
+  return data;
+
+ fail:
+
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not a hfsplus filesystem");
+
+  grub_free (data);
+  return 0;
+}
+
+/* Compare the on disk catalog key KEYA with the catalog key we are
+   looking for (KEYB).  */
+static int
+grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya,
+			 struct grub_hfsplus_key_internal *keyb)
+{
+  struct grub_hfsplus_catkey *catkey_a = &keya->catkey;
+  struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey;
+  char *filename;
+  int i;
+  int diff;
+
+  diff = grub_be_to_cpu32 (catkey_a->parent) - catkey_b->parent;
+  if (diff)
+    return diff;
+
+  /* Change the filename in keya so the endianness is correct.  */
+  for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++)
+    catkey_a->name[i] = grub_be_to_cpu16 (catkey_a->name[i]);
+
+  filename = grub_malloc (grub_be_to_cpu16 (catkey_a->namelen) + 1);
+
+  if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey_a->name,
+			    grub_be_to_cpu16 (catkey_a->namelen)))
+    return -1; /* XXX: This error never occurs, but in case it happens
+		  just skip this entry.  */
+
+  diff = grub_strncmp (filename, catkey_b->name,
+		       grub_be_to_cpu16 (catkey_a->namelen));
+
+  grub_free (filename);
+
+  /* The endianness was changed to host format, change it back to
+     whatever it was.  */
+  for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++)
+    catkey_a->name[i] = grub_cpu_to_be16 (catkey_a->name[i]);
+  return diff;
+}
+
+/* Compare the on disk extent overflow key KEYA with the extent
+   overflow key we are looking for (KEYB).  */
+static int
+grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
+			 struct grub_hfsplus_key_internal *keyb)
+{
+  struct grub_hfsplus_extkey *extkey_a = &keya->extkey;
+  struct grub_hfsplus_extkey_internal *extkey_b = &keyb->extkey;
+  int diff;
+
+  diff = grub_be_to_cpu32 (extkey_a->fileid) - extkey_b->fileid;
+
+  if (diff)
+    return diff;
+
+  diff = grub_be_to_cpu32 (extkey_a->start) - extkey_b->start;
+  return diff;
+}
+
+static char *
+grub_hfsplus_read_symlink (grub_fshelp_node_t node)
+{
+  char *symlink;
+  grub_ssize_t numread;
+
+  symlink = grub_malloc (node->size + 1);
+  if (!symlink)
+    return 0;
+
+  numread = grub_hfsplus_read_file (node, 0, 0, node->size, symlink);
+  if (numread != (grub_ssize_t) node->size)
+    {
+      grub_free (symlink);
+      return 0;
+    }
+  symlink[node->size] = '\0';
+
+  return symlink;
+}
+
+static int
+grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree,
+				 struct grub_hfsplus_btnode *first_node,
+				 int first_rec,
+				 int (*hook) (void *record))
+{
+  int rec;
+
+  for (;;)
+    {
+      char *cnode = (char *) first_node;
+
+      /* Iterate over all records in this node.  */
+      for (rec = first_rec; rec < grub_be_to_cpu16 (first_node->count); rec++)
+	{
+	  if (hook (grub_hfsplus_btree_recptr (btree, first_node, rec)))
+	    return 1;
+	}
+
+      if (! first_node->next)
+	break;
+
+      if (grub_hfsplus_read_file (&btree->file, 0,
+				  (grub_be_to_cpu32 (first_node->next)
+				   * btree->nodesize),
+				  btree->nodesize, cnode) <= 0)
+	return 1;
+
+      /* Don't skip any record in the next iteration.  */
+      first_rec = 0;
+    }
+
+  return 0;
+}
+
+/* Lookup the node described by KEY in the B+ Tree BTREE.  Compare
+   keys using the function COMPARE_KEYS.  When a match is found,
+   return the node in MATCHNODE and a pointer to the data in this node
+   in KEYOFFSET.  MATCHNODE should be freed by the caller.  */
+static grub_err_t
+grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
+			   struct grub_hfsplus_key_internal *key,
+			   int (*compare_keys) (struct grub_hfsplus_key *keya,
+						struct grub_hfsplus_key_internal *keyb),
+			   struct grub_hfsplus_btnode **matchnode, int *keyoffset)
+{
+  grub_uint64_t currnode;
+  char *node;
+  struct grub_hfsplus_btnode *nodedesc;
+  int rec;
+
+  node = grub_malloc (btree->nodesize);
+  if (! node)
+    return grub_errno;
+
+  currnode = btree->root;
+  while (1)
+    {
+      int match = 0;
+
+      /* Read a node.  */
+      if (grub_hfsplus_read_file (&btree->file, 0,
+				  (long)currnode * (long)btree->nodesize,
+				  btree->nodesize, (char *) node) <= 0)
+	{
+	  grub_free (node);
+	  return grub_error (GRUB_ERR_BAD_FS, "Couldn't read i-node.");
+	}
+
+      nodedesc = (struct grub_hfsplus_btnode *) node;
+
+      /* Find the record in this tree.  */
+      for (rec = 0; rec < grub_be_to_cpu16 (nodedesc->count); rec++)
+	{
+	  struct grub_hfsplus_key *currkey;
+	  currkey = grub_hfsplus_btree_recptr (btree, nodedesc, rec);
+
+	  /* The action that has to be taken depend on the type of
+	     record.  */
+	  if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_LEAF
+	      && compare_keys (currkey, key) == 0)
+	    {
+	      /* An exact match was found!  */
+
+	      *matchnode = nodedesc;
+	      *keyoffset = rec;
+
+	      return 0;
+	    }
+	  else if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_INDEX)
+	    {
+	      grub_uint32_t *pointer;
+
+	      /* The place where the key could have been found didn't
+		 contain the key.  This means that the previous match
+		 is the one that should be followed.  */
+	      if (compare_keys (currkey, key) > 0)
+		break;
+
+	      /* Mark the last key which is lower or equal to the key
+		 that we are looking for.  The last match that is
+		 found will be used to locate the child which can
+		 contain the record.  */
+	      pointer = (grub_uint32_t *) ((char *) currkey
+					   + grub_be_to_cpu16 (currkey->keylen)
+					   + 2);
+	      currnode = grub_be_to_cpu32 (*pointer);
+	      match = 1;
+	    }
+	}
+
+      /* No match is found, no record with this key exists in the
+	 tree.  */
+      if (! match)
+	{
+	  *matchnode = 0;
+	  grub_free (node);
+	  return 1;
+	}
+    }
+}
+
+static int
+grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
+			  int NESTED_FUNC_ATTR
+			  (*hook) (const char *filename,
+				   enum grub_fshelp_filetype filetype,
+				   grub_fshelp_node_t node))
+{
+  int ret = 0;
+
+  auto int list_nodes (void *record);
+  int list_nodes (void *record)
+    {
+      struct grub_hfsplus_catkey *catkey;
+      char *filename;
+      int i;
+      struct grub_fshelp_node *node;
+      struct grub_hfsplus_catfile *fileinfo;
+      enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN;
+
+      catkey = (struct grub_hfsplus_catkey *) record;
+
+      fileinfo =
+	(struct grub_hfsplus_catfile *) ((char *) record
+					 + grub_be_to_cpu16 (catkey->keylen)
+					 + 2 + (grub_be_to_cpu16(catkey->keylen)
+						% 2));
+
+      /* Stop iterating when the last directory entry is found.  */
+      if (grub_be_to_cpu32 (catkey->parent) != dir->fileid)
+	return 1;
+
+      /* Determine the type of the node that is found.  */
+      if (grub_be_to_cpu16 (fileinfo->type) == GRUB_HFSPLUS_FILETYPE_REG)
+	{
+	  int mode = (grub_be_to_cpu16 (fileinfo->mode)
+		      & GRUB_HFSPLUS_FILEMODE_MASK);
+
+	  if (mode == GRUB_HFSPLUS_FILEMODE_REG)
+	    type = GRUB_FSHELP_REG;
+	  else if (mode == GRUB_HFSPLUS_FILEMODE_SYMLINK)
+	    type = GRUB_FSHELP_SYMLINK;
+	  else
+	    type = GRUB_FSHELP_UNKNOWN;
+	}
+      else if (grub_be_to_cpu16 (fileinfo->type) == GRUB_HFSPLUS_FILETYPE_DIR)
+	type = GRUB_FSHELP_DIR;
+
+      if (type == GRUB_FSHELP_UNKNOWN)
+	return 0;
+
+      /* Make sure the byte order of the UTF16 string is correct.  */
+      for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++)
+	{
+	  catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]);
+
+	  /* If the name is obviously invalid, skip this node.  */
+	  if (catkey->name[i] == 0)
+	    return 0;
+	}
+
+      filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) + 1);
+      if (! filename)
+	return 0;
+
+      if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name,
+				grub_be_to_cpu16 (catkey->namelen)))
+	{
+	  grub_free (filename);
+	  return 0;
+	}
+
+      filename[grub_be_to_cpu16 (catkey->namelen)] = '\0';
+
+      /* Restore the byte order to what it was previously.  */
+      for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++)
+	catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]);
+
+      /* hfs+ is case insensitive.  */
+      if (! dir->data->case_sensitive)
+	type |= GRUB_FSHELP_CASE_INSENSITIVE;
+
+      /* Only accept valid nodes.  */
+      if (grub_strlen (filename) == grub_be_to_cpu16 (catkey->namelen))
+	{
+	  /* A valid node is found; setup the node and call the
+	     callback function.  */
+	  node = grub_malloc (sizeof (*node));
+	  node->data = dir->data;
+
+	  grub_memcpy (node->extents, fileinfo->data.extents,
+		       sizeof (node->extents));
+	  node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800;
+	  node->size = grub_be_to_cpu64 (fileinfo->data.size);
+	  node->fileid = grub_be_to_cpu32 (fileinfo->fileid);
+
+	  ret = hook (filename, type, node);
+	}
+
+      grub_free (filename);
+
+      return ret;
+    }
+
+  struct grub_hfsplus_key_internal intern;
+  struct grub_hfsplus_btnode *node;
+  int ptr;
+
+  /* Create a key that points to the first entry in the directory.  */
+  intern.catkey.parent = dir->fileid;
+  intern.catkey.name = "";
+
+  /* First lookup the first entry.  */
+  if (grub_hfsplus_btree_search (&dir->data->catalog_tree, &intern,
+				 grub_hfsplus_cmp_catkey, &node, &ptr))
+    return 0;
+
+  /* Iterate over all entries in this directory.  */
+  grub_hfsplus_btree_iterate_node (&dir->data->catalog_tree, node, ptr,
+				   list_nodes);
+
+  grub_free (node);
+
+  return ret;
+}
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_hfsplus_open (struct grub_file *file, const char *name)
+{
+  struct grub_hfsplus_data *data;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfsplus_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->dirroot, &fdiro,
+			 grub_hfsplus_iterate_dir,
+			 grub_hfsplus_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  file->size = fdiro->size;
+  data->opened_file = *fdiro;
+  grub_free (fdiro);
+
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+ fail:
+  if (data && fdiro != &data->dirroot)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_hfsplus_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+
+/* Read LEN bytes data from FILE into BUF.  */
+static grub_ssize_t
+grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_hfsplus_data *data =
+    (struct grub_hfsplus_data *) file->data;
+
+  int size = grub_hfsplus_read_file (&data->opened_file, file->read_hook,
+				     file->offset, len, buf);
+
+  return size;
+}
+
+
+static grub_err_t
+grub_hfsplus_dir (grub_device_t device, const char *path,
+		  int (*hook) (const char *filename,
+			       const struct grub_dirhook_info *info))
+{
+  struct grub_hfsplus_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+				     enum grub_fshelp_filetype filetype,
+				     grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      info.mtimeset = 1;
+      info.mtime = node->mtime;
+      info.case_insensitive = !! (filetype & GRUB_FSHELP_CASE_INSENSITIVE);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfsplus_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  /* Find the directory that should be opened.  */
+  grub_fshelp_find_file (path, &data->dirroot, &fdiro,
+			 grub_hfsplus_iterate_dir,
+			 grub_hfsplus_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  /* Iterate over all entries in this directory.  */
+  grub_hfsplus_iterate_dir (fdiro, iterate);
+
+ fail:
+  if (data && fdiro != &data->dirroot)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_hfsplus_label (grub_device_t device __attribute__((unused))
+		    , char **label __attribute__((unused)))
+{
+  /* XXX: It's not documented how to read a label.  */
+  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+		     "reading the label of a HFS+ "
+		     "partition is not implemented");
+}
+
+/* Get mtime.  */
+static grub_err_t
+grub_hfsplus_mtime (grub_device_t device, grub_int32_t *tm)
+{
+  struct grub_hfsplus_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfsplus_mount (disk);
+  if (!data)
+    *tm = 0;
+  else
+    *tm = grub_be_to_cpu32 (data->volheader.utime) - 2082844800;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+
+}
+
+static grub_err_t
+grub_hfsplus_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_hfsplus_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfsplus_mount (disk);
+  if (data)
+    {
+      *uuid = grub_malloc (16 + sizeof ('\0'));
+      grub_sprintf (*uuid, "%016llx",
+		    (unsigned long long)
+		    grub_be_to_cpu64 (data->volheader.num_serial));
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+
+static struct grub_fs grub_hfsplus_fs =
+  {
+    .name = "hfsplus",
+    .dir = grub_hfsplus_dir,
+    .open = grub_hfsplus_open,
+    .read = grub_hfsplus_read,
+    .close = grub_hfsplus_close,
+    .label = grub_hfsplus_label,
+    .mtime = grub_hfsplus_mtime,
+    .uuid = grub_hfsplus_uuid,
+#ifdef GRUB_UTIL
+    .reserved_first_sector = 1,
+#endif
+    .next = 0
+  };
+
+GRUB_MOD_INIT(hfsplus)
+{
+  grub_fs_register (&grub_hfsplus_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(hfsplus)
+{
+  grub_fs_unregister (&grub_hfsplus_fs);
+}
diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c
new file mode 100644
index 0000000..4032e12
--- /dev/null
+++ b/fs/i386/pc/pxe.c
@@ -0,0 +1,324 @@
+/* pxe.c - Driver to provide access to the pxe filesystem  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/fs.h>
+#include <grub/mm.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/bufio.h>
+
+#include <grub/machine/pxe.h>
+#include <grub/machine/memory.h>
+
+#define SEGMENT(x)	((x) >> 4)
+#define OFFSET(x)	((x) & 0xF)
+#define SEGOFS(x)	((SEGMENT(x) << 16) + OFFSET(x))
+#define LINEAR(x)	(void *) (((x >> 16) <<4) + (x & 0xFFFF))
+
+struct grub_pxenv *grub_pxe_pxenv;
+grub_uint32_t grub_pxe_your_ip;
+grub_uint32_t grub_pxe_server_ip;
+grub_uint32_t grub_pxe_gateway_ip;
+int grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE;
+
+static grub_file_t curr_file = 0;
+
+struct grub_pxe_data
+{
+  grub_uint32_t packet_number;
+  grub_uint32_t block_size;
+  char filename[0];
+};
+
+static int
+grub_pxe_iterate (int (*hook) (const char *name))
+{
+  if (hook ("pxe"))
+    return 1;
+  return 0;
+}
+
+static grub_err_t
+grub_pxe_open (const char *name, grub_disk_t disk)
+{
+  if (grub_strcmp (name, "pxe"))
+      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk");
+
+  disk->total_sectors = 0;
+  disk->id = (unsigned long) "pxe";
+
+  disk->has_partitions = 0;
+  disk->data = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_pxe_close (grub_disk_t disk __attribute((unused)))
+{
+}
+
+static grub_err_t
+grub_pxe_read (grub_disk_t disk __attribute((unused)),
+               grub_disk_addr_t sector __attribute((unused)),
+               grub_size_t size __attribute((unused)),
+               char *buf __attribute((unused)))
+{
+  return GRUB_ERR_OUT_OF_RANGE;
+}
+
+static grub_err_t
+grub_pxe_write (grub_disk_t disk __attribute((unused)),
+                grub_disk_addr_t sector __attribute((unused)),
+                grub_size_t size __attribute((unused)),
+                const char *buf __attribute((unused)))
+{
+  return GRUB_ERR_OUT_OF_RANGE;
+}
+
+static struct grub_disk_dev grub_pxe_dev =
+  {
+    .name = "pxe",
+    .id = GRUB_DISK_DEVICE_PXE_ID,
+    .iterate = grub_pxe_iterate,
+    .open = grub_pxe_open,
+    .close = grub_pxe_close,
+    .read = grub_pxe_read,
+    .write = grub_pxe_write,
+    .next = 0
+  };
+
+static grub_err_t
+grub_pxefs_dir (grub_device_t device UNUSED, const char *path UNUSED,
+		int (*hook) (const char *filename,
+			     const struct grub_dirhook_info *info) UNUSED)
+{
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_pxefs_open (struct grub_file *file, const char *name)
+{
+  union
+    {
+      struct grub_pxenv_tftp_get_fsize c1;
+      struct grub_pxenv_tftp_open c2;
+    } c;
+  struct grub_pxe_data *data;
+  grub_file_t file_int, bufio;
+
+  if (curr_file != 0)
+    {
+      grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2);
+      curr_file = 0;
+    }
+
+  c.c1.server_ip = grub_pxe_server_ip;
+  c.c1.gateway_ip = grub_pxe_gateway_ip;
+  grub_strcpy ((char *)&c.c1.filename[0], name);
+  grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1);
+  if (c.c1.status)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+
+  file->size = c.c1.file_size;
+
+  c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
+  c.c2.packet_size = grub_pxe_blksize;
+  grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2);
+  if (c.c2.status)
+    return grub_error (GRUB_ERR_BAD_FS, "open fails");
+
+  data = grub_zalloc (sizeof (struct grub_pxe_data) + grub_strlen (name) + 1);
+  if (! data)
+    return grub_errno;
+
+  data->block_size = grub_pxe_blksize;
+  grub_strcpy (data->filename, name);
+
+  file_int = grub_malloc (sizeof (*file_int));
+  if (! file_int)
+    {
+      grub_free (data);
+      return grub_errno;
+    }
+
+  file->data = data;
+  grub_memcpy (file_int, file, sizeof (struct grub_file));
+  curr_file = file_int;
+
+  bufio = grub_bufio_open (file_int, data->block_size);
+  if (! bufio)
+    {
+      grub_free (file_int);
+      grub_free (data);
+      return grub_errno;
+    }
+
+  grub_memcpy (file, bufio, sizeof (struct grub_file));
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_ssize_t
+grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_pxenv_tftp_read c;
+  struct grub_pxe_data *data;
+  grub_uint32_t pn, r;
+
+  data = file->data;
+
+  pn = grub_divmod64 (file->offset, data->block_size, &r);
+  if (r)
+    {
+      grub_error (GRUB_ERR_BAD_FS,
+		  "read access must be aligned to packet size");
+      return -1;
+    }
+
+  if ((curr_file != file) || (data->packet_number > pn))
+    {
+      struct grub_pxenv_tftp_open o;
+
+      if (curr_file != 0)
+        grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o);
+
+      o.server_ip = grub_pxe_server_ip;
+      o.gateway_ip = grub_pxe_gateway_ip;
+      grub_strcpy ((char *)&o.filename[0], data->filename);
+      o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
+      o.packet_size = data->block_size;
+      grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o);
+      if (o.status)
+	{
+	  grub_error (GRUB_ERR_BAD_FS, "open fails");
+	  return -1;
+	}
+      data->packet_number = 0;
+      curr_file = file;
+    }
+
+  c.buffer = SEGOFS (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
+  while (pn >= data->packet_number)
+    {
+      c.buffer_size = grub_pxe_blksize;
+      grub_pxe_call (GRUB_PXENV_TFTP_READ, &c);
+      if (c.status)
+        {
+          grub_error (GRUB_ERR_BAD_FS, "read fails");
+          return -1;
+        }
+      data->packet_number++;
+    }
+
+  grub_memcpy (buf, (char *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, len);
+
+  return len;
+}
+
+static grub_err_t
+grub_pxefs_close (grub_file_t file)
+{
+  struct grub_pxenv_tftp_close c;
+
+  if (curr_file == file)
+    {
+      grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c);
+      curr_file = 0;
+    }
+
+  grub_free (file->data);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_pxefs_label (grub_device_t device __attribute ((unused)),
+		   char **label __attribute ((unused)))
+{
+  *label = 0;
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_fs grub_pxefs_fs =
+  {
+    .name = "pxefs",
+    .dir = grub_pxefs_dir,
+    .open = grub_pxefs_open,
+    .read = grub_pxefs_read,
+    .close = grub_pxefs_close,
+    .label = grub_pxefs_label,
+    .next = 0
+  };
+
+static void
+grub_pxe_detect (void)
+{
+  struct grub_pxenv *pxenv;
+  struct grub_pxenv_get_cached_info ci;
+  struct grub_pxenv_boot_player *bp;
+
+  pxenv = grub_pxe_scan ();
+  if (! pxenv)
+    return;
+
+  ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
+  ci.buffer = 0;
+  ci.buffer_size = 0;
+  grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci);
+  if (ci.status)
+    return;
+
+  bp = LINEAR (ci.buffer);
+
+  grub_pxe_your_ip = bp->your_ip;
+  grub_pxe_server_ip = bp->server_ip;
+  grub_pxe_gateway_ip = bp->gateway_ip;
+
+  grub_pxe_pxenv = pxenv;
+}
+
+void
+grub_pxe_unload (void)
+{
+  if (grub_pxe_pxenv)
+    {
+      grub_fs_unregister (&grub_pxefs_fs);
+      grub_disk_dev_unregister (&grub_pxe_dev);
+
+      grub_pxe_pxenv = 0;
+    }
+}
+
+GRUB_MOD_INIT(pxe)
+{
+  grub_pxe_detect ();
+  if (grub_pxe_pxenv)
+    {
+      grub_disk_dev_register (&grub_pxe_dev);
+      grub_fs_register (&grub_pxefs_fs);
+    }
+}
+
+GRUB_MOD_FINI(pxe)
+{
+  grub_pxe_unload ();
+}
diff --git a/fs/iso9660.c b/fs/iso9660.c
new file mode 100644
index 0000000..9b7ce76
--- /dev/null
+++ b/fs/iso9660.c
@@ -0,0 +1,884 @@
+/* iso9660.c - iso9660 implementation with extensions:
+   SUSP, Rock Ridge.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+#define GRUB_ISO9660_FSTYPE_DIR		0040000
+#define GRUB_ISO9660_FSTYPE_REG		0100000
+#define GRUB_ISO9660_FSTYPE_SYMLINK	0120000
+#define GRUB_ISO9660_FSTYPE_MASK	0170000
+
+#define GRUB_ISO9660_LOG2_BLKSZ		2
+#define GRUB_ISO9660_BLKSZ		2048
+
+#define GRUB_ISO9660_RR_DOT		2
+#define GRUB_ISO9660_RR_DOTDOT		4
+
+#define GRUB_ISO9660_VOLDESC_BOOT	0
+#define GRUB_ISO9660_VOLDESC_PRIMARY	1
+#define GRUB_ISO9660_VOLDESC_SUPP	2
+#define GRUB_ISO9660_VOLDESC_PART	3
+#define GRUB_ISO9660_VOLDESC_END	255
+
+/* The head of a volume descriptor.  */
+struct grub_iso9660_voldesc
+{
+  grub_uint8_t type;
+  grub_uint8_t magic[5];
+  grub_uint8_t version;
+} __attribute__ ((packed));
+
+/* A directory entry.  */
+struct grub_iso9660_dir
+{
+  grub_uint8_t len;
+  grub_uint8_t ext_sectors;
+  grub_uint32_t first_sector;
+  grub_uint32_t first_sector_be;
+  grub_uint32_t size;
+  grub_uint32_t size_be;
+  grub_uint8_t unused1[7];
+  grub_uint8_t flags;
+  grub_uint8_t unused2[6];
+  grub_uint8_t namelen;
+} __attribute__ ((packed));
+
+struct grub_iso9660_date
+{
+  grub_uint8_t year[4];
+  grub_uint8_t month[2];
+  grub_uint8_t day[2];
+  grub_uint8_t hour[2];
+  grub_uint8_t minute[2];
+  grub_uint8_t second[2];
+  grub_uint8_t hundredth[2];
+  grub_uint8_t offset;
+} __attribute__ ((packed));
+
+/* The primary volume descriptor.  Only little endian is used.  */
+struct grub_iso9660_primary_voldesc
+{
+  struct grub_iso9660_voldesc voldesc;
+  grub_uint8_t unused1[33];
+  grub_uint8_t volname[32];
+  grub_uint8_t unused2[16];
+  grub_uint8_t escape[32];
+  grub_uint8_t unused3[12];
+  grub_uint32_t path_table_size;
+  grub_uint8_t unused4[4];
+  grub_uint32_t path_table;
+  grub_uint8_t unused5[12];
+  struct grub_iso9660_dir rootdir;
+  grub_uint8_t unused6[624];
+  struct grub_iso9660_date created;
+  struct grub_iso9660_date modified;
+} __attribute__ ((packed));
+
+/* A single entry in the path table.  */
+struct grub_iso9660_path
+{
+  grub_uint8_t len;
+  grub_uint8_t sectors;
+  grub_uint32_t first_sector;
+  grub_uint16_t parentdir;
+  grub_uint8_t name[0];
+} __attribute__ ((packed));
+
+/* An entry in the System Usage area of the directory entry.  */
+struct grub_iso9660_susp_entry
+{
+  grub_uint8_t sig[2];
+  grub_uint8_t len;
+  grub_uint8_t version;
+  grub_uint8_t data[0];
+} __attribute__ ((packed));
+
+/* The CE entry.  This is used to describe the next block where data
+   can be found.  */
+struct grub_iso9660_susp_ce
+{
+  struct grub_iso9660_susp_entry entry;
+  grub_uint32_t blk;
+  grub_uint32_t blk_be;
+  grub_uint32_t off;
+  grub_uint32_t off_be;
+  grub_uint32_t len;
+  grub_uint32_t len_be;
+} __attribute__ ((packed));
+
+struct grub_iso9660_data
+{
+  struct grub_iso9660_primary_voldesc voldesc;
+  grub_disk_t disk;
+  unsigned int first_sector;
+  unsigned int length;
+  int rockridge;
+  int susp_skip;
+  int joliet;
+};
+
+struct grub_fshelp_node
+{
+  struct grub_iso9660_data *data;
+  unsigned int size;
+  unsigned int blk;
+  unsigned int dir_blk;
+  unsigned int dir_off;
+};
+
+static grub_dl_t my_mod;
+
+
+/* Iterate over the susp entries, starting with block SUA_BLOCK on the
+   offset SUA_POS with a size of SUA_SIZE bytes.  Hook is called for
+   every entry.  */
+static grub_err_t
+grub_iso9660_susp_iterate (struct grub_iso9660_data *data,
+			   int sua_block, int sua_pos, int sua_size,
+			   grub_err_t (*hook)
+			   (struct grub_iso9660_susp_entry *entry))
+{
+  char *sua;
+  struct grub_iso9660_susp_entry *entry;
+
+  auto grub_err_t load_sua (void);
+
+  /* Load a part of the System Usage Area.  */
+  grub_err_t load_sua (void)
+    {
+      sua = grub_malloc (sua_size);
+      if (!sua)
+	return grub_errno;
+
+      if (grub_disk_read (data->disk, sua_block, sua_pos,
+			  sua_size, sua))
+	return grub_errno;
+
+      entry = (struct grub_iso9660_susp_entry *) sua;
+      return 0;
+    }
+
+  if (load_sua ())
+    return grub_errno;
+
+  for (; (char *) entry < (char *) sua + sua_size - 1;
+       entry = (struct grub_iso9660_susp_entry *)
+	 ((char *) entry + entry->len))
+    {
+      /* The last entry.  */
+      if (grub_strncmp ((char *) entry->sig, "ST", 2) == 0)
+	break;
+
+      /* Additional entries are stored elsewhere.  */
+      if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0)
+	{
+	  struct grub_iso9660_susp_ce *ce;
+
+	  ce = (struct grub_iso9660_susp_ce *) entry;
+	  sua_size = grub_le_to_cpu32 (ce->len);
+	  sua_pos = grub_le_to_cpu32 (ce->off);
+	  sua_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ;
+
+	  grub_free (sua);
+	  if (load_sua ())
+	    return grub_errno;
+	}
+
+      if (hook (entry))
+	{
+	  grub_free (sua);
+	  return 0;
+	}
+    }
+
+  grub_free (sua);
+  return 0;
+}
+
+static char *
+grub_iso9660_convert_string (grub_uint16_t *us, int len)
+{
+  char *p;
+  int i;
+
+  p = grub_malloc (len * 4 + 1);
+  if (! p)
+    return p;
+
+  for (i=0; i<len; i++)
+    us[i] = grub_be_to_cpu16 (us[i]);
+
+  *grub_utf16_to_utf8 ((grub_uint8_t *) p, us, len) = '\0';
+
+  return p;
+}
+
+static struct grub_iso9660_data *
+grub_iso9660_mount (grub_disk_t disk)
+{
+  struct grub_iso9660_data *data = 0;
+  struct grub_iso9660_dir rootdir;
+  int sua_pos;
+  int sua_size;
+  char *sua;
+  struct grub_iso9660_susp_entry *entry;
+  struct grub_iso9660_primary_voldesc voldesc;
+  int block;
+
+  auto grub_err_t susp_iterate (struct grub_iso9660_susp_entry *);
+
+  grub_err_t susp_iterate (struct grub_iso9660_susp_entry *susp_entry)
+    {
+      /* The "ER" entry is used to detect extensions.  The
+	 `IEEE_P1285' extension means Rock ridge.  */
+      if (grub_strncmp ((char *) susp_entry->sig, "ER", 2) == 0)
+	{
+	  data->rockridge = 1;
+	  return 1;
+	}
+      return 0;
+    }
+
+  data = grub_zalloc (sizeof (struct grub_iso9660_data));
+  if (! data)
+    return 0;
+
+  data->disk = disk;
+
+  block = 16;
+  do
+    {
+      int copy_voldesc = 0;
+
+      /* Read the superblock.  */
+      if (grub_disk_read (disk, block << GRUB_ISO9660_LOG2_BLKSZ, 0,
+			  sizeof (struct grub_iso9660_primary_voldesc),
+			  (char *) &voldesc))
+        {
+          grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
+          goto fail;
+        }
+
+      if (grub_strncmp ((char *) voldesc.voldesc.magic, "CD001", 5) != 0)
+        {
+          grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
+          goto fail;
+        }
+
+      if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY)
+        copy_voldesc = 1;
+      else if ((voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) &&
+               (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) &&
+               ((voldesc.escape[2] == 0x40) ||	/* UCS-2 Level 1.  */
+                (voldesc.escape[2] == 0x43) ||  /* UCS-2 Level 2.  */
+                (voldesc.escape[2] == 0x45)))	/* UCS-2 Level 3.  */
+        {
+          copy_voldesc = 1;
+          data->joliet = 1;
+        }
+
+      if (copy_voldesc)
+        grub_memcpy((char *) &data->voldesc, (char *) &voldesc,
+                    sizeof (struct grub_iso9660_primary_voldesc));
+
+      block++;
+    } while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END);
+
+  /* Read the system use area and test it to see if SUSP is
+     supported.  */
+  if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
+			     << GRUB_ISO9660_LOG2_BLKSZ), 0,
+		      sizeof (rootdir), (char *) &rootdir))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
+      goto fail;
+    }
+
+  sua_pos = (sizeof (rootdir) + rootdir.namelen
+	     + (rootdir.namelen % 2) - 1);
+  sua_size = rootdir.len - sua_pos;
+
+  sua = grub_malloc (sua_size);
+  if (! sua)
+    goto fail;
+
+  if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
+			     << GRUB_ISO9660_LOG2_BLKSZ), sua_pos,
+		      sua_size, sua))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
+      goto fail;
+    }
+
+  entry = (struct grub_iso9660_susp_entry *) sua;
+
+  /* Test if the SUSP protocol is used on this filesystem.  */
+  if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0)
+    {
+      /* The 2nd data byte stored how many bytes are skipped every time
+	 to get to the SUA (System Usage Area).  */
+      data->susp_skip = entry->data[2];
+      entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len);
+
+      /* Iterate over the entries in the SUA area to detect
+	 extensions.  */
+      if (grub_iso9660_susp_iterate (data,
+				     (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
+				      << GRUB_ISO9660_LOG2_BLKSZ),
+				     sua_pos, sua_size, susp_iterate))
+	goto fail;
+    }
+
+  return data;
+
+ fail:
+  grub_free (data);
+  return 0;
+}
+
+
+static char *
+grub_iso9660_read_symlink (grub_fshelp_node_t node)
+{
+  struct grub_iso9660_dir dirent;
+  int sua_off;
+  int sua_size;
+  char *symlink = 0;
+  int addslash = 0;
+
+  auto void add_part (const char *part, int len);
+  auto grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *);
+
+  /* Extend the symlink.  */
+  void add_part (const char *part, int len)
+    {
+      int size = grub_strlen (symlink);
+
+      symlink = grub_realloc (symlink, size + len + 1);
+      if (! symlink)
+	return;
+
+      grub_strncat (symlink, part, len);
+    }
+
+  /* Read in a symlink.  */
+  grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *entry)
+    {
+      if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0)
+	{
+	  unsigned int pos = 1;
+
+	  /* The symlink is not stored as a POSIX symlink, translate it.  */
+	  while (pos < grub_le_to_cpu32 (entry->len))
+	    {
+	      if (addslash)
+		{
+		  add_part ("/", 1);
+		  addslash = 0;
+		}
+
+	      /* The current position is the `Component Flag'.  */
+	      switch (entry->data[pos] & 30)
+		{
+		case 0:
+		  {
+		    /* The data on pos + 2 is the actual data, pos + 1
+		       is the length.  Both are part of the `Component
+		       Record'.  */
+		    add_part ((char *) &entry->data[pos + 2],
+			      entry->data[pos + 1]);
+		    if ((entry->data[pos] & 1))
+		      addslash = 1;
+
+		    break;
+		  }
+
+		case 2:
+		  add_part ("./", 2);
+		  break;
+
+		case 4:
+		  add_part ("../", 3);
+		  break;
+
+		case 8:
+		  add_part ("/", 1);
+		  break;
+		}
+	      /* In pos + 1 the length of the `Component Record' is
+		 stored.  */
+	      pos += entry->data[pos + 1] + 2;
+	    }
+
+	  /* Check if `grub_realloc' failed.  */
+	  if (grub_errno)
+	    return grub_errno;
+	}
+
+      return 0;
+    }
+
+  if (grub_disk_read (node->data->disk, node->dir_blk, node->dir_off,
+		      sizeof (dirent), (char *) &dirent))
+    return 0;
+
+  sua_off = (sizeof (dirent) + dirent.namelen + 1 - (dirent.namelen % 2)
+	     + node->data->susp_skip);
+  sua_size = dirent.len - sua_off;
+
+  symlink = grub_malloc (1);
+  if (!symlink)
+    return 0;
+
+  *symlink = '\0';
+
+  if (grub_iso9660_susp_iterate (node->data, node->dir_blk,
+				 node->dir_off + sua_off,
+				 sua_size, susp_iterate_sl))
+    {
+      grub_free (symlink);
+      return 0;
+    }
+
+  return symlink;
+}
+
+
+static int
+grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
+			  int NESTED_FUNC_ATTR
+			  (*hook) (const char *filename,
+				   enum grub_fshelp_filetype filetype,
+				   grub_fshelp_node_t node))
+{
+  struct grub_iso9660_dir dirent;
+  unsigned int offset = 0;
+  char *filename;
+  int filename_alloc = 0;
+  enum grub_fshelp_filetype type;
+
+  auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *);
+
+  grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *entry)
+    {
+      /* The filename in the rock ridge entry.  */
+      if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0)
+	{
+	  /* The flags are stored at the data position 0, here the
+	     filename type is stored.  */
+	  if (entry->data[0] & GRUB_ISO9660_RR_DOT)
+	    filename = ".";
+	  else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT)
+	    filename = "..";
+	  else
+	    {
+	      int size = 1;
+	      if (filename)
+		{
+		  size += grub_strlen (filename);
+		  grub_realloc (filename,
+				grub_strlen (filename)
+				+ entry->len);
+		}
+	      else
+		{
+		  size = entry->len - 5;
+		  filename = grub_zalloc (size + 1);
+		}
+	      filename_alloc = 1;
+	      grub_strncpy (filename, (char *) &entry->data[1], size);
+	      filename[size] = '\0';
+	    }
+	}
+      /* The mode information (st_mode).  */
+      else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0)
+	{
+	  /* At position 0 of the PX record the st_mode information is
+	     stored (little-endian).  */
+	  grub_uint32_t mode = ((entry->data[0] + (entry->data[1] << 8))
+				& GRUB_ISO9660_FSTYPE_MASK);
+
+	  switch (mode)
+	    {
+	    case GRUB_ISO9660_FSTYPE_DIR:
+	      type = GRUB_FSHELP_DIR;
+	      break;
+	    case GRUB_ISO9660_FSTYPE_REG:
+	      type = GRUB_FSHELP_REG;
+	      break;
+	    case GRUB_ISO9660_FSTYPE_SYMLINK:
+	      type = GRUB_FSHELP_SYMLINK;
+	      break;
+	    default:
+	      type = GRUB_FSHELP_UNKNOWN;
+	    }
+	}
+
+      return 0;
+    }
+
+  while (offset < dir->size)
+    {
+      if (grub_disk_read (dir->data->disk,
+			  (dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
+			  + offset / GRUB_DISK_SECTOR_SIZE,
+			  offset % GRUB_DISK_SECTOR_SIZE,
+			  sizeof (dirent), (char *) &dirent))
+	return 0;
+
+      /* The end of the block, skip to the next one.  */
+      if (!dirent.len)
+	{
+	  offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ;
+	  continue;
+	}
+
+      {
+	char name[dirent.namelen + 1];
+	int nameoffset = offset + sizeof (dirent);
+	struct grub_fshelp_node *node;
+	int sua_off = (sizeof (dirent) + dirent.namelen + 1
+		       - (dirent.namelen % 2));
+	int sua_size = dirent.len - sua_off;
+
+	sua_off += offset + dir->data->susp_skip;
+
+	filename = 0;
+	filename_alloc = 0;
+	type = GRUB_FSHELP_UNKNOWN;
+
+	if (dir->data->rockridge
+	    && grub_iso9660_susp_iterate (dir->data,
+					  (dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
+					  + (sua_off
+					     / GRUB_DISK_SECTOR_SIZE),
+					  sua_off % GRUB_DISK_SECTOR_SIZE,
+					  sua_size, susp_iterate_dir))
+	  return 0;
+
+	/* Read the name.  */
+	if (grub_disk_read (dir->data->disk,
+			    (dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
+			    + nameoffset / GRUB_DISK_SECTOR_SIZE,
+			    nameoffset % GRUB_DISK_SECTOR_SIZE,
+			    dirent.namelen, (char *) name))
+	  return 0;
+
+	node = grub_malloc (sizeof (struct grub_fshelp_node));
+	if (!node)
+	  return 0;
+
+	/* Setup a new node.  */
+	node->data = dir->data;
+	node->size = grub_le_to_cpu32 (dirent.size);
+	node->blk = grub_le_to_cpu32 (dirent.first_sector);
+	node->dir_blk = ((dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
+			 + offset / GRUB_DISK_SECTOR_SIZE);
+	node->dir_off = offset % GRUB_DISK_SECTOR_SIZE;
+
+	/* If the filetype was not stored using rockridge, use
+	   whatever is stored in the iso9660 filesystem.  */
+	if (type == GRUB_FSHELP_UNKNOWN)
+	  {
+	    if ((dirent.flags & 3) == 2)
+	      type = GRUB_FSHELP_DIR;
+	    else
+	      type = GRUB_FSHELP_REG;
+	  }
+
+	/* The filename was not stored in a rock ridge entry.  Read it
+	   from the iso9660 filesystem.  */
+	if (!filename)
+	  {
+	    name[dirent.namelen] = '\0';
+	    filename = grub_strrchr (name, ';');
+	    if (filename)
+	      *filename = '\0';
+
+	    if (dirent.namelen == 1 && name[0] == 0)
+	      filename = ".";
+	    else if (dirent.namelen == 1 && name[0] == 1)
+	      filename = "..";
+	    else
+	      filename = name;
+	  }
+
+        if (dir->data->joliet)
+          {
+            char *oldname;
+
+            oldname = filename;
+            filename = grub_iso9660_convert_string
+                  ((grub_uint16_t *) oldname, dirent.namelen >> 1);
+
+            if (filename_alloc)
+              grub_free (oldname);
+
+            filename_alloc = 1;
+          }
+
+	if (hook (filename, type, node))
+	  {
+	    if (filename_alloc)
+	      grub_free (filename);
+	    return 1;
+	  }
+	if (filename_alloc)
+	  grub_free (filename);
+      }
+
+      offset += dirent.len;
+    }
+
+  return 0;
+}
+
+
+
+static grub_err_t
+grub_iso9660_dir (grub_device_t device, const char *path,
+		  int (*hook) (const char *filename,
+			       const struct grub_dirhook_info *info))
+{
+  struct grub_iso9660_data *data = 0;
+  struct grub_fshelp_node rootnode;
+  struct grub_fshelp_node *foundnode;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+				     enum grub_fshelp_filetype filetype,
+				     grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_iso9660_mount (device->disk);
+  if (! data)
+    goto fail;
+
+  rootnode.data = data;
+  rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector);
+  rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size);
+
+  /* Use the fshelp function to traverse the path.  */
+  if (grub_fshelp_find_file (path, &rootnode,
+			     &foundnode,
+			     grub_iso9660_iterate_dir,
+			     grub_iso9660_read_symlink,
+			     GRUB_FSHELP_DIR))
+    goto fail;
+
+  /* List the files in the directory.  */
+  grub_iso9660_iterate_dir (foundnode, iterate);
+
+  if (foundnode != &rootnode)
+    grub_free (foundnode);
+
+ fail:
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_iso9660_open (struct grub_file *file, const char *name)
+{
+  struct grub_iso9660_data *data;
+  struct grub_fshelp_node rootnode;
+  struct grub_fshelp_node *foundnode;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_iso9660_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  rootnode.data = data;
+  rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector);
+  rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size);
+
+  /* Use the fshelp function to traverse the path.  */
+  if (grub_fshelp_find_file (name, &rootnode,
+			     &foundnode,
+			     grub_iso9660_iterate_dir,
+			     grub_iso9660_read_symlink,
+			     GRUB_FSHELP_REG))
+    goto fail;
+
+  data->first_sector = foundnode->blk;
+  data->length = foundnode->size;
+
+  file->data = data;
+  file->size = foundnode->size;
+  file->offset = 0;
+
+  return 0;
+
+ fail:
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+static grub_ssize_t
+grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_iso9660_data *data =
+    (struct grub_iso9660_data *) file->data;
+
+  /* XXX: The file is stored in as a single extent.  */
+  data->disk->read_hook = file->read_hook;
+  grub_disk_read (data->disk,
+		  data->first_sector << GRUB_ISO9660_LOG2_BLKSZ,
+		  file->offset,
+		  len, buf);
+  data->disk->read_hook = 0;
+
+  return len;
+}
+
+
+static grub_err_t
+grub_iso9660_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_err_t
+grub_iso9660_label (grub_device_t device, char **label)
+{
+  struct grub_iso9660_data *data;
+  data = grub_iso9660_mount (device->disk);
+
+  if (data)
+    {
+      if (data->joliet)
+        *label = grub_iso9660_convert_string
+                 ((grub_uint16_t *) &data->voldesc.volname, 16);
+      else
+        *label = grub_strndup ((char *) data->voldesc.volname, 32);
+      grub_free (data);
+    }
+  else
+    *label = 0;
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_iso9660_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_iso9660_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_iso9660_mount (disk);
+  if (data)
+    {
+      if (! data->voldesc.modified.year[0] && ! data->voldesc.modified.year[1]
+	  && ! data->voldesc.modified.year[2] && ! data->voldesc.modified.year[3]
+	  && ! data->voldesc.modified.month[0] && ! data->voldesc.modified.month[1]
+	  && ! data->voldesc.modified.day[0] && ! data->voldesc.modified.day[1]
+	  && ! data->voldesc.modified.hour[0] && ! data->voldesc.modified.hour[1]
+	  && ! data->voldesc.modified.minute[0] && ! data->voldesc.modified.minute[1]
+	  && ! data->voldesc.modified.second[0] && ! data->voldesc.modified.second[1]
+	  && ! data->voldesc.modified.hundredth[0] && ! data->voldesc.modified.hundredth[1])
+	{
+	  grub_error (GRUB_ERR_BAD_NUMBER, "No creation date in filesystem to generate UUID.");
+	  *uuid = NULL;
+	}
+      else
+	{
+	  *uuid = grub_malloc (sizeof ("YYYY-MM-DD-HH-mm-ss-hh"));
+	  grub_sprintf (*uuid, "%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c",
+			data->voldesc.modified.year[0], data->voldesc.modified.year[1],
+			data->voldesc.modified.year[2], data->voldesc.modified.year[3],
+			data->voldesc.modified.month[0], data->voldesc.modified.month[1],
+			data->voldesc.modified.day[0], data->voldesc.modified.day[1],
+			data->voldesc.modified.hour[0], data->voldesc.modified.hour[1],
+			data->voldesc.modified.minute[0], data->voldesc.modified.minute[1],
+			data->voldesc.modified.second[0], data->voldesc.modified.second[1],
+			data->voldesc.modified.hundredth[0], data->voldesc.modified.hundredth[1]);
+	}
+    }
+  else
+    *uuid = NULL;
+
+	grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+
+static struct grub_fs grub_iso9660_fs =
+  {
+    .name = "iso9660",
+    .dir = grub_iso9660_dir,
+    .open = grub_iso9660_open,
+    .read = grub_iso9660_read,
+    .close = grub_iso9660_close,
+    .label = grub_iso9660_label,
+    .uuid = grub_iso9660_uuid,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(iso9660)
+{
+  grub_fs_register (&grub_iso9660_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(iso9660)
+{
+  grub_fs_unregister (&grub_iso9660_fs);
+}
diff --git a/fs/jfs.c b/fs/jfs.c
new file mode 100644
index 0000000..b73f9bd
--- /dev/null
+++ b/fs/jfs.c
@@ -0,0 +1,902 @@
+/* jfs.c - JFS.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+
+#define GRUB_JFS_MAX_SYMLNK_CNT	8
+#define GRUB_JFS_FILETYPE_MASK	0170000
+#define GRUB_JFS_FILETYPE_REG	0100000
+#define GRUB_JFS_FILETYPE_LNK	0120000
+#define GRUB_JFS_FILETYPE_DIR	0040000
+
+#define GRUB_JFS_SBLOCK		64
+#define GRUB_JFS_AGGR_INODE	2
+#define GRUB_JFS_FS1_INODE_BLK	104
+
+#define GRUB_JFS_TREE_LEAF	2
+
+struct grub_jfs_sblock
+{
+  /* The magic for JFS.  It should contain the string "JFS1".  */
+  grub_uint8_t magic[4];
+  grub_uint32_t version;
+  grub_uint64_t ag_size;
+
+  /* The size of a filesystem block in bytes.  XXX: currently only
+     4096 was tested.  */
+  grub_uint32_t blksz;
+  grub_uint16_t log2_blksz;
+
+  grub_uint8_t unused[71];
+  grub_uint8_t volname[11];
+  grub_uint8_t unused2[32];
+  grub_uint8_t uuid[16];
+};
+
+struct grub_jfs_extent
+{
+  /* The length of the extent in filesystem blocks.  */
+  grub_uint16_t length;
+  grub_uint8_t length2;
+
+  /* The physical offset of the first block on the disk.  */
+  grub_uint8_t blk1;
+  grub_uint32_t blk2;
+} __attribute__ ((packed));
+
+struct grub_jfs_iag
+{
+  grub_uint8_t unused[3072];
+  struct grub_jfs_extent inodes[128];
+} __attribute__ ((packed));
+
+
+/* The head of the tree used to find extents.  */
+struct grub_jfs_treehead
+{
+  grub_uint64_t next;
+  grub_uint64_t prev;
+
+  grub_uint8_t flags;
+  grub_uint8_t unused;
+
+  grub_uint16_t count;
+  grub_uint16_t max;
+  grub_uint8_t unused2[10];
+} __attribute__ ((packed));
+
+/* A node in the extent tree.  */
+struct grub_jfs_tree_extent
+{
+  grub_uint8_t flags;
+  grub_uint16_t unused;
+
+  /* The offset is the key used to lookup an extent.  */
+  grub_uint8_t offset1;
+  grub_uint32_t offset2;
+
+  struct grub_jfs_extent extent;
+} __attribute__ ((packed));
+
+/* The tree of directory entries.  */
+struct grub_jfs_tree_dir
+{
+  /* Pointers to the previous and next tree headers of other nodes on
+     this level.  */
+  grub_uint64_t nextb;
+  grub_uint64_t prevb;
+
+  grub_uint8_t flags;
+
+  /* The amount of dirents in this node.  */
+  grub_uint8_t count;
+  grub_uint8_t freecnt;
+  grub_uint8_t freelist;
+  grub_uint8_t maxslot;
+
+  /* The location of the sorted array of pointers to dirents.  */
+  grub_uint8_t sindex;
+  grub_uint8_t unused[10];
+} __attribute__ ((packed));
+
+/* An internal node in the dirents tree.  */
+struct grub_jfs_internal_dirent
+{
+  struct grub_jfs_extent ex;
+  grub_uint8_t next;
+  grub_uint8_t len;
+  grub_uint16_t namepart[11];
+} __attribute__ ((packed));
+
+/* A leaf node in the dirents tree.  */
+struct grub_jfs_leaf_dirent
+{
+  /* The inode for this dirent.  */
+  grub_uint32_t inode;
+  grub_uint8_t next;
+
+  /* The size of the name.  */
+  grub_uint8_t len;
+  grub_uint16_t namepart[11];
+  grub_uint32_t index;
+} __attribute__ ((packed));
+
+/* A leaf in the dirents tree.  This one is used if the previously
+   dirent was not big enough to store the name.  */
+struct grub_jfs_leaf_next_dirent
+{
+  grub_uint8_t next;
+  grub_uint8_t len;
+  grub_uint16_t namepart[15];
+} __attribute__ ((packed));
+
+struct grub_jfs_inode
+{
+  grub_uint32_t stamp;
+  grub_uint32_t fileset;
+  grub_uint32_t inode;
+  grub_uint8_t unused[12];
+  grub_uint64_t size;
+  grub_uint8_t unused2[20];
+  grub_uint32_t mode;
+  grub_uint8_t unused3[72];
+  grub_uint8_t unused4[96];
+
+  union
+  {
+    /* The tree describing the extents of the file.  */
+    struct __attribute__ ((packed))
+    {
+      struct grub_jfs_treehead tree;
+      struct grub_jfs_tree_extent extents[16];
+    } file;
+    union
+    {
+      /* The tree describing the dirents.  */
+      struct
+      {
+	grub_uint8_t unused[16];
+	grub_uint8_t flags;
+
+	/* Amount of dirents in this node.  */
+	grub_uint8_t count;
+	grub_uint8_t freecnt;
+	grub_uint8_t freelist;
+	grub_uint32_t idotdot;
+	grub_uint8_t sorted[8];
+      } header;
+      struct grub_jfs_leaf_dirent dirents[8];
+    } dir __attribute__ ((packed));
+    /* Fast symlink.  */
+    struct
+    {
+      grub_uint8_t unused[32];
+      grub_uint8_t path[128];
+    } symlink;
+  } __attribute__ ((packed));
+} __attribute__ ((packed));
+
+struct grub_jfs_data
+{
+  struct grub_jfs_sblock sblock;
+  grub_disk_t disk;
+  struct grub_jfs_inode fileset;
+  struct grub_jfs_inode currinode;
+  int pos;
+  int linknest;
+} __attribute__ ((packed));
+
+struct grub_jfs_diropen
+{
+  int index;
+  union
+  {
+    struct grub_jfs_tree_dir header;
+    struct grub_jfs_leaf_dirent dirent[0];
+    struct grub_jfs_leaf_next_dirent next_dirent[0];
+    char sorted[0];
+  } *dirpage __attribute__ ((packed));
+  struct grub_jfs_data *data;
+  struct grub_jfs_inode *inode;
+  int count;
+  char *sorted;
+  struct grub_jfs_leaf_dirent *leaf;
+  struct grub_jfs_leaf_next_dirent *next_leaf;
+
+  /* The filename and inode of the last read dirent.  */
+  char name[255];
+  grub_uint32_t ino;
+} __attribute__ ((packed));
+
+
+static grub_dl_t my_mod;
+
+static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, int ino);
+
+/* Get the block number for the block BLK in the node INODE in the
+   mounted filesystem DATA.  */
+static int
+grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode,
+		unsigned int blk)
+{
+  auto int getblk (struct grub_jfs_treehead *treehead,
+		   struct grub_jfs_tree_extent *extents);
+
+  int getblk (struct grub_jfs_treehead *treehead,
+	      struct grub_jfs_tree_extent *extents)
+    {
+      int found = -1;
+      int i;
+
+      for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++)
+	{
+	  if (treehead->flags & GRUB_JFS_TREE_LEAF)
+	    {
+	      /* Read the leafnode.  */
+	      if (grub_le_to_cpu32 (extents[i].offset2) <= blk
+		  && ((grub_le_to_cpu16 (extents[i].extent.length))
+		      + (extents[i].extent.length2 << 8)
+		      + grub_le_to_cpu32 (extents[i].offset2)) > blk)
+		return (blk - grub_le_to_cpu32 (extents[i].offset2)
+			+ grub_le_to_cpu32 (extents[i].extent.blk2));
+	    }
+	  else
+	    if (blk >= grub_le_to_cpu32 (extents[i].offset2))
+	      found = i;
+	}
+
+      if (found != -1)
+	{
+	  struct
+	  {
+	    struct grub_jfs_treehead treehead;
+	    struct grub_jfs_tree_extent extents[254];
+	  } tree;
+
+	  if (grub_disk_read (data->disk,
+			      grub_le_to_cpu32 (extents[found].extent.blk2)
+			      << (grub_le_to_cpu16 (data->sblock.log2_blksz)
+				  - GRUB_DISK_SECTOR_BITS), 0,
+			      sizeof (tree), (char *) &tree))
+	    return -1;
+
+	  return getblk (&tree.treehead, &tree.extents[0]);
+	}
+
+      return -1;
+    }
+
+  return getblk (&inode->file.tree, &inode->file.extents[0]);
+}
+
+
+static grub_err_t
+grub_jfs_read_inode (struct grub_jfs_data *data, int ino,
+		     struct grub_jfs_inode *inode)
+{
+  struct grub_jfs_iag iag;
+  int iagnum = ino / 4096;
+  int inoext = (ino % 4096) / 32;
+  int inonum = (ino % 4096) % 32;
+  grub_uint32_t iagblk;
+  grub_uint32_t inoblk;
+
+  iagblk = grub_jfs_blkno (data, &data->fileset, iagnum + 1);
+  if (grub_errno)
+    return grub_errno;
+
+  /* Read in the IAG.  */
+  if (grub_disk_read (data->disk,
+		      iagblk << (grub_le_to_cpu16 (data->sblock.log2_blksz)
+				 - GRUB_DISK_SECTOR_BITS), 0,
+		      sizeof (struct grub_jfs_iag), &iag))
+    return grub_errno;
+
+  inoblk = grub_le_to_cpu32 (iag.inodes[inoext].blk2);
+  inoblk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz)
+	      - GRUB_DISK_SECTOR_BITS);
+  inoblk += inonum;
+
+  if (grub_disk_read (data->disk, inoblk, 0,
+		      sizeof (struct grub_jfs_inode), inode))
+    return grub_errno;
+
+  return 0;
+}
+
+
+static struct grub_jfs_data *
+grub_jfs_mount (grub_disk_t disk)
+{
+  struct grub_jfs_data *data = 0;
+
+  data = grub_malloc (sizeof (struct grub_jfs_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  if (grub_disk_read (disk, GRUB_JFS_SBLOCK, 0,
+		      sizeof (struct grub_jfs_sblock), &data->sblock))
+    goto fail;
+
+  if (grub_strncmp ((char *) (data->sblock.magic), "JFS1", 4))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a jfs filesystem");
+      goto fail;
+    }
+
+  data->disk = disk;
+  data->pos = 0;
+  data->linknest = 0;
+
+  /* Read the inode of the first fileset.  */
+  if (grub_disk_read (data->disk, GRUB_JFS_FS1_INODE_BLK, 0,
+		      sizeof (struct grub_jfs_inode), &data->fileset))
+    goto fail;
+
+  return data;
+
+ fail:
+  grub_free (data);
+
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not a jfs filesystem");
+
+  return 0;
+}
+
+
+static struct grub_jfs_diropen *
+grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode)
+{
+  struct grub_jfs_internal_dirent *de;
+  struct grub_jfs_diropen *diro;
+  int blk;
+
+  de = (struct grub_jfs_internal_dirent *) inode->dir.dirents;
+
+  if (!((grub_le_to_cpu32 (inode->mode)
+	 & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      return 0;
+    }
+
+  diro = grub_zalloc (sizeof (struct grub_jfs_diropen));
+  if (!diro)
+    return 0;
+
+  diro->data = data;
+  diro->inode = inode;
+
+  /* Check if the entire tree is contained within the inode.  */
+  if (inode->file.tree.flags & GRUB_JFS_TREE_LEAF)
+    {
+      diro->leaf = inode->dir.dirents;
+      diro->next_leaf = (struct grub_jfs_leaf_next_dirent *) de;
+      diro->sorted = (char *) (inode->dir.header.sorted);
+      diro->count = inode->dir.header.count;
+
+      return diro;
+    }
+
+  diro->dirpage = grub_malloc (grub_le_to_cpu32 (data->sblock.blksz));
+  if (!diro->dirpage)
+    {
+      grub_free (diro);
+      return 0;
+    }
+
+  blk = grub_le_to_cpu32 (de[inode->dir.header.sorted[0]].ex.blk2);
+  blk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS);
+
+  /* Read in the nodes until we are on the leaf node level.  */
+  do
+    {
+      int index;
+      if (grub_disk_read (data->disk, blk, 0,
+			  grub_le_to_cpu32 (data->sblock.blksz),
+			  diro->dirpage->sorted))
+	{
+	  grub_free (diro->dirpage);
+	  grub_free (diro);
+	  return 0;
+	}
+
+      de = (struct grub_jfs_internal_dirent *) diro->dirpage->dirent;
+      index = diro->dirpage->sorted[diro->dirpage->header.sindex * 32];
+      blk = (grub_le_to_cpu32 (de[index].ex.blk2)
+	     << (grub_le_to_cpu16 (data->sblock.log2_blksz)
+		 - GRUB_DISK_SECTOR_BITS));
+    } while (!(diro->dirpage->header.flags & GRUB_JFS_TREE_LEAF));
+
+  diro->leaf = diro->dirpage->dirent;
+  diro->next_leaf = diro->dirpage->next_dirent;
+  diro->sorted = &diro->dirpage->sorted[diro->dirpage->header.sindex * 32];
+  diro->count = diro->dirpage->header.count;
+
+  return diro;
+}
+
+
+static void
+grub_jfs_closedir (struct grub_jfs_diropen *diro)
+{
+  if (!diro)
+    return;
+  grub_free (diro->dirpage);
+  grub_free (diro);
+}
+
+
+/* Read in the next dirent from the directory described by DIRO.  */
+static grub_err_t
+grub_jfs_getent (struct grub_jfs_diropen *diro)
+{
+  int strpos = 0;
+  struct grub_jfs_leaf_dirent *leaf;
+  struct grub_jfs_leaf_next_dirent *next_leaf;
+  int len;
+  int nextent;
+  grub_uint16_t filename[255];
+
+  auto void addstr (grub_uint16_t *uname, int ulen);
+
+  /* Add the unicode string to the utf16 filename buffer.  */
+  void addstr (grub_uint16_t *name, int ulen)
+    {
+      while (ulen--)
+	filename[strpos++] = *(name++);
+    }
+
+  /* The last node, read in more.  */
+  if (diro->index == diro->count)
+    {
+      unsigned int next;
+
+      /* If the inode contains the entry tree or if this was the last
+	 node, there is nothing to read.  */
+      if ((diro->inode->file.tree.flags & GRUB_JFS_TREE_LEAF)
+	  || !grub_le_to_cpu64 (diro->dirpage->header.nextb))
+	return GRUB_ERR_OUT_OF_RANGE;
+
+      next = grub_le_to_cpu64 (diro->dirpage->header.nextb);
+      next <<= (grub_le_to_cpu16 (diro->data->sblock.log2_blksz)
+		- GRUB_DISK_SECTOR_BITS);
+
+      if (grub_disk_read (diro->data->disk, next, 0,
+			  grub_le_to_cpu32 (diro->data->sblock.blksz),
+			  diro->dirpage->sorted))
+	return grub_errno;
+
+      diro->leaf = diro->dirpage->dirent;
+      diro->next_leaf = diro->dirpage->next_dirent;
+      diro->sorted = &diro->dirpage->sorted[diro->dirpage->header.sindex * 32];
+      diro->count = diro->dirpage->header.count;
+      diro->index = 0;
+    }
+
+  leaf = &diro->leaf[(int) diro->sorted[diro->index]];
+  next_leaf = &diro->next_leaf[diro->index];
+
+  len = leaf->len;
+  if (!len)
+    {
+      diro->index++;
+      return grub_jfs_getent (diro);
+    }
+
+  addstr (leaf->namepart, len < 11 ? len : 11);
+  diro->ino = grub_le_to_cpu32 (leaf->inode);
+  len -= 11;
+
+  /* Move down to the leaf level.  */
+  nextent = leaf->next;
+  if (leaf->next != 255)
+    do
+      {
+ 	next_leaf = &diro->next_leaf[nextent];
+	addstr (next_leaf->namepart, len < 15 ? len : 15 );
+
+	len -= 15;
+	nextent = next_leaf->next;
+      } while (next_leaf->next != 255 && len > 0);
+
+  diro->index++;
+
+  /* Convert the temporary UTF16 filename to UTF8.  */
+  *grub_utf16_to_utf8 ((grub_uint8_t *) (diro->name), filename, strpos) = '\0';
+
+  return 0;
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_jfs_read_file (struct grub_jfs_data *data,
+		    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+				       unsigned offset, unsigned length),
+		    int pos, grub_size_t len, char *buf)
+{
+  int i;
+  int blockcnt;
+
+  blockcnt = ((len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1)
+	      / grub_le_to_cpu32 (data->sblock.blksz));
+
+  for (i = pos / grub_le_to_cpu32 (data->sblock.blksz); i < blockcnt; i++)
+    {
+      int blknr;
+      int blockoff = pos % grub_le_to_cpu32 (data->sblock.blksz);
+      int blockend = grub_le_to_cpu32 (data->sblock.blksz);
+
+      int skipfirst = 0;
+
+      blknr = grub_jfs_blkno (data, &data->currinode, i);
+      if (grub_errno)
+	return -1;
+
+      /* Last block.  */
+      if (i == blockcnt - 1)
+	{
+	  blockend = (len + pos) % grub_le_to_cpu32 (data->sblock.blksz);
+
+	  if (!blockend)
+	    blockend = grub_le_to_cpu32 (data->sblock.blksz);
+	}
+
+      /* First block.  */
+      if (i == (pos / (int) grub_le_to_cpu32 (data->sblock.blksz)))
+	{
+	  skipfirst = blockoff;
+	  blockend -= skipfirst;
+	}
+
+      data->disk->read_hook = read_hook;
+      grub_disk_read (data->disk,
+		      blknr << (grub_le_to_cpu16 (data->sblock.log2_blksz)
+				- GRUB_DISK_SECTOR_BITS),
+		      skipfirst, blockend, buf);
+
+      data->disk->read_hook = 0;
+      if (grub_errno)
+	return -1;
+
+      buf += grub_le_to_cpu32 (data->sblock.blksz) - skipfirst;
+    }
+
+  return len;
+}
+
+
+/* Find the file with the pathname PATH on the filesystem described by
+   DATA.  */
+static grub_err_t
+grub_jfs_find_file (struct grub_jfs_data *data, const char *path)
+{
+  char fpath[grub_strlen (path)];
+  char *name = fpath;
+  char *next;
+  unsigned int pos = 0;
+  struct grub_jfs_diropen *diro;
+
+  grub_strncpy (fpath, path, grub_strlen (path) + 1);
+
+  if (grub_jfs_read_inode (data, GRUB_JFS_AGGR_INODE, &data->currinode))
+    return grub_errno;
+
+  /* Skip the first slashes.  */
+  while (*name == '/')
+    {
+      name++;
+      if (!*name)
+	return 0;
+    }
+
+  /* Extract the actual part from the pathname.  */
+  next = grub_strchr (name, '/');
+  if (next)
+    {
+      while (*next == '/')
+	{
+	  next[0] = '\0';
+	  next++;
+	}
+    }
+  diro = grub_jfs_opendir (data, &data->currinode);
+  if (!diro)
+    return grub_errno;
+
+  for (;;)
+    {
+      if (grub_strlen (name) == 0)
+	return GRUB_ERR_NONE;
+
+      if (grub_jfs_getent (diro) == GRUB_ERR_OUT_OF_RANGE)
+	break;
+
+      /* Check if the current direntry matches the current part of the
+	 pathname.  */
+      if (!grub_strcmp (name, diro->name))
+	{
+	  int ino = diro->ino;
+	  int dirino = grub_le_to_cpu32 (data->currinode.inode);
+
+	  grub_jfs_closedir (diro);
+	  diro = 0;
+
+	  if (grub_jfs_read_inode (data, ino, &data->currinode))
+	    break;
+
+	  /* Check if this is a symlink.  */
+	  if ((grub_le_to_cpu32 (data->currinode.mode)
+	       & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_LNK)
+	    {
+	      grub_jfs_lookup_symlink (data, dirino);
+	      if (grub_errno)
+		return grub_errno;
+	    }
+
+	  if (!next)
+	    return 0;
+
+	  pos = 0;
+
+	  name = next;
+	  next = grub_strchr (name, '/');
+	  if (next)
+	    {
+	      next[0] = '\0';
+	      next++;
+	    }
+
+	  /* Open this directory for reading dirents.  */
+	  diro = grub_jfs_opendir (data, &data->currinode);
+	  if (!diro)
+	    return grub_errno;
+
+	  continue;
+	}
+    }
+
+  grub_jfs_closedir (diro);
+  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_jfs_lookup_symlink (struct grub_jfs_data *data, int ino)
+{
+  int size = grub_le_to_cpu64 (data->currinode.size);
+  char symlink[size + 1];
+
+  if (++data->linknest > GRUB_JFS_MAX_SYMLNK_CNT)
+    return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
+
+  if (size <= 128)
+    grub_strncpy (symlink, (char *) (data->currinode.symlink.path), 128);
+  else if (grub_jfs_read_file (data, 0, 0, size, symlink) < 0)
+    return grub_errno;
+
+  symlink[size] = '\0';
+
+  /* The symlink is an absolute path, go back to the root inode.  */
+  if (symlink[0] == '/')
+    ino = 2;
+
+  /* Now load in the old inode.  */
+  if (grub_jfs_read_inode (data, ino, &data->currinode))
+    return grub_errno;
+
+  grub_jfs_find_file (data, symlink);
+  if (grub_errno)
+    grub_error (grub_errno, "Can not follow symlink `%s'.", symlink);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_jfs_dir (grub_device_t device, const char *path,
+	      int (*hook) (const char *filename,
+			   const struct grub_dirhook_info *info))
+{
+  struct grub_jfs_data *data = 0;
+  struct grub_jfs_diropen *diro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_jfs_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  if (grub_jfs_find_file (data, path))
+    goto fail;
+
+  diro = grub_jfs_opendir (data, &data->currinode);
+  if (!diro)
+    goto fail;
+
+  /* Iterate over the dirents in the directory that was found.  */
+  while (grub_jfs_getent (diro) != GRUB_ERR_OUT_OF_RANGE)
+    {
+      struct grub_jfs_inode inode;
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+
+      if (grub_jfs_read_inode (data, diro->ino, &inode))
+	goto fail;
+
+      info.dir = (grub_le_to_cpu32 (inode.mode)
+		  & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR;
+      if (hook (diro->name, &info))
+	goto fail;
+    }
+
+  /* XXX: GRUB_ERR_OUT_OF_RANGE is used for the last dirent.  */
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_errno = 0;
+
+ fail:
+  grub_jfs_closedir (diro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_jfs_open (struct grub_file *file, const char *name)
+{
+  struct grub_jfs_data *data;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_jfs_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  grub_jfs_find_file (data, name);
+  if (grub_errno)
+    goto fail;
+
+  /* It is only possible for open regular files.  */
+  if (! ((grub_le_to_cpu32 (data->currinode.mode)
+	  & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_REG))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file");
+      goto fail;
+    }
+
+  file->data = data;
+  file->size = grub_le_to_cpu64 (data->currinode.size);
+
+  return 0;
+
+ fail:
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+static grub_ssize_t
+grub_jfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_jfs_data *data =
+    (struct grub_jfs_data *) file->data;
+
+  return grub_jfs_read_file (data, file->read_hook, file->offset, len, buf);
+}
+
+
+static grub_err_t
+grub_jfs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_jfs_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_jfs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_jfs_mount (disk);
+  if (data)
+    {
+      *uuid = grub_malloc (40 + sizeof ('\0'));
+
+      grub_sprintf (*uuid, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		    data->sblock.uuid[0], data->sblock.uuid[1],
+		    data->sblock.uuid[2], data->sblock.uuid[3],
+		    data->sblock.uuid[4], data->sblock.uuid[5],
+		    data->sblock.uuid[6], data->sblock.uuid[7],
+		    data->sblock.uuid[8], data->sblock.uuid[9],
+		    data->sblock.uuid[10], data->sblock.uuid[11],
+		    data->sblock.uuid[12], data->sblock.uuid[13],
+		    data->sblock.uuid[14], data->sblock.uuid[15]);
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_jfs_label (grub_device_t device, char **label)
+{
+  struct grub_jfs_data *data;
+  data = grub_jfs_mount (device->disk);
+
+  if (data)
+    *label = grub_strndup ((char *) (data->sblock.volname), 11);
+  else
+    *label = 0;
+
+  return grub_errno;
+}
+
+
+static struct grub_fs grub_jfs_fs =
+  {
+    .name = "jfs",
+    .dir = grub_jfs_dir,
+    .open = grub_jfs_open,
+    .read = grub_jfs_read,
+    .close = grub_jfs_close,
+    .label = grub_jfs_label,
+    .uuid = grub_jfs_uuid,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(jfs)
+{
+  grub_fs_register (&grub_jfs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(jfs)
+{
+  grub_fs_unregister (&grub_jfs_fs);
+}
diff --git a/fs/minix.c b/fs/minix.c
new file mode 100644
index 0000000..08eb607
--- /dev/null
+++ b/fs/minix.c
@@ -0,0 +1,614 @@
+/* minix.c - The minix filesystem, version 1 and 2.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+
+#define GRUB_MINIX_MAGIC	0x137F
+#define GRUB_MINIX2_MAGIC	0x2468
+#define GRUB_MINIX_MAGIC_30	0x138F
+#define GRUB_MINIX2_MAGIC_30	0x2478
+#define GRUB_MINIX_BSIZE	1024U
+#define GRUB_MINIX_LOG2_BSIZE	1
+#define GRUB_MINIX_ROOT_INODE	1
+#define GRUB_MINIX_MAX_SYMLNK_CNT	8
+#define GRUB_MINIX_SBLOCK	2
+
+#define GRUB_MINIX_IFDIR	0040000U
+#define GRUB_MINIX_IFLNK	0120000U
+
+#define GRUB_MINIX_INODE(data,field) (data->version == 1 ? \
+                           data->inode.  field : data->inode2.  field)
+#define GRUB_MINIX_INODE_ENDIAN(data,field,bits1,bits2) (data->version == 1 ?	\
+                        grub_le_to_cpu##bits1 (data->inode.field) :		\
+                        grub_le_to_cpu##bits2 (data->inode2.field))
+#define GRUB_MINIX_INODE_SIZE(data) GRUB_MINIX_INODE_ENDIAN (data,size,16,32)
+#define GRUB_MINIX_INODE_MODE(data) GRUB_MINIX_INODE_ENDIAN (data,mode,16,16)
+#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) GRUB_MINIX_INODE_ENDIAN		\
+                                               (data,dir_zones[blk],16,32)
+#define GRUB_MINIX_INODE_INDIR_ZONE(data)				\
+                        GRUB_MINIX_INODE_ENDIAN (data,indir_zone,16,32)
+#define GRUB_MINIX_INODE_DINDIR_ZONE(data)					\
+                        GRUB_MINIX_INODE_ENDIAN (data,double_indir_zone,16,32)
+#define GRUB_MINIX_INODE_BLKSZ(data) (data->version == 1 ? 2 : 4)
+#define GRUB_MINIX_LOG2_ZONESZ	(GRUB_MINIX_LOG2_BSIZE				\
+				 + grub_le_to_cpu16 (sblock->log2_zone_size))
+#define GRUB_MINIX_ZONESZ	(GRUB_MINIX_BSIZE 				\
+				 << grub_le_to_cpu16 (sblock->log2_zone_size))
+
+struct grub_minix_sblock
+{
+  grub_uint16_t inode_cnt;
+  grub_uint16_t zone_cnt;
+  grub_uint16_t inode_bmap_size;
+  grub_uint16_t zone_bmap_size;
+  grub_uint16_t first_data_zone;
+  grub_uint16_t log2_zone_size;
+  grub_uint32_t max_file_size;
+  grub_uint16_t magic;
+};
+
+struct grub_minix_inode
+{
+  grub_uint16_t mode;
+  grub_uint16_t uid;
+  grub_uint16_t size;
+  grub_uint32_t ctime;
+  grub_uint8_t gid;
+  grub_uint8_t nlinks;
+  grub_uint16_t dir_zones[7];
+  grub_uint16_t indir_zone;
+  grub_uint16_t double_indir_zone;
+};
+
+struct grub_minix2_inode
+{
+  grub_uint16_t mode;
+  grub_uint16_t nlinks;
+  grub_uint16_t uid;
+  grub_uint16_t gid;
+  grub_uint32_t size;
+  grub_uint32_t atime;
+  grub_uint32_t mtime;
+  grub_uint32_t ctime;
+  grub_uint32_t dir_zones[7];
+  grub_uint32_t indir_zone;
+  grub_uint32_t double_indir_zone;
+  grub_uint32_t unused;
+
+};
+
+/* Information about a "mounted" minix filesystem.  */
+struct grub_minix_data
+{
+  struct grub_minix_sblock sblock;
+  struct grub_minix_inode inode;
+  struct grub_minix2_inode inode2;
+  int ino;
+  int linknest;
+  grub_disk_t disk;
+  int version;
+  int filename_size;
+};
+
+static grub_dl_t my_mod;
+
+static grub_err_t grub_minix_find_file (struct grub_minix_data *data,
+					const char *path);
+
+static int
+grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
+{
+  struct grub_minix_sblock *sblock = &data->sblock;
+  int indir;
+
+  auto int grub_get_indir (int, int);
+
+  /* Read the block pointer in ZONE, on the offset NUM.  */
+  int grub_get_indir (int zone, int num)
+    {
+      if (data->version == 1)
+	{
+	  grub_uint16_t indir16;
+	  grub_disk_read (data->disk,
+			  zone << GRUB_MINIX_LOG2_ZONESZ,
+			  sizeof (grub_uint16_t) * num,
+			  sizeof (grub_uint16_t), (char *) &indir16);
+	  return grub_le_to_cpu16 (indir16);
+	}
+      else
+	{
+	  grub_uint32_t indir32;
+	  grub_disk_read (data->disk,
+			  zone << GRUB_MINIX_LOG2_ZONESZ,
+			  sizeof (grub_uint32_t) * num,
+			  sizeof (grub_uint32_t), (char *) &indir32);
+	  return grub_le_to_cpu32 (indir32);
+	}
+    }
+
+  /* Direct block.  */
+  if (blk < 7)
+    return GRUB_MINIX_INODE_DIR_ZONES (data, blk);
+
+  /* Indirect block.  */
+  blk -= 7;
+  if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
+    {
+      indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
+      return indir;
+    }
+
+  /* Double indirect block.  */
+  blk -= GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data);
+  if (blk < (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
+      * (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)))
+    {
+      indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data),
+			      blk / GRUB_MINIX_ZONESZ);
+
+      indir = grub_get_indir (indir, blk % GRUB_MINIX_ZONESZ);
+
+      return indir;
+    }
+
+  /* This should never happen.  */
+  grub_error (GRUB_ERR_OUT_OF_RANGE, "file bigger than maximum size");
+
+  return 0;
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_minix_read_file (struct grub_minix_data *data,
+		      void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+					 unsigned offset, unsigned length),
+		      int pos, grub_disk_addr_t len, char *buf)
+{
+  struct grub_minix_sblock *sblock = &data->sblock;
+  int i;
+  int blockcnt;
+
+  /* Adjust len so it we can't read past the end of the file.  */
+  if (len + pos > GRUB_MINIX_INODE_SIZE (data))
+    len = GRUB_MINIX_INODE_SIZE (data) - pos;
+
+  blockcnt = (len + pos + GRUB_MINIX_BSIZE - 1) / GRUB_MINIX_BSIZE;
+
+  for (i = pos / GRUB_MINIX_BSIZE; i < blockcnt; i++)
+    {
+      int blknr;
+      int blockoff = pos % GRUB_MINIX_BSIZE;
+      int blockend = GRUB_MINIX_BSIZE;
+
+      int skipfirst = 0;
+
+      blknr = grub_minix_get_file_block (data, i);
+      if (grub_errno)
+	return -1;
+
+      /* Last block.  */
+      if (i == blockcnt - 1)
+	{
+	  blockend = (len + pos) % GRUB_MINIX_BSIZE;
+
+	  if (!blockend)
+	    blockend = GRUB_MINIX_BSIZE;
+	}
+
+      /* First block.  */
+      if (i == (pos / (int) GRUB_MINIX_BSIZE))
+	{
+	  skipfirst = blockoff;
+	  blockend -= skipfirst;
+	}
+
+      data->disk->read_hook = read_hook;
+      grub_disk_read (data->disk, blknr << GRUB_MINIX_LOG2_ZONESZ,
+		      skipfirst, blockend, buf);
+
+      data->disk->read_hook = 0;
+      if (grub_errno)
+	return -1;
+
+      buf += GRUB_MINIX_BSIZE - skipfirst;
+    }
+
+  return len;
+}
+
+
+/* Read inode INO from the mounted filesystem described by DATA.  This
+   inode is used by default now.  */
+static grub_err_t
+grub_minix_read_inode (struct grub_minix_data *data, int ino)
+{
+  struct grub_minix_sblock *sblock = &data->sblock;
+
+  /* Block in which the inode is stored.  */
+  int block;
+  data->ino = ino;
+
+  /* The first inode in minix is inode 1.  */
+  ino--;
+
+  block = ((2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
+	    + grub_le_to_cpu16 (sblock->zone_bmap_size))
+	   << GRUB_MINIX_LOG2_BSIZE);
+
+  if (data->version == 1)
+    {
+      block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
+      int offs = (ino % (GRUB_DISK_SECTOR_SIZE
+			 / sizeof (struct grub_minix_inode))
+		  * sizeof (struct grub_minix_inode));
+
+      grub_disk_read (data->disk, block, offs,
+		      sizeof (struct grub_minix_inode), &data->inode);
+    }
+  else
+    {
+      block += ino / (GRUB_DISK_SECTOR_SIZE
+		      / sizeof (struct grub_minix2_inode));
+      int offs = (ino
+		  % (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix2_inode))
+		  * sizeof (struct grub_minix2_inode));
+
+      grub_disk_read (data->disk, block, offs,
+		      sizeof (struct grub_minix2_inode),&data->inode2);
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+
+/* Lookup the symlink the current inode points to.  INO is the inode
+   number of the directory the symlink is relative to.  */
+static grub_err_t
+grub_minix_lookup_symlink (struct grub_minix_data *data, int ino)
+{
+  char symlink[GRUB_MINIX_INODE_SIZE (data) + 1];
+
+  if (++data->linknest > GRUB_MINIX_MAX_SYMLNK_CNT)
+    return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
+
+  if (grub_minix_read_file (data, 0, 0,
+			    GRUB_MINIX_INODE_SIZE (data), symlink) < 0)
+    return grub_errno;
+
+  symlink[GRUB_MINIX_INODE_SIZE (data)] = '\0';
+
+  /* The symlink is an absolute path, go back to the root inode.  */
+  if (symlink[0] == '/')
+    ino = GRUB_MINIX_ROOT_INODE;
+
+  /* Now load in the old inode.  */
+  if (grub_minix_read_inode (data, ino))
+    return grub_errno;
+
+  grub_minix_find_file (data, symlink);
+  if (grub_errno)
+    grub_error (grub_errno, "Can not follow symlink `%s'.", symlink);
+
+  return grub_errno;
+}
+
+
+/* Find the file with the pathname PATH on the filesystem described by
+   DATA.  */
+static grub_err_t
+grub_minix_find_file (struct grub_minix_data *data, const char *path)
+{
+  char fpath[grub_strlen (path) + 1];
+  char *name = fpath;
+  char *next;
+  unsigned int pos = 0;
+  int dirino;
+
+  grub_strcpy (fpath, path);
+
+  /* Skip the first slash.  */
+  if (name[0] == '/')
+    {
+      name++;
+      if (!*name)
+	return 0;
+    }
+
+  /* Extract the actual part from the pathname.  */
+  next = grub_strchr (name, '/');
+  if (next)
+    {
+      next[0] = '\0';
+      next++;
+    }
+
+  do
+    {
+      grub_uint16_t ino;
+      char filename[data->filename_size + 1];
+
+      if (grub_strlen (name) == 0)
+	return GRUB_ERR_NONE;
+
+      if (grub_minix_read_file (data, 0, pos, sizeof (ino),
+				(char *) &ino) < 0)
+	return grub_errno;
+      if (grub_minix_read_file (data, 0, pos + sizeof (ino),
+				data->filename_size, (char *) filename)< 0)
+	return grub_errno;
+
+      filename[data->filename_size] = '\0';
+
+      /* Check if the current direntry matches the current part of the
+	 pathname.  */
+      if (!grub_strcmp (name, filename))
+	{
+	  dirino = data->ino;
+	  grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
+
+	  /* Follow the symlink.  */
+	  if ((GRUB_MINIX_INODE_MODE (data)
+	       & GRUB_MINIX_IFLNK) == GRUB_MINIX_IFLNK)
+	    {
+	      grub_minix_lookup_symlink (data, dirino);
+	      if (grub_errno)
+		return grub_errno;
+	    }
+
+	  if (!next)
+	    return 0;
+
+	  pos = 0;
+
+	  name = next;
+	  next = grub_strchr (name, '/');
+	  if (next)
+	    {
+	      next[0] = '\0';
+	      next++;
+	    }
+
+     	  if ((GRUB_MINIX_INODE_MODE (data)
+	       & GRUB_MINIX_IFDIR) != GRUB_MINIX_IFDIR)
+	    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+
+	  continue;
+	}
+
+      pos += sizeof (ino) + data->filename_size;
+    } while (pos < GRUB_MINIX_INODE_SIZE (data));
+
+  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+  return grub_errno;
+}
+
+
+/* Mount the filesystem on the disk DISK.  */
+static struct grub_minix_data *
+grub_minix_mount (grub_disk_t disk)
+{
+  struct grub_minix_data *data;
+
+  data = grub_malloc (sizeof (struct grub_minix_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  grub_disk_read (disk, GRUB_MINIX_SBLOCK, 0,
+		  sizeof (struct grub_minix_sblock),&data->sblock);
+  if (grub_errno)
+    goto fail;
+
+  if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC)
+    {
+      data->version = 1;
+      data->filename_size = 14;
+    }
+  else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC)
+    {
+      data->version = 2;
+      data->filename_size = 14;
+    }
+  else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC_30)
+    {
+      data->version = 1;
+      data->filename_size = 30;
+    }
+  else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC_30)
+    {
+      data->version = 2;
+      data->filename_size = 30;
+    }
+  else
+    goto fail;
+
+  data->disk = disk;
+  data->linknest = 0;
+
+  return data;
+
+ fail:
+  grub_free (data);
+  grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem");
+  return 0;
+}
+
+static grub_err_t
+grub_minix_dir (grub_device_t device, const char *path,
+		  int (*hook) (const char *filename,
+			       const struct grub_dirhook_info *info))
+{
+  struct grub_minix_data *data = 0;
+  struct grub_minix_sblock *sblock;
+  unsigned int pos = 0;
+
+  data = grub_minix_mount (device->disk);
+  if (!data)
+    return grub_errno;
+
+  grub_minix_read_inode (data, GRUB_MINIX_ROOT_INODE);
+  if (grub_errno)
+    goto fail;
+
+  sblock = &data->sblock;
+
+  grub_minix_find_file (data, path);
+  if (grub_errno)
+    goto fail;
+
+  if ((GRUB_MINIX_INODE_MODE (data) & GRUB_MINIX_IFDIR) != GRUB_MINIX_IFDIR)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      goto fail;
+    }
+
+  while (pos < GRUB_MINIX_INODE_SIZE (data))
+    {
+      grub_uint16_t ino;
+      char filename[data->filename_size + 1];
+      int dirino = data->ino;
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+
+
+      if (grub_minix_read_file (data, 0, pos, sizeof (ino),
+				(char *) &ino) < 0)
+	return grub_errno;
+
+      if (grub_minix_read_file (data, 0, pos + sizeof (ino),
+				data->filename_size,
+				(char *) filename) < 0)
+	return grub_errno;
+      filename[data->filename_size] = '\0';
+
+      /* The filetype is not stored in the dirent.  Read the inode to
+	 find out the filetype.  This *REALLY* sucks.  */
+      grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
+      info.dir = ((GRUB_MINIX_INODE_MODE (data)
+		   & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
+      if (hook (filename, &info) ? 1 : 0)
+	break;
+
+      /* Load the old inode back in.  */
+      grub_minix_read_inode (data, dirino);
+
+      pos += sizeof (ino) + data->filename_size;
+    }
+
+ fail:
+  grub_free (data);
+  return grub_errno;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_minix_open (struct grub_file *file, const char *name)
+{
+  struct grub_minix_data *data;
+  data = grub_minix_mount (file->device->disk);
+  if (!data)
+    return grub_errno;
+
+  /* Open the inode op the root directory.  */
+  grub_minix_read_inode (data, GRUB_MINIX_ROOT_INODE);
+  if (grub_errno)
+    {
+      grub_free (data);
+      return grub_errno;
+    }
+
+  if (!name || name[0] != '/')
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
+      return grub_errno;
+    }
+
+  /* Traverse the directory tree to the node that should be
+     opened.  */
+  grub_minix_find_file (data, name);
+  if (grub_errno)
+    {
+      grub_free (data);
+      return grub_errno;
+    }
+
+  file->data = data;
+  file->size = GRUB_MINIX_INODE_SIZE (data);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_ssize_t
+grub_minix_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_minix_data *data =
+    (struct grub_minix_data *) file->data;
+
+  return grub_minix_read_file (data, file->read_hook, file->offset, len, buf);
+}
+
+
+static grub_err_t
+grub_minix_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_err_t
+grub_minix_label (grub_device_t device __attribute ((unused)),
+		char **label __attribute ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+
+
+static struct grub_fs grub_minix_fs =
+  {
+    .name = "minix",
+    .dir = grub_minix_dir,
+    .open = grub_minix_open,
+    .read = grub_minix_read,
+    .close = grub_minix_close,
+    .label = grub_minix_label,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(minix)
+{
+  grub_fs_register (&grub_minix_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(minix)
+{
+  grub_fs_unregister (&grub_minix_fs);
+}
diff --git a/fs/ntfs.c b/fs/ntfs.c
new file mode 100644
index 0000000..163f3e0
--- /dev/null
+++ b/fs/ntfs.c
@@ -0,0 +1,1108 @@
+/* ntfs.c - NTFS filesystem */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/fshelp.h>
+#include <grub/ntfs.h>
+
+static grub_dl_t my_mod;
+
+ntfscomp_func_t grub_ntfscomp_func;
+
+static grub_err_t
+fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic)
+{
+  int ss;
+  char *pu;
+  grub_uint16_t us;
+
+  if (grub_memcmp (buf, magic, 4))
+    return grub_error (GRUB_ERR_BAD_FS, "%s label not found", magic);
+
+  ss = u16at (buf, 6) - 1;
+  if (ss * (int) data->blocksize != len * GRUB_DISK_SECTOR_SIZE)
+    return grub_error (GRUB_ERR_BAD_FS, "Size not match",
+		       ss * (int) data->blocksize,
+		       len * GRUB_DISK_SECTOR_SIZE);
+  pu = buf + u16at (buf, 4);
+  us = u16at (pu, 0);
+  buf -= 2;
+  while (ss > 0)
+    {
+      buf += data->blocksize;
+      pu += 2;
+      if (u16at (buf, 0) != us)
+	return grub_error (GRUB_ERR_BAD_FS, "Fixup signature not match");
+      v16at (buf, 0) = v16at (pu, 0);
+      ss--;
+    }
+
+  return 0;
+}
+
+static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf,
+			    grub_uint32_t mftno);
+static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest,
+			     grub_uint32_t ofs, grub_uint32_t len,
+			     int cached,
+			     void
+			     NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
+							    sector,
+							    unsigned offset,
+							    unsigned length));
+
+static grub_err_t read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
+			     grub_uint32_t ofs, grub_uint32_t len,
+			     int cached,
+			     void
+			     NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
+							    sector,
+							    unsigned offset,
+							    unsigned length));
+
+static void
+init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
+{
+  at->mft = mft;
+  at->flags = (mft == &mft->data->mmft) ? AF_MMFT : 0;
+  at->attr_nxt = mft->buf + u16at (mft->buf, 0x14);
+  at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL;
+}
+
+static void
+free_attr (struct grub_ntfs_attr *at)
+{
+  grub_free (at->emft_buf);
+  grub_free (at->edat_buf);
+  grub_free (at->sbuf);
+}
+
+static char *
+find_attr (struct grub_ntfs_attr *at, unsigned char attr)
+{
+  if (at->flags & AF_ALST)
+    {
+    retry:
+      while (at->attr_nxt < at->attr_end)
+	{
+	  at->attr_cur = at->attr_nxt;
+	  at->attr_nxt += u16at (at->attr_cur, 4);
+	  if (((unsigned char) *at->attr_cur == attr) || (attr == 0))
+	    {
+	      char *new_pos;
+
+	      if (at->flags & AF_MMFT)
+		{
+		  if ((grub_disk_read
+		       (at->mft->data->disk, v32at (at->attr_cur, 0x10), 0,
+			512, at->emft_buf))
+		      ||
+		      (grub_disk_read
+		       (at->mft->data->disk, v32at (at->attr_cur, 0x14), 0,
+			512, at->emft_buf + 512)))
+		    return NULL;
+
+		  if (fixup
+		      (at->mft->data, at->emft_buf, at->mft->data->mft_size,
+		       "FILE"))
+		    return NULL;
+		}
+	      else
+		{
+		  if (read_mft (at->mft->data, at->emft_buf,
+				u32at (at->attr_cur, 0x10)))
+		    return NULL;
+		}
+
+	      new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)];
+	      while ((unsigned char) *new_pos != 0xFF)
+		{
+		  if (((unsigned char) *new_pos ==
+		       (unsigned char) *at->attr_cur)
+		      && (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18)))
+		    {
+		      return new_pos;
+		    }
+		  new_pos += u16at (new_pos, 4);
+		}
+	      grub_error (GRUB_ERR_BAD_FS,
+			  "Can\'t find 0x%X in attribute list",
+			  (unsigned char) *at->attr_cur);
+	      return NULL;
+	    }
+	}
+      return NULL;
+    }
+  at->attr_cur = at->attr_nxt;
+  while ((unsigned char) *at->attr_cur != 0xFF)
+    {
+      at->attr_nxt += u16at (at->attr_cur, 4);
+      if ((unsigned char) *at->attr_cur == AT_ATTRIBUTE_LIST)
+	at->attr_end = at->attr_cur;
+      if (((unsigned char) *at->attr_cur == attr) || (attr == 0))
+	return at->attr_cur;
+      at->attr_cur = at->attr_nxt;
+    }
+  if (at->attr_end)
+    {
+      char *pa;
+
+      at->emft_buf = grub_malloc (at->mft->data->mft_size << BLK_SHR);
+      if (at->emft_buf == NULL)
+	return NULL;
+
+      pa = at->attr_end;
+      if (pa[8])
+	{
+          int n;
+
+          n = ((u32at (pa, 0x30) + GRUB_DISK_SECTOR_SIZE - 1)
+               & (~(GRUB_DISK_SECTOR_SIZE - 1)));
+	  at->attr_cur = at->attr_end;
+	  at->edat_buf = grub_malloc (n);
+	  if (!at->edat_buf)
+	    return NULL;
+	  if (read_data (at, pa, at->edat_buf, 0, n, 0, 0))
+	    {
+	      grub_error (GRUB_ERR_BAD_FS,
+			  "Fail to read non-resident attribute list");
+	      return NULL;
+	    }
+	  at->attr_nxt = at->edat_buf;
+	  at->attr_end = at->edat_buf + u32at (pa, 0x30);
+	}
+      else
+	{
+	  at->attr_nxt = at->attr_end + u16at (pa, 0x14);
+	  at->attr_end = at->attr_end + u32at (pa, 4);
+	}
+      at->flags |= AF_ALST;
+      while (at->attr_nxt < at->attr_end)
+	{
+	  if (((unsigned char) *at->attr_nxt == attr) || (attr == 0))
+	    break;
+	  at->attr_nxt += u16at (at->attr_nxt, 4);
+	}
+      if (at->attr_nxt >= at->attr_end)
+	return NULL;
+
+      if ((at->flags & AF_MMFT) && (attr == AT_DATA))
+	{
+	  at->flags |= AF_GPOS;
+	  at->attr_cur = at->attr_nxt;
+	  pa = at->attr_cur;
+	  v32at (pa, 0x10) = at->mft->data->mft_start;
+	  v32at (pa, 0x14) = at->mft->data->mft_start + 1;
+	  pa = at->attr_nxt + u16at (pa, 4);
+	  while (pa < at->attr_end)
+	    {
+	      if ((unsigned char) *pa != attr)
+		break;
+	      if (read_attr
+		  (at, pa + 0x10,
+		   u32at (pa, 0x10) * (at->mft->data->mft_size << BLK_SHR),
+		   at->mft->data->mft_size << BLK_SHR, 0, 0))
+		return NULL;
+	      pa += u16at (pa, 4);
+	    }
+	  at->attr_nxt = at->attr_cur;
+	  at->flags &= ~AF_GPOS;
+	}
+      goto retry;
+    }
+  return NULL;
+}
+
+static char *
+locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft,
+	     unsigned char attr)
+{
+  char *pa;
+
+  init_attr (at, mft);
+  if ((pa = find_attr (at, attr)) == NULL)
+    return NULL;
+  if ((at->flags & AF_ALST) == 0)
+    {
+      while (1)
+	{
+	  if ((pa = find_attr (at, attr)) == NULL)
+	    break;
+	  if (at->flags & AF_ALST)
+	    return pa;
+	}
+      grub_errno = GRUB_ERR_NONE;
+      free_attr (at);
+      init_attr (at, mft);
+      pa = find_attr (at, attr);
+    }
+  return pa;
+}
+
+static char *
+read_run_data (char *run, int nn, grub_uint32_t * val, int sig)
+{
+  grub_uint32_t r, v;
+
+  r = 0;
+  v = 1;
+
+  while (nn--)
+    {
+      r += v * (*(unsigned char *) (run++));
+      v <<= 8;
+    }
+
+  if ((sig) && (r & (v >> 1)))
+    r -= v;
+
+  *val = r;
+  return run;
+}
+
+grub_err_t
+grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx)
+{
+  int c1, c2;
+  grub_uint32_t val;
+  char *run;
+
+  run = ctx->cur_run;
+retry:
+  c1 = ((unsigned char) (*run) & 0xF);
+  c2 = ((unsigned char) (*run) >> 4);
+  if (!c1)
+    {
+      if ((ctx->attr) && (ctx->attr->flags & AF_ALST))
+	{
+	  void NESTED_FUNC_ATTR (*save_hook) (grub_disk_addr_t sector,
+					      unsigned offset,
+					      unsigned length);
+
+	  save_hook = ctx->comp.disk->read_hook;
+	  ctx->comp.disk->read_hook = 0;
+	  run = find_attr (ctx->attr, (unsigned char) *ctx->attr->attr_cur);
+	  ctx->comp.disk->read_hook = save_hook;
+	  if (run)
+	    {
+	      if (run[8] == 0)
+		return grub_error (GRUB_ERR_BAD_FS,
+				   "$DATA should be non-resident");
+
+	      run += u16at (run, 0x20);
+	      ctx->curr_lcn = 0;
+	      goto retry;
+	    }
+	}
+      return grub_error (GRUB_ERR_BAD_FS, "Run list overflown");
+    }
+  run = read_run_data (run + 1, c1, &val, 0);	/* length of current VCN */
+  ctx->curr_vcn = ctx->next_vcn;
+  ctx->next_vcn += val;
+  run = read_run_data (run, c2, &val, 1);	/* offset to previous LCN */
+  ctx->curr_lcn += val;
+  if (val == 0)
+    ctx->flags |= RF_BLNK;
+  else
+    ctx->flags &= ~RF_BLNK;
+  ctx->cur_run = run;
+  return 0;
+}
+
+static grub_disk_addr_t
+grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block)
+{
+  struct grub_ntfs_rlst *ctx;
+
+  ctx = (struct grub_ntfs_rlst *) node;
+  if ((grub_uint32_t) block >= ctx->next_vcn)
+    {
+      if (grub_ntfs_read_run_list (ctx))
+	return -1;
+      return ctx->curr_lcn;
+    }
+  else
+    return (ctx->flags & RF_BLNK) ? 0 : ((grub_uint32_t) block -
+					 ctx->curr_vcn + ctx->curr_lcn);
+}
+
+static grub_err_t
+read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs,
+	   grub_uint32_t len, int cached,
+	   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+					       unsigned offset,
+					       unsigned length))
+{
+  grub_uint32_t vcn;
+  struct grub_ntfs_rlst cc, *ctx;
+
+  if (len == 0)
+    return 0;
+
+  grub_memset (&cc, 0, sizeof (cc));
+  ctx = &cc;
+  ctx->attr = at;
+  ctx->comp.spc = at->mft->data->spc;
+  ctx->comp.disk = at->mft->data->disk;
+
+  if (pa[8] == 0)
+    {
+      if (ofs + len > u32at (pa, 0x10))
+	return grub_error (GRUB_ERR_BAD_FS, "Read out of range");
+      grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len);
+      return 0;
+    }
+
+  if (u16at (pa, 0xC) & FLAG_COMPRESSED)
+    ctx->flags |= RF_COMP;
+  else
+    ctx->flags &= ~RF_COMP;
+  ctx->cur_run = pa + u16at (pa, 0x20);
+
+  if (ctx->flags & RF_COMP)
+    {
+      if (!cached)
+	return grub_error (GRUB_ERR_BAD_FS, "Attribute can\'t be compressed");
+
+      if (at->sbuf)
+	{
+	  if ((ofs & (~(COM_LEN - 1))) == at->save_pos)
+	    {
+	      grub_uint32_t n;
+
+	      n = COM_LEN - (ofs - at->save_pos);
+	      if (n > len)
+		n = len;
+
+	      grub_memcpy (dest, at->sbuf + ofs - at->save_pos, n);
+	      if (n == len)
+		return 0;
+
+	      dest += n;
+	      len -= n;
+	      ofs += n;
+	    }
+	}
+      else
+	{
+	  at->sbuf = grub_malloc (COM_LEN);
+	  if (at->sbuf == NULL)
+	    return grub_errno;
+	  at->save_pos = 1;
+	}
+
+      vcn = ctx->target_vcn = (ofs / COM_LEN) * (COM_SEC / ctx->comp.spc);
+      ctx->target_vcn &= ~0xF;
+    }
+  else
+    vcn = ctx->target_vcn = (ofs >> BLK_SHR) / ctx->comp.spc;
+
+  ctx->next_vcn = u32at (pa, 0x10);
+  ctx->curr_lcn = 0;
+  while (ctx->next_vcn <= ctx->target_vcn)
+    {
+      if (grub_ntfs_read_run_list (ctx))
+	return grub_errno;
+    }
+
+  if (at->flags & AF_GPOS)
+    {
+      grub_uint32_t st0, st1;
+
+      st0 =
+	(ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc +
+	((ofs >> BLK_SHR) % ctx->comp.spc);
+      st1 = st0 + 1;
+      if (st1 ==
+	  (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc)
+	{
+	  if (grub_ntfs_read_run_list (ctx))
+	    return grub_errno;
+	  st1 = ctx->curr_lcn * ctx->comp.spc;
+	}
+      v32at (dest, 0) = st0;
+      v32at (dest, 4) = st1;
+      return 0;
+    }
+
+  if (!(ctx->flags & RF_COMP))
+    {
+      unsigned int pow;
+
+      if (!grub_fshelp_log2blksize (ctx->comp.spc, &pow))
+	grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx,
+			       read_hook, ofs, len, dest,
+			       grub_ntfs_read_block, ofs + len, pow);
+      return grub_errno;
+    }
+
+  return (grub_ntfscomp_func) ? grub_ntfscomp_func (at, dest, ofs, len, ctx,
+						    vcn) :
+    grub_error (GRUB_ERR_BAD_FS, "ntfscomp module not loaded");
+}
+
+static grub_err_t
+read_attr (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs,
+	   grub_uint32_t len, int cached,
+	   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+					       unsigned offset,
+					       unsigned length))
+{
+  char *save_cur;
+  unsigned char attr;
+  char *pp;
+  grub_err_t ret;
+
+  save_cur = at->attr_cur;
+  at->attr_nxt = at->attr_cur;
+  attr = (unsigned char) *at->attr_nxt;
+  if (at->flags & AF_ALST)
+    {
+      char *pa;
+      grub_uint32_t vcn;
+
+      vcn = ofs / (at->mft->data->spc << BLK_SHR);
+      pa = at->attr_nxt + u16at (at->attr_nxt, 4);
+      while (pa < at->attr_end)
+	{
+	  if ((unsigned char) *pa != attr)
+	    break;
+	  if (u32at (pa, 8) > vcn)
+	    break;
+	  at->attr_nxt = pa;
+	  pa += u16at (pa, 4);
+	}
+    }
+  pp = find_attr (at, attr);
+  if (pp)
+    ret = read_data (at, pp, dest, ofs, len, cached, read_hook);
+  else
+    ret =
+      (grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS,
+					      "Attribute not found");
+  at->attr_cur = save_cur;
+  return ret;
+}
+
+static grub_err_t
+read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno)
+{
+  if (read_attr
+      (&data->mmft.attr, buf, mftno * (data->mft_size << BLK_SHR),
+       data->mft_size << BLK_SHR, 0, 0))
+    return grub_error (GRUB_ERR_BAD_FS, "Read MFT 0x%X fails", mftno);
+  return fixup (data, buf, data->mft_size, "FILE");
+}
+
+static grub_err_t
+init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno)
+{
+  unsigned short flag;
+
+  mft->inode_read = 1;
+
+  mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR);
+  if (mft->buf == NULL)
+    return grub_errno;
+
+  if (read_mft (mft->data, mft->buf, mftno))
+    return grub_errno;
+
+  flag = u16at (mft->buf, 0x16);
+  if ((flag & 1) == 0)
+    return grub_error (GRUB_ERR_BAD_FS, "MFT 0x%X is not in use", mftno);
+
+  if ((flag & 2) == 0)
+    {
+      char *pa;
+
+      pa = locate_attr (&mft->attr, mft, AT_DATA);
+      if (pa == NULL)
+	return grub_error (GRUB_ERR_BAD_FS, "No $DATA in MFT 0x%X", mftno);
+
+      if (!pa[8])
+	mft->size = u32at (pa, 0x10);
+      else
+	mft->size = u64at (pa, 0x30);
+
+      if ((mft->attr.flags & AF_ALST) == 0)
+	mft->attr.attr_end = 0;	/*  Don't jump to attribute list */
+    }
+  else
+    init_attr (&mft->attr, mft);
+
+  return 0;
+}
+
+static void
+free_file (struct grub_ntfs_file *mft)
+{
+  free_attr (&mft->attr);
+  grub_free (mft->buf);
+}
+
+static int
+list_file (struct grub_ntfs_file *diro, char *pos,
+	   int NESTED_FUNC_ATTR
+	   (*hook) (const char *filename,
+		    enum grub_fshelp_filetype filetype,
+		    grub_fshelp_node_t node))
+{
+  char *np;
+  int ns;
+
+  while (1)
+    {
+      char *ustr, namespace;
+
+      if (pos[0xC] & 2)		/* end signature */
+	break;
+
+      np = pos + 0x50;
+      ns = (unsigned char) *(np++);
+      namespace = *(np++);
+
+      /*
+       *  Ignore files in DOS namespace, as they will reappear as Win32
+       *  names.
+       */
+      if ((ns) && (namespace != 2))
+	{
+	  enum grub_fshelp_filetype type;
+	  struct grub_ntfs_file *fdiro;
+
+	  if (u16at (pos, 4))
+	    {
+	      grub_error (GRUB_ERR_BAD_FS, "64-bit MFT number");
+	      return 0;
+	    }
+
+	  type =
+	    (u32at (pos, 0x48) & ATTR_DIRECTORY) ? GRUB_FSHELP_DIR :
+	    GRUB_FSHELP_REG;
+
+	  fdiro = grub_zalloc (sizeof (struct grub_ntfs_file));
+	  if (!fdiro)
+	    return 0;
+
+	  fdiro->data = diro->data;
+	  fdiro->ino = u32at (pos, 0);
+
+	  ustr = grub_malloc (ns * 4 + 1);
+	  if (ustr == NULL)
+	    return 0;
+	  *grub_utf16_to_utf8 ((grub_uint8_t *) ustr, (grub_uint16_t *) np,
+			       ns) = '\0';
+
+          if (namespace)
+            type |= GRUB_FSHELP_CASE_INSENSITIVE;
+
+	  if (hook (ustr, type, fdiro))
+	    {
+	      grub_free (ustr);
+	      return 1;
+	    }
+
+	  grub_free (ustr);
+	}
+      pos += u16at (pos, 8);
+    }
+  return 0;
+}
+
+static int
+grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
+		       int NESTED_FUNC_ATTR
+		       (*hook) (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node))
+{
+  unsigned char *bitmap;
+  struct grub_ntfs_attr attr, *at;
+  char *cur_pos, *indx, *bmp;
+  int bitmap_len, ret = 0;
+  struct grub_ntfs_file *mft;
+
+  mft = (struct grub_ntfs_file *) dir;
+
+  if (!mft->inode_read)
+    {
+      if (init_file (mft, mft->ino))
+	return 0;
+    }
+
+  indx = NULL;
+  bmp = NULL;
+
+  at = &attr;
+  init_attr (at, mft);
+  while (1)
+    {
+      if ((cur_pos = find_attr (at, AT_INDEX_ROOT)) == NULL)
+	{
+	  grub_error (GRUB_ERR_BAD_FS, "No $INDEX_ROOT");
+	  goto done;
+	}
+
+      /* Resident, Namelen=4, Offset=0x18, Flags=0x00, Name="$I30" */
+      if ((u32at (cur_pos, 8) != 0x180400) ||
+	  (u32at (cur_pos, 0x18) != 0x490024) ||
+	  (u32at (cur_pos, 0x1C) != 0x300033))
+	continue;
+      cur_pos += u16at (cur_pos, 0x14);
+      if (*cur_pos != 0x30)	/* Not filename index */
+	continue;
+      break;
+    }
+
+  cur_pos += 0x10;		/* Skip index root */
+  ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook);
+  if (ret)
+    goto done;
+
+  bitmap = NULL;
+  bitmap_len = 0;
+  free_attr (at);
+  init_attr (at, mft);
+  while ((cur_pos = find_attr (at, AT_BITMAP)) != NULL)
+    {
+      int ofs;
+
+      ofs = (unsigned char) cur_pos[0xA];
+      /* Namelen=4, Name="$I30" */
+      if ((cur_pos[9] == 4) &&
+	  (u32at (cur_pos, ofs) == 0x490024) &&
+	  (u32at (cur_pos, ofs + 4) == 0x300033))
+	{
+          int is_resident = (cur_pos[8] == 0);
+
+          bitmap_len = ((is_resident) ? u32at (cur_pos, 0x10) :
+                        u32at (cur_pos, 0x28));
+
+          bmp = grub_malloc (bitmap_len);
+          if (bmp == NULL)
+            goto done;
+
+	  if (is_resident)
+	    {
+              grub_memcpy (bmp, (char *) (cur_pos + u16at (cur_pos, 0x14)),
+                           bitmap_len);
+	    }
+          else
+            {
+              if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0))
+                {
+                  grub_error (GRUB_ERR_BAD_FS,
+                              "Fails to read non-resident $BITMAP");
+                  goto done;
+                }
+              bitmap_len = u32at (cur_pos, 0x30);
+            }
+
+          bitmap = (unsigned char *) bmp;
+	  break;
+	}
+    }
+
+  free_attr (at);
+  cur_pos = locate_attr (at, mft, AT_INDEX_ALLOCATION);
+  while (cur_pos != NULL)
+    {
+      /* Non-resident, Namelen=4, Offset=0x40, Flags=0, Name="$I30" */
+      if ((u32at (cur_pos, 8) == 0x400401) &&
+	  (u32at (cur_pos, 0x40) == 0x490024) &&
+	  (u32at (cur_pos, 0x44) == 0x300033))
+	break;
+      cur_pos = find_attr (at, AT_INDEX_ALLOCATION);
+    }
+
+  if ((!cur_pos) && (bitmap))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "$BITMAP without $INDEX_ALLOCATION");
+      goto done;
+    }
+
+  if (bitmap)
+    {
+      grub_uint32_t v, i;
+
+      indx = grub_malloc (mft->data->idx_size << BLK_SHR);
+      if (indx == NULL)
+	goto done;
+
+      v = 1;
+      for (i = 0; i < (grub_uint32_t) bitmap_len * 8; i++)
+	{
+	  if (*bitmap & v)
+	    {
+	      if ((read_attr
+		   (at, indx, i * (mft->data->idx_size << BLK_SHR),
+		    (mft->data->idx_size << BLK_SHR), 0, 0))
+		  || (fixup (mft->data, indx, mft->data->idx_size, "INDX")))
+		goto done;
+	      ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook);
+	      if (ret)
+		goto done;
+	    }
+	  v <<= 1;
+	  if (v >= 0x100)
+	    {
+	      v = 1;
+	      bitmap++;
+	    }
+	}
+    }
+
+done:
+  free_attr (at);
+  grub_free (indx);
+  grub_free (bmp);
+
+  return ret;
+}
+
+static struct grub_ntfs_data *
+grub_ntfs_mount (grub_disk_t disk)
+{
+  struct grub_ntfs_bpb bpb;
+  struct grub_ntfs_data *data = 0;
+
+  if (!disk)
+    goto fail;
+
+  data = (struct grub_ntfs_data *) grub_zalloc (sizeof (*data));
+  if (!data)
+    goto fail;
+
+  data->disk = disk;
+
+  /* Read the BPB.  */
+  if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
+    goto fail;
+
+  if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4))
+    goto fail;
+
+  data->blocksize = grub_le_to_cpu16 (bpb.bytes_per_sector);
+  data->spc = bpb.sectors_per_cluster * (data->blocksize >> BLK_SHR);
+
+  if (bpb.clusters_per_mft > 0)
+    data->mft_size = data->spc * bpb.clusters_per_mft;
+  else
+    data->mft_size = 1 << (-bpb.clusters_per_mft - BLK_SHR);
+
+  if (bpb.clusters_per_index > 0)
+    data->idx_size = data->spc * bpb.clusters_per_index;
+  else
+    data->idx_size = 1 << (-bpb.clusters_per_index - BLK_SHR);
+
+  data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) * data->spc;
+
+  if ((data->mft_size > MAX_MFT) || (data->idx_size > MAX_IDX))
+    goto fail;
+
+  data->mmft.data = data;
+  data->cmft.data = data;
+
+  data->mmft.buf = grub_malloc (data->mft_size << BLK_SHR);
+  if (!data->mmft.buf)
+    goto fail;
+
+  if (grub_disk_read
+      (disk, data->mft_start, 0, data->mft_size << BLK_SHR, data->mmft.buf))
+    goto fail;
+
+  data->uuid = grub_le_to_cpu64 (bpb.num_serial);
+
+  if (fixup (data, data->mmft.buf, data->mft_size, "FILE"))
+    goto fail;
+
+  if (!locate_attr (&data->mmft.attr, &data->mmft, AT_DATA))
+    goto fail;
+
+  if (init_file (&data->cmft, FILE_ROOT))
+    goto fail;
+
+  return data;
+
+fail:
+  grub_error (GRUB_ERR_BAD_FS, "not an ntfs filesystem");
+
+  if (data)
+    {
+      free_file (&data->mmft);
+      free_file (&data->cmft);
+      grub_free (data);
+    }
+  return 0;
+}
+
+static grub_err_t
+grub_ntfs_dir (grub_device_t device, const char *path,
+	       int (*hook) (const char *filename,
+			    const struct grub_dirhook_info *info))
+{
+  struct grub_ntfs_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+				     enum grub_fshelp_filetype filetype,
+				     grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node)
+  {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+  }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ntfs_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate_dir,
+			 0, GRUB_FSHELP_DIR);
+
+  if (grub_errno)
+    goto fail;
+
+  grub_ntfs_iterate_dir (fdiro, iterate);
+
+fail:
+  if ((fdiro) && (fdiro != &data->cmft))
+    {
+      free_file (fdiro);
+      grub_free (fdiro);
+    }
+  if (data)
+    {
+      free_file (&data->mmft);
+      free_file (&data->cmft);
+      grub_free (data);
+    }
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_ntfs_open (grub_file_t file, const char *name)
+{
+  struct grub_ntfs_data *data = 0;
+  struct grub_fshelp_node *mft = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ntfs_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->cmft, &mft, grub_ntfs_iterate_dir,
+			 0, GRUB_FSHELP_REG);
+
+  if (grub_errno)
+    goto fail;
+
+  if (mft != &data->cmft)
+    {
+      free_file (&data->cmft);
+      grub_memcpy (&data->cmft, mft, sizeof (*mft));
+      grub_free (mft);
+      if (!data->cmft.inode_read)
+	{
+	  if (init_file (&data->cmft, data->cmft.ino))
+	    goto fail;
+	}
+    }
+
+  file->size = data->cmft.size;
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+fail:
+  if (data)
+    {
+      free_file (&data->mmft);
+      free_file (&data->cmft);
+      grub_free (data);
+    }
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_ntfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_ntfs_file *mft;
+
+  mft = &((struct grub_ntfs_data *) file->data)->cmft;
+  if (file->read_hook)
+    mft->attr.save_pos = 1;
+
+  read_attr (&mft->attr, buf, file->offset, len, 1, file->read_hook);
+  return (grub_errno) ? 0 : len;
+}
+
+static grub_err_t
+grub_ntfs_close (grub_file_t file)
+{
+  struct grub_ntfs_data *data;
+
+  data = file->data;
+
+  if (data)
+    {
+      free_file (&data->mmft);
+      free_file (&data->cmft);
+      grub_free (data);
+    }
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_ntfs_label (grub_device_t device, char **label)
+{
+  struct grub_ntfs_data *data = 0;
+  struct grub_fshelp_node *mft = 0;
+  char *pa;
+
+  grub_dl_ref (my_mod);
+
+  *label = 0;
+
+  data = grub_ntfs_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file ("/$Volume", &data->cmft, &mft, grub_ntfs_iterate_dir,
+			 0, GRUB_FSHELP_REG);
+
+  if (grub_errno)
+    goto fail;
+
+  if (!mft->inode_read)
+    {
+      mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR);
+      if (mft->buf == NULL)
+	goto fail;
+
+      if (read_mft (mft->data, mft->buf, mft->ino))
+	goto fail;
+    }
+
+  init_attr (&mft->attr, mft);
+  pa = find_attr (&mft->attr, AT_VOLUME_NAME);
+  if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10)))
+    {
+      char *buf;
+      int len;
+
+      len = u32at (pa, 0x10) / 2;
+      buf = grub_malloc (len * 4 + 1);
+      pa += u16at (pa, 0x14);
+      *grub_utf16_to_utf8 ((grub_uint8_t *) buf, (grub_uint16_t *) pa, len) =
+	'\0';
+      *label = buf;
+    }
+
+fail:
+  if ((mft) && (mft != &data->cmft))
+    {
+      free_file (mft);
+      grub_free (mft);
+    }
+  if (data)
+    {
+      free_file (&data->mmft);
+      free_file (&data->cmft);
+      grub_free (data);
+    }
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_ntfs_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_ntfs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ntfs_mount (disk);
+  if (data)
+    {
+      *uuid = grub_malloc (16 + sizeof ('\0'));
+      grub_sprintf (*uuid, "%016llx", (unsigned long long) data->uuid);
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_ntfs_fs =
+  {
+    .name = "ntfs",
+    .dir = grub_ntfs_dir,
+    .open = grub_ntfs_open,
+    .read = grub_ntfs_read,
+    .close = grub_ntfs_close,
+    .label = grub_ntfs_label,
+    .uuid = grub_ntfs_uuid,
+#ifdef GRUB_UTIL
+    .reserved_first_sector = 1,
+#endif
+    .next = 0
+};
+
+GRUB_MOD_INIT (ntfs)
+{
+  grub_fs_register (&grub_ntfs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI (ntfs)
+{
+  grub_fs_unregister (&grub_ntfs_fs);
+}
diff --git a/fs/ntfscomp.c b/fs/ntfscomp.c
new file mode 100644
index 0000000..20c79ac
--- /dev/null
+++ b/fs/ntfscomp.c
@@ -0,0 +1,374 @@
+/* ntfscomp.c - compression support for the NTFS filesystem */
+/*
+ *  Copyright (C) 2007 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/fshelp.h>
+#include <grub/ntfs.h>
+
+static grub_err_t
+decomp_nextvcn (struct grub_ntfs_comp *cc)
+{
+  if (cc->comp_head >= cc->comp_tail)
+    return grub_error (GRUB_ERR_BAD_FS, "Compression block overflown");
+  if (grub_disk_read
+      (cc->disk,
+       (cc->comp_table[cc->comp_head][1] -
+	(cc->comp_table[cc->comp_head][0] - cc->cbuf_vcn)) * cc->spc, 0,
+       cc->spc << BLK_SHR, cc->cbuf))
+    return grub_errno;
+  cc->cbuf_vcn++;
+  if ((cc->cbuf_vcn >= cc->comp_table[cc->comp_head][0]))
+    cc->comp_head++;
+  cc->cbuf_ofs = 0;
+  return 0;
+}
+
+static grub_err_t
+decomp_getch (struct grub_ntfs_comp *cc, unsigned char *res)
+{
+  if (cc->cbuf_ofs >= (cc->spc << BLK_SHR))
+    {
+      if (decomp_nextvcn (cc))
+	return grub_errno;
+    }
+  *res = (unsigned char) cc->cbuf[cc->cbuf_ofs++];
+  return 0;
+}
+
+static grub_err_t
+decomp_get16 (struct grub_ntfs_comp *cc, grub_uint16_t * res)
+{
+  unsigned char c1 = 0, c2 = 0;
+
+  if ((decomp_getch (cc, &c1)) || (decomp_getch (cc, &c2)))
+    return grub_errno;
+  *res = ((grub_uint16_t) c2) * 256 + ((grub_uint16_t) c1);
+  return 0;
+}
+
+/* Decompress a block (4096 bytes) */
+static grub_err_t
+decomp_block (struct grub_ntfs_comp *cc, char *dest)
+{
+  grub_uint16_t flg, cnt;
+
+  if (decomp_get16 (cc, &flg))
+    return grub_errno;
+  cnt = (flg & 0xFFF) + 1;
+
+  if (dest)
+    {
+      if (flg & 0x8000)
+	{
+	  unsigned char tag;
+	  grub_uint32_t bits, copied;
+
+	  bits = copied = tag = 0;
+	  while (cnt > 0)
+	    {
+	      if (copied > COM_LEN)
+		return grub_error (GRUB_ERR_BAD_FS,
+				   "Compression block too large");
+
+	      if (!bits)
+		{
+		  if (decomp_getch (cc, &tag))
+		    return grub_errno;
+
+		  bits = 8;
+		  cnt--;
+		  if (cnt <= 0)
+		    break;
+		}
+	      if (tag & 1)
+		{
+		  grub_uint32_t i, len, delta, code, lmask, dshift;
+		  grub_uint16_t word;
+
+		  if (decomp_get16 (cc, &word))
+		    return grub_errno;
+
+		  code = word;
+		  cnt -= 2;
+
+		  if (!copied)
+		    {
+		      grub_error (GRUB_ERR_BAD_FS, "Context window empty");
+		      return 0;
+		    }
+
+		  for (i = copied - 1, lmask = 0xFFF, dshift = 12; i >= 0x10;
+		       i >>= 1)
+		    {
+		      lmask >>= 1;
+		      dshift--;
+		    }
+
+		  delta = code >> dshift;
+		  len = (code & lmask) + 3;
+
+		  for (i = 0; i < len; i++)
+		    {
+		      dest[copied] = dest[copied - delta - 1];
+		      copied++;
+		    }
+		}
+	      else
+		{
+		  unsigned char ch = 0;
+
+		  if (decomp_getch (cc, &ch))
+		    return grub_errno;
+		  dest[copied++] = ch;
+		  cnt--;
+		}
+	      tag >>= 1;
+	      bits--;
+	    }
+	  return 0;
+	}
+      else
+	{
+	  if (cnt != COM_LEN)
+	    return grub_error (GRUB_ERR_BAD_FS,
+			       "Invalid compression block size");
+	}
+    }
+
+  while (cnt > 0)
+    {
+      int n;
+
+      n = (cc->spc << BLK_SHR) - cc->cbuf_ofs;
+      if (n > cnt)
+	n = cnt;
+      if ((dest) && (n))
+	{
+	  grub_memcpy (dest, &cc->cbuf[cc->cbuf_ofs], n);
+	  dest += n;
+	}
+      cnt -= n;
+      cc->cbuf_ofs += n;
+      if ((cnt) && (decomp_nextvcn (cc)))
+	return grub_errno;
+    }
+  return 0;
+}
+
+static grub_err_t
+read_block (struct grub_ntfs_rlst *ctx, char *buf, int num)
+{
+  int cpb = COM_SEC / ctx->comp.spc;
+
+  while (num)
+    {
+      int nn;
+
+      if ((ctx->target_vcn & 0xF) == 0)
+	{
+
+	  if (ctx->comp.comp_head != ctx->comp.comp_tail)
+	    return grub_error (GRUB_ERR_BAD_FS, "Invalid compression block");
+	  ctx->comp.comp_head = ctx->comp.comp_tail = 0;
+	  ctx->comp.cbuf_vcn = ctx->target_vcn;
+	  ctx->comp.cbuf_ofs = (ctx->comp.spc << BLK_SHR);
+	  if (ctx->target_vcn >= ctx->next_vcn)
+	    {
+	      if (grub_ntfs_read_run_list (ctx))
+		return grub_errno;
+	    }
+	  while (ctx->target_vcn + 16 > ctx->next_vcn)
+	    {
+	      if (ctx->flags & RF_BLNK)
+		break;
+	      ctx->comp.comp_table[ctx->comp.comp_tail][0] = ctx->next_vcn;
+	      ctx->comp.comp_table[ctx->comp.comp_tail][1] =
+		ctx->curr_lcn + ctx->next_vcn - ctx->curr_vcn;
+	      ctx->comp.comp_tail++;
+	      if (grub_ntfs_read_run_list (ctx))
+		return grub_errno;
+	    }
+	}
+
+      nn = (16 - (ctx->target_vcn & 0xF)) / cpb;
+      if (nn > num)
+	nn = num;
+      num -= nn;
+
+      if (ctx->flags & RF_BLNK)
+	{
+	  ctx->target_vcn += nn * cpb;
+	  if (ctx->comp.comp_tail == 0)
+	    {
+	      if (buf)
+		{
+		  grub_memset (buf, 0, nn * COM_LEN);
+		  buf += nn * COM_LEN;
+		}
+	    }
+	  else
+	    {
+	      while (nn)
+		{
+		  if (decomp_block (&ctx->comp, buf))
+		    return grub_errno;
+		  if (buf)
+		    buf += COM_LEN;
+		  nn--;
+		}
+	    }
+	}
+      else
+	{
+	  nn *= cpb;
+	  while ((ctx->comp.comp_head < ctx->comp.comp_tail) && (nn))
+	    {
+	      int tt;
+
+	      tt =
+		ctx->comp.comp_table[ctx->comp.comp_head][0] -
+		ctx->target_vcn;
+	      if (tt > nn)
+		tt = nn;
+	      ctx->target_vcn += tt;
+	      if (buf)
+		{
+		  if (grub_disk_read
+		      (ctx->comp.disk,
+		       (ctx->comp.comp_table[ctx->comp.comp_head][1] -
+			(ctx->comp.comp_table[ctx->comp.comp_head][0] -
+			 ctx->target_vcn)) * ctx->comp.spc, 0,
+		       tt * (ctx->comp.spc << BLK_SHR), buf))
+		    return grub_errno;
+		  buf += tt * (ctx->comp.spc << BLK_SHR);
+		}
+	      nn -= tt;
+	      if (ctx->target_vcn >=
+		  ctx->comp.comp_table[ctx->comp.comp_head][0])
+		ctx->comp.comp_head++;
+	    }
+	  if (nn)
+	    {
+	      if (buf)
+		{
+		  if (grub_disk_read
+		      (ctx->comp.disk,
+		       (ctx->target_vcn - ctx->curr_vcn +
+			ctx->curr_lcn) * ctx->comp.spc, 0,
+		       nn * (ctx->comp.spc << BLK_SHR), buf))
+		    return grub_errno;
+		  buf += nn * (ctx->comp.spc << BLK_SHR);
+		}
+	      ctx->target_vcn += nn;
+	    }
+	}
+    }
+  return 0;
+}
+
+static grub_err_t
+ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs,
+	  grub_uint32_t len, struct grub_ntfs_rlst *ctx, grub_uint32_t vcn)
+{
+  grub_err_t ret;
+
+  ctx->comp.comp_head = ctx->comp.comp_tail = 0;
+  ctx->comp.cbuf = grub_malloc ((ctx->comp.spc) << BLK_SHR);
+  if (!ctx->comp.cbuf)
+    return 0;
+
+  ret = 0;
+
+  //ctx->comp.disk->read_hook = read_hook;
+
+  if ((vcn > ctx->target_vcn) &&
+      (read_block
+       (ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / COM_SEC)))
+    {
+      ret = grub_errno;
+      goto quit;
+    }
+
+  if (ofs % COM_LEN)
+    {
+      grub_uint32_t t, n, o;
+
+      t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR);
+      if (read_block (ctx, at->sbuf, 1))
+	{
+	  ret = grub_errno;
+	  goto quit;
+	}
+
+      at->save_pos = t;
+
+      o = ofs % COM_LEN;
+      n = COM_LEN - o;
+      if (n > len)
+	n = len;
+      grub_memcpy (dest, &at->sbuf[o], n);
+      if (n == len)
+	goto quit;
+      dest += n;
+      len -= n;
+    }
+
+  if (read_block (ctx, dest, len / COM_LEN))
+    {
+      ret = grub_errno;
+      goto quit;
+    }
+
+  dest += (len / COM_LEN) * COM_LEN;
+  len = len % COM_LEN;
+  if (len)
+    {
+      grub_uint32_t t;
+
+      t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR);
+      if (read_block (ctx, at->sbuf, 1))
+	{
+	  ret = grub_errno;
+	  goto quit;
+	}
+
+      at->save_pos = t;
+
+      grub_memcpy (dest, at->sbuf, len);
+    }
+
+quit:
+  //ctx->comp.disk->read_hook = 0;
+  if (ctx->comp.cbuf)
+    grub_free (ctx->comp.cbuf);
+  return ret;
+}
+
+GRUB_MOD_INIT (ntfscomp)
+{
+  grub_ntfscomp_func = ntfscomp;
+}
+
+GRUB_MOD_FINI (ntfscomp)
+{
+  grub_ntfscomp_func = NULL;
+}
diff --git a/fs/reiserfs.c b/fs/reiserfs.c
new file mode 100644
index 0000000..fb4f1bc
--- /dev/null
+++ b/fs/reiserfs.c
@@ -0,0 +1,1376 @@
+/* reiserfs.c - ReiserFS versions up to 3.6 */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+  TODO:
+  implement journal handling (ram replay)
+  test tail packing & direct files
+  validate partition label position
+*/
+
+#if 0
+# define GRUB_REISERFS_DEBUG
+# define GRUB_REISERFS_JOURNALING
+# define GRUB_HEXDUMP
+#endif
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+#define MIN(a, b) \
+  ({ typeof (a) _a = (a); \
+     typeof (b) _b = (b); \
+     _a < _b ? _a : _b; })
+
+#define MAX(a, b) \
+  ({ typeof (a) _a = (a); \
+     typeof (b) _b = (b); \
+     _a > _b ? _a : _b; })
+
+#define REISERFS_SUPER_BLOCK_OFFSET 0x10000
+#define REISERFS_MAGIC_LEN 12
+#define REISERFS_MAGIC_STRING "ReIsEr"
+#define REISERFS_MAGIC_DESC_BLOCK "ReIsErLB"
+/* If the 3rd bit of an item state is set, then it's visible.  */
+#define GRUB_REISERFS_VISIBLE_MASK ((grub_uint16_t) 0x04)
+#define REISERFS_MAX_LABEL_LENGTH 16
+#define REISERFS_LABEL_OFFSET 0x64
+
+#define S_IFLNK 0xA000
+
+static grub_dl_t my_mod;
+
+#define assert(boolean) real_assert (boolean, __FILE__, __LINE__)
+static inline void
+real_assert (int boolean, const char *file, const int line)
+{
+  if (! boolean)
+    grub_printf ("Assertion failed at %s:%d\n", file, line);
+}
+
+enum grub_reiserfs_item_type
+  {
+    GRUB_REISERFS_STAT,
+    GRUB_REISERFS_DIRECTORY,
+    GRUB_REISERFS_DIRECT,
+    GRUB_REISERFS_INDIRECT,
+    /* Matches both _DIRECT and _INDIRECT when searching.  */
+    GRUB_REISERFS_ANY,
+    GRUB_REISERFS_UNKNOWN
+  };
+
+struct grub_reiserfs_superblock
+{
+  grub_uint32_t block_count;
+  grub_uint32_t block_free_count;
+  grub_uint32_t root_block;
+  grub_uint32_t journal_block;
+  grub_uint32_t journal_device;
+  grub_uint32_t journal_original_size;
+  grub_uint32_t journal_max_transaction_size;
+  grub_uint32_t journal_block_count;
+  grub_uint32_t journal_max_batch;
+  grub_uint32_t journal_max_commit_age;
+  grub_uint32_t journal_max_transaction_age;
+  grub_uint16_t block_size;
+  grub_uint16_t oid_max_size;
+  grub_uint16_t oid_current_size;
+  grub_uint16_t state;
+  grub_uint8_t magic_string[REISERFS_MAGIC_LEN];
+  grub_uint32_t function_hash_code;
+  grub_uint16_t tree_height;
+  grub_uint16_t bitmap_number;
+  grub_uint16_t version;
+  grub_uint16_t reserved;
+  grub_uint32_t inode_generation;
+  grub_uint8_t unused[4];
+  grub_uint16_t uuid[8];
+} __attribute__ ((packed));
+
+struct grub_reiserfs_journal_header
+{
+  grub_uint32_t last_flush_uid;
+  grub_uint32_t unflushed_offset;
+  grub_uint32_t mount_id;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_description_block
+{
+  grub_uint32_t id;
+  grub_uint32_t len;
+  grub_uint32_t mount_id;
+  grub_uint32_t real_blocks[0];
+} __attribute__ ((packed));
+
+struct grub_reiserfs_commit_block
+{
+  grub_uint32_t id;
+  grub_uint32_t len;
+  grub_uint32_t real_blocks[0];
+} __attribute__ ((packed));
+
+struct grub_reiserfs_stat_item_v1
+{
+  grub_uint16_t mode;
+  grub_uint16_t hardlink_count;
+  grub_uint16_t uid;
+  grub_uint16_t gid;
+  grub_uint32_t size;
+  grub_uint32_t atime;
+  grub_uint32_t mtime;
+  grub_uint32_t ctime;
+  grub_uint32_t rdev;
+  grub_uint32_t first_direct_byte;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_stat_item_v2
+{
+  grub_uint16_t mode;
+  grub_uint16_t reserved;
+  grub_uint32_t hardlink_count;
+  grub_uint64_t size;
+  grub_uint32_t uid;
+  grub_uint32_t gid;
+  grub_uint32_t atime;
+  grub_uint32_t mtime;
+  grub_uint32_t ctime;
+  grub_uint32_t blocks;
+  grub_uint32_t first_direct_byte;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_key
+{
+  grub_uint32_t directory_id;
+  grub_uint32_t object_id;
+  union
+  {
+    struct
+    {
+      grub_uint32_t offset;
+      grub_uint32_t type;
+    } v1 __attribute__ ((packed));
+    struct
+    {
+      grub_uint64_t offset_type;
+    } v2 __attribute__ ((packed));
+  } u;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_item_header
+{
+  struct grub_reiserfs_key key;
+  union
+  {
+    grub_uint16_t free_space;
+    grub_uint16_t entry_count;
+  } u __attribute__ ((packed));
+  grub_uint16_t item_size;
+  grub_uint16_t item_location;
+  grub_uint16_t version;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_block_header
+{
+  grub_uint16_t level;
+  grub_uint16_t item_count;
+  grub_uint16_t free_space;
+  grub_uint16_t reserved;
+  struct grub_reiserfs_key block_right_delimiting_key;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_disk_child
+{
+  grub_uint32_t block_number;
+  grub_uint16_t size;
+  grub_uint16_t reserved;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_directory_header
+{
+  grub_uint32_t offset;
+  grub_uint32_t directory_id;
+  grub_uint32_t object_id;
+  grub_uint16_t location;
+  grub_uint16_t state;
+} __attribute__ ((packed));
+
+struct grub_fshelp_node
+{
+  struct grub_reiserfs_data *data;
+  grub_uint32_t block_number; /* 0 if node is not found.  */
+  grub_uint16_t block_position;
+  grub_uint64_t next_offset;
+  enum grub_reiserfs_item_type type; /* To know how to read the header.  */
+  struct grub_reiserfs_item_header header;
+};
+
+/* Returned when opening a file.  */
+struct grub_reiserfs_data
+{
+  struct grub_reiserfs_superblock superblock;
+  grub_disk_t disk;
+};
+
+/* Internal-only functions. Not to be used outside of this file.  */
+
+/* Return the type of given v2 key.  */
+static enum grub_reiserfs_item_type
+grub_reiserfs_get_key_v2_type (const struct grub_reiserfs_key *key)
+{
+  switch (grub_le_to_cpu64 (key->u.v2.offset_type) >> 60)
+    {
+    case 0:
+      return GRUB_REISERFS_STAT;
+    case 15:
+      return GRUB_REISERFS_ANY;
+    case 3:
+      return GRUB_REISERFS_DIRECTORY;
+    case 2:
+      return GRUB_REISERFS_DIRECT;
+    case 1:
+      return GRUB_REISERFS_INDIRECT;
+    }
+  return GRUB_REISERFS_UNKNOWN;
+}
+
+/* Return the type of given v1 key.  */
+static enum grub_reiserfs_item_type
+grub_reiserfs_get_key_v1_type (const struct grub_reiserfs_key *key)
+{
+  switch (grub_le_to_cpu32 (key->u.v1.type))
+    {
+    case 0:
+      return GRUB_REISERFS_STAT;
+    case 555:
+      return GRUB_REISERFS_ANY;
+    case 500:
+      return GRUB_REISERFS_DIRECTORY;
+    case 0x20000000:
+    case 0xFFFFFFFF:
+      return GRUB_REISERFS_DIRECT;
+    case 0x10000000:
+    case 0xFFFFFFFE:
+      return GRUB_REISERFS_INDIRECT;
+    }
+  return GRUB_REISERFS_UNKNOWN;
+}
+
+/* Return 1 if the given key is version 1 key, 2 otherwise.  */
+static int
+grub_reiserfs_get_key_version (const struct grub_reiserfs_key *key)
+{
+  return grub_reiserfs_get_key_v1_type (key) == GRUB_REISERFS_UNKNOWN ? 2 : 1;
+}
+
+#ifdef GRUB_HEXDUMP
+static void
+grub_hexdump (char *buffer, grub_size_t len)
+{
+  grub_size_t a;
+  for (a = 0; a < len; a++)
+    {
+      if (! (a & 0x0F))
+        grub_printf ("\n%08x  ", a);
+      grub_printf ("%02x ",
+                   ((unsigned int) ((unsigned char *) buffer)[a]) & 0xFF);
+    }
+  grub_printf ("\n");
+}
+#endif
+
+#ifdef GRUB_REISERFS_DEBUG
+static grub_uint64_t
+grub_reiserfs_get_key_offset (const struct grub_reiserfs_key *key);
+
+static enum grub_reiserfs_item_type
+grub_reiserfs_get_key_type (const struct grub_reiserfs_key *key);
+
+static void
+grub_reiserfs_print_key (const struct grub_reiserfs_key *key)
+{
+  unsigned int a;
+  char *reiserfs_type_strings[] = {
+    "stat     ",
+    "directory",
+    "direct   ",
+    "indirect ",
+    "any      ",
+    "unknown  "
+  };
+
+  for (a = 0; a < sizeof (struct grub_reiserfs_key); a++)
+    grub_printf ("%02x ", ((unsigned int) ((unsigned char *) key)[a]) & 0xFF);
+  grub_printf ("parent id = 0x%08x, self id = 0x%08x, type = %s, offset = ",
+               grub_le_to_cpu32 (key->directory_id),
+               grub_le_to_cpu32 (key->object_id),
+               reiserfs_type_strings [grub_reiserfs_get_key_type (key)]);
+  if (grub_reiserfs_get_key_version (key) == 1)
+    grub_printf("%08x", (unsigned int) grub_reiserfs_get_key_offset (key));
+  else
+    grub_printf("0x%07x%08x",
+                (unsigned) (grub_reiserfs_get_key_offset (key) >> 32),
+                (unsigned) (grub_reiserfs_get_key_offset (key) & 0xFFFFFFFF));
+  grub_printf ("\n");
+}
+#endif
+
+/* Return the offset of given key.  */
+static grub_uint64_t
+grub_reiserfs_get_key_offset (const struct grub_reiserfs_key *key)
+{
+  if (grub_reiserfs_get_key_version (key) == 1)
+    return grub_le_to_cpu32 (key->u.v1.offset);
+  else
+    return grub_le_to_cpu64 (key->u.v2.offset_type) & (~0ULL >> 4);
+}
+
+/* Set the offset of given key.  */
+static void
+grub_reiserfs_set_key_offset (struct grub_reiserfs_key *key,
+                              grub_uint64_t value)
+{
+  if (grub_reiserfs_get_key_version (key) == 1)
+    key->u.v1.offset = grub_cpu_to_le32 (value);
+  else
+    key->u.v2.offset_type \
+      = ((key->u.v2.offset_type & grub_cpu_to_le64 (15ULL << 60))
+         | grub_cpu_to_le64 (value & (~0ULL >> 4)));
+}
+
+/* Return the type of given key.  */
+static enum grub_reiserfs_item_type
+grub_reiserfs_get_key_type (const struct grub_reiserfs_key *key)
+{
+  if (grub_reiserfs_get_key_version (key) == 1)
+    return grub_reiserfs_get_key_v1_type (key);
+  else
+    return grub_reiserfs_get_key_v2_type (key);
+}
+
+/* Set the type of given key, with given version number.  */
+static void
+grub_reiserfs_set_key_type (struct grub_reiserfs_key *key,
+                            enum grub_reiserfs_item_type grub_type,
+                            int version)
+{
+  grub_uint32_t type;
+
+  switch (grub_type)
+    {
+    case GRUB_REISERFS_STAT:
+      type = 0;
+      break;
+    case GRUB_REISERFS_ANY:
+      type = (version == 1) ? 555 : 15;
+      break;
+    case GRUB_REISERFS_DIRECTORY:
+      type = (version == 1) ? 500 : 3;
+      break;
+    case GRUB_REISERFS_DIRECT:
+      type = (version == 1) ? 0xFFFFFFFF : 2;
+      break;
+    case GRUB_REISERFS_INDIRECT:
+      type = (version == 1) ? 0xFFFFFFFE : 1;
+      break;
+    default:
+      return;
+    }
+
+  if (version == 1)
+    key->u.v1.type = grub_cpu_to_le32 (type);
+  else
+    key->u.v2.offset_type
+      = ((key->u.v2.offset_type & grub_cpu_to_le64 (~0ULL >> 4))
+         | grub_cpu_to_le64 ((grub_uint64_t) type << 60));
+
+  assert (grub_reiserfs_get_key_type (key) == grub_type);
+}
+
+/* -1 if key 1 if lower than key 2.
+   0 if key 1 is equal to key 2.
+   1 if key 1 is higher than key 2.  */
+static int
+grub_reiserfs_compare_keys (const struct grub_reiserfs_key *key1,
+                            const struct grub_reiserfs_key *key2)
+{
+  grub_uint64_t offset1, offset2;
+  enum grub_reiserfs_item_type type1, type2;
+  grub_uint32_t id1, id2;
+
+  if (! key1 || ! key2)
+    return -2;
+
+  id1 = grub_le_to_cpu32 (key1->directory_id);
+  id2 = grub_le_to_cpu32 (key2->directory_id);
+  if (id1 < id2)
+    return -1;
+  if (id1 > id2)
+    return 1;
+
+  id1 = grub_le_to_cpu32 (key1->object_id);
+  id2 = grub_le_to_cpu32 (key2->object_id);
+  if (id1 < id2)
+    return -1;
+  if (id1 > id2)
+    return 1;
+
+  offset1 = grub_reiserfs_get_key_offset (key1);
+  offset2 = grub_reiserfs_get_key_offset (key2);
+  if (offset1 < offset2)
+    return -1;
+  if (offset1 > offset2)
+    return 1;
+
+  type1 = grub_reiserfs_get_key_type (key1);
+  type2 = grub_reiserfs_get_key_type (key2);
+  if ((type1 == GRUB_REISERFS_ANY
+       && (type2 == GRUB_REISERFS_DIRECT
+           || type2 == GRUB_REISERFS_INDIRECT))
+      || (type2 == GRUB_REISERFS_ANY
+          && (type1 == GRUB_REISERFS_DIRECT
+              || type1 == GRUB_REISERFS_INDIRECT)))
+    return 0;
+  if (type1 < type2)
+    return -1;
+  if (type1 > type2)
+    return 1;
+
+  return 0;
+}
+
+/* Find the item identified by KEY in mounted filesystem DATA, and fill ITEM
+   accordingly to what was found.  */
+static grub_err_t
+grub_reiserfs_get_item (struct grub_reiserfs_data *data,
+                        const struct grub_reiserfs_key *key,
+                        struct grub_fshelp_node *item)
+{
+  grub_uint32_t block_number;
+  struct grub_reiserfs_block_header *block_header = 0;
+  struct grub_reiserfs_key *block_key = 0;
+  grub_uint16_t block_size, item_count, current_level;
+  grub_uint16_t i;
+  grub_uint16_t previous_level = ~0;
+  struct grub_reiserfs_item_header *item_headers = 0;
+
+  if (! data)
+    {
+      grub_error (GRUB_ERR_TEST_FAILURE, "data is NULL");
+      goto fail;
+    }
+
+  if (! key)
+    {
+      grub_error (GRUB_ERR_TEST_FAILURE, "key is NULL");
+      goto fail;
+    }
+
+  if (! item)
+    {
+      grub_error (GRUB_ERR_TEST_FAILURE, "item is NULL");
+      goto fail;
+    }
+
+  block_size = grub_le_to_cpu16 (data->superblock.block_size);
+  block_number = grub_le_to_cpu32 (data->superblock.root_block);
+#ifdef GRUB_REISERFS_DEBUG
+  grub_printf("Searching for ");
+  grub_reiserfs_print_key (key);
+#endif
+  block_header = grub_malloc (block_size);
+  if (! block_header)
+    goto fail;
+
+  item->next_offset = 0;
+  do
+    {
+      grub_disk_read (data->disk,
+                      block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
+                      (((grub_off_t) block_number * block_size)
+                       & (GRUB_DISK_SECTOR_SIZE - 1)),
+                      block_size, block_header);
+      if (grub_errno)
+        goto fail;
+      current_level = grub_le_to_cpu16 (block_header->level);
+      grub_dprintf ("reiserfs_tree", " at level %d\n", current_level);
+      if (current_level >= previous_level)
+        {
+          grub_dprintf ("reiserfs_tree", "level loop detected, aborting\n");
+          grub_error (GRUB_ERR_FILE_READ_ERROR, "level loop");
+          goto fail;
+        }
+      previous_level = current_level;
+      item_count = grub_le_to_cpu16 (block_header->item_count);
+      grub_dprintf ("reiserfs_tree", " number of contained items : %d\n",
+                    item_count);
+      if (current_level > 1)
+        {
+          /* Internal node. Navigate to the child that should contain
+             the searched key.  */
+          struct grub_reiserfs_key *keys
+            = (struct grub_reiserfs_key *) (block_header + 1);
+          struct grub_reiserfs_disk_child *children
+            = ((struct grub_reiserfs_disk_child *)
+               (keys + item_count));
+
+          for (i = 0;
+               i < item_count
+                 && grub_reiserfs_compare_keys (key, &(keys[i])) >= 0;
+               i++)
+            {
+#ifdef GRUB_REISERFS_DEBUG
+              grub_printf("i %03d/%03d ", i + 1, item_count + 1);
+              grub_reiserfs_print_key (&(keys[i]));
+#endif
+            }
+          block_number = grub_le_to_cpu32 (children[i].block_number);
+	  if ((i < item_count) && (key->directory_id == keys[i].directory_id)
+	       && (key->object_id == keys[i].object_id))
+	    item->next_offset = grub_reiserfs_get_key_offset(&(keys[i]));
+#ifdef GRUB_REISERFS_DEBUG
+          if (i == item_count
+              || grub_reiserfs_compare_keys (key, &(keys[i])) == 0)
+            grub_printf(">");
+          else
+            grub_printf("<");
+          if (i < item_count)
+            {
+              grub_printf (" %03d/%03d ", i + 1, item_count + 1);
+              grub_reiserfs_print_key (&(keys[i]));
+              if (i + 1 < item_count)
+                {
+                  grub_printf ("+ %03d/%03d ", i + 2, item_count);
+                  grub_reiserfs_print_key (&(keys[i + 1]));
+                }
+            }
+          else
+            grub_printf ("Accessing rightmost child at block %d.\n",
+                         block_number);
+#endif
+        }
+      else
+        {
+          /* Leaf node.  Check that the key is actually present.  */
+          item_headers
+            = (struct grub_reiserfs_item_header *) (block_header + 1);
+          for (i = 0;
+               i < item_count
+                 && (grub_reiserfs_compare_keys (key, &(item_headers[i].key))
+                     != 0);
+               i++)
+            {
+#ifdef GRUB_REISERFS_DEBUG
+              if (key->directory_id == item_headers[i].key.directory_id && \
+                  key->object_id == item_headers[i].key.object_id)
+                grub_printf("C");
+              else
+                grub_printf(" ");
+              grub_printf(" %03d/%03d ", i + 1, item_count);
+              grub_reiserfs_print_key (&(item_headers[i].key));
+#endif
+            }
+          if (i < item_count)
+            block_key = &(item_headers[i].key);
+        }
+    }
+  while (current_level > 1);
+
+  item->data = data;
+
+  if (i == item_count || grub_reiserfs_compare_keys (key, block_key))
+    {
+      item->block_number = 0;
+      item->block_position = 0;
+      item->type = GRUB_REISERFS_UNKNOWN;
+#ifdef GRUB_REISERFS_DEBUG
+      grub_printf("Not found.\n");
+#endif
+    }
+  else
+    {
+      item->block_number = block_number;
+      item->block_position = i;
+      item->type = grub_reiserfs_get_key_type (block_key);
+      grub_memcpy (&(item->header), &(item_headers[i]),
+                   sizeof (struct grub_reiserfs_item_header));
+#ifdef GRUB_REISERFS_DEBUG
+      grub_printf ("F %03d/%03d ", i + 1, item_count);
+      grub_reiserfs_print_key (block_key);
+#endif
+    }
+
+  assert (grub_errno == GRUB_ERR_NONE);
+  grub_free (block_header);
+  return GRUB_ERR_NONE;
+
+ fail:
+  assert (grub_errno != GRUB_ERR_NONE);
+  grub_free (block_header);
+  assert (grub_errno != GRUB_ERR_NONE);
+  return grub_errno;
+}
+
+/* Return the path of the file which is pointed at by symlink NODE.  */
+static char *
+grub_reiserfs_read_symlink (grub_fshelp_node_t node)
+{
+  char *symlink_buffer = 0;
+  grub_uint16_t block_size;
+  grub_disk_addr_t block;
+  grub_off_t offset;
+  grub_size_t len;
+  struct grub_fshelp_node found;
+  struct grub_reiserfs_key key;
+
+  grub_memcpy (&key, &(node->header.key), sizeof (key));
+  grub_reiserfs_set_key_offset (&key, 1);
+  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_DIRECT,
+                              grub_reiserfs_get_key_version (&key));
+
+  if (grub_reiserfs_get_item (node->data, &key, &found) != GRUB_ERR_NONE)
+    goto fail;
+
+  if (found.block_number == 0)
+    goto fail;
+
+  block_size = grub_le_to_cpu16 (node->data->superblock.block_size);
+  len = grub_le_to_cpu16 (found.header.item_size);
+  block = found.block_number * (block_size  >> GRUB_DISK_SECTOR_BITS);
+  offset = grub_le_to_cpu16 (found.header.item_location);
+
+  symlink_buffer = grub_malloc (len + 1);
+  if (! symlink_buffer)
+    goto fail;
+
+  grub_disk_read (node->data->disk, block, offset, len, symlink_buffer);
+  if (grub_errno)
+    goto fail;
+
+  symlink_buffer[len] = 0;
+  return symlink_buffer;
+
+ fail:
+  grub_free (symlink_buffer);
+  return 0;
+}
+
+/* Fill the mounted filesystem structure and return it.  */
+static struct grub_reiserfs_data *
+grub_reiserfs_mount (grub_disk_t disk)
+{
+  struct grub_reiserfs_data *data = 0;
+  data = grub_malloc (sizeof (*data));
+  if (! data)
+    goto fail;
+  grub_disk_read (disk, REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE,
+                  0, sizeof (data->superblock), &(data->superblock));
+  if (grub_errno)
+    goto fail;
+  if (grub_memcmp (data->superblock.magic_string,
+                   REISERFS_MAGIC_STRING, sizeof (REISERFS_MAGIC_STRING) - 1))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a reiserfs filesystem");
+      goto fail;
+    }
+  data->disk = disk;
+  return data;
+
+ fail:
+  /* Disk is too small to contain a ReiserFS.  */
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not a reiserfs filesystem");
+
+  grub_free (data);
+  return 0;
+}
+
+/* Call HOOK for each file in directory ITEM.  */
+static int
+grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
+                           int NESTED_FUNC_ATTR
+                           (*hook) (const char *filename,
+                                    enum grub_fshelp_filetype filetype,
+                                    grub_fshelp_node_t node))
+{
+  struct grub_reiserfs_data *data = item->data;
+  struct grub_reiserfs_block_header *block_header = 0;
+  grub_uint16_t block_size, block_position;
+  grub_uint32_t block_number;
+  grub_uint64_t next_offset = item->next_offset;
+  int ret = 0;
+
+  if (item->type != GRUB_REISERFS_DIRECTORY)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                  "grub_reiserfs_iterate_dir called on a non-directory item");
+      goto fail;
+    }
+  block_size = grub_le_to_cpu16 (data->superblock.block_size);
+  block_header = grub_malloc (block_size);
+  if (! block_header)
+    goto fail;
+  block_number = item->block_number;
+  block_position = item->block_position;
+  grub_dprintf ("reiserfs", "Iterating directory...\n");
+  do
+    {
+      struct grub_reiserfs_directory_header *directory_headers;
+      struct grub_fshelp_node directory_item;
+      grub_uint16_t entry_count, entry_number;
+      struct grub_reiserfs_item_header *item_headers;
+
+      grub_disk_read (data->disk,
+                      block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
+                      (((grub_off_t) block_number * block_size)
+                       & (GRUB_DISK_SECTOR_SIZE - 1)),
+                      block_size, (char *) block_header);
+      if (grub_errno)
+        goto fail;
+
+#if 0
+      if (grub_le_to_cpu16 (block_header->level) != 1)
+        {
+          grub_error (GRUB_ERR_TEST_FAILURE,
+                      "reiserfs: block %d is not a leaf block",
+                      block_number);
+          goto fail;
+        }
+#endif
+
+      item_headers = (struct grub_reiserfs_item_header *) (block_header + 1);
+      directory_headers
+        = ((struct grub_reiserfs_directory_header *)
+           ((char *) block_header
+            + grub_le_to_cpu16 (item_headers[block_position].item_location)));
+      entry_count
+        = grub_le_to_cpu16 (item_headers[block_position].u.entry_count);
+      for (entry_number = 0; entry_number < entry_count; entry_number++)
+        {
+          struct grub_reiserfs_directory_header *directory_header
+            = &directory_headers[entry_number];
+          grub_uint16_t entry_state
+            = grub_le_to_cpu16 (directory_header->state);
+
+          if (entry_state & GRUB_REISERFS_VISIBLE_MASK)
+            {
+              grub_fshelp_node_t entry_item;
+              struct grub_reiserfs_key entry_key;
+              enum grub_reiserfs_item_type entry_type;
+              char *entry_name;
+
+              entry_name = (((char *) directory_headers)
+                            + grub_le_to_cpu16 (directory_header->location));
+              entry_key.directory_id = directory_header->directory_id;
+              entry_key.object_id = directory_header->object_id;
+              entry_key.u.v2.offset_type = 0;
+              grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_DIRECTORY,
+                                          2);
+              grub_reiserfs_set_key_offset (&entry_key, 1);
+
+              entry_item = grub_malloc (sizeof (*entry_item));
+              if (! entry_item)
+                goto fail;
+
+              if (grub_reiserfs_get_item (data, &entry_key, entry_item)
+                  != GRUB_ERR_NONE)
+                {
+                  grub_free (entry_item);
+                  goto fail;
+                }
+
+              if (entry_item->type == GRUB_REISERFS_DIRECTORY)
+                entry_type = GRUB_FSHELP_DIR;
+              else
+                {
+                  grub_uint32_t entry_block_number;
+                  /* Order is very important here.
+                     First set the offset to 0 using current key version.
+                     Then change the key type, which affects key version
+                     detection.  */
+                  grub_reiserfs_set_key_offset (&entry_key, 0);
+                  grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_STAT,
+                                              2);
+                  if (grub_reiserfs_get_item (data, &entry_key, entry_item)
+                      != GRUB_ERR_NONE)
+                    {
+                      grub_free (entry_item);
+                      goto fail;
+                    }
+
+                  if (entry_item->block_number != 0)
+                    {
+                      grub_uint16_t entry_version;
+                      entry_version
+                        = grub_le_to_cpu16 (entry_item->header.version);
+                      entry_block_number = entry_item->block_number;
+#if 0
+		      grub_dprintf ("reiserfs",
+                                    "version %04x block %08x (%08x) position %08x\n",
+                                    entry_version, entry_block_number,
+                                    ((grub_disk_addr_t) entry_block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
+                                    grub_le_to_cpu16 (entry_item->header.item_location));
+#endif
+                      if (entry_version == 0) /* Version 1 stat item. */
+                        {
+                          struct grub_reiserfs_stat_item_v1 entry_v1_stat;
+                          grub_disk_read (data->disk,
+                                          entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
+                                          grub_le_to_cpu16 (entry_item->header.item_location),
+                                          sizeof (entry_v1_stat),
+                                          (char *) &entry_v1_stat);
+                          if (grub_errno)
+                            goto fail;
+#if 0
+			  grub_dprintf ("reiserfs",
+                                        "%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n",
+                                        grub_le_to_cpu16 (entry_v1_stat.mode),
+                                        grub_le_to_cpu16 (entry_v1_stat.hardlink_count),
+                                        grub_le_to_cpu16 (entry_v1_stat.uid),
+                                        grub_le_to_cpu16 (entry_v1_stat.gid),
+                                        grub_le_to_cpu32 (entry_v1_stat.size),
+                                        grub_le_to_cpu32 (entry_v1_stat.atime),
+                                        grub_le_to_cpu32 (entry_v1_stat.mtime),
+                                        grub_le_to_cpu32 (entry_v1_stat.ctime),
+                                        grub_le_to_cpu32 (entry_v1_stat.rdev),
+                                        grub_le_to_cpu32 (entry_v1_stat.first_direct_byte));
+			  grub_dprintf ("reiserfs",
+                                        "%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n",
+                                        entry_v1_stat.mode,
+                                        entry_v1_stat.hardlink_count,
+                                        entry_v1_stat.uid,
+                                        entry_v1_stat.gid,
+                                        entry_v1_stat.size,
+                                        entry_v1_stat.atime,
+                                        entry_v1_stat.mtime,
+                                        entry_v1_stat.ctime,
+                                        entry_v1_stat.rdev,
+                                        entry_v1_stat.first_direct_byte);
+#endif
+                          if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK)
+                              == S_IFLNK)
+                            entry_type = GRUB_FSHELP_SYMLINK;
+                          else
+                            entry_type = GRUB_FSHELP_REG;
+                        }
+                      else
+                        {
+                          struct grub_reiserfs_stat_item_v2 entry_v2_stat;
+                          grub_disk_read (data->disk,
+                                          entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
+                                          grub_le_to_cpu16 (entry_item->header.item_location),
+                                          sizeof (entry_v2_stat),
+                                          (char *) &entry_v2_stat);
+                          if (grub_errno)
+                            goto fail;
+#if 0
+			  grub_dprintf ("reiserfs",
+                                        "%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n",
+                                        grub_le_to_cpu16 (entry_v2_stat.mode),
+                                        grub_le_to_cpu16 (entry_v2_stat.reserved),
+                                        grub_le_to_cpu32 (entry_v2_stat.hardlink_count),
+                                        (unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) >> 32),
+                                        (unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) && 0xFFFFFFFF),
+                                        grub_le_to_cpu32 (entry_v2_stat.uid),
+                                        grub_le_to_cpu32 (entry_v2_stat.gid),
+                                        grub_le_to_cpu32 (entry_v2_stat.atime),
+                                        grub_le_to_cpu32 (entry_v2_stat.mtime),
+                                        grub_le_to_cpu32 (entry_v2_stat.ctime),
+                                        grub_le_to_cpu32 (entry_v2_stat.blocks),
+                                        grub_le_to_cpu32 (entry_v2_stat.first_direct_byte));
+			  grub_dprintf ("reiserfs",
+                                        "%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n",
+                                        entry_v2_stat.mode,
+                                        entry_v2_stat.reserved,
+                                        entry_v2_stat.hardlink_count,
+                                        (unsigned int) (entry_v2_stat.size >> 32),
+                                        (unsigned int) (entry_v2_stat.size && 0xFFFFFFFF),
+                                        entry_v2_stat.uid,
+                                        entry_v2_stat.gid,
+                                        entry_v2_stat.atime,
+                                        entry_v2_stat.mtime,
+                                        entry_v2_stat.ctime,
+                                        entry_v2_stat.blocks,
+                                        entry_v2_stat.first_direct_byte);
+#endif
+                          if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK)
+                              == S_IFLNK)
+                            entry_type = GRUB_FSHELP_SYMLINK;
+                          else
+                            entry_type = GRUB_FSHELP_REG;
+                        }
+                    }
+                  else
+                    {
+                      /* Pseudo file ".." never has stat block.  */
+                      if (grub_strcmp (entry_name, ".."))
+                        grub_dprintf ("reiserfs",
+                                      "Warning : %s has no stat block !\n",
+                                      entry_name);
+                      grub_free (entry_item);
+                      continue;
+                    }
+                }
+              if (hook (entry_name, entry_type, entry_item))
+                {
+                  grub_dprintf ("reiserfs", "Found : %s, type=%d\n",
+                                entry_name, entry_type);
+                  ret = 1;
+                  goto found;
+                }
+
+              *entry_name = 0; /* Make sure next entry name (which is just
+                                  before this one in disk order) stops before
+                                  the current one.  */
+            }
+        }
+
+      if (next_offset == 0)
+        break;
+
+      grub_reiserfs_set_key_offset (&(item_headers[block_position].key),
+                                    next_offset);
+      if (grub_reiserfs_get_item (data, &(item_headers[block_position].key),
+                                  &directory_item) != GRUB_ERR_NONE)
+        goto fail;
+      block_number = directory_item.block_number;
+      block_position = directory_item.block_position;
+      next_offset = directory_item.next_offset;
+    }
+  while (block_number);
+
+ found:
+  assert (grub_errno == GRUB_ERR_NONE);
+  grub_free (block_header);
+  return ret;
+ fail:
+  assert (grub_errno != GRUB_ERR_NONE);
+  grub_free (block_header);
+  return 0;
+}
+
+/****************************************************************************/
+/* grub api functions */
+/****************************************************************************/
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_reiserfs_open (struct grub_file *file, const char *name)
+{
+  struct grub_reiserfs_data *data = 0;
+  struct grub_fshelp_node root, *found = 0, info;
+  struct grub_reiserfs_key key;
+  grub_uint32_t block_number;
+  grub_uint16_t entry_version, block_size, entry_location;
+
+  grub_dl_ref (my_mod);
+  data = grub_reiserfs_mount (file->device->disk);
+  if (! data)
+    goto fail;
+  block_size = grub_le_to_cpu16 (data->superblock.block_size);
+  key.directory_id = grub_cpu_to_le32 (1);
+  key.object_id = grub_cpu_to_le32 (2);
+  key.u.v2.offset_type = 0;
+  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_DIRECTORY, 2);
+  grub_reiserfs_set_key_offset (&key, 1);
+  if (grub_reiserfs_get_item (data, &key, &root) != GRUB_ERR_NONE)
+    goto fail;
+  if (root.block_number == 0)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "Unable to find root item");
+      goto fail; /* Should never happen since checked at mount.  */
+    }
+  grub_fshelp_find_file (name, &root, &found,
+                         grub_reiserfs_iterate_dir,
+                         grub_reiserfs_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+  key.directory_id = found->header.key.directory_id;
+  key.object_id = found->header.key.object_id;
+  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_STAT, 2);
+  grub_reiserfs_set_key_offset (&key, 0);
+  if (grub_reiserfs_get_item (data, &key, &info) != GRUB_ERR_NONE)
+    goto fail;
+  if (info.block_number == 0)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "Unable to find searched item");
+      goto fail;
+    }
+  entry_version = grub_le_to_cpu16 (info.header.version);
+  entry_location = grub_le_to_cpu16 (info.header.item_location);
+  block_number = info.block_number;
+  if (entry_version == 0) /* Version 1 stat item. */
+    {
+      struct grub_reiserfs_stat_item_v1 entry_v1_stat;
+      grub_disk_read (data->disk,
+                      block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
+                      entry_location
+                      + (((grub_off_t) block_number * block_size)
+                         & (GRUB_DISK_SECTOR_SIZE - 1)),
+                      sizeof (entry_v1_stat), &entry_v1_stat);
+      if (grub_errno)
+        goto fail;
+      file->size = (grub_off_t) grub_le_to_cpu64 (entry_v1_stat.size);
+    }
+  else
+    {
+      struct grub_reiserfs_stat_item_v2 entry_v2_stat;
+      grub_disk_read (data->disk,
+                      block_number * (block_size  >> GRUB_DISK_SECTOR_BITS),
+                      entry_location
+                      + (((grub_off_t) block_number * block_size)
+                         & (GRUB_DISK_SECTOR_SIZE - 1)),
+                      sizeof (entry_v2_stat), &entry_v2_stat);
+      if (grub_errno)
+        goto fail;
+      file->size = (grub_off_t) grub_le_to_cpu64 (entry_v2_stat.size);
+    }
+  grub_dprintf ("reiserfs", "file size : %d (%08x%08x)\n",
+                (unsigned int) file->size,
+                (unsigned int) (file->size >> 32), (unsigned int) file->size);
+  file->offset = 0;
+  file->data = found;
+  return GRUB_ERR_NONE;
+
+ fail:
+  assert (grub_errno != GRUB_ERR_NONE);
+  grub_free (found);
+  grub_free (data);
+  grub_dl_unref (my_mod);
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  unsigned int indirect_block, indirect_block_count;
+  struct grub_reiserfs_key key;
+  struct grub_fshelp_node *node = file->data;
+  struct grub_reiserfs_data *data = node->data;
+  struct grub_fshelp_node found;
+  grub_uint16_t block_size = grub_le_to_cpu16 (data->superblock.block_size);
+  grub_uint16_t item_size;
+  grub_uint32_t *indirect_block_ptr = 0;
+  grub_uint64_t current_key_offset = 1;
+  grub_off_t initial_position, current_position, final_position, length;
+  grub_disk_addr_t block;
+  grub_off_t offset;
+
+  key.directory_id = node->header.key.directory_id;
+  key.object_id = node->header.key.object_id;
+  key.u.v2.offset_type = 0;
+  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_ANY, 2);
+  initial_position = file->offset;
+  current_position = 0;
+  final_position = MIN (len + initial_position, file->size);
+  grub_dprintf ("reiserfs",
+		"Reading from %lld to %lld (%lld instead of requested %ld)\n",
+		(unsigned long long) initial_position,
+		(unsigned long long) final_position,
+		(unsigned long long) (final_position - initial_position),
+		(unsigned long) len);
+  while (current_position < final_position)
+    {
+      grub_reiserfs_set_key_offset (&key, current_key_offset);
+
+      if (grub_reiserfs_get_item (data, &key, &found) != GRUB_ERR_NONE)
+        goto fail;
+      if (found.block_number == 0)
+        goto fail;
+      item_size = grub_le_to_cpu16 (found.header.item_size);
+      switch (found.type)
+        {
+        case GRUB_REISERFS_DIRECT:
+          block = found.block_number * (block_size  >> GRUB_DISK_SECTOR_BITS);
+          grub_dprintf ("reiserfs_blocktype", "D: %u\n", (unsigned) block);
+          if (initial_position < current_position + item_size)
+            {
+              offset = MAX ((signed) (initial_position - current_position), 0);
+              length = (MIN (item_size, final_position - current_position)
+                        - offset);
+              grub_dprintf ("reiserfs",
+                            "Reading direct block %u from %u to %u...\n",
+                            (unsigned) block, (unsigned) offset,
+                            (unsigned) (offset + length));
+              found.data->disk->read_hook = file->read_hook;
+              grub_disk_read (found.data->disk,
+                              block,
+                              offset
+                              + grub_le_to_cpu16 (found.header.item_location),
+                              length, buf);
+              found.data->disk->read_hook = 0;
+              if (grub_errno)
+                goto fail;
+              buf += length;
+              current_position += offset + length;
+            }
+          else
+            current_position += item_size;
+          break;
+        case GRUB_REISERFS_INDIRECT:
+          indirect_block_count = item_size / sizeof (*indirect_block_ptr);
+          indirect_block_ptr = grub_malloc (item_size);
+          if (! indirect_block_ptr)
+            goto fail;
+          grub_disk_read (found.data->disk,
+                          found.block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
+                          grub_le_to_cpu16 (found.header.item_location),
+                          item_size, indirect_block_ptr);
+          if (grub_errno)
+            goto fail;
+          found.data->disk->read_hook = file->read_hook;
+          for (indirect_block = 0;
+               indirect_block < indirect_block_count
+                 && current_position < final_position;
+               indirect_block++)
+            {
+              block = grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) *
+                      (block_size >> GRUB_DISK_SECTOR_BITS);
+              grub_dprintf ("reiserfs_blocktype", "I: %u\n", (unsigned) block);
+              if (current_position + block_size >= initial_position)
+                {
+                  offset = MAX ((signed) (initial_position - current_position),
+                                0);
+                  length = (MIN (block_size, final_position - current_position)
+                            - offset);
+                  grub_dprintf ("reiserfs",
+                                "Reading indirect block %u from %u to %u...\n",
+                                (unsigned) block, (unsigned) offset,
+                                (unsigned) (offset + length));
+#if 0
+                  grub_dprintf ("reiserfs",
+                                "\nib=%04d/%04d, ip=%d, cp=%d, fp=%d, off=%d, l=%d, tl=%d\n",
+                                indirect_block + 1, indirect_block_count,
+                                initial_position, current_position,
+                                final_position, offset, length, len);
+#endif
+                  grub_disk_read (found.data->disk, block, offset, length, buf);
+                  if (grub_errno)
+                    goto fail;
+                  buf += length;
+                  current_position += offset + length;
+                }
+              else
+                current_position += block_size;
+            }
+          found.data->disk->read_hook = 0;
+          grub_free (indirect_block_ptr);
+          indirect_block_ptr = 0;
+          break;
+        default:
+          goto fail;
+        }
+      current_key_offset = current_position + 1;
+    }
+
+  grub_dprintf ("reiserfs",
+		"Have successfully read %lld bytes (%ld requested)\n",
+		(unsigned long long) (current_position - initial_position),
+		(unsigned long) len);
+  return current_position - initial_position;
+/*
+  switch (found.type)
+    {
+      case GRUB_REISERFS_DIRECT:
+        read_length = MIN (len, item_size - file->offset);
+        grub_disk_read (found.data->disk,
+                        (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
+                        grub_le_to_cpu16 (found.header.item_location) + file->offset,
+                        read_length, buf);
+        if (grub_errno)
+          goto fail;
+        break;
+      case GRUB_REISERFS_INDIRECT:
+        indirect_block_count = item_size / sizeof (*indirect_block_ptr);
+        indirect_block_ptr = grub_malloc (item_size);
+        if (!indirect_block_ptr)
+          goto fail;
+        grub_disk_read (found.data->disk,
+                        (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
+                        grub_le_to_cpu16 (found.header.item_location),
+                        item_size, (char *) indirect_block_ptr);
+        if (grub_errno)
+          goto fail;
+        len = MIN (len, file->size - file->offset);
+        for (indirect_block = file->offset / block_size;
+             indirect_block < indirect_block_count && read_length < len;
+             indirect_block++)
+          {
+            read = MIN (block_size, len - read_length);
+            grub_disk_read (found.data->disk,
+                            (grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) * block_size) / GRUB_DISK_SECTOR_SIZE,
+                            file->offset % block_size, read,
+                            ((void *) buf) + read_length);
+            if (grub_errno)
+              goto fail;
+            read_length += read;
+          }
+        grub_free (indirect_block_ptr);
+        break;
+      default:
+        goto fail;
+    }
+
+  return read_length;*/
+
+ fail:
+  grub_free (indirect_block_ptr);
+  return 0;
+}
+
+/* Close the file FILE.  */
+static grub_err_t
+grub_reiserfs_close (grub_file_t file)
+{
+  struct grub_fshelp_node *node = file->data;
+  struct grub_reiserfs_data *data = node->data;
+
+  grub_free (data);
+  grub_free (node);
+  grub_dl_unref (my_mod);
+  return GRUB_ERR_NONE;
+}
+
+/* Call HOOK with each file under DIR.  */
+static grub_err_t
+grub_reiserfs_dir (grub_device_t device, const char *path,
+                   int (*hook) (const char *filename,
+				const struct grub_dirhook_info *info))
+{
+  struct grub_reiserfs_data *data = 0;
+  struct grub_fshelp_node root, *found;
+  struct grub_reiserfs_key root_key;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                     enum grub_fshelp_filetype filetype,
+                                     grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+                                enum grub_fshelp_filetype filetype,
+                                grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+  grub_dl_ref (my_mod);
+  data = grub_reiserfs_mount (device->disk);
+  if (! data)
+    goto fail;
+  root_key.directory_id = grub_cpu_to_le32 (1);
+  root_key.object_id = grub_cpu_to_le32 (2);
+  root_key.u.v2.offset_type = 0;
+  grub_reiserfs_set_key_type (&root_key, GRUB_REISERFS_DIRECTORY, 2);
+  grub_reiserfs_set_key_offset (&root_key, 1);
+  if (grub_reiserfs_get_item (data, &root_key, &root) != GRUB_ERR_NONE)
+    goto fail;
+  if (root.block_number == 0)
+    {
+      grub_error(GRUB_ERR_BAD_FS, "Root not found");
+      goto fail;
+    }
+  grub_fshelp_find_file (path, &root, &found, grub_reiserfs_iterate_dir,
+                         grub_reiserfs_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+  grub_reiserfs_iterate_dir (found, iterate);
+  grub_free (data);
+  grub_dl_unref (my_mod);
+  return GRUB_ERR_NONE;
+
+ fail:
+  grub_free (data);
+  grub_dl_unref (my_mod);
+  return grub_errno;
+}
+
+/* Return the label of the device DEVICE in LABEL.  The label is
+   returned in a grub_malloc'ed buffer and should be freed by the
+   caller.  */
+static grub_err_t
+grub_reiserfs_label (grub_device_t device, char **label)
+{
+  *label = grub_malloc (REISERFS_MAX_LABEL_LENGTH);
+  if (*label)
+    {
+      grub_disk_read (device->disk,
+                      REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE,
+                      REISERFS_LABEL_OFFSET, REISERFS_MAX_LABEL_LENGTH,
+                      *label);
+    }
+  return grub_errno;
+}
+
+static grub_err_t
+grub_reiserfs_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_reiserfs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_reiserfs_mount (disk);
+  if (data)
+    {
+      *uuid = grub_malloc (sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"));
+      grub_sprintf (*uuid, "%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
+		    grub_be_to_cpu16 (data->superblock.uuid[0]), grub_be_to_cpu16 (data->superblock.uuid[1]),
+		    grub_be_to_cpu16 (data->superblock.uuid[2]), grub_be_to_cpu16 (data->superblock.uuid[3]),
+		    grub_be_to_cpu16 (data->superblock.uuid[4]), grub_be_to_cpu16 (data->superblock.uuid[5]),
+		    grub_be_to_cpu16 (data->superblock.uuid[6]), grub_be_to_cpu16 (data->superblock.uuid[7]));
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_reiserfs_fs =
+  {
+    .name = "reiserfs",
+    .dir = grub_reiserfs_dir,
+    .open = grub_reiserfs_open,
+    .read = grub_reiserfs_read,
+    .close = grub_reiserfs_close,
+    .label = grub_reiserfs_label,
+    .uuid = grub_reiserfs_uuid,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(reiserfs)
+{
+  grub_fs_register (&grub_reiserfs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(reiserfs)
+{
+  grub_fs_unregister (&grub_reiserfs_fs);
+}
diff --git a/fs/sfs.c b/fs/sfs.c
new file mode 100644
index 0000000..ec59b73
--- /dev/null
+++ b/fs/sfs.c
@@ -0,0 +1,597 @@
+/* sfs.c - Amiga Smart FileSystem.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+/* The common header for a block.  */
+struct grub_sfs_bheader
+{
+  grub_uint8_t magic[4];
+  grub_uint32_t chksum;
+  grub_uint32_t ipointtomyself;
+} __attribute__ ((packed));
+
+/* The sfs rootblock.  */
+struct grub_sfs_rblock
+{
+  struct grub_sfs_bheader header;
+  grub_uint32_t version;
+  grub_uint8_t unused1[36];
+  grub_uint32_t blocksize;
+  grub_uint8_t unused2[40];
+  grub_uint8_t unused3[8];
+  grub_uint32_t rootobject;
+  grub_uint32_t btree;
+} __attribute__ ((packed));
+
+/* A SFS object container.  */
+struct grub_sfs_obj
+{
+  grub_uint8_t unused1[4];
+  grub_uint32_t nodeid;
+  grub_uint8_t unused2[4];
+  union
+  {
+    struct
+    {
+      grub_uint32_t first_block;
+      grub_uint32_t size;
+    } file __attribute__ ((packed));
+    struct
+    {
+      grub_uint32_t hashtable;
+      grub_uint32_t dir_objc;
+    } dir __attribute__ ((packed));
+  } file_dir;
+  grub_uint8_t unused3[4];
+  grub_uint8_t type;
+  grub_uint8_t filename[1];
+  grub_uint8_t comment[1];
+} __attribute__ ((packed));
+
+#define	GRUB_SFS_TYPE_DELETED	32
+#define	GRUB_SFS_TYPE_SYMLINK	64
+#define	GRUB_SFS_TYPE_DIR	128
+
+/* A SFS object container.  */
+struct grub_sfs_objc
+{
+  struct grub_sfs_bheader header;
+  grub_uint32_t parent;
+  grub_uint32_t next;
+  grub_uint32_t prev;
+  /* The amount of objects depends on the blocksize.  */
+  struct grub_sfs_obj objects[1];
+} __attribute__ ((packed));
+
+struct grub_sfs_btree_node
+{
+  grub_uint32_t key;
+  grub_uint32_t data;
+} __attribute__ ((packed));
+
+struct grub_sfs_btree_extent
+{
+  grub_uint32_t key;
+  grub_uint32_t next;
+  grub_uint32_t prev;
+  grub_uint16_t size;
+} __attribute__ ((packed));
+
+struct grub_sfs_btree
+{
+  struct grub_sfs_bheader header;
+  grub_uint16_t nodes;
+  grub_uint8_t leaf;
+  grub_uint8_t nodesize;
+  /* Normally this can be kind of node, but just extents are
+     supported.  */
+  struct grub_sfs_btree_node node[1];
+} __attribute__ ((packed));
+
+
+
+struct grub_fshelp_node
+{
+  struct grub_sfs_data *data;
+  int block;
+  int size;
+};
+
+/* Information about a "mounted" sfs filesystem.  */
+struct grub_sfs_data
+{
+  struct grub_sfs_rblock rblock;
+  struct grub_fshelp_node diropen;
+  grub_disk_t disk;
+
+  /* Blocksize in sectors.  */
+  unsigned int blocksize;
+
+  /* Label of the filesystem.  */
+  char *label;
+};
+
+static grub_dl_t my_mod;
+
+
+/* Lookup the extent starting with BLOCK in the filesystem described
+   by DATA.  Return the extent size in SIZE and the following extent
+   in NEXTEXT.  */
+static grub_err_t
+grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block,
+		      int *size, int *nextext)
+{
+  char *treeblock;
+  struct grub_sfs_btree *tree;
+  int i;
+  int next;
+  int prev;
+
+  treeblock = grub_malloc (data->blocksize);
+  if (!block)
+    return 0;
+
+  next = grub_be_to_cpu32 (data->rblock.btree);
+  tree = (struct grub_sfs_btree *) treeblock;
+
+  /* Handle this level in the btree.  */
+  do
+    {
+      prev = 0;
+
+      grub_disk_read (data->disk, next, 0, data->blocksize, treeblock);
+      if (grub_errno)
+	{
+	  grub_free (treeblock);
+	  return grub_errno;
+	}
+
+      for (i = grub_be_to_cpu16 (tree->nodes) - 1; i >= 0; i--)
+	{
+
+#define EXTNODE(tree, index)						\
+	((struct grub_sfs_btree_node *) (((char *) &(tree)->node[0])	\
+					 + (index) * (tree)->nodesize))
+
+	  /* Follow the tree down to the leaf level.  */
+	  if ((grub_be_to_cpu32 (EXTNODE(tree, i)->key) <= block)
+	      && !tree->leaf)
+	    {
+	      next = grub_be_to_cpu32 (EXTNODE (tree, i)->data);
+	      break;
+	    }
+
+	  /* If the leaf level is reached, just find the correct extent.  */
+	  if (grub_be_to_cpu32 (EXTNODE (tree, i)->key) == block && tree->leaf)
+	    {
+	      struct grub_sfs_btree_extent *extent;
+	      extent = (struct grub_sfs_btree_extent *) EXTNODE (tree, i);
+
+	      /* We found a correct leaf.  */
+	      *size = grub_be_to_cpu16 (extent->size);
+	      *nextext = grub_be_to_cpu32 (extent->next);
+
+	      grub_free (treeblock);
+	      return 0;
+	    }
+
+#undef EXTNODE
+
+	}
+    } while (!tree->leaf);
+
+  grub_free (treeblock);
+
+  return grub_error (GRUB_ERR_FILE_READ_ERROR, "SFS extent not found");
+}
+
+static grub_disk_addr_t
+grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  int blk = node->block;
+  int size = 0;
+  int next = 0;
+
+  while (blk)
+    {
+      grub_err_t err;
+
+      /* In case of the first block we don't have to lookup the
+	 extent, the minimum size is always 1.  */
+      if (fileblock == 0)
+	return blk;
+
+      err = grub_sfs_read_extent (node->data, blk, &size, &next);
+      if (err)
+	return 0;
+
+      if (fileblock < (unsigned int) size)
+	return fileblock + blk;
+
+      fileblock -= size;
+
+      blk = next;
+    }
+
+  grub_error (GRUB_ERR_FILE_READ_ERROR,
+	      "reading a SFS block outside the extent");
+
+  return 0;
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_sfs_read_file (grub_fshelp_node_t node,
+		    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+				       unsigned offset, unsigned length),
+		    int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+				pos, len, buf, grub_sfs_read_block,
+				node->size, 0);
+}
+
+
+static struct grub_sfs_data *
+grub_sfs_mount (grub_disk_t disk)
+{
+  struct grub_sfs_data *data;
+  struct grub_sfs_objc *rootobjc;
+  char *rootobjc_data = 0;
+  unsigned int blk;
+
+  data = grub_malloc (sizeof (*data));
+  if (!data)
+    return 0;
+
+  /* Read the rootblock.  */
+  grub_disk_read (disk, 0, 0, sizeof (struct grub_sfs_rblock),
+		  &data->rblock);
+  if (grub_errno)
+    goto fail;
+
+  /* Make sure this is a sfs filesystem.  */
+  if (grub_strncmp ((char *) (data->rblock.header.magic), "SFS", 4))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a sfs filesystem");
+      goto fail;
+    }
+
+  data->blocksize = grub_be_to_cpu32 (data->rblock.blocksize);
+  rootobjc_data = grub_malloc (data->blocksize);
+  if (! rootobjc_data)
+    goto fail;
+
+  /* Read the root object container.  */
+  grub_disk_read (disk, grub_be_to_cpu32 (data->rblock.rootobject), 0,
+		  data->blocksize, rootobjc_data);
+  if (grub_errno)
+    goto fail;
+
+  rootobjc = (struct grub_sfs_objc *) rootobjc_data;
+
+  blk = grub_be_to_cpu32 (rootobjc->objects[0].file_dir.dir.dir_objc);
+  data->diropen.size = 0;
+  data->diropen.block = blk;
+  data->diropen.data = data;
+  data->disk = disk;
+  data->label = grub_strdup ((char *) (rootobjc->objects[0].filename));
+
+  return data;
+
+ fail:
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not an sfs filesystem");
+
+  grub_free (data);
+  grub_free (rootobjc_data);
+  return 0;
+}
+
+
+static char *
+grub_sfs_read_symlink (grub_fshelp_node_t node)
+{
+  struct grub_sfs_data *data = node->data;
+  char *symlink;
+  char *block;
+
+  block = grub_malloc (data->blocksize);
+  if (!block)
+    return 0;
+
+  grub_disk_read (data->disk, node->block, 0, data->blocksize, block);
+  if (grub_errno)
+    {
+      grub_free (block);
+      return 0;
+    }
+
+  /* This is just a wild guess, but it always worked for me.  How the
+     SLNK block looks like is not documented in the SFS docs.  */
+  symlink = grub_strdup (&block[24]);
+  grub_free (block);
+  if (!symlink)
+    return 0;
+
+  return symlink;
+}
+
+static int
+grub_sfs_iterate_dir (grub_fshelp_node_t dir,
+		       int NESTED_FUNC_ATTR
+		       (*hook) (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node))
+{
+  struct grub_fshelp_node *node = 0;
+  struct grub_sfs_data *data = dir->data;
+  char *objc_data;
+  struct grub_sfs_objc *objc;
+  unsigned int next = dir->block;
+  int pos;
+
+  auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
+						  int size, int type);
+
+  int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
+					     int size, int type)
+    {
+      node = grub_malloc (sizeof (*node));
+      if (!node)
+	return 1;
+
+      node->data = data;
+      node->size = size;
+      node->block = block;
+
+      return hook (name, type, node);
+    }
+
+  objc_data = grub_malloc (data->blocksize);
+  if (!objc_data)
+    goto fail;
+
+  /* The Object container can consist of multiple blocks, iterate over
+     every block.  */
+  while (next)
+    {
+      grub_disk_read (data->disk, next, 0, data->blocksize, objc_data);
+      if (grub_errno)
+	goto fail;
+
+      objc = (struct grub_sfs_objc *) objc_data;
+
+      pos = (char *) &objc->objects[0] - (char *) objc;
+
+      /* Iterate over all entries in this block.  */
+      while (pos + sizeof (struct grub_sfs_obj) < data->blocksize)
+	{
+	  struct grub_sfs_obj *obj;
+	  obj = (struct grub_sfs_obj *) ((char *) objc + pos);
+	  char *filename = (char *) (obj->filename);
+	  int len;
+	  enum grub_fshelp_filetype type;
+	  unsigned int block;
+
+	  /* The filename and comment dynamically increase the size of
+	     the object.  */
+	  len = grub_strlen (filename);
+	  len += grub_strlen (filename + len + 1);
+
+	  pos += sizeof (*obj) + len;
+	  /* Round up to a multiple of two bytes.  */
+	  pos = ((pos + 1) >> 1) << 1;
+
+	  if (grub_strlen (filename) == 0)
+	    continue;
+
+	  /* First check if the file was not deleted.  */
+	  if (obj->type & GRUB_SFS_TYPE_DELETED)
+	    continue;
+	  else if (obj->type & GRUB_SFS_TYPE_SYMLINK)
+	    type = GRUB_FSHELP_SYMLINK;
+	  else if (obj->type & GRUB_SFS_TYPE_DIR)
+	    type = GRUB_FSHELP_DIR;
+	  else
+	    type = GRUB_FSHELP_REG;
+
+	  if (type == GRUB_FSHELP_DIR)
+	    block = grub_be_to_cpu32 (obj->file_dir.dir.dir_objc);
+	  else
+	    block = grub_be_to_cpu32 (obj->file_dir.file.first_block);
+
+	  if (grub_sfs_create_node (filename, block,
+				    grub_be_to_cpu32 (obj->file_dir.file.size),
+				    type))
+	    {
+	      grub_free (objc_data);
+	      return 1;
+	    }
+	}
+
+      next = grub_be_to_cpu32 (objc->next);
+    }
+
+ fail:
+  grub_free (objc_data);
+  return 0;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_sfs_open (struct grub_file *file, const char *name)
+{
+  struct grub_sfs_data *data;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_sfs_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_sfs_iterate_dir,
+			 grub_sfs_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  file->size = fdiro->size;
+  data->diropen = *fdiro;
+  grub_free (fdiro);
+
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+ fail:
+  if (data && fdiro != &data->diropen)
+    grub_free (fdiro);
+  if (data)
+    grub_free (data->label);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_sfs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+
+/* Read LEN bytes data from FILE into BUF.  */
+static grub_ssize_t
+grub_sfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_sfs_data *data = (struct grub_sfs_data *) file->data;
+
+  int size = grub_sfs_read_file (&data->diropen, file->read_hook,
+				 file->offset, len, buf);
+
+  return size;
+}
+
+
+static grub_err_t
+grub_sfs_dir (grub_device_t device, const char *path,
+	       int (*hook) (const char *filename,
+			    const struct grub_dirhook_info *info))
+{
+  struct grub_sfs_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+				     enum grub_fshelp_filetype filetype,
+				     grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_sfs_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_sfs_iterate_dir,
+			grub_sfs_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  grub_sfs_iterate_dir (fdiro, iterate);
+
+ fail:
+  if (data && fdiro != &data->diropen)
+    grub_free (fdiro);
+  if (data)
+    grub_free (data->label);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_sfs_label (grub_device_t device, char **label)
+{
+  struct grub_sfs_data *data;
+  grub_disk_t disk = device->disk;
+
+  data = grub_sfs_mount (disk);
+  if (data)
+    *label = data->label;
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+static struct grub_fs grub_sfs_fs =
+  {
+    .name = "sfs",
+    .dir = grub_sfs_dir,
+    .open = grub_sfs_open,
+    .read = grub_sfs_read,
+    .close = grub_sfs_close,
+    .label = grub_sfs_label,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(sfs)
+{
+  grub_fs_register (&grub_sfs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(sfs)
+{
+  grub_fs_unregister (&grub_sfs_fs);
+}
diff --git a/fs/tar.c b/fs/tar.c
new file mode 100644
index 0000000..6ab62bc
--- /dev/null
+++ b/fs/tar.c
@@ -0,0 +1,2 @@
+#define MODE_USTAR 1
+#include "cpio.c"
diff --git a/fs/udf.c b/fs/udf.c
new file mode 100644
index 0000000..9dfe431
--- /dev/null
+++ b/fs/udf.c
@@ -0,0 +1,916 @@
+/* udf.c - Universal Disk Format filesystem.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+#define GRUB_UDF_MAX_PDS		2
+#define GRUB_UDF_MAX_PMS		6
+
+#define U16				grub_le_to_cpu16
+#define U32				grub_le_to_cpu32
+#define U64				grub_le_to_cpu64
+
+#define GRUB_UDF_LOG2_BLKSZ		2
+#define GRUB_UDF_BLKSZ			2048
+
+#define GRUB_UDF_TAG_IDENT_PVD		0x0001
+#define GRUB_UDF_TAG_IDENT_AVDP		0x0002
+#define GRUB_UDF_TAG_IDENT_VDP		0x0003
+#define GRUB_UDF_TAG_IDENT_IUVD		0x0004
+#define GRUB_UDF_TAG_IDENT_PD		0x0005
+#define GRUB_UDF_TAG_IDENT_LVD		0x0006
+#define GRUB_UDF_TAG_IDENT_USD		0x0007
+#define GRUB_UDF_TAG_IDENT_TD		0x0008
+#define GRUB_UDF_TAG_IDENT_LVID		0x0009
+
+#define GRUB_UDF_TAG_IDENT_FSD		0x0100
+#define GRUB_UDF_TAG_IDENT_FID		0x0101
+#define GRUB_UDF_TAG_IDENT_AED		0x0102
+#define GRUB_UDF_TAG_IDENT_IE		0x0103
+#define GRUB_UDF_TAG_IDENT_TE		0x0104
+#define GRUB_UDF_TAG_IDENT_FE		0x0105
+#define GRUB_UDF_TAG_IDENT_EAHD		0x0106
+#define GRUB_UDF_TAG_IDENT_USE		0x0107
+#define GRUB_UDF_TAG_IDENT_SBD		0x0108
+#define GRUB_UDF_TAG_IDENT_PIE		0x0109
+#define GRUB_UDF_TAG_IDENT_EFE		0x010A
+
+#define GRUB_UDF_ICBTAG_TYPE_UNDEF	0x00
+#define GRUB_UDF_ICBTAG_TYPE_USE	0x01
+#define GRUB_UDF_ICBTAG_TYPE_PIE	0x02
+#define GRUB_UDF_ICBTAG_TYPE_IE		0x03
+#define GRUB_UDF_ICBTAG_TYPE_DIRECTORY	0x04
+#define GRUB_UDF_ICBTAG_TYPE_REGULAR	0x05
+#define GRUB_UDF_ICBTAG_TYPE_BLOCK	0x06
+#define GRUB_UDF_ICBTAG_TYPE_CHAR	0x07
+#define GRUB_UDF_ICBTAG_TYPE_EA		0x08
+#define GRUB_UDF_ICBTAG_TYPE_FIFO	0x09
+#define GRUB_UDF_ICBTAG_TYPE_SOCKET	0x0A
+#define GRUB_UDF_ICBTAG_TYPE_TE		0x0B
+#define GRUB_UDF_ICBTAG_TYPE_SYMLINK	0x0C
+#define GRUB_UDF_ICBTAG_TYPE_STREAMDIR	0x0D
+
+#define GRUB_UDF_ICBTAG_FLAG_AD_MASK	0x0007
+#define GRUB_UDF_ICBTAG_FLAG_AD_SHORT	0x0000
+#define GRUB_UDF_ICBTAG_FLAG_AD_LONG	0x0001
+#define GRUB_UDF_ICBTAG_FLAG_AD_EXT	0x0002
+#define GRUB_UDF_ICBTAG_FLAG_AD_IN_ICB	0x0003
+
+#define GRUB_UDF_EXT_NORMAL		0x00000000
+#define GRUB_UDF_EXT_NREC_ALLOC		0x40000000
+#define GRUB_UDF_EXT_NREC_NALLOC	0x80000000
+#define GRUB_UDF_EXT_MASK		0xC0000000
+
+#define GRUB_UDF_FID_CHAR_HIDDEN	0x01
+#define GRUB_UDF_FID_CHAR_DIRECTORY	0x02
+#define GRUB_UDF_FID_CHAR_DELETED	0x04
+#define GRUB_UDF_FID_CHAR_PARENT	0x08
+#define GRUB_UDF_FID_CHAR_METADATA	0x10
+
+#define GRUB_UDF_STD_IDENT_BEA01	"BEA01"
+#define GRUB_UDF_STD_IDENT_BOOT2	"BOOT2"
+#define GRUB_UDF_STD_IDENT_CD001	"CD001"
+#define GRUB_UDF_STD_IDENT_CDW02	"CDW02"
+#define GRUB_UDF_STD_IDENT_NSR02	"NSR02"
+#define GRUB_UDF_STD_IDENT_NSR03	"NSR03"
+#define GRUB_UDF_STD_IDENT_TEA01	"TEA01"
+
+#define GRUB_UDF_CHARSPEC_TYPE_CS0	0x00
+#define GRUB_UDF_CHARSPEC_TYPE_CS1	0x01
+#define GRUB_UDF_CHARSPEC_TYPE_CS2	0x02
+#define GRUB_UDF_CHARSPEC_TYPE_CS3	0x03
+#define GRUB_UDF_CHARSPEC_TYPE_CS4	0x04
+#define GRUB_UDF_CHARSPEC_TYPE_CS5	0x05
+#define GRUB_UDF_CHARSPEC_TYPE_CS6	0x06
+#define GRUB_UDF_CHARSPEC_TYPE_CS7	0x07
+#define GRUB_UDF_CHARSPEC_TYPE_CS8	0x08
+
+#define GRUB_UDF_PARTMAP_TYPE_1		1
+#define GRUB_UDF_PARTMAP_TYPE_2		2
+
+struct grub_udf_lb_addr
+{
+  grub_uint32_t block_num;
+  grub_uint16_t part_ref;
+} __attribute__ ((packed));
+
+struct grub_udf_short_ad
+{
+  grub_uint32_t length;
+  grub_uint32_t position;
+} __attribute__ ((packed));
+
+struct grub_udf_long_ad
+{
+  grub_uint32_t length;
+  struct grub_udf_lb_addr block;
+  grub_uint8_t imp_use[6];
+} __attribute__ ((packed));
+
+struct grub_udf_extent_ad
+{
+  grub_uint32_t length;
+  grub_uint32_t start;
+} __attribute__ ((packed));
+
+struct grub_udf_charspec
+{
+  grub_uint8_t charset_type;
+  grub_uint8_t charset_info[63];
+} __attribute__ ((packed));
+
+struct grub_udf_timestamp
+{
+  grub_uint16_t type_and_timezone;
+  grub_uint16_t year;
+  grub_uint8_t month;
+  grub_uint8_t day;
+  grub_uint8_t hour;
+  grub_uint8_t minute;
+  grub_uint8_t second;
+  grub_uint8_t centi_seconds;
+  grub_uint8_t hundreds_of_micro_seconds;
+  grub_uint8_t micro_seconds;
+} __attribute__ ((packed));
+
+struct grub_udf_regid
+{
+  grub_uint8_t flags;
+  grub_uint8_t ident[23];
+  grub_uint8_t ident_suffix[8];
+} __attribute__ ((packed));
+
+struct grub_udf_tag
+{
+  grub_uint16_t tag_ident;
+  grub_uint16_t desc_version;
+  grub_uint8_t tag_checksum;
+  grub_uint8_t reserved;
+  grub_uint16_t tag_serial_number;
+  grub_uint16_t desc_crc;
+  grub_uint16_t desc_crc_length;
+  grub_uint32_t tag_location;
+} __attribute__ ((packed));
+
+struct grub_udf_fileset
+{
+  struct grub_udf_tag tag;
+  struct grub_udf_timestamp datetime;
+  grub_uint16_t interchange_level;
+  grub_uint16_t max_interchange_level;
+  grub_uint32_t charset_list;
+  grub_uint32_t max_charset_list;
+  grub_uint32_t fileset_num;
+  grub_uint32_t fileset_desc_num;
+  struct grub_udf_charspec vol_charset;
+  grub_uint8_t vol_ident[128];
+  struct grub_udf_charspec fileset_charset;
+  grub_uint8_t fileset_ident[32];
+  grub_uint8_t copyright_file_ident[32];
+  grub_uint8_t abstract_file_ident[32];
+  struct grub_udf_long_ad root_icb;
+  struct grub_udf_regid domain_ident;
+  struct grub_udf_long_ad next_ext;
+  struct grub_udf_long_ad streamdir_icb;
+} __attribute__ ((packed));
+
+struct grub_udf_icbtag
+{
+  grub_uint32_t prior_recorded_num_direct_entries;
+  grub_uint16_t strategy_type;
+  grub_uint16_t strategy_parameter;
+  grub_uint16_t num_entries;
+  grub_uint8_t reserved;
+  grub_uint8_t file_type;
+  struct grub_udf_lb_addr parent_idb;
+  grub_uint16_t flags;
+} __attribute__ ((packed));
+
+struct grub_udf_file_ident
+{
+  struct grub_udf_tag tag;
+  grub_uint16_t version_num;
+  grub_uint8_t characteristics;
+  grub_uint8_t file_ident_length;
+  struct grub_udf_long_ad icb;
+  grub_uint16_t imp_use_length;
+} __attribute__ ((packed));
+
+struct grub_udf_file_entry
+{
+  struct grub_udf_tag tag;
+  struct grub_udf_icbtag icbtag;
+  grub_uint32_t uid;
+  grub_uint32_t gid;
+  grub_uint32_t permissions;
+  grub_uint16_t link_count;
+  grub_uint8_t record_format;
+  grub_uint8_t record_display_attr;
+  grub_uint32_t record_length;
+  grub_uint64_t file_size;
+  grub_uint64_t blocks_recorded;
+  struct grub_udf_timestamp access_time;
+  struct grub_udf_timestamp modification_time;
+  struct grub_udf_timestamp attr_time;
+  grub_uint32_t checkpoint;
+  struct grub_udf_long_ad extended_attr_idb;
+  struct grub_udf_regid imp_ident;
+  grub_uint64_t unique_id;
+  grub_uint32_t ext_attr_length;
+  grub_uint32_t alloc_descs_length;
+  grub_uint8_t ext_attr[1872];
+} __attribute__ ((packed));
+
+struct grub_udf_extended_file_entry
+{
+  struct grub_udf_tag tag;
+  struct grub_udf_icbtag icbtag;
+  grub_uint32_t uid;
+  grub_uint32_t gid;
+  grub_uint32_t permissions;
+  grub_uint16_t link_count;
+  grub_uint8_t record_format;
+  grub_uint8_t record_display_attr;
+  grub_uint32_t record_length;
+  grub_uint64_t file_size;
+  grub_uint64_t object_size;
+  grub_uint64_t blocks_recorded;
+  struct grub_udf_timestamp access_time;
+  struct grub_udf_timestamp modification_time;
+  struct grub_udf_timestamp create_time;
+  struct grub_udf_timestamp attr_time;
+  grub_uint32_t checkpoint;
+  grub_uint32_t reserved;
+  struct grub_udf_long_ad extended_attr_icb;
+  struct grub_udf_long_ad streamdir_icb;
+  struct grub_udf_regid imp_ident;
+  grub_uint64_t unique_id;
+  grub_uint32_t ext_attr_length;
+  grub_uint32_t alloc_descs_length;
+  grub_uint8_t ext_attr[1832];
+} __attribute__ ((packed));
+
+struct grub_udf_vrs
+{
+  grub_uint8_t type;
+  grub_uint8_t magic[5];
+  grub_uint8_t version;
+} __attribute__ ((packed));
+
+struct grub_udf_avdp
+{
+  struct grub_udf_tag tag;
+  struct grub_udf_extent_ad vds;
+} __attribute__ ((packed));
+
+struct grub_udf_pd
+{
+  struct grub_udf_tag tag;
+  grub_uint32_t seq_num;
+  grub_uint16_t flags;
+  grub_uint16_t part_num;
+  struct grub_udf_regid contents;
+  grub_uint8_t contents_use[128];
+  grub_uint32_t access_type;
+  grub_uint32_t start;
+  grub_uint32_t length;
+} __attribute__ ((packed));
+
+struct grub_udf_partmap
+{
+  grub_uint8_t type;
+  grub_uint8_t length;
+  union
+  {
+    struct
+    {
+      grub_uint16_t seq_num;
+      grub_uint16_t part_num;
+    } type1;
+
+    struct
+    {
+      grub_uint8_t ident[62];
+    } type2;
+  };
+};
+
+struct grub_udf_lvd
+{
+  struct grub_udf_tag tag;
+  grub_uint32_t seq_num;
+  struct grub_udf_charspec charset;
+  grub_uint8_t ident[128];
+  grub_uint32_t bsize;
+  struct grub_udf_regid domain_ident;
+  struct grub_udf_long_ad root_fileset;
+  grub_uint32_t map_table_length;
+  grub_uint32_t num_part_maps;
+  struct grub_udf_regid imp_ident;
+  grub_uint8_t imp_use[128];
+  struct grub_udf_extent_ad integrity_seq_ext;
+  grub_uint8_t part_maps[1608];
+} __attribute__ ((packed));
+
+struct grub_udf_data
+{
+  grub_disk_t disk;
+  struct grub_udf_lvd lvd;
+  struct grub_udf_pd pds[GRUB_UDF_MAX_PDS];
+  struct grub_udf_partmap *pms[GRUB_UDF_MAX_PMS];
+  struct grub_udf_long_ad root_icb;
+  int npd, npm;
+};
+
+struct grub_fshelp_node
+{
+  struct grub_udf_data *data;
+  union
+  {
+    struct grub_udf_file_entry fe;
+    struct grub_udf_extended_file_entry efe;
+  };
+  int part_ref;
+};
+
+static grub_dl_t my_mod;
+
+static grub_uint32_t
+grub_udf_get_block (struct grub_udf_data *data,
+		    grub_uint16_t part_ref, grub_uint32_t block)
+{
+  part_ref = U16 (part_ref);
+
+  if (part_ref >= data->npm)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "invalid part ref");
+      return 0;
+    }
+
+  return (U32 (data->pds[data->pms[part_ref]->type1.part_num].start)
+          + U32 (block));
+}
+
+static grub_err_t
+grub_udf_read_icb (struct grub_udf_data *data,
+		   struct grub_udf_long_ad *icb,
+		   struct grub_fshelp_node *node)
+{
+  grub_uint32_t block;
+
+  block = grub_udf_get_block (data,
+			      icb->block.part_ref,
+                              icb->block.block_num);
+
+  if (grub_errno)
+    return grub_errno;
+
+  if (grub_disk_read (data->disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+		      sizeof (struct grub_udf_file_entry),
+		      &node->fe))
+    return grub_errno;
+
+  if ((U16 (node->fe.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FE) &&
+      (U16 (node->fe.tag.tag_ident) != GRUB_UDF_TAG_IDENT_EFE))
+    return grub_error (GRUB_ERR_BAD_FS, "invalid fe/efe descriptor");
+
+  node->part_ref = icb->block.part_ref;
+  node->data = data;
+  return 0;
+}
+
+static grub_disk_addr_t
+grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  char *ptr;
+  int len;
+  grub_disk_addr_t filebytes;
+
+  if (U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE)
+    {
+      ptr = (char *) &node->fe.ext_attr[0] + U32 (node->fe.ext_attr_length);
+      len = U32 (node->fe.alloc_descs_length);
+    }
+  else
+    {
+      ptr = (char *) &node->efe.ext_attr[0] + U32 (node->efe.ext_attr_length);
+      len = U32 (node->efe.alloc_descs_length);
+    }
+
+  if ((U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK)
+      == GRUB_UDF_ICBTAG_FLAG_AD_SHORT)
+    {
+      struct grub_udf_short_ad *ad = (struct grub_udf_short_ad *) ptr;
+
+      len /= sizeof (struct grub_udf_short_ad);
+      filebytes = fileblock * GRUB_UDF_BLKSZ;
+      while (len > 0)
+	{
+	  if (filebytes < U32 (ad->length))
+	    return ((U32 (ad->position) & GRUB_UDF_EXT_MASK) ? 0 :
+                    (grub_udf_get_block (node->data,
+                                         node->part_ref,
+                                         ad->position)
+                     + (filebytes / GRUB_UDF_BLKSZ)));
+
+	  filebytes -= U32 (ad->length);
+	  ad++;
+	  len--;
+	}
+    }
+  else
+    {
+      struct grub_udf_long_ad *ad = (struct grub_udf_long_ad *) ptr;
+
+      len /= sizeof (struct grub_udf_long_ad);
+      filebytes = fileblock * GRUB_UDF_BLKSZ;
+      while (len > 0)
+	{
+	  if (filebytes < U32 (ad->length))
+	    return ((U32 (ad->block.block_num) & GRUB_UDF_EXT_MASK) ?  0 :
+                    (grub_udf_get_block (node->data,
+                                         ad->block.part_ref,
+                                         ad->block.block_num)
+		     + (filebytes / GRUB_UDF_BLKSZ)));
+
+	  filebytes -= U32 (ad->length);
+	  ad++;
+	  len--;
+	}
+    }
+
+  return 0;
+}
+
+static grub_ssize_t
+grub_udf_read_file (grub_fshelp_node_t node,
+		    void NESTED_FUNC_ATTR
+		    (*read_hook) (grub_disk_addr_t sector,
+				  unsigned offset, unsigned length),
+		    int pos, grub_size_t len, char *buf)
+{
+  switch (U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK)
+    {
+    case GRUB_UDF_ICBTAG_FLAG_AD_IN_ICB:
+      {
+	char *ptr;
+
+	ptr = ((U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) ?
+	       ((char *) &node->fe.ext_attr[0]
+                + U32 (node->fe.ext_attr_length)) :
+	       ((char *) &node->efe.ext_attr[0]
+                + U32 (node->efe.ext_attr_length)));
+
+	grub_memcpy (buf, ptr + pos, len);
+
+	return len;
+      }
+
+    case GRUB_UDF_ICBTAG_FLAG_AD_EXT:
+      grub_error (GRUB_ERR_BAD_FS, "invalid extent type");
+      return 0;
+    }
+
+  return  grub_fshelp_read_file (node->data->disk, node, read_hook,
+                                 pos, len, buf, grub_udf_read_block,
+                                 U64 (node->fe.file_size),
+                                 GRUB_UDF_LOG2_BLKSZ);
+}
+
+static int sblocklist[] = { 256, 512, 0 };
+
+static struct grub_udf_data *
+grub_udf_mount (grub_disk_t disk)
+{
+  struct grub_udf_data *data = 0;
+  struct grub_udf_fileset root_fs;
+  int *sblklist = sblocklist;
+  grub_uint32_t block;
+  int i;
+
+  data = grub_malloc (sizeof (struct grub_udf_data));
+  if (!data)
+    return 0;
+
+  data->disk = disk;
+
+  /* Search for Volume Recognition Sequence (VRS).  */
+  for (block = 16;; block++)
+    {
+      struct grub_udf_vrs vrs;
+
+      if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+			  sizeof (struct grub_udf_vrs), &vrs))
+	{
+	  grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem");
+	  goto fail;
+	}
+
+      if ((!grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_NSR03, 5)) ||
+	  (!grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_NSR02, 5)))
+	break;
+
+      if ((grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_BEA01, 5)) &&
+	  (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_BOOT2, 5)) &&
+	  (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_CD001, 5)) &&
+	  (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_CDW02, 5)) &&
+	  (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_TEA01, 5)))
+	{
+	  grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem");
+	  goto fail;
+	}
+    }
+
+  /* Search for Anchor Volume Descriptor Pointer (AVDP).  */
+  while (1)
+    {
+      struct grub_udf_avdp avdp;
+
+      if (grub_disk_read (disk, *sblklist << GRUB_UDF_LOG2_BLKSZ, 0,
+			  sizeof (struct grub_udf_avdp), &avdp))
+	{
+	  grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem");
+	  goto fail;
+	}
+
+      if (U16 (avdp.tag.tag_ident) == GRUB_UDF_TAG_IDENT_AVDP)
+	{
+	  block = U32 (avdp.vds.start);
+	  break;
+	}
+
+      sblklist++;
+      if (*sblklist == 0)
+	{
+	  grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem");
+	  goto fail;
+	}
+    }
+
+  data->npd = data->npm = 0;
+  /* Locate Partition Descriptor (PD) and Logical Volume Descriptor (LVD).  */
+  while (1)
+    {
+      struct grub_udf_tag tag;
+
+      if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+			  sizeof (struct grub_udf_tag), &tag))
+	{
+	  grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem");
+	  goto fail;
+	}
+
+      tag.tag_ident = U16 (tag.tag_ident);
+      if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PD)
+	{
+	  if (data->npd >= GRUB_UDF_MAX_PDS)
+	    {
+	      grub_error (GRUB_ERR_BAD_FS, "too many PDs");
+	      goto fail;
+	    }
+
+	  if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+			      sizeof (struct grub_udf_pd),
+			      &data->pds[data->npd]))
+	    {
+	      grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem");
+	      goto fail;
+	    }
+
+	  data->npd++;
+	}
+      else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_LVD)
+	{
+	  int k;
+
+	  struct grub_udf_partmap *ppm;
+
+	  if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+			      sizeof (struct grub_udf_lvd),
+			      &data->lvd))
+	    {
+	      grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem");
+	      goto fail;
+	    }
+
+	  if (data->npm + U32 (data->lvd.num_part_maps) > GRUB_UDF_MAX_PMS)
+	    {
+	      grub_error (GRUB_ERR_BAD_FS, "too many partition maps");
+	      goto fail;
+	    }
+
+	  ppm = (struct grub_udf_partmap *) &data->lvd.part_maps;
+	  for (k = U32 (data->lvd.num_part_maps); k > 0; k--)
+	    {
+	      if (ppm->type != GRUB_UDF_PARTMAP_TYPE_1)
+		{
+		  grub_error (GRUB_ERR_BAD_FS, "partmap type not supported");
+		  goto fail;
+		}
+
+	      data->pms[data->npm++] = ppm;
+	      ppm = (struct grub_udf_partmap *) ((char *) ppm +
+                                                 U32 (ppm->length));
+	    }
+	}
+      else if (tag.tag_ident > GRUB_UDF_TAG_IDENT_TD)
+	{
+	  grub_error (GRUB_ERR_BAD_FS, "invalid tag ident");
+	  goto fail;
+	}
+      else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_TD)
+	break;
+
+      block++;
+    }
+
+  for (i = 0; i < data->npm; i++)
+    {
+      int j;
+
+      for (j = 0; j < data->npd; j++)
+	if (data->pms[i]->type1.part_num == data->pds[j].part_num)
+	  {
+	    data->pms[i]->type1.part_num = j;
+	    break;
+	  }
+
+      if (j == data->npd)
+	{
+	  grub_error (GRUB_ERR_BAD_FS, "can\'t find PD");
+	  goto fail;
+	}
+    }
+
+  block = grub_udf_get_block (data,
+			      data->lvd.root_fileset.block.part_ref,
+			      data->lvd.root_fileset.block.block_num);
+
+  if (grub_errno)
+    goto fail;
+
+  if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+		      sizeof (struct grub_udf_fileset), &root_fs))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem");
+      goto fail;
+    }
+
+  if (U16 (root_fs.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FSD)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "invalid fileset descriptor");
+      goto fail;
+    }
+
+  data->root_icb = root_fs.root_icb;
+
+  return data;
+
+fail:
+  grub_free (data);
+  return 0;
+}
+
+static int
+grub_udf_iterate_dir (grub_fshelp_node_t dir,
+		      int NESTED_FUNC_ATTR
+		      (*hook) (const char *filename,
+			       enum grub_fshelp_filetype filetype,
+			       grub_fshelp_node_t node))
+{
+  grub_fshelp_node_t child;
+  struct grub_udf_file_ident dirent;
+  grub_uint32_t offset = 0;
+
+  child = grub_malloc (sizeof (struct grub_fshelp_node));
+  if (!child)
+    return 0;
+
+  /* The current directory is not stored.  */
+  grub_memcpy ((char *) child, (char *) dir,
+	       sizeof (struct grub_fshelp_node));
+
+  if (hook (".", GRUB_FSHELP_DIR, child))
+    return 1;
+
+  while (offset < U64 (dir->fe.file_size))
+    {
+      if (grub_udf_read_file (dir, 0, offset, sizeof (dirent),
+			      (char *) &dirent) != sizeof (dirent))
+	return 0;
+
+      if (U16 (dirent.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FID)
+	{
+	  grub_error (GRUB_ERR_BAD_FS, "invalid fid tag");
+	  return 0;
+	}
+
+      child = grub_malloc (sizeof (struct grub_fshelp_node));
+      if (!child)
+	return 0;
+
+      if (grub_udf_read_icb (dir->data, &dirent.icb, child))
+	return 0;
+
+      offset += sizeof (dirent) + U16 (dirent.imp_use_length);
+      if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT)
+	{
+	  /* This is the parent directory.  */
+	  if (hook ("..", GRUB_FSHELP_DIR, child))
+	    return 1;
+	}
+      else
+	{
+	  enum grub_fshelp_filetype type;
+	  char filename[dirent.file_ident_length + 1];
+
+	  type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ?
+		  (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG));
+
+	  if ((grub_udf_read_file (dir, 0, offset,
+				   dirent.file_ident_length, filename))
+	      != dirent.file_ident_length)
+	    return 0;
+
+	  filename[dirent.file_ident_length] = 0;
+	  if (hook (&filename[1], type, child))
+	    return 1;
+	}
+
+      /* Align to dword boundary.  */
+      offset = (offset + dirent.file_ident_length + 3) & (~3);
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_udf_dir (grub_device_t device, const char *path,
+	      int (*hook) (const char *filename,
+			   const struct grub_dirhook_info *info))
+{
+  struct grub_udf_data *data = 0;
+  struct grub_fshelp_node rootnode;
+  struct grub_fshelp_node *foundnode;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+				     enum grub_fshelp_filetype filetype,
+				     grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node)
+  {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+  }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_udf_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  if (grub_udf_read_icb (data, &data->root_icb, &rootnode))
+    goto fail;
+
+  if (grub_fshelp_find_file (path, &rootnode,
+			     &foundnode,
+			     grub_udf_iterate_dir, 0, GRUB_FSHELP_DIR))
+    goto fail;
+
+  grub_udf_iterate_dir (foundnode, iterate);
+
+  if (foundnode != &rootnode)
+    grub_free (foundnode);
+
+fail:
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_udf_open (struct grub_file *file, const char *name)
+{
+  struct grub_udf_data *data;
+  struct grub_fshelp_node rootnode;
+  struct grub_fshelp_node *foundnode;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_udf_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  if (grub_udf_read_icb (data, &data->root_icb, &rootnode))
+    goto fail;
+
+  if (grub_fshelp_find_file (name, &rootnode,
+			     &foundnode,
+			     grub_udf_iterate_dir, 0, GRUB_FSHELP_REG))
+    goto fail;
+
+  file->data = foundnode;
+  file->offset = 0;
+  file->size = U64 (foundnode->fe.file_size);
+
+  return 0;
+
+fail:
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_udf_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data;
+
+  return grub_udf_read_file (node, file->read_hook, file->offset, len, buf);
+}
+
+static grub_err_t
+grub_udf_close (grub_file_t file)
+{
+  if (file->data)
+    {
+      struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data;
+
+      grub_free (node->data);
+      grub_free (node);
+    }
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_udf_label (grub_device_t device, char **label)
+{
+  struct grub_udf_data *data;
+  data = grub_udf_mount (device->disk);
+
+  if (data)
+    {
+      *label = grub_strdup ((char *) &data->lvd.ident[1]);
+      grub_free (data);
+    }
+  else
+    *label = 0;
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_udf_fs = {
+  .name = "udf",
+  .dir = grub_udf_dir,
+  .open = grub_udf_open,
+  .read = grub_udf_read,
+  .close = grub_udf_close,
+  .label = grub_udf_label,
+  .next = 0
+};
+
+GRUB_MOD_INIT (udf)
+{
+  grub_fs_register (&grub_udf_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI (udf)
+{
+  grub_fs_unregister (&grub_udf_fs);
+}
diff --git a/fs/ufs.c b/fs/ufs.c
new file mode 100644
index 0000000..c94ad99
--- /dev/null
+++ b/fs/ufs.c
@@ -0,0 +1,816 @@
+/* ufs.c - Unix File System */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+
+#ifdef MODE_UFS2
+#define GRUB_UFS_MAGIC		0x19540119
+#else
+#define GRUB_UFS_MAGIC		0x11954
+#endif
+
+#define GRUB_UFS_INODE		2
+#define GRUB_UFS_FILETYPE_DIR	4
+#define GRUB_UFS_FILETYPE_LNK	10
+#define GRUB_UFS_MAX_SYMLNK_CNT	8
+
+#define GRUB_UFS_DIRBLKS	12
+#define GRUB_UFS_INDIRBLKS	3
+
+#define GRUB_UFS_ATTR_TYPE      0160000
+#define GRUB_UFS_ATTR_FILE	0100000
+#define GRUB_UFS_ATTR_DIR	0040000
+#define GRUB_UFS_ATTR_LNK       0120000
+
+#define GRUB_UFS_VOLNAME_LEN	32
+
+/* Calculate in which group the inode can be found.  */
+#define UFS_BLKSZ(sblock) (grub_le_to_cpu32 (sblock->bsize))
+
+#define INODE(data,field) data->inode.  field
+#ifdef MODE_UFS2
+#define INODE_ENDIAN(data,field,bits1,bits2) grub_le_to_cpu##bits2 (data->inode.field)
+#else
+#define INODE_ENDIAN(data,field,bits1,bits2) grub_le_to_cpu##bits1 (data->inode.field)
+#endif
+
+#define INODE_SIZE(data) INODE_ENDIAN (data,size,32,64)
+#define INODE_NBLOCKS(data) INODE_ENDIAN (data,nblocks,32,64)
+
+#define INODE_MODE(data) INODE_ENDIAN (data,mode,16,16)
+#ifdef MODE_UFS2
+#define INODE_BLKSZ 8
+#else
+#define INODE_BLKSZ 4
+#endif
+#ifdef MODE_UFS2
+#define UFS_INODE_PER_BLOCK 2
+#else
+#define UFS_INODE_PER_BLOCK 4
+#endif
+#define INODE_DIRBLOCKS(data,blk) INODE_ENDIAN \
+                                   (data,blocks.dir_blocks[blk],32,64)
+#define INODE_INDIRBLOCKS(data,blk) INODE_ENDIAN \
+                                     (data,blocks.indir_blocks[blk],32,64)
+
+/* The blocks on which the superblock can be found.  */
+static int sblocklist[] = { 128, 16, 0, 512, -1 };
+
+struct grub_ufs_sblock
+{
+  grub_uint8_t unused[16];
+  /* The offset of the inodes in the cylinder group.  */
+  grub_uint32_t inoblk_offs;
+
+  grub_uint8_t unused2[4];
+
+  /* The start of the cylinder group.  */
+  grub_uint32_t cylg_offset;
+  grub_uint32_t cylg_mask;
+
+  grub_uint32_t mtime;
+  grub_uint8_t unused4[12];
+
+  /* The size of a block in bytes.  */
+  grub_int32_t bsize;
+  grub_uint8_t unused5[48];
+
+  /* The size of filesystem blocks to disk blocks.  */
+  grub_uint32_t log2_blksz;
+  grub_uint8_t unused6[40];
+  grub_uint32_t uuidhi;
+  grub_uint32_t uuidlow;
+  grub_uint8_t unused7[32];
+
+  /* Inodes stored per cylinder group.  */
+  grub_uint32_t ino_per_group;
+
+  /* The frags per cylinder group.  */
+  grub_uint32_t frags_per_group;
+
+  grub_uint8_t unused8[488];
+
+  /* Volume name for UFS2.  */
+  grub_uint8_t volume_name[GRUB_UFS_VOLNAME_LEN];
+  grub_uint8_t unused9[360];
+
+  grub_uint64_t mtime2;
+  grub_uint8_t unused10[292];
+
+  /* Magic value to check if this is really a UFS filesystem.  */
+  grub_uint32_t magic;
+};
+
+#ifdef MODE_UFS2
+/* UFS inode.  */
+struct grub_ufs_inode
+{
+  grub_uint16_t mode;
+  grub_uint16_t nlinks;
+  grub_uint32_t uid;
+  grub_uint32_t gid;
+  grub_uint32_t blocksize;
+  grub_int64_t size;
+  grub_int64_t nblocks;
+  grub_uint64_t atime;
+  grub_uint64_t mtime;
+  grub_uint64_t ctime;
+  grub_uint64_t create_time;
+  grub_uint32_t atime_sec;
+  grub_uint32_t mtime_sec;
+  grub_uint32_t ctime_sec;
+  grub_uint32_t create_time_sec;
+  grub_uint32_t gen;
+  grub_uint32_t kernel_flags;
+  grub_uint32_t flags;
+  grub_uint32_t extsz;
+  grub_uint64_t ext[2];
+  union
+  {
+    struct
+    {
+      grub_uint64_t dir_blocks[GRUB_UFS_DIRBLKS];
+      grub_uint64_t indir_blocks[GRUB_UFS_INDIRBLKS];
+    } blocks;
+    grub_uint8_t symlink[(GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS) * 8];
+  };
+
+  grub_uint8_t unused[24];
+} __attribute__ ((packed));
+#else
+/* UFS inode.  */
+struct grub_ufs_inode
+{
+  grub_uint16_t mode;
+  grub_uint16_t nlinks;
+  grub_uint16_t uid;
+  grub_uint16_t gid;
+  grub_int64_t size;
+  grub_uint64_t atime;
+  grub_uint64_t mtime;
+  grub_uint64_t ctime;
+  union
+  {
+    struct
+    {
+      grub_uint32_t dir_blocks[GRUB_UFS_DIRBLKS];
+      grub_uint32_t indir_blocks[GRUB_UFS_INDIRBLKS];
+    } blocks;
+    grub_uint8_t symlink[(GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS) * 4];
+  };
+  grub_uint32_t flags;
+  grub_uint32_t nblocks;
+  grub_uint32_t gen;
+  grub_uint32_t unused;
+  grub_uint8_t pad[12];
+} __attribute__ ((packed));
+#endif
+
+/* Directory entry.  */
+struct grub_ufs_dirent
+{
+  grub_uint32_t ino;
+  grub_uint16_t direntlen;
+  union
+  {
+    grub_uint16_t namelen;
+    struct
+    {
+      grub_uint8_t filetype_bsd;
+      grub_uint8_t namelen_bsd;
+    };
+  };
+} __attribute__ ((packed));
+
+/* Information about a "mounted" ufs filesystem.  */
+struct grub_ufs_data
+{
+  struct grub_ufs_sblock sblock;
+  grub_disk_t disk;
+  struct grub_ufs_inode inode;
+  int ino;
+  int linknest;
+};
+
+static grub_dl_t my_mod;
+
+/* Forward declaration.  */
+static grub_err_t grub_ufs_find_file (struct grub_ufs_data *data,
+				      const char *path);
+
+
+static grub_disk_addr_t
+grub_ufs_get_file_block (struct grub_ufs_data *data, unsigned int blk)
+{
+  struct grub_ufs_sblock *sblock = &data->sblock;
+  unsigned int indirsz;
+  int log2_blksz;
+
+  /* Direct.  */
+  if (blk < GRUB_UFS_DIRBLKS)
+    return INODE_DIRBLOCKS (data, blk);
+
+  log2_blksz = grub_le_to_cpu32 (data->sblock.log2_blksz);
+
+  blk -= GRUB_UFS_DIRBLKS;
+
+  indirsz = UFS_BLKSZ (sblock) / INODE_BLKSZ;
+  /* Single indirect block.  */
+  if (blk < indirsz)
+    {
+#ifdef MODE_UFS2
+      grub_uint64_t indir[UFS_BLKSZ (sblock) / sizeof (grub_uint64_t)];
+#else
+      grub_uint32_t indir[UFS_BLKSZ (sblock) / sizeof (grub_uint32_t)];
+#endif
+      grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 0) << log2_blksz,
+		      0, sizeof (indir), indir);
+      return indir[blk];
+    }
+  blk -= indirsz;
+
+  /* Double indirect block.  */
+  if (blk < indirsz * indirsz)
+    {
+#ifdef MODE_UFS2
+      grub_uint64_t indir[UFS_BLKSZ (sblock) / sizeof (grub_uint64_t)];
+#else
+      grub_uint32_t indir[UFS_BLKSZ (sblock) / sizeof (grub_uint32_t)];
+#endif
+
+      grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 1) << log2_blksz,
+		      0, sizeof (indir), indir);
+      grub_disk_read (data->disk,
+		      (indir [blk / indirsz])
+		      << log2_blksz,
+		      0, sizeof (indir), indir);
+
+      return indir[blk % indirsz];
+    }
+
+
+  grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+	      "ufs does not support triple indirect blocks");
+  return 0;
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_ufs_read_file (struct grub_ufs_data *data,
+		    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+				       unsigned offset, unsigned length),
+		    int pos, grub_size_t len, char *buf)
+{
+  struct grub_ufs_sblock *sblock = &data->sblock;
+  int i;
+  int blockcnt;
+
+  /* Adjust len so it we can't read past the end of the file.  */
+  if (len + pos > INODE_SIZE (data))
+    len = INODE_SIZE (data) - pos;
+
+  blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) / UFS_BLKSZ (sblock);
+
+  for (i = pos / UFS_BLKSZ (sblock); i < blockcnt; i++)
+    {
+      int blknr;
+      int blockoff = pos % UFS_BLKSZ (sblock);
+      int blockend = UFS_BLKSZ (sblock);
+
+      int skipfirst = 0;
+
+      blknr = grub_ufs_get_file_block (data, i);
+      if (grub_errno)
+	return -1;
+
+      /* Last block.  */
+      if (i == blockcnt - 1)
+	{
+	  blockend = (len + pos) % UFS_BLKSZ (sblock);
+
+	  if (!blockend)
+	    blockend = UFS_BLKSZ (sblock);
+	}
+
+      /* First block.  */
+      if (i == (pos / (int) UFS_BLKSZ (sblock)))
+	{
+	  skipfirst = blockoff;
+	  blockend -= skipfirst;
+	}
+
+      /* XXX: If the block number is 0 this block is not stored on
+	 disk but is zero filled instead.  */
+      if (blknr)
+	{
+	  data->disk->read_hook = read_hook;
+	  grub_disk_read (data->disk,
+			  blknr << grub_le_to_cpu32 (data->sblock.log2_blksz),
+			  skipfirst, blockend, buf);
+	  data->disk->read_hook = 0;
+	  if (grub_errno)
+	    return -1;
+	}
+      else
+	grub_memset (buf, UFS_BLKSZ (sblock) - skipfirst, 0);
+
+      buf += UFS_BLKSZ (sblock) - skipfirst;
+    }
+
+  return len;
+}
+
+/* Read inode INO from the mounted filesystem described by DATA.  This
+   inode is used by default now.  */
+static grub_err_t
+grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode)
+{
+  struct grub_ufs_sblock *sblock = &data->sblock;
+
+  /* Determine the group the inode is in.  */
+  int group = ino / grub_le_to_cpu32 (sblock->ino_per_group);
+
+  /* Determine the inode within the group.  */
+  int grpino = ino % grub_le_to_cpu32 (sblock->ino_per_group);
+
+  /* The first block of the group.  */
+  int grpblk = group * (grub_le_to_cpu32 (sblock->frags_per_group));
+
+#ifndef MODE_UFS2
+  grpblk += grub_le_to_cpu32 (sblock->cylg_offset)
+    * (group & (~grub_le_to_cpu32 (sblock->cylg_mask)));
+#endif
+
+  if (!inode)
+    {
+      inode = (char *) &data->inode;
+      data->ino = ino;
+    }
+
+  grub_disk_read (data->disk,
+		  ((grub_le_to_cpu32 (sblock->inoblk_offs) + grpblk)
+		   << grub_le_to_cpu32 (data->sblock.log2_blksz))
+		  + grpino / UFS_INODE_PER_BLOCK,
+		  (grpino % UFS_INODE_PER_BLOCK)
+		  * sizeof (struct grub_ufs_inode),
+		  sizeof (struct grub_ufs_inode),
+		  inode);
+
+  return grub_errno;
+}
+
+
+/* Lookup the symlink the current inode points to.  INO is the inode
+   number of the directory the symlink is relative to.  */
+static grub_err_t
+grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
+{
+  char symlink[INODE_SIZE (data)];
+
+  if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT)
+    return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
+
+  if (INODE_NBLOCKS (data) == 0)
+    grub_strcpy (symlink, (char *) INODE (data, symlink));
+  else
+    {
+      grub_disk_read (data->disk,
+		      (INODE_DIRBLOCKS (data, 0)
+		       << grub_le_to_cpu32 (data->sblock.log2_blksz)),
+		      0, INODE_SIZE (data), symlink);
+      symlink[INODE_SIZE (data)] = '\0';
+    }
+
+  /* The symlink is an absolute path, go back to the root inode.  */
+  if (symlink[0] == '/')
+    ino = GRUB_UFS_INODE;
+
+  /* Now load in the old inode.  */
+  if (grub_ufs_read_inode (data, ino, 0))
+    return grub_errno;
+
+  grub_ufs_find_file (data, symlink);
+  if (grub_errno)
+    grub_error (grub_errno, "Can not follow symlink `%s'.", symlink);
+
+  return grub_errno;
+}
+
+
+/* Find the file with the pathname PATH on the filesystem described by
+   DATA.  */
+static grub_err_t
+grub_ufs_find_file (struct grub_ufs_data *data, const char *path)
+{
+  char fpath[grub_strlen (path) + 1];
+  char *name = fpath;
+  char *next;
+  unsigned int pos = 0;
+  int dirino;
+
+  grub_strcpy (fpath, path);
+
+  /* Skip the first slash.  */
+  if (name[0] == '/')
+    {
+      name++;
+      if (!*name)
+	return 0;
+    }
+
+  /* Extract the actual part from the pathname.  */
+  next = grub_strchr (name, '/');
+  if (next)
+    {
+      next[0] = '\0';
+      next++;
+    }
+
+  do
+    {
+      struct grub_ufs_dirent dirent;
+      int namelen;
+
+      if (grub_strlen (name) == 0)
+	return GRUB_ERR_NONE;
+
+      if (grub_ufs_read_file (data, 0, pos, sizeof (dirent),
+			      (char *) &dirent) < 0)
+	return grub_errno;
+
+#ifdef MODE_UFS2
+      namelen = dirent.namelen_bsd;
+#else
+      namelen = grub_le_to_cpu16 (dirent.namelen);
+#endif
+      {
+	char filename[namelen + 1];
+
+	if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
+				namelen, filename) < 0)
+	  return grub_errno;
+
+	filename[namelen] = '\0';
+
+	if (!grub_strcmp (name, filename))
+	  {
+	    dirino = data->ino;
+	    grub_ufs_read_inode (data, grub_le_to_cpu32 (dirent.ino), 0);
+
+	    if ((INODE_MODE(data) & GRUB_UFS_ATTR_TYPE)
+		== GRUB_UFS_ATTR_LNK)
+	      {
+		grub_ufs_lookup_symlink (data, dirino);
+		if (grub_errno)
+		  return grub_errno;
+	      }
+
+	    if (!next)
+	      return 0;
+
+	    pos = 0;
+
+	    name = next;
+	    next = grub_strchr (name, '/');
+	    if (next)
+	      {
+		next[0] = '\0';
+		next++;
+	      }
+
+	    if ((INODE_MODE(data) & GRUB_UFS_ATTR_TYPE) != GRUB_UFS_ATTR_DIR)
+	      return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+
+	    continue;
+	  }
+      }
+
+      pos += grub_le_to_cpu16 (dirent.direntlen);
+    } while (pos < INODE_SIZE (data));
+
+  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+  return grub_errno;
+}
+
+
+/* Mount the filesystem on the disk DISK.  */
+static struct grub_ufs_data *
+grub_ufs_mount (grub_disk_t disk)
+{
+  struct grub_ufs_data *data;
+  int *sblklist = sblocklist;
+
+  data = grub_malloc (sizeof (struct grub_ufs_data));
+  if (!data)
+    return 0;
+
+  /* Find a UFS sblock.  */
+  while (*sblklist != -1)
+    {
+      grub_disk_read (disk, *sblklist, 0, sizeof (struct grub_ufs_sblock),
+		      &data->sblock);
+      if (grub_errno)
+	goto fail;
+
+      if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC)
+	{
+	  data->disk = disk;
+	  data->linknest = 0;
+	  return data;
+	}
+      sblklist++;
+    }
+
+ fail:
+
+  if (grub_errno == GRUB_ERR_NONE || grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    {
+#ifdef MODE_UFS2
+      grub_error (GRUB_ERR_BAD_FS, "not an ufs2 filesystem");
+#else
+      grub_error (GRUB_ERR_BAD_FS, "not an ufs1 filesystem");
+#endif
+    }
+
+  grub_free (data);
+
+  return 0;
+}
+
+
+static grub_err_t
+grub_ufs_dir (grub_device_t device, const char *path,
+	       int (*hook) (const char *filename,
+			    const struct grub_dirhook_info *info))
+{
+  struct grub_ufs_data *data;
+  struct grub_ufs_sblock *sblock;
+  unsigned int pos = 0;
+
+  data = grub_ufs_mount (device->disk);
+  if (!data)
+    return grub_errno;
+
+  grub_ufs_read_inode (data, GRUB_UFS_INODE, 0);
+  if (grub_errno)
+    return grub_errno;
+
+  sblock = &data->sblock;
+
+  if (!path || path[0] != '/')
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
+      return grub_errno;
+    }
+
+  grub_ufs_find_file (data, path);
+  if (grub_errno)
+    goto fail;
+
+  if ((INODE_MODE (data) & GRUB_UFS_ATTR_TYPE) != GRUB_UFS_ATTR_DIR)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      goto fail;
+    }
+
+  while (pos < INODE_SIZE (data))
+    {
+      struct grub_ufs_dirent dirent;
+      int namelen;
+
+      if (grub_ufs_read_file (data, 0, pos, sizeof (dirent),
+			      (char *) &dirent) < 0)
+	break;
+
+#ifdef MODE_UFS2
+      namelen = dirent.namelen_bsd;
+#else
+      namelen = grub_le_to_cpu16 (dirent.namelen);
+#endif
+
+      {
+	char filename[namelen + 1];
+	struct grub_dirhook_info info;
+	struct grub_ufs_inode inode;
+
+	grub_memset (&info, 0, sizeof (info));
+
+	if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
+				namelen, filename) < 0)
+	  break;
+
+	filename[namelen] = '\0';
+	grub_ufs_read_inode (data, dirent.ino, (char *) &inode);
+
+	info.dir = ((grub_le_to_cpu16 (inode.mode) & GRUB_UFS_ATTR_TYPE)
+		    == GRUB_UFS_ATTR_DIR);
+	info.mtime = grub_le_to_cpu64 (inode.mtime);
+	info.mtimeset = 1;
+
+	if (hook (filename, &info))
+	  break;
+      }
+
+      pos += grub_le_to_cpu16 (dirent.direntlen);
+    }
+
+ fail:
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_ufs_open (struct grub_file *file, const char *name)
+{
+  struct grub_ufs_data *data;
+  data = grub_ufs_mount (file->device->disk);
+  if (!data)
+    return grub_errno;
+
+  grub_ufs_read_inode (data, 2, 0);
+  if (grub_errno)
+    {
+      grub_free (data);
+      return grub_errno;
+    }
+
+  if (!name || name[0] != '/')
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
+      return grub_errno;
+    }
+
+  grub_ufs_find_file (data, name);
+  if (grub_errno)
+    {
+      grub_free (data);
+      return grub_errno;
+    }
+
+  file->data = data;
+  file->size = INODE_SIZE (data);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_ssize_t
+grub_ufs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_ufs_data *data =
+    (struct grub_ufs_data *) file->data;
+
+  return grub_ufs_read_file (data, file->read_hook, file->offset, len, buf);
+}
+
+
+static grub_err_t
+grub_ufs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  return GRUB_ERR_NONE;
+}
+
+
+#ifdef MODE_UFS2
+static grub_err_t
+grub_ufs_label (grub_device_t device, char **label)
+{
+  struct grub_ufs_data *data = 0;
+
+  grub_dl_ref (my_mod);
+
+  *label = 0;
+
+  data = grub_ufs_mount (device->disk);
+  if (data)
+    *label = grub_strdup ((char *) data->sblock.volume_name);
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+#endif
+
+static grub_err_t
+grub_ufs_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_ufs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ufs_mount (disk);
+  if (data && (data->sblock.uuidhi != 0 || data->sblock.uuidlow != 0))
+    {
+      *uuid = grub_malloc (16 + sizeof ('\0'));
+      grub_sprintf (*uuid, "%08x%08x",
+		    (unsigned) grub_le_to_cpu32 (data->sblock.uuidhi),
+		    (unsigned) grub_le_to_cpu32 (data->sblock.uuidlow));
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+/* Get mtime.  */
+static grub_err_t
+grub_ufs_mtime (grub_device_t device, grub_int32_t *tm)
+{
+  struct grub_ufs_data *data = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ufs_mount (device->disk);
+  if (!data)
+    *tm = 0;
+  else
+#ifdef MODE_UFS2
+    *tm = grub_le_to_cpu64 (data->sblock.mtime2);
+#else
+    *tm = grub_le_to_cpu32 (data->sblock.mtime);
+#endif
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+
+static struct grub_fs grub_ufs_fs =
+  {
+#ifdef MODE_UFS2
+    .name = "ufs2",
+#else
+    .name = "ufs1",
+#endif
+    .dir = grub_ufs_dir,
+    .open = grub_ufs_open,
+    .read = grub_ufs_read,
+    .close = grub_ufs_close,
+#ifdef MODE_UFS2
+    .label = grub_ufs_label,
+#endif
+    .uuid = grub_ufs_uuid,
+    .mtime = grub_ufs_mtime,
+    .next = 0
+  };
+
+#ifdef MODE_UFS2
+GRUB_MOD_INIT(ufs2)
+#else
+GRUB_MOD_INIT(ufs1)
+#endif
+{
+  grub_fs_register (&grub_ufs_fs);
+  my_mod = mod;
+}
+
+#ifdef MODE_UFS2
+GRUB_MOD_FINI(ufs2)
+#else
+GRUB_MOD_FINI(ufs1)
+#endif
+{
+  grub_fs_unregister (&grub_ufs_fs);
+}
+
diff --git a/fs/ufs2.c b/fs/ufs2.c
new file mode 100644
index 0000000..7f4eb95
--- /dev/null
+++ b/fs/ufs2.c
@@ -0,0 +1,3 @@
+/* ufs2.c - Unix File System 2 */
+#define MODE_UFS2 1
+#include "ufs.c"
diff --git a/fs/xfs.c b/fs/xfs.c
new file mode 100644
index 0000000..1b18bef
--- /dev/null
+++ b/fs/xfs.c
@@ -0,0 +1,820 @@
+/* xfs.c - XFS.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+#define	XFS_INODE_EXTENTS	9
+
+#define XFS_INODE_FORMAT_INO	1
+#define XFS_INODE_FORMAT_EXT	2
+#define XFS_INODE_FORMAT_BTREE	3
+
+
+struct grub_xfs_sblock
+{
+  grub_uint8_t magic[4];
+  grub_uint32_t bsize;
+  grub_uint8_t unused1[24];
+  grub_uint16_t uuid[8];
+  grub_uint8_t unused2[8];
+  grub_uint64_t rootino;
+  grub_uint8_t unused3[20];
+  grub_uint32_t agsize;
+  grub_uint8_t unused4[20];
+  grub_uint8_t label[12];
+  grub_uint8_t log2_bsize;
+  grub_uint8_t log2_sect;
+  grub_uint8_t log2_inode;
+  grub_uint8_t log2_inop;
+  grub_uint8_t log2_agblk;
+  grub_uint8_t unused6[67];
+  grub_uint8_t log2_dirblk;
+} __attribute__ ((packed));
+
+struct grub_xfs_dir_header
+{
+  grub_uint8_t count;
+  grub_uint8_t smallino;
+  union
+  {
+    grub_uint32_t i4;
+    grub_uint64_t i8;
+  } parent __attribute__ ((packed));
+} __attribute__ ((packed));
+
+struct grub_xfs_dir_entry
+{
+  grub_uint8_t len;
+  grub_uint16_t offset;
+  char name[1];
+  /* Inode number follows, 32 bits.  */
+} __attribute__ ((packed));
+
+struct grub_xfs_dir2_entry
+{
+  grub_uint64_t inode;
+  grub_uint8_t len;
+} __attribute__ ((packed));
+
+typedef grub_uint32_t grub_xfs_extent[4];
+
+struct grub_xfs_btree_node
+{
+  grub_uint8_t magic[4];
+  grub_uint16_t level;
+  grub_uint16_t numrecs;
+  grub_uint64_t left;
+  grub_uint64_t right;
+  grub_uint64_t keys[1];
+}  __attribute__ ((packed));
+
+struct grub_xfs_btree_root
+{
+  grub_uint16_t level;
+  grub_uint16_t numrecs;
+  grub_uint64_t keys[1];
+}  __attribute__ ((packed));
+
+struct grub_xfs_inode
+{
+  grub_uint8_t magic[2];
+  grub_uint16_t mode;
+  grub_uint8_t version;
+  grub_uint8_t format;
+  grub_uint8_t unused2[50];
+  grub_uint64_t size;
+  grub_uint64_t nblocks;
+  grub_uint32_t extsize;
+  grub_uint32_t nextents;
+  grub_uint8_t unused3[20];
+  union
+  {
+    char raw[156];
+    struct dir
+    {
+      struct grub_xfs_dir_header dirhead;
+      struct grub_xfs_dir_entry direntry[1];
+    } dir;
+    grub_xfs_extent extents[XFS_INODE_EXTENTS];
+    struct grub_xfs_btree_root btree;
+  } data __attribute__ ((packed));
+} __attribute__ ((packed));
+
+struct grub_xfs_dirblock_tail
+{
+  grub_uint32_t leaf_count;
+  grub_uint32_t leaf_stale;
+} __attribute__ ((packed));
+
+struct grub_fshelp_node
+{
+  struct grub_xfs_data *data;
+  grub_uint64_t ino;
+  int inode_read;
+  struct grub_xfs_inode inode;
+};
+
+struct grub_xfs_data
+{
+  struct grub_xfs_sblock sblock;
+  grub_disk_t disk;
+  int pos;
+  int bsize;
+  int agsize;
+  struct grub_fshelp_node diropen;
+};
+
+static grub_dl_t my_mod;
+
+
+
+/* Filetype information as used in inodes.  */
+#define FILETYPE_INO_MASK	0170000
+#define FILETYPE_INO_REG	0100000
+#define FILETYPE_INO_DIRECTORY	0040000
+#define FILETYPE_INO_SYMLINK	0120000
+
+#define GRUB_XFS_INO_AGBITS(data)		\
+  ((data)->sblock.log2_agblk + (data)->sblock.log2_inop)
+#define GRUB_XFS_INO_INOINAG(data, ino)		\
+  (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1))
+#define GRUB_XFS_INO_AG(data,ino)		\
+  (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data))
+
+#define GRUB_XFS_FSB_TO_BLOCK(data, fsb) \
+  (((fsb) >> (data)->sblock.log2_agblk) * (data)->agsize \
+ + ((fsb) & ((1LL << (data)->sblock.log2_agblk) - 1)))
+
+#define GRUB_XFS_EXTENT_OFFSET(exts,ex) \
+	((grub_be_to_cpu32 (exts[ex][0]) & ~(1 << 31)) << 23 \
+	| grub_be_to_cpu32 (exts[ex][1]) >> 9)
+
+#define GRUB_XFS_EXTENT_BLOCK(exts,ex)		\
+  ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex][1]) \
+		  & (0x1ff)) << 43 \
+   | (grub_uint64_t) grub_be_to_cpu32 (exts[ex][2]) << 11 \
+   | grub_be_to_cpu32 (exts[ex][3]) >> 21)
+
+#define GRUB_XFS_EXTENT_SIZE(exts,ex)		\
+  (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 20) - 1))
+
+#define GRUB_XFS_ROUND_TO_DIRENT(pos)	((((pos) + 8 - 1) / 8) * 8)
+#define GRUB_XFS_NEXT_DIRENT(pos,len)		\
+  (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2)
+
+static inline grub_uint64_t
+grub_xfs_inode_block (struct grub_xfs_data *data,
+		      grub_uint64_t ino)
+{
+  long long int inoinag = GRUB_XFS_INO_INOINAG (data, ino);
+  long long ag = GRUB_XFS_INO_AG (data, ino);
+  long long block;
+
+  block = (inoinag >> data->sblock.log2_inop) + ag * data->agsize;
+  block <<= (data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS);
+  return block;
+}
+
+
+static inline int
+grub_xfs_inode_offset (struct grub_xfs_data *data,
+		       grub_uint64_t ino)
+{
+  int inoag = GRUB_XFS_INO_INOINAG (data, ino);
+  return ((inoag & ((1 << data->sblock.log2_inop) - 1)) <<
+	  data->sblock.log2_inode);
+}
+
+
+static grub_err_t
+grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
+		     struct grub_xfs_inode *inode)
+{
+  grub_uint64_t block = grub_xfs_inode_block (data, ino);
+  int offset = grub_xfs_inode_offset (data, ino);
+
+  /* Read the inode.  */
+  if (grub_disk_read (data->disk, block, offset,
+		      1 << data->sblock.log2_inode, inode))
+    return grub_errno;
+
+  if (grub_strncmp ((char *) inode->magic, "IN", 2))
+    return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode.\n");
+
+  return 0;
+}
+
+
+static grub_disk_addr_t
+grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  struct grub_xfs_btree_node *leaf = 0;
+  int ex, nrec;
+  grub_xfs_extent *exts;
+  grub_uint64_t ret = 0;
+
+  if (node->inode.format == XFS_INODE_FORMAT_BTREE)
+    {
+      grub_uint64_t *keys;
+
+      leaf = grub_malloc (node->data->sblock.bsize);
+      if (leaf == 0)
+        return 0;
+
+      nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs);
+      keys = &node->inode.data.btree.keys[0];
+      do
+        {
+          int i;
+
+          for (i = 0; i < nrec; i++)
+            {
+              if (fileblock < grub_be_to_cpu64 (keys[i]))
+                break;
+            }
+
+          /* Sparse block.  */
+          if (i == 0)
+            {
+              grub_free (leaf);
+              return 0;
+            }
+
+          if (grub_disk_read (node->data->disk,
+                              grub_be_to_cpu64 (keys[i - 1 + nrec])
+                              << (node->data->sblock.log2_bsize
+                                  - GRUB_DISK_SECTOR_BITS),
+                              0, node->data->sblock.bsize, leaf))
+            return 0;
+
+          if (grub_strncmp ((char *) leaf->magic, "BMAP", 4))
+            {
+              grub_free (leaf);
+              grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node.\n");
+              return 0;
+            }
+
+          nrec = grub_be_to_cpu16 (leaf->numrecs);
+          keys = &leaf->keys[0];
+        } while (leaf->level);
+      exts = (grub_xfs_extent *) keys;
+    }
+  else if (node->inode.format == XFS_INODE_FORMAT_EXT)
+    {
+      nrec = grub_be_to_cpu32 (node->inode.nextents);
+      exts = &node->inode.data.extents[0];
+    }
+  else
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+		  "xfs does not support inode format %d yet",
+		  node->inode.format);
+      return 0;
+    }
+
+  /* Iterate over each extent to figure out which extent has
+     the block we are looking for.  */
+  for (ex = 0; ex < nrec; ex++)
+    {
+      grub_uint64_t start = GRUB_XFS_EXTENT_BLOCK (exts, ex);
+      grub_uint64_t offset = GRUB_XFS_EXTENT_OFFSET (exts, ex);
+      grub_uint64_t size = GRUB_XFS_EXTENT_SIZE (exts, ex);
+
+      /* Sparse block.  */
+      if (fileblock < offset)
+        break;
+      else if (fileblock < offset + size)
+        {
+          ret = (fileblock - offset + start);
+          break;
+        }
+    }
+
+  if (leaf)
+    grub_free (leaf);
+
+  return GRUB_XFS_FSB_TO_BLOCK(node->data, ret);
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_xfs_read_file (grub_fshelp_node_t node,
+		     void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+					unsigned offset, unsigned length),
+		     int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+				pos, len, buf, grub_xfs_read_block,
+				grub_be_to_cpu64 (node->inode.size),
+				node->data->sblock.log2_bsize
+				- GRUB_DISK_SECTOR_BITS);
+}
+
+
+static char *
+grub_xfs_read_symlink (grub_fshelp_node_t node)
+{
+  int size = grub_be_to_cpu64 (node->inode.size);
+
+  switch (node->inode.format)
+    {
+    case XFS_INODE_FORMAT_INO:
+      return grub_strndup (node->inode.data.raw, size);
+
+    case XFS_INODE_FORMAT_EXT:
+      {
+	char *symlink;
+	grub_ssize_t numread;
+
+	symlink = grub_malloc (size + 1);
+	if (!symlink)
+	  return 0;
+
+	numread = grub_xfs_read_file (node, 0, 0, size, symlink);
+	if (numread != size)
+	  {
+	    grub_free (symlink);
+	    return 0;
+	  }
+	symlink[size] = '\0';
+	return symlink;
+      }
+    }
+
+  return 0;
+}
+
+
+static enum grub_fshelp_filetype
+grub_xfs_mode_to_filetype (grub_uint16_t mode)
+{
+  if ((grub_be_to_cpu16 (mode)
+       & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY)
+    return GRUB_FSHELP_DIR;
+  else if ((grub_be_to_cpu16 (mode)
+	    & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK)
+    return GRUB_FSHELP_SYMLINK;
+  else if ((grub_be_to_cpu16 (mode)
+	    & FILETYPE_INO_MASK) == FILETYPE_INO_REG)
+    return GRUB_FSHELP_REG;
+  return GRUB_FSHELP_UNKNOWN;
+}
+
+
+static int
+grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+		       int NESTED_FUNC_ATTR
+		       (*hook) (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node))
+{
+  struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
+  auto int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename);
+
+  int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename)
+    {
+      struct grub_fshelp_node *fdiro;
+
+      fdiro = grub_malloc (sizeof (struct grub_fshelp_node)
+			   - sizeof (struct grub_xfs_inode)
+			   + (1 << diro->data->sblock.log2_inode));
+      if (!fdiro)
+	return 0;
+
+      /* The inode should be read, otherwise the filetype can
+	 not be determined.  */
+      fdiro->ino = ino;
+      fdiro->inode_read = 1;
+      fdiro->data = diro->data;
+      grub_xfs_read_inode (diro->data, ino, &fdiro->inode);
+
+      return hook (filename,
+		   grub_xfs_mode_to_filetype (fdiro->inode.mode),
+		   fdiro);
+    }
+
+  switch (diro->inode.format)
+    {
+    case XFS_INODE_FORMAT_INO:
+      {
+	struct grub_xfs_dir_entry *de = &diro->inode.data.dir.direntry[0];
+	int smallino = !diro->inode.data.dir.dirhead.smallino;
+	int i;
+	grub_uint64_t parent;
+
+	/* If small inode numbers are used to pack the direntry, the
+	   parent inode number is small too.  */
+	if (smallino)
+	  {
+	    parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4);
+	    parent = grub_cpu_to_be64 (parent);
+	    /* The header is a bit smaller than usual.  */
+	    de = (struct grub_xfs_dir_entry *) ((char *) de - 4);
+	  }
+	else
+	  {
+	    parent = diro->inode.data.dir.dirhead.parent.i8;
+	  }
+
+	/* Synthesize the direntries for `.' and `..'.  */
+	if (call_hook (diro->ino, "."))
+	  return 1;
+
+	if (call_hook (parent, ".."))
+	  return 1;
+
+	for (i = 0; i < diro->inode.data.dir.dirhead.count; i++)
+	  {
+	    grub_uint64_t ino;
+	    void *inopos = (((char *) de)
+			    + sizeof (struct grub_xfs_dir_entry)
+			    + de->len - 1);
+	    char name[de->len + 1];
+
+	    if (smallino)
+	      {
+		ino = grub_be_to_cpu32 (*(grub_uint32_t *) inopos);
+		ino = grub_cpu_to_be64 (ino);
+	      }
+	    else
+	      ino = *(grub_uint64_t *) inopos;
+
+	    grub_memcpy (name, de->name, de->len);
+	    name[de->len] = '\0';
+	    if (call_hook (ino, name))
+	      return 1;
+
+	    de = ((struct grub_xfs_dir_entry *)
+		  (((char *) de)+ sizeof (struct grub_xfs_dir_entry) + de->len
+		   + ((smallino ? sizeof (grub_uint32_t)
+		       : sizeof (grub_uint64_t))) - 1));
+	  }
+	break;
+      }
+
+    case XFS_INODE_FORMAT_BTREE:
+    case XFS_INODE_FORMAT_EXT:
+      {
+	grub_ssize_t numread;
+	char *dirblock;
+	grub_uint64_t blk;
+        int dirblk_size, dirblk_log2;
+
+        dirblk_log2 = (dir->data->sblock.log2_bsize
+                       + dir->data->sblock.log2_dirblk);
+        dirblk_size = 1 << dirblk_log2;
+
+	dirblock = grub_malloc (dirblk_size);
+	if (! dirblock)
+	  return 0;
+
+	/* Iterate over every block the directory has.  */
+	for (blk = 0;
+	     blk < (grub_be_to_cpu64 (dir->inode.size)
+		    >> dirblk_log2);
+	     blk++)
+	  {
+	    /* The header is skipped, the first direntry is stored
+	       from byte 16.  */
+	    int pos = 16;
+	    int entries;
+	    int tail_start = (dirblk_size
+			      - sizeof (struct grub_xfs_dirblock_tail));
+
+	    struct grub_xfs_dirblock_tail *tail;
+	    tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start];
+
+	    numread = grub_xfs_read_file (dir, 0,
+					  blk << dirblk_log2,
+					  dirblk_size, dirblock);
+	    if (numread != dirblk_size)
+	      return 0;
+
+	    entries = (grub_be_to_cpu32 (tail->leaf_count)
+		       - grub_be_to_cpu32 (tail->leaf_stale));
+
+	    /* Iterate over all entries within this block.  */
+	    while (pos < (dirblk_size
+			  - (int) sizeof (struct grub_xfs_dir2_entry)))
+	      {
+		struct grub_xfs_dir2_entry *direntry;
+		grub_uint16_t *freetag;
+		char *filename;
+
+		direntry = (struct grub_xfs_dir2_entry *) &dirblock[pos];
+		freetag = (grub_uint16_t *) direntry;
+
+		if (*freetag == 0XFFFF)
+		  {
+		    grub_uint16_t *skip = (grub_uint16_t *) (freetag + 1);
+
+		    /* This entry is not used, go to the next one.  */
+		    pos += grub_be_to_cpu16 (*skip);
+
+		    continue;
+		  }
+
+		filename = &dirblock[pos + sizeof (*direntry)];
+		/* The byte after the filename is for the tag, which
+		   is not used by GRUB.  So it can be overwritten.  */
+		filename[direntry->len] = '\0';
+
+		if (call_hook (direntry->inode, filename))
+		  {
+		    grub_free (dirblock);
+		    return 1;
+		  }
+
+		/* Check if last direntry in this block is
+		   reached.  */
+		entries--;
+		if (!entries)
+		  break;
+
+		/* Select the next directory entry.  */
+		pos = GRUB_XFS_NEXT_DIRENT (pos, direntry->len);
+		pos = GRUB_XFS_ROUND_TO_DIRENT (pos);
+	      }
+	  }
+	grub_free (dirblock);
+	break;
+      }
+
+    default:
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+		  "xfs does not support inode format %d yet",
+		  diro->inode.format);
+    }
+  return 0;
+}
+
+
+static struct grub_xfs_data *
+grub_xfs_mount (grub_disk_t disk)
+{
+  struct grub_xfs_data *data = 0;
+
+  data = grub_zalloc (sizeof (struct grub_xfs_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  if (grub_disk_read (disk, 0, 0,
+		      sizeof (struct grub_xfs_sblock), &data->sblock))
+    goto fail;
+
+  if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a xfs filesystem");
+      goto fail;
+    }
+
+  data = grub_realloc (data,
+		       sizeof (struct grub_xfs_data)
+		       - sizeof (struct grub_xfs_inode)
+		       + (1 << data->sblock.log2_inode));
+
+  if (! data)
+    goto fail;
+
+  data->diropen.data = data;
+  data->diropen.ino = data->sblock.rootino;
+  data->diropen.inode_read = 1;
+  data->bsize = grub_be_to_cpu32 (data->sblock.bsize);
+  data->agsize = grub_be_to_cpu32 (data->sblock.agsize);
+
+  data->disk = disk;
+  data->pos = 0;
+
+  grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode);
+
+  return data;
+ fail:
+
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not an xfs filesystem");
+
+  grub_free (data);
+
+  return 0;
+}
+
+
+static grub_err_t
+grub_xfs_dir (grub_device_t device, const char *path,
+	      int (*hook) (const char *filename,
+			   const struct grub_dirhook_info *info))
+{
+  struct grub_xfs_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+				     enum grub_fshelp_filetype filetype,
+				     grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+				enum grub_fshelp_filetype filetype,
+				grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_xfs_mount (device->disk);
+  if (!data)
+    goto mount_fail;
+
+  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_xfs_iterate_dir,
+			 grub_xfs_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  grub_xfs_iterate_dir (fdiro, iterate);
+
+ fail:
+  if (fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+ mount_fail:
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_xfs_open (struct grub_file *file, const char *name)
+{
+  struct grub_xfs_data *data;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_xfs_mount (file->device->disk);
+  if (!data)
+    goto mount_fail;
+
+  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_xfs_iterate_dir,
+			 grub_xfs_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  if (!fdiro->inode_read)
+    {
+      grub_xfs_read_inode (data, fdiro->ino, &fdiro->inode);
+      if (grub_errno)
+	goto fail;
+    }
+
+  if (fdiro != &data->diropen)
+    grub_memcpy (&data->diropen, fdiro,
+		 sizeof (struct grub_fshelp_node)
+		 - sizeof (struct grub_xfs_inode)
+		 + (1 << data->sblock.log2_inode));
+
+  file->size = grub_be_to_cpu64 (data->diropen.inode.size);
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+ fail:
+  if (fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+ mount_fail:
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_ssize_t
+grub_xfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_xfs_data *data =
+    (struct grub_xfs_data *) file->data;
+
+  return grub_xfs_read_file (&data->diropen, file->read_hook,
+			      file->offset, len, buf);
+}
+
+
+static grub_err_t
+grub_xfs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_err_t
+grub_xfs_label (grub_device_t device, char **label)
+{
+  struct grub_xfs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_xfs_mount (disk);
+  if (data)
+    *label = grub_strndup ((char *) (data->sblock.label), 12);
+  else
+    *label = 0;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_xfs_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_xfs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_xfs_mount (disk);
+  if (data)
+    {
+      *uuid = grub_malloc (sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"));
+      grub_sprintf (*uuid, "%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
+		    grub_be_to_cpu16 (data->sblock.uuid[0]), grub_be_to_cpu16 (data->sblock.uuid[1]),
+		    grub_be_to_cpu16 (data->sblock.uuid[2]), grub_be_to_cpu16 (data->sblock.uuid[3]),
+		    grub_be_to_cpu16 (data->sblock.uuid[4]), grub_be_to_cpu16 (data->sblock.uuid[5]),
+		    grub_be_to_cpu16 (data->sblock.uuid[6]), grub_be_to_cpu16 (data->sblock.uuid[7]));
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+
+static struct grub_fs grub_xfs_fs =
+  {
+    .name = "xfs",
+    .dir = grub_xfs_dir,
+    .open = grub_xfs_open,
+    .read = grub_xfs_read,
+    .close = grub_xfs_close,
+    .label = grub_xfs_label,
+    .uuid = grub_xfs_uuid,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(xfs)
+{
+  grub_fs_register (&grub_xfs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(xfs)
+{
+  grub_fs_unregister (&grub_xfs_fs);
+}
diff --git a/gencmdlist.sh b/gencmdlist.sh
new file mode 100644
index 0000000..7f25490
--- /dev/null
+++ b/gencmdlist.sh
@@ -0,0 +1,22 @@
+#! /bin/sh
+#
+# Copyright (C) 2005  Free Software Foundation, Inc.
+#
+# This gensymlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect command names.
+
+module=$1
+
+grep -v "^#" | sed -n \
+ -e "/grub_register_command *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $module/;p;}" \
+ -e "/grub_register_extcmd *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}" \
+ -e "/grub_register_command_p1 *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}"
+
diff --git a/gendistlist.sh b/gendistlist.sh
new file mode 100755
index 0000000..7f6c32a
--- /dev/null
+++ b/gendistlist.sh
@@ -0,0 +1,45 @@
+#! /bin/sh
+#
+# Copyright (C) 2005, 2008, 2009  Free Software Foundation, Inc.
+#
+# This gendistlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Generate a list of distributed files.
+
+EXTRA_DISTFILES="AUTHORS COPYING ChangeLog DISTLIST INSTALL NEWS README \
+	THANKS TODO Makefile.in aclocal.m4 autogen.sh config.guess \
+	config.h.in config.sub configure configure.ac gencmdlist.sh \
+	gendistlist.sh genfslist.sh genhandlerlist.sh geninit.sh \
+	geninitheader.sh genkernsyms.sh.in genmk.rb genmoddep.awk \
+	genmodsrc.sh genpartmaplist.sh genparttoollist.sh \
+	gensymlist.sh.in install-sh mkinstalldirs stamp-h.in"
+
+DISTDIRS="boot bus commands conf disk docs efiemu font fs hello hook include io \
+	kern lib loader mmap normal partmap parttool script term util video"
+
+LC_COLLATE=C
+export LC_COLLATE
+
+for f in $EXTRA_DISTFILES; do
+    echo $f
+done
+
+dir=`dirname $0`
+cd $dir
+
+for dir in $DISTDIRS; do
+  for d in `find $dir -type d | sed '/\/\.svn$/d;\/\.svn\//d' | sort`; do
+    find $d -maxdepth 1 -name '*.[chSy]' -o -name '*.mk' -o -name '*.rmk' \
+      -o -name '*.rb' -o -name '*.in' -o -name '*.tex' -o -name '*.texi' \
+      -o -name '*.info' -o -name 'grub.cfg' -o -name 'README' \
+      -o -name '*.sc' -o -name 'mdate-sh' -o -name '*.sh' \
+      -o -name 'grub-dumpdevtree' -o -name '*.lua' | sort
+  done
+done
diff --git a/genfslist.sh b/genfslist.sh
new file mode 100644
index 0000000..6fa7e92
--- /dev/null
+++ b/genfslist.sh
@@ -0,0 +1,26 @@
+#! /bin/sh
+#
+# Copyright (C) 2005,2008  Free Software Foundation, Inc.
+#
+# This gensymlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect fs names.
+
+module=$1
+
+# Ignore kernel.mod.
+if test $module = kernel; then
+    exit
+fi
+
+# For now, this emits only a module name, if the module registers a filesystem.
+if grep -v "^#" | grep '^ *grub_fs_register' >/dev/null 2>&1; then
+    echo $module
+fi
diff --git a/genhandlerlist.sh b/genhandlerlist.sh
new file mode 100644
index 0000000..6446a98
--- /dev/null
+++ b/genhandlerlist.sh
@@ -0,0 +1,23 @@
+#! /bin/sh
+#
+# Copyright (C) 2009  Free Software Foundation, Inc.
+#
+# This script is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect command names.
+
+module=$1
+
+grep -v "^#" | sed -n \
+ -e "/grub_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $module/;p;}" \
+ -e "/grub_reader_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/reader.\1: $module/;p;}" \
+ -e "/grub_term_register_input *( *\"/{s/.*( *\"\([^\"]*\)\".*/terminal_input.\1: $module/;p;}" \
+ -e "/grub_term_register_output *( *\"/{s/.*( *\"\([^\"]*\)\".*/terminal_output.\1: $module/;p;}" \
+ -e "/grub_menu_viewer_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/menu_viewer.\1: $module/;p;}"
diff --git a/geninit.sh b/geninit.sh
new file mode 100644
index 0000000..43d2d16
--- /dev/null
+++ b/geninit.sh
@@ -0,0 +1,75 @@
+#! /bin/sh
+#
+# Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
+#
+# This gensymlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+lst="$1"
+shift
+
+header=`echo "${lst}" | sed -e "s/\.lst$/.h/g"`
+
+cat <<EOF
+/* This file is automatically generated by geninit.sh. DO NOT EDIT! */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <$header>
+
+EOF
+
+cat <<EOF
+void
+grub_init_all (void)
+{
+EOF
+
+while read line; do
+  file=`echo $line | cut -f1 -d:`
+  if echo $@ | grep $file >/dev/null; then
+    echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/  grub_\1_init ();/'
+  fi
+done < ${lst}
+
+cat <<EOF
+}
+EOF
+
+cat <<EOF
+void
+grub_fini_all (void)
+{
+EOF
+
+while read line; do
+  file=`echo $line | cut -f1 -d:`
+  if echo $@ | grep $file >/dev/null; then
+    echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/  grub_\1_fini ();/'
+  fi
+done < ${lst}
+
+cat <<EOF
+}
+EOF
diff --git a/geninitheader.sh b/geninitheader.sh
new file mode 100644
index 0000000..5ad1428
--- /dev/null
+++ b/geninitheader.sh
@@ -0,0 +1,45 @@
+#! /bin/sh
+#
+# Copyright (C) 2005,2007  Free Software Foundation, Inc.
+#
+# This gensymlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+lst="$1"
+shift
+
+cat <<EOF
+/* This file is automatically generated by gensymlist.sh. DO NOT EDIT! */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+EOF
+
+cat <<EOF
+void grub_init_all (void);
+void grub_fini_all (void);
+EOF
+
+grep -v '^#' "${lst}" | sed -n '/GRUB_MOD_INIT *([a-zA-Z0-9_]*)/{s/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/void grub_\1_init (void);/;p;}'
+grep -v '^#' "${lst}" | sed -n '/GRUB_MOD_INIT *([a-zA-Z0-9_]*)/{s/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/void grub_\1_fini (void);/;p;}'
diff --git a/genkernsyms.sh.in b/genkernsyms.sh.in
new file mode 100644
index 0000000..3dec582
--- /dev/null
+++ b/genkernsyms.sh.in
@@ -0,0 +1,27 @@
+#! /bin/sh
+#
+# Copyright (C) 2002,2006,2008  Free Software Foundation, Inc.
+#
+# This gensymlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+### The configure script will replace these variables.
+
+: ${srcdir=@srcdir@}
+: ${CC=@CC@}
+
+u=
+grep "^#define HAVE_ASM_USCORE" config.h >/dev/null 2>&1 && u="_"
+
+$CC -DGRUB_SYMBOL_GENERATOR=1 -E -I. -Iinclude -I"$srcdir/include" $* \
+  | grep -v '^#' \
+  | sed -n \
+        -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/'"$u"'\1 kernel/;p;}' \
+        -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/'"$u"'\1 kernel/;p;}' \
+  | sort -u
diff --git a/genmk.rb b/genmk.rb
new file mode 100644
index 0000000..50bf88f
--- /dev/null
+++ b/genmk.rb
@@ -0,0 +1,443 @@
+#! /usr/bin/ruby -w
+#
+# Copyright (C) 2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+#
+# This genmk.rb is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+module Enumerable
+  def collect_with_index
+    ret = []
+    self.each_with_index do |item, index|
+      ret.push(yield(item, index))
+    end
+    ret
+  end
+end
+
+class String
+  def to_var
+    self.gsub(/[^a-zA-Z0-9_@]/, '_')
+  end
+
+  def suffix(str)
+    self.sub(/\.[^\.]*$/, '') + '.' + str
+  end
+
+  def to_obj
+    self.sub(/\.[^\.]*$/, '').to_var + '.o'
+  end
+end
+
+class Image
+  def initialize(dir, name)
+    @dir = dir
+    @name = name
+    @rule_count = 0
+  end
+  attr_reader :dir, :name
+
+  def rule(sources)
+    prefix = @name.to_var
+    @rule_count += 1
+    exe = @name.suffix('exec')
+    objs = sources.collect do |src|
+      raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
+      prefix + '-' + src.to_obj
+    end
+    objs_str = objs.join(' ')
+    deps = objs.collect {|obj| obj.suffix('d')}
+    deps_str = deps.join(' ')
+
+"
+clean-image-#{@name}.#{@rule_count}:
+	rm -f #{@name} #{exe} #{objs_str}
+
+CLEAN_IMAGE_TARGETS += clean-image-#{@name}.#{@rule_count}
+
+mostlyclean-image-#{@name}.#{@rule_count}:
+	rm -f #{deps_str}
+
+MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-#{@name}.#{@rule_count}
+
+ifneq ($(TARGET_APPLE_CC),1)
+#{@name}: #{exe}
+	$(OBJCOPY) -O $(#{prefix}_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
+else
+ifneq (#{exe},kernel.exec)
+#{@name}: #{exe} ./grub-macho2img
+	./grub-macho2img $< $@
+else
+#{@name}: #{exe} ./grub-macho2img
+	./grub-macho2img --bss $< $@
+endif
+endif
+
+#{exe}: #{objs_str}
+	$(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS)
+
+" + objs.collect_with_index do |obj, i|
+      src = sources[i]
+      fake_obj = File.basename(src).suffix('o')
+      dep = deps[i]
+      flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
+      extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end
+      dir = File.dirname(src)
+
+      "#{obj}: #{src} $(#{src}_DEPENDENCIES)
+	$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $<
+-include #{dep}
+
+"
+    end.join('')
+  end
+end
+
+# Use PModule instead Module, to avoid name conflicting.
+class PModule
+  def initialize(dir, name)
+    @dir = dir
+    @name = name
+    @rule_count = 0
+  end
+  attr_reader :dir, :name
+
+  def rule(sources)
+    prefix = @name.to_var
+    @rule_count += 1
+    objs = sources.collect do |src|
+      raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
+      prefix + '-' + src.to_obj
+    end
+    objs_str = objs.join(' ')
+    deps = objs.collect {|obj| obj.suffix('d')}
+    deps_str = deps.join(' ')
+    pre_obj = 'pre-' + @name.suffix('o')
+    mod_src = 'mod-' + @name.suffix('c')
+    mod_obj = mod_src.suffix('o')
+    defsym = 'def-' + @name.suffix('lst')
+    undsym = 'und-' + @name.suffix('lst')
+    mod_name = File.basename(@name, '.mod')
+    symbolic_name = mod_name.sub(/\.[^\.]*$/, '')
+
+"
+clean-module-#{@name}.#{@rule_count}:
+	rm -f #{@name} #{mod_obj} #{mod_src} #{pre_obj} #{objs_str} #{undsym}
+
+CLEAN_MODULE_TARGETS += clean-module-#{@name}.#{@rule_count}
+
+ifneq ($(#{prefix}_EXPORTS),no)
+clean-module-#{@name}-symbol.#{@rule_count}:
+	rm -f #{defsym}
+
+CLEAN_MODULE_TARGETS += clean-module-#{@name}-symbol.#{@rule_count}
+DEFSYMFILES += #{defsym}
+endif
+mostlyclean-module-#{@name}.#{@rule_count}:
+	rm -f #{deps_str}
+
+MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-#{@name}.#{@rule_count}
+UNDSYMFILES += #{undsym}
+
+ifneq ($(TARGET_APPLE_CC),1)
+#{@name}: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF)
+	-rm -f $@
+	$(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{pre_obj} #{mod_obj}
+	if test ! -z \"$(TARGET_OBJ2ELF)\"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
+else
+#{@name}: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF)
+	-rm -f $@
+	-rm -f $@.bin
+	$(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin #{pre_obj} #{mod_obj}
+	$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
+	-rm -f $@.bin
+endif
+
+#{pre_obj}: $(#{prefix}_DEPENDENCIES) #{objs_str}
+	-rm -f $@
+	$(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{objs_str}
+
+#{mod_obj}: #{mod_src}
+	$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(#{prefix}_CFLAGS) -c -o $@ $<
+
+#{mod_src}: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh '#{mod_name}' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(#{prefix}_EXPORTS),no)
+ifneq ($(TARGET_APPLE_CC),1)
+#{defsym}: #{pre_obj}
+	$(NM) -g --defined-only -P -p $< | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@
+else
+#{defsym}: #{pre_obj}
+	$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@
+endif
+endif
+
+#{undsym}: #{pre_obj}
+	echo '#{mod_name}' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+" + objs.collect_with_index do |obj, i|
+      src = sources[i]
+      fake_obj = File.basename(src).suffix('o')
+      extra_target = obj.sub(/\.[^\.]*$/, '') + '-extra'
+      command = 'cmd-' + obj.suffix('lst')
+      fs = 'fs-' + obj.suffix('lst')
+      partmap = 'partmap-' + obj.suffix('lst')
+      handler = 'handler-' + obj.suffix('lst')
+      parttool = 'parttool-' + obj.suffix('lst')
+      dep = deps[i]
+      flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
+      extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end
+      dir = File.dirname(src)
+
+      "#{obj}: #{src} $(#{src}_DEPENDENCIES)
+	$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $<
+-include #{dep}
+
+clean-module-#{extra_target}.#{@rule_count}:
+	rm -f #{command} #{fs} #{partmap} #{handler} #{parttool}
+
+CLEAN_MODULE_TARGETS += clean-module-#{extra_target}.#{@rule_count}
+
+COMMANDFILES += #{command}
+FSFILES += #{fs}
+PARTTOOLFILES += #{parttool}
+PARTMAPFILES += #{partmap}
+HANDLERFILES += #{handler}
+
+#{command}: #{src} $(#{src}_DEPENDENCIES) gencmdlist.sh
+	set -e; \
+	  $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
+	  | sh $(srcdir)/gencmdlist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
+
+#{fs}: #{src} $(#{src}_DEPENDENCIES) genfslist.sh
+	set -e; \
+	  $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
+	  | sh $(srcdir)/genfslist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
+
+#{parttool}: #{src} $(#{src}_DEPENDENCIES) genparttoollist.sh
+	set -e; \
+	  $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
+	  | sh $(srcdir)/genparttoollist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
+
+#{partmap}: #{src} $(#{src}_DEPENDENCIES) genpartmaplist.sh
+	set -e; \
+	  $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
+	  | sh $(srcdir)/genpartmaplist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
+
+#{handler}: #{src} $(#{src}_DEPENDENCIES) genhandlerlist.sh
+	set -e; \
+	  $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
+	  | sh $(srcdir)/genhandlerlist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
+
+"
+    end.join('')
+  end
+end
+
+class Utility
+  def initialize(dir, name)
+    @dir = dir
+    @name = name
+    @rule_count = 0
+  end
+  def print_tail()
+    prefix = @name.to_var
+    print "#{@name}: $(#{prefix}_DEPENDENCIES) $(#{prefix}_OBJECTS)
+	$(CC) -o $@ $(#{prefix}_OBJECTS) $(LDFLAGS) $(#{prefix}_LDFLAGS)
+
+"
+  end
+  attr_reader :dir, :name
+
+  def rule(sources)
+    prefix = @name.to_var
+    @rule_count += 1
+    objs = sources.collect do |src|
+      raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
+      prefix + '-' + src.to_obj
+    end
+    objs_str = objs.join(' ');
+    deps = objs.collect {|obj| obj.suffix('d')}
+    deps_str = deps.join(' ');
+
+    "
+clean-utility-#{@name}.#{@rule_count}:
+	rm -f #{@name}$(EXEEXT) #{objs_str}
+
+CLEAN_UTILITY_TARGETS += clean-utility-#{@name}.#{@rule_count}
+
+mostlyclean-utility-#{@name}.#{@rule_count}:
+	rm -f #{deps_str}
+
+MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-#{@name}.#{@rule_count}
+
+#{prefix}_OBJECTS += #{objs_str}
+
+" + objs.collect_with_index do |obj, i|
+      src = sources[i]
+      fake_obj = File.basename(src).suffix('o')
+      dep = deps[i]
+      dir = File.dirname(src)
+
+      "#{obj}: #{src} $(#{src}_DEPENDENCIES)
+	$(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(#{prefix}_CFLAGS) -MD -c -o $@ $<
+-include #{dep}
+
+"
+    end.join('')
+  end
+end
+
+class Program
+  def initialize(dir, name)
+    @dir = dir
+    @name = name
+  end
+  attr_reader :dir, :name
+
+  def rule(sources)
+    prefix = @name.to_var
+    objs = sources.collect do |src|
+      raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
+      prefix + '-' + src.to_obj
+    end
+    objs_str = objs.join(' ');
+    deps = objs.collect {|obj| obj.suffix('d')}
+    deps_str = deps.join(' ');
+
+    "CLEANFILES += #{@name} #{objs_str}
+MOSTLYCLEANFILES += #{deps_str}
+
+#{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str}
+	$(TARGET_CC) -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS)
+
+" + objs.collect_with_index do |obj, i|
+      src = sources[i]
+      fake_obj = File.basename(src).suffix('o')
+      dep = deps[i]
+      flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
+      extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end
+      dir = File.dirname(src)
+
+      "#{obj}: #{src} $(#{src}_DEPENDENCIES)
+	$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $<
+-include #{dep}
+
+"
+    end.join('')
+  end
+end
+
+class Script
+  def initialize(dir, name)
+    @dir = dir
+    @name = name
+  end
+  attr_reader :dir, :name
+
+  def rule(sources)
+    if sources.length != 1
+      raise "only a single source file must be specified for a script"
+    end
+    src = sources[0]
+    if /\.in$/ !~ src
+      raise "unknown source file `#{src}'"
+    end
+
+    "CLEANFILES += #{@name}
+
+#{@name}: #{src} $(#{src}_DEPENDENCIES) config.status
+	./config.status --file=#{name}:#{src}
+	chmod +x $@
+
+"
+  end
+end
+
+images = []
+utils = []
+pmodules = []
+programs = []
+scripts = []
+
+l = gets
+print l
+print "# Generated by genmk.rb, please don't edit!\n"
+
+cont = false
+str = nil
+while l = gets
+  if cont
+    str += l
+  else
+    str = l
+  end
+
+  print l
+  cont = (/\\$/ =~ l)
+  unless cont
+    str.gsub!(/\\\n/, ' ')
+
+    if /^([a-zA-Z0-9_]+)\s*\+?=\s*(.*?)\s*$/ =~ str
+      var, args = $1, $2
+
+      if var =~ /^([a-zA-Z0-9_]+)_([A-Z]+)$/
+	prefix, type = $1, $2
+
+	case type
+	when 'IMAGES'
+	  images += args.split(/\s+/).collect do |img|
+	    Image.new(prefix, img)
+	  end
+
+	when 'MODULES'
+	  pmodules += args.split(/\s+/).collect do |pmod|
+	    PModule.new(prefix, pmod)
+	  end
+
+	when 'UTILITIES'
+	  utils += args.split(/\s+/).collect do |util|
+	    Utility.new(prefix, util)
+	  end
+
+	when 'PROGRAMS'
+	  programs += args.split(/\s+/).collect do |prog|
+	    Program.new(prefix, prog)
+	  end
+
+	when 'SCRIPTS'
+	  scripts += args.split(/\s+/).collect do |script|
+	    Script.new(prefix, script)
+	  end
+
+	when 'SOURCES'
+	  if img = images.detect() {|i| i.name.to_var == prefix}
+	    print img.rule(args.split(/\s+/))
+	  elsif pmod = pmodules.detect() {|m| m.name.to_var == prefix}
+	    print pmod.rule(args.split(/\s+/))
+	  elsif util = utils.detect() {|u| u.name.to_var == prefix}
+	    print util.rule(args.split(/\s+/))
+	  elsif program = programs.detect() {|u| u.name.to_var == prefix}
+	    print program.rule(args.split(/\s+/))
+	  elsif script = scripts.detect() {|s| s.name.to_var == prefix}
+	    print script.rule(args.split(/\s+/))
+	  end
+	end
+      end
+
+    end
+
+  end
+
+end
+utils.each {|util| util.print_tail()}
+
diff --git a/genmoddep.awk b/genmoddep.awk
new file mode 100644
index 0000000..f7f085e
--- /dev/null
+++ b/genmoddep.awk
@@ -0,0 +1,62 @@
+#! /usr/bin/awk -f
+#
+# Copyright (C) 2006  Free Software Foundation, Inc.
+#
+# This genmoddep.awk is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read defined symbols from stdin.
+BEGIN {
+  while (getline <"/dev/stdin") {
+    symtab[$1] = $2
+  }
+}
+
+# The first line contains a module name.
+FNR == 1 {
+  module = $1
+  next
+};
+
+# The rest is undefined symbols.
+{
+  if ($1 in symtab) {
+    modtab[module] = modtab[module] " " symtab[$1];
+  }
+  else {
+    printf "%s in %s is not defined\n", $1, module >"/dev/stderr";
+    error++;
+    exit;
+  }
+}
+
+# Output the result.
+END {
+  if (error == 1)
+    exit 1;
+
+  for (mod in modtab) {
+    # Remove duplications.
+    split(modtab[mod], depmods, " ");
+    for (depmod in uniqmods) {
+      delete uniqmods[depmod];
+    }
+    for (i in depmods) {
+      depmod = depmods[i];
+      # Ignore kernel, as always loaded.
+      if (depmod != "kernel" && depmod != mod)
+	uniqmods[depmod] = 1;
+    }
+    modlist = ""
+    for (depmod in uniqmods) {
+      modlist = modlist " " depmod;
+    }
+    printf "%s:%s\n", mod, modlist;
+  }
+}
diff --git a/genmodsrc.sh b/genmodsrc.sh
new file mode 100644
index 0000000..2d42055
--- /dev/null
+++ b/genmodsrc.sh
@@ -0,0 +1,47 @@
+#! /bin/sh
+#
+# Copyright (C) 2002,2007  Free Software Foundation, Inc.
+#
+# This genmodsrc.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+set -e
+
+mod_name="$1"
+deps="$2"
+
+cat <<EOF
+/* This file is automatically generated by genmodsrc.sh. DO NOT EDIT! */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+
+EOF
+
+echo "GRUB_MOD_NAME(${mod_name});"
+
+for mod in `grep "^${mod_name}:" ${deps} | sed 's/^[^:]*://'`; do
+  echo "GRUB_MOD_DEP(${mod});"
+done
diff --git a/genpartmaplist.sh b/genpartmaplist.sh
new file mode 100644
index 0000000..fceb0f8
--- /dev/null
+++ b/genpartmaplist.sh
@@ -0,0 +1,26 @@
+#! /bin/sh
+#
+# Copyright (C) 2005, 2008  Free Software Foundation, Inc.
+#
+# This script is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect partmap names.
+
+module=$1
+
+# Ignore kernel.mod.
+if test $module = kernel; then
+    exit
+fi
+
+# For now, this emits only a module name, if the module registers a partition map.
+if grep -v "^#" | grep '^ *grub_partition_map_register' >/dev/null 2>&1; then
+    echo $module
+fi
diff --git a/genparttoollist.sh b/genparttoollist.sh
new file mode 100644
index 0000000..48a0efe
--- /dev/null
+++ b/genparttoollist.sh
@@ -0,0 +1,19 @@
+#! /bin/sh
+#
+# Copyright (C) 2009  Free Software Foundation, Inc.
+#
+# This gensymlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect parttool names.
+
+module=$1
+
+grep -v "^#" | sed -n \
+ -e "/grub_parttool_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $module/;p;}"
diff --git a/gensymlist.sh.in b/gensymlist.sh.in
new file mode 100644
index 0000000..8f50b99
--- /dev/null
+++ b/gensymlist.sh.in
@@ -0,0 +1,77 @@
+#! /bin/sh
+#
+# Copyright (C) 2002,2006,2007,2008  Free Software Foundation, Inc.
+#
+# This gensymlist.sh.in is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+### The configure script will replace these variables.
+
+: ${srcdir=@srcdir@}
+: ${CC=@CC@}
+
+
+cat <<EOF
+/* This file is automatically generated by gensymlist.sh. DO NOT EDIT! */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+EOF
+
+for i in $*; do
+  echo "#include <$i>"
+done
+
+cat <<EOF
+
+#define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; }
+
+void
+grub_register_exported_symbols (void)
+{
+EOF
+
+cat <<EOF
+  struct symtab { const char *name; void *addr; };
+  struct symtab *p;
+  static struct symtab tab[] =
+    {
+EOF
+
+$CC -DGRUB_SYMBOL_GENERATOR=1 -E -I. -Iinclude -I"$srcdir/include" $* \
+  | grep -v '^#' \
+  | sed -n \
+        -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/      {"\1", \1},/;p;}' \
+        -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/      {"\1", \&\1},/;p;}' \
+  | sort -u
+
+cat <<EOF
+      {0, 0}
+    };
+
+  COMPILE_TIME_ASSERT (sizeof (tab) > sizeof (tab[0]));
+  for (p = tab; p->name; p++)
+    grub_dl_register_symbol (p->name, p->addr, 0);
+}
+EOF
diff --git a/hello/hello.c b/hello/hello.c
new file mode 100644
index 0000000..be60761
--- /dev/null
+++ b/hello/hello.c
@@ -0,0 +1,48 @@
+/* hello.c - test module for dynamic loading */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007  Free Software Foundation, Inc.
+ *  Copyright (C) 2003  NIIBE Yutaka <gniibe@m17n.org>
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/extcmd.h>
+
+static grub_err_t
+grub_cmd_hello (struct grub_extcmd *cmd __attribute__ ((unused)),
+		int argc __attribute__ ((unused)),
+		char **args __attribute__ ((unused)))
+{
+  grub_printf ("Hello World\n");
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(hello)
+{
+  cmd = grub_register_extcmd ("hello", grub_cmd_hello, GRUB_COMMAND_FLAG_BOTH,
+			      "hello", "Say hello", 0);
+}
+
+GRUB_MOD_FINI(hello)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/hook/datehook.c b/hook/datehook.c
new file mode 100644
index 0000000..b7663cc
--- /dev/null
+++ b/hook/datehook.c
@@ -0,0 +1,105 @@
+/* datehook.c - Module to install datetime hooks.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/datetime.h>
+
+static char *grub_datetime_names[] =
+{
+  "YEAR",
+  "MONTH",
+  "DAY",
+  "HOUR",
+  "MINUTE",
+  "SECOND",
+  "WEEKDAY",
+};
+
+static char *
+grub_read_hook_datetime (struct grub_env_var *var,
+                         const char *val __attribute__ ((unused)))
+{
+  struct grub_datetime datetime;
+  static char buf[6];
+
+  buf[0] = 0;
+  if (! grub_get_datetime (&datetime))
+    {
+      int i;
+
+      for (i = 0; i < 7; i++)
+        if (! grub_strcmp (var->name, grub_datetime_names[i]))
+          {
+            int n;
+
+            switch (i)
+              {
+              case 0:
+                n = datetime.year;
+                break;
+              case 1:
+                n = datetime.month;
+                break;
+              case 2:
+                n = datetime.day;
+                break;
+              case 3:
+                n = datetime.hour;
+                break;
+              case 4:
+                n = datetime.minute;
+                break;
+              case 5:
+                n = datetime.second;
+                break;
+              default:
+                return grub_get_weekday_name (&datetime);
+              }
+
+            grub_sprintf (buf, "%d", n);
+            break;
+          }
+    }
+
+  return buf;
+}
+
+GRUB_MOD_INIT(datetime)
+{
+  int i;
+
+  for (i = 0; i < 7; i++)
+    grub_register_variable_hook (grub_datetime_names[i],
+                                 grub_read_hook_datetime, 0);
+}
+
+GRUB_MOD_FINI(datetime)
+{
+  int i;
+
+  for (i = 0; i < 7; i++)
+    {
+      grub_register_variable_hook (grub_datetime_names[i], 0, 0);
+      grub_env_unset (grub_datetime_names[i]);
+    }
+}
diff --git a/include/grub/acorn_filecore.h b/include/grub/acorn_filecore.h
new file mode 100644
index 0000000..6cda6cf
--- /dev/null
+++ b/include/grub/acorn_filecore.h
@@ -0,0 +1,53 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ACORN_FILECORE_HEADER
+#define GRUB_ACORN_FILECORE_HEADER	1
+
+#include <grub/types.h>
+
+struct grub_filecore_disc_record
+{
+  grub_uint8_t log2secsize;
+  grub_uint8_t secspertrack;
+  grub_uint8_t heads;
+  grub_uint8_t density;
+  grub_uint8_t idlen;
+  grub_uint8_t log2bpmb;
+  grub_uint8_t skew;
+  grub_uint8_t bootoption;
+  /* In bits 0-5, flags in bits 6 and 7.  */
+  grub_uint8_t lowsector;
+  grub_uint8_t nzones;
+  grub_uint16_t zone_spare;
+  grub_uint32_t root_address;
+  /* Disc size in bytes.  */
+  grub_uint32_t disc_size;
+  grub_uint16_t cycle_id;
+  char disc_name[10];
+  /* Yes, it is 32 bits!  */
+  grub_uint32_t disctype;
+  /* Most significant part of the disc size.  */
+  grub_uint32_t disc_size2;
+  grub_uint8_t share_size;
+  grub_uint8_t big_flag;
+  grub_uint8_t reserved[18];
+};
+
+
+#endif /* ! GRUB_ACORN_FILECORE_HEADER */
diff --git a/include/grub/acpi.h b/include/grub/acpi.h
new file mode 100644
index 0000000..7933db8
--- /dev/null
+++ b/include/grub/acpi.h
@@ -0,0 +1,75 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ACPI_HEADER
+#define GRUB_ACPI_HEADER	1
+
+#include <grub/types.h>
+#include <grub/err.h>
+
+struct grub_acpi_rsdp_v10
+{
+  grub_uint8_t signature[8];
+  grub_uint8_t checksum;
+  grub_uint8_t oemid[6];
+  grub_uint8_t revision;
+  grub_uint32_t rsdt_addr;
+} __attribute__ ((packed));
+
+struct grub_acpi_rsdp_v20
+{
+  struct grub_acpi_rsdp_v10 rsdpv1;
+  grub_uint32_t length;
+  grub_uint64_t xsdt_addr;
+  grub_uint8_t checksum;
+  grub_uint8_t reserved[3];
+} __attribute__ ((packed));
+
+struct grub_acpi_table_header
+{
+  grub_uint8_t signature[4];
+  grub_uint32_t length;
+  grub_uint8_t revision;
+  grub_uint8_t checksum;
+  grub_uint8_t oemid[6];
+  grub_uint8_t oemtable[8];
+  grub_uint32_t oemrev;
+  grub_uint8_t creator_id[4];
+  grub_uint32_t creator_rev;
+} __attribute__ ((packed));
+
+struct grub_acpi_fadt
+{
+  struct grub_acpi_table_header hdr;
+  grub_uint32_t facs_addr;
+  grub_uint32_t dsdt_addr;
+  grub_uint8_t somefields1[88];
+  grub_uint64_t facs_xaddr;
+  grub_uint64_t dsdt_xaddr;
+  grub_uint8_t somefields2[96];
+} __attribute__ ((packed));
+
+struct grub_acpi_rsdp_v10 *grub_acpi_get_rsdpv1 (void);
+struct grub_acpi_rsdp_v20 *grub_acpi_get_rsdpv2 (void);
+struct grub_acpi_rsdp_v10 *grub_machine_acpi_get_rsdpv1 (void);
+struct grub_acpi_rsdp_v20 *grub_machine_acpi_get_rsdpv2 (void);
+grub_uint8_t grub_byte_checksum (void *base, grub_size_t size);
+
+grub_err_t grub_acpi_create_ebda (void);
+
+#endif /* ! GRUB_ACPI_HEADER */
diff --git a/include/grub/aout.h b/include/grub/aout.h
new file mode 100644
index 0000000..c5650dd
--- /dev/null
+++ b/include/grub/aout.h
@@ -0,0 +1,91 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_AOUT_HEADER
+#define GRUB_AOUT_HEADER 1
+
+#include <grub/types.h>
+
+struct grub_aout32_header
+{
+  grub_uint32_t a_midmag;	/* htonl(flags<<26 | mid<<16 | magic) */
+  grub_uint32_t a_text;		/* text segment size */
+  grub_uint32_t a_data;		/* initialized data size */
+  grub_uint32_t a_bss;		/* uninitialized data size */
+  grub_uint32_t a_syms;		/* symbol table size */
+  grub_uint32_t a_entry;	/* entry point */
+  grub_uint32_t a_trsize;	/* text relocation size */
+  grub_uint32_t a_drsize;	/* data relocation size */
+};
+
+struct grub_aout64_header
+{
+  grub_uint32_t a_midmag;	/* htonl(flags<<26 | mid<<16 | magic) */
+  grub_uint64_t a_text;		/* text segment size */
+  grub_uint64_t a_data;		/* initialized data size */
+  grub_uint64_t a_bss;		/* uninitialized data size */
+  grub_uint64_t a_syms;		/* symbol table size */
+  grub_uint64_t a_entry;	/* entry point */
+  grub_uint64_t a_trsize;	/* text relocation size */
+  grub_uint64_t a_drsize;	/* data relocation size */
+};
+
+union grub_aout_header
+{
+  struct grub_aout32_header aout32;
+  struct grub_aout64_header aout64;
+};
+
+#define AOUT_TYPE_NONE		0
+#define AOUT_TYPE_AOUT32	1
+#define AOUT_TYPE_AOUT64	6
+
+#define	AOUT32_OMAGIC		0x107	/* 0407 old impure format */
+#define	AOUT32_NMAGIC		0x108	/* 0410 read-only text */
+#define	AOUT32_ZMAGIC		0x10b	/* 0413 demand load format */
+#define AOUT32_QMAGIC		0xcc	/* 0314 "compact" demand load format */
+
+#define AOUT64_OMAGIC		0x1001
+#define AOUT64_ZMAGIC		0x1002
+#define AOUT64_NMAGIC		0x1003
+
+#define	AOUT_MID_ZERO		0	/* unknown - implementation dependent */
+#define	AOUT_MID_SUN010		1	/* sun 68010/68020 binary */
+#define	AOUT_MID_SUN020		2	/* sun 68020-only binary */
+#define AOUT_MID_I386		134	/* i386 BSD binary */
+#define AOUT_MID_SPARC		138	/* sparc */
+#define	AOUT_MID_HP200		200	/* hp200 (68010) BSD binary */
+#define	AOUT_MID_HP300		300	/* hp300 (68020+68881) BSD binary */
+#define	AOUT_MID_HPUX		0x20C	/* hp200/300 HP-UX binary */
+#define	AOUT_MID_HPUX800	0x20B	/* hp800 HP-UX binary */
+
+#define AOUT_FLAG_PIC		0x10	/* contains position independent code */
+#define AOUT_FLAG_DYNAMIC	0x20	/* contains run-time link-edit info */
+#define AOUT_FLAG_DPMASK	0x30	/* mask for the above */
+
+#define AOUT_GETMAGIC(header) ((header).a_midmag & 0xffff)
+#define AOUT_GETMID(header) ((header).a_midmag >> 16) & 0x03ff)
+#define AOUT_GETFLAG(header) ((header).a_midmag >> 26) & 0x3f)
+
+int EXPORT_FUNC(grub_aout_get_type) (union grub_aout_header *header);
+
+grub_err_t EXPORT_FUNC(grub_aout_load) (grub_file_t file, int offset,
+                                        grub_addr_t load_addr, int load_size,
+                                        grub_addr_t bss_end_addr);
+
+#endif /* ! GRUB_AOUT_HEADER */
diff --git a/include/grub/ata.h b/include/grub/ata.h
new file mode 100644
index 0000000..aaa2e14
--- /dev/null
+++ b/include/grub/ata.h
@@ -0,0 +1,168 @@
+/* ata.h - ATA disk access.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ATA_HEADER
+#define GRUB_ATA_HEADER 1
+
+#include <grub/misc.h>
+#include <grub/symbol.h>
+/* XXX: For now this only works on i386.  */
+#include <grub/cpu/io.h>
+
+typedef enum
+  {
+    GRUB_ATA_CHS,
+    GRUB_ATA_LBA,
+    GRUB_ATA_LBA48
+  } grub_ata_addressing_t;
+
+#define GRUB_ATA_REG_DATA	0
+#define GRUB_ATA_REG_ERROR	1
+#define GRUB_ATA_REG_FEATURES	1
+#define GRUB_ATA_REG_SECTORS	2
+#define GRUB_ATAPI_REG_IREASON	2
+#define GRUB_ATA_REG_SECTNUM	3
+#define GRUB_ATA_REG_CYLLSB	4
+#define GRUB_ATA_REG_CYLMSB	5
+#define GRUB_ATA_REG_LBALOW	3
+#define GRUB_ATA_REG_LBAMID	4
+#define GRUB_ATAPI_REG_CNTLOW	4
+#define GRUB_ATA_REG_LBAHIGH	5
+#define GRUB_ATAPI_REG_CNTHIGH	5
+#define GRUB_ATA_REG_DISK	6
+#define GRUB_ATA_REG_CMD	7
+#define GRUB_ATA_REG_STATUS	7
+
+#define GRUB_ATA_REG2_CONTROL	0
+
+#define GRUB_ATA_STATUS_ERR	0x01
+#define GRUB_ATA_STATUS_INDEX	0x02
+#define GRUB_ATA_STATUS_ECC	0x04
+#define GRUB_ATA_STATUS_DRQ	0x08
+#define GRUB_ATA_STATUS_SEEK	0x10
+#define GRUB_ATA_STATUS_WRERR	0x20
+#define GRUB_ATA_STATUS_READY	0x40
+#define GRUB_ATA_STATUS_BUSY	0x80
+
+/* ATAPI interrupt reason values (I/O, D/C bits).  */
+#define GRUB_ATAPI_IREASON_MASK     0x3
+#define GRUB_ATAPI_IREASON_DATA_OUT 0x0
+#define GRUB_ATAPI_IREASON_CMD_OUT  0x1
+#define GRUB_ATAPI_IREASON_DATA_IN  0x2
+#define GRUB_ATAPI_IREASON_ERROR    0x3
+
+enum grub_ata_commands
+  {
+    GRUB_ATA_CMD_CHECK_POWER_MODE	= 0xe5,
+    GRUB_ATA_CMD_IDENTIFY_DEVICE	= 0xec,
+    GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE	= 0xa1,
+    GRUB_ATA_CMD_IDLE			= 0xe3,
+    GRUB_ATA_CMD_PACKET			= 0xa0,
+    GRUB_ATA_CMD_READ_SECTORS		= 0x20,
+    GRUB_ATA_CMD_READ_SECTORS_EXT	= 0x24,
+    GRUB_ATA_CMD_SECURITY_FREEZE_LOCK	= 0xf5,
+    GRUB_ATA_CMD_SET_FEATURES		= 0xef,
+    GRUB_ATA_CMD_SLEEP			= 0xe6,
+    GRUB_ATA_CMD_SMART			= 0xb0,
+    GRUB_ATA_CMD_STANDBY_IMMEDIATE	= 0xe0,
+    GRUB_ATA_CMD_WRITE_SECTORS		= 0x30,
+    GRUB_ATA_CMD_WRITE_SECTORS_EXT	= 0x34,
+  };
+
+enum grub_ata_timeout_milliseconds
+  {
+    GRUB_ATA_TOUT_STD  =  1000,  /* 1s standard timeout.  */
+    GRUB_ATA_TOUT_DATA = 10000   /* 10s DATA I/O timeout.  */
+  };
+
+struct grub_ata_device
+{
+  /* IDE port to use.  */
+  int port;
+
+  /* IO addresses on which the registers for this device can be
+     found.  */
+  int ioaddress;
+  int ioaddress2;
+
+  /* Two devices can be connected to a single cable.  Use this field
+     to select device 0 (commonly known as "master") or device 1
+     (commonly known as "slave").  */
+  int device;
+
+  /* Addressing methods available for accessing this device.  If CHS
+     is only available, use that.  Otherwise use LBA, except for the
+     high sectors.  In that case use LBA48.  */
+  grub_ata_addressing_t addr;
+
+  /* Sector count.  */
+  grub_uint64_t size;
+
+  /* CHS maximums.  */
+  grub_uint16_t cylinders;
+  grub_uint16_t heads;
+  grub_uint16_t sectors_per_track;
+
+  /* Set to 0 for ATA, set to 1 for ATAPI.  */
+  int atapi;
+
+  struct grub_ata_device *next;
+};
+
+grub_err_t EXPORT_FUNC(grub_ata_wait_not_busy) (struct grub_ata_device *dev,
+                                                int milliseconds);
+grub_err_t EXPORT_FUNC(grub_ata_wait_drq) (struct grub_ata_device *dev,
+					   int rw, int milliseconds);
+void EXPORT_FUNC(grub_ata_pio_read) (struct grub_ata_device *dev,
+				     char *buf, grub_size_t size);
+
+static inline void
+grub_ata_regset (struct grub_ata_device *dev, int reg, int val)
+{
+  grub_outb (val, dev->ioaddress + reg);
+}
+
+static inline grub_uint8_t
+grub_ata_regget (struct grub_ata_device *dev, int reg)
+{
+  return grub_inb (dev->ioaddress + reg);
+}
+
+static inline void
+grub_ata_regset2 (struct grub_ata_device *dev, int reg, int val)
+{
+  grub_outb (val, dev->ioaddress2 + reg);
+}
+
+static inline grub_uint8_t
+grub_ata_regget2 (struct grub_ata_device *dev, int reg)
+{
+  return grub_inb (dev->ioaddress2 + reg);
+}
+
+static inline grub_err_t
+grub_ata_check_ready (struct grub_ata_device *dev)
+{
+  if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY)
+    return grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_STD);
+
+  return GRUB_ERR_NONE;
+}
+
+#endif /* ! GRUB_ATA_HEADER */
diff --git a/include/grub/auth.h b/include/grub/auth.h
new file mode 100644
index 0000000..da930ee
--- /dev/null
+++ b/include/grub/auth.h
@@ -0,0 +1,45 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef GRUB_AURH_HEADER
+#define GRUB_AUTH_HEADER	1
+
+#include <grub/err.h>
+
+/* Macros for indistinguishibility.  */
+#define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, "Access denied.")
+#define GRUB_GET_PASSWORD(string, len) grub_cmdline_get ("Enter password: ", \
+							 string, len,	\
+							 '*', 0, 0)
+
+/* Like strcmp but untimeable. Accepts NULL as second argument.  */
+int grub_auth_strcmp (const char *user_input, const char *template);
+/* Like strcmp but untimeable and ignores commas in needle.  */
+int grub_auth_strword (const char *haystack, const char *needle);
+
+typedef grub_err_t (*grub_auth_callback_t) (const char*, void *);
+
+grub_err_t grub_auth_register_authentication (const char *user,
+					      grub_auth_callback_t callback,
+					      void *arg);
+grub_err_t grub_auth_unregister_authentication (const char *user);
+
+grub_err_t grub_auth_authenticate (const char *user);
+grub_err_t grub_auth_deauthenticate (const char *user);
+grub_err_t grub_auth_check_authentication (const char *userlist);
+
+#endif /* ! GRUB_AUTH_HEADER */
diff --git a/include/grub/autoefi.h b/include/grub/autoefi.h
new file mode 100644
index 0000000..4acd439
--- /dev/null
+++ b/include/grub/autoefi.h
@@ -0,0 +1,75 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+/* This file provides some abstractions so that the same code compiles with
+   both efi and efiemu
+ */
+#ifndef GRUB_AUTOEFI_HEADER
+#define GRUB_AUTOEFI_HEADER	1
+
+#include <grub/machine/machine.h>
+
+#ifdef GRUB_MACHINE_EFI
+# include <grub/efi/efi.h>
+# define grub_autoefi_get_memory_map grub_efi_get_memory_map
+# define grub_autoefi_finish_boot_services grub_efi_finish_boot_services
+# define grub_autoefi_system_table grub_efi_system_table
+# define grub_autoefi_mmap_iterate grub_machine_mmap_iterate
+static inline grub_err_t grub_autoefi_prepare (void)
+{
+  return GRUB_ERR_NONE;
+};
+# define GRUB_AUTOEFI_MEMORY_AVAILABLE GRUB_MACHINE_MEMORY_AVAILABLE
+# define GRUB_AUTOEFI_MEMORY_RESERVED GRUB_MACHINE_MEMORY_RESERVED
+# ifdef GRUB_MACHINE_MEMORY_ACPI
+#  define GRUB_AUTOEFI_MEMORY_ACPI GRUB_MACHINE_MEMORY_ACPI
+# endif
+# ifdef GRUB_MACHINE_MEMORY_NVS
+#  define GRUB_AUTOEFI_MEMORY_NVS GRUB_MACHINE_MEMORY_NVS
+# endif
+# ifdef GRUB_MACHINE_MEMORY_CODE
+#  define GRUB_AUTOEFI_MEMORY_CODE GRUB_MACHINE_MEMORY_CODE
+# endif
+# define SYSTEM_TABLE_SIZEOF(x) (sizeof(grub_efi_system_table->x))
+# define SYSTEM_TABLE_VAR(x) ((void *)&(grub_efi_system_table->x))
+# define SYSTEM_TABLE_PTR(x) ((void *)(grub_efi_system_table->x))
+# define SIZEOF_OF_UINTN sizeof (grub_efi_uintn_t)
+# define SYSTEM_TABLE(x) (grub_efi_system_table->x)
+# define EFI_PRESENT 1
+#else
+# include <grub/efiemu/efiemu.h>
+# define grub_autoefi_get_memory_map grub_efiemu_get_memory_map
+# define grub_autoefi_finish_boot_services grub_efiemu_finish_boot_services
+# define grub_autoefi_system_table grub_efiemu_system_table
+# define grub_autoefi_mmap_iterate grub_efiemu_mmap_iterate
+# define grub_autoefi_prepare grub_efiemu_prepare
+# define GRUB_AUTOEFI_MEMORY_AVAILABLE GRUB_EFIEMU_MEMORY_AVAILABLE
+# define GRUB_AUTOEFI_MEMORY_RESERVED GRUB_EFIEMU_MEMORY_RESERVED
+# define GRUB_AUTOEFI_MEMORY_ACPI GRUB_EFIEMU_MEMORY_ACPI
+# define GRUB_AUTOEFI_MEMORY_NVS GRUB_EFIEMU_MEMORY_NVS
+# define GRUB_AUTOEFI_MEMORY_CODE GRUB_EFIEMU_MEMORY_CODE
+# define SYSTEM_TABLE_SIZEOF GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF
+# define SYSTEM_TABLE_VAR GRUB_EFIEMU_SYSTEM_TABLE_VAR
+# define SYSTEM_TABLE_PTR GRUB_EFIEMU_SYSTEM_TABLE_PTR
+# define SIZEOF_OF_UINTN GRUB_EFIEMU_SIZEOF_OF_UINTN
+# define SYSTEM_TABLE GRUB_EFIEMU_SYSTEM_TABLE
+# define grub_efi_allocate_pages(x,y) (x)
+# define grub_efi_free_pages(x,y) GRUB_EFI_SUCCESS
+# define EFI_PRESENT 1
+#endif
+
+#endif
diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h
new file mode 100644
index 0000000..42c439d
--- /dev/null
+++ b/include/grub/bitmap.h
@@ -0,0 +1,70 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BITMAP_HEADER
+#define GRUB_BITMAP_HEADER	1
+
+#include <grub/err.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+struct grub_video_bitmap
+{
+  /* Bitmap format description.  */
+  struct grub_video_mode_info mode_info;
+
+  /* Pointer to bitmap data formatted according to mode_info.  */
+  void *data;
+};
+
+struct grub_video_bitmap_reader
+{
+  /* File extension for this bitmap type (including dot).  */
+  const char *extension;
+
+  /* Reader function to load bitmap.  */
+  grub_err_t (*reader) (struct grub_video_bitmap **bitmap,
+                        const char *filename);
+
+  /* Next reader.  */
+  struct grub_video_bitmap_reader *next;
+};
+typedef struct grub_video_bitmap_reader *grub_video_bitmap_reader_t;
+
+void grub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader);
+void grub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader);
+
+grub_err_t grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
+                                     unsigned int width, unsigned int height,
+                                     enum grub_video_blit_format blit_format);
+
+grub_err_t grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap);
+
+grub_err_t grub_video_bitmap_load (struct grub_video_bitmap **bitmap,
+                                   const char *filename);
+
+unsigned int grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap);
+unsigned int grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap);
+
+void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap,
+                                      struct grub_video_mode_info *mode_info);
+
+void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap);
+
+#endif /* ! GRUB_BITMAP_HEADER */
diff --git a/include/grub/boot.h b/include/grub/boot.h
new file mode 100644
index 0000000..2357748
--- /dev/null
+++ b/include/grub/boot.h
@@ -0,0 +1,27 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BOOT_HEADER
+#define GRUB_BOOT_HEADER	1
+
+#define GRUB_BOOT_VERSION_MAJOR	4
+#define GRUB_BOOT_VERSION_MINOR	0
+#define GRUB_BOOT_VERSION	((GRUB_BOOT_VERSION_MINOR << 8) \
+					| GRUB_BOOT_VERSION_MAJOR)
+
+#endif /* ! GRUB_BOOT_HEADER */
diff --git a/include/grub/bufio.h b/include/grub/bufio.h
new file mode 100644
index 0000000..9a2294c
--- /dev/null
+++ b/include/grub/bufio.h
@@ -0,0 +1,28 @@
+/* bufio.h - prototypes for bufio */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BUFIO_H
+#define GRUB_BUFIO_H	1
+
+#include <grub/file.h>
+
+grub_file_t grub_bufio_open (grub_file_t io, int size);
+grub_file_t grub_buffile_open (const char *name, int size);
+
+#endif /* ! GRUB_BUFIO_H */
diff --git a/include/grub/cache.h b/include/grub/cache.h
new file mode 100644
index 0000000..745af43
--- /dev/null
+++ b/include/grub/cache.h
@@ -0,0 +1,28 @@
+/* cache.h - Flush the processor's cache.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CACHE_H
+#define GRUB_CACHE_H	1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len);
+
+#endif /* ! GRUB_CACHE_HEADER */
diff --git a/include/grub/command.h b/include/grub/command.h
new file mode 100644
index 0000000..6e9942b
--- /dev/null
+++ b/include/grub/command.h
@@ -0,0 +1,127 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_COMMAND_HEADER
+#define GRUB_COMMAND_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/list.h>
+
+/* Can be run in the command-line.  */
+#define GRUB_COMMAND_FLAG_CMDLINE	0x1
+/* Can be run in the menu.  */
+#define GRUB_COMMAND_FLAG_MENU		0x2
+/* Can be run in both interfaces.  */
+#define GRUB_COMMAND_FLAG_BOTH		0x3
+/* Only for the command title.  */
+#define GRUB_COMMAND_FLAG_TITLE		0x4
+/* Don't print the command on booting.  */
+#define GRUB_COMMAND_FLAG_NO_ECHO	0x8
+/* This is an extended command.  */
+#define GRUB_COMMAND_FLAG_EXTCMD	0x10
+/* This is an dynamic command.  */
+#define GRUB_COMMAND_FLAG_DYNCMD	0x20
+
+struct grub_command;
+
+typedef grub_err_t (*grub_command_func_t) (struct grub_command *cmd,
+					   int argc, char **argv);
+
+/* The command description.  */
+struct grub_command
+{
+  /* The next element.  */
+  struct grub_command *next;
+
+  /* The name.  */
+  const char *name;
+
+    /* The priority.  */
+  int prio;
+
+  /* The callback function.  */
+  grub_command_func_t func;
+
+  /* The flags.  */
+  unsigned flags;
+
+  /* The summary of the command usage.  */
+  const char *summary;
+
+  /* The description of the command.  */
+  const char *description;
+
+  /* Arbitrary data.  */
+  void *data;
+};
+typedef struct grub_command *grub_command_t;
+
+extern grub_command_t EXPORT_VAR(grub_command_list);
+
+grub_command_t
+EXPORT_FUNC(grub_register_command_prio) (const char *name,
+					 grub_command_func_t func,
+					 const char *summary,
+					 const char *description,
+					 int prio);
+void EXPORT_FUNC(grub_unregister_command) (grub_command_t cmd);
+
+static inline grub_command_t
+grub_register_command (const char *name,
+		       grub_command_func_t func,
+		       const char *summary,
+		       const char *description)
+{
+  return grub_register_command_prio (name, func, summary, description, 0);
+}
+
+static inline grub_command_t
+grub_register_command_p1 (const char *name,
+			  grub_command_func_t func,
+			  const char *summary,
+			  const char *description)
+{
+  return grub_register_command_prio (name, func, summary, description, 1);
+}
+
+static inline grub_command_t
+grub_command_find (const char *name)
+{
+  return grub_named_list_find (GRUB_AS_NAMED_LIST (grub_command_list), name);
+}
+
+static inline grub_err_t
+grub_command_execute (const char *name, int argc, char **argv)
+{
+  grub_command_t cmd;
+
+  cmd = grub_command_find (name);
+  return (cmd) ? cmd->func (cmd, argc, argv) : GRUB_ERR_FILE_NOT_FOUND;
+}
+
+static inline int
+grub_command_iterate (int (*func) (grub_command_t))
+{
+  return grub_list_iterate (GRUB_AS_LIST (grub_command_list),
+			    (grub_list_hook_t) func);
+}
+
+void grub_register_core_commands (void);
+
+#endif /* ! GRUB_COMMAND_HEADER */
diff --git a/include/grub/datetime.h b/include/grub/datetime.h
new file mode 100644
index 0000000..2dbba55
--- /dev/null
+++ b/include/grub/datetime.h
@@ -0,0 +1,48 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_DATETIME_HEADER
+#define KERNEL_DATETIME_HEADER	1
+
+#include <grub/types.h>
+#include <grub/err.h>
+
+struct grub_datetime
+{
+  grub_uint16_t year;
+  grub_uint8_t month;
+  grub_uint8_t day;
+  grub_uint8_t hour;
+  grub_uint8_t minute;
+  grub_uint8_t second;
+};
+
+/* Return date and time.  */
+grub_err_t grub_get_datetime (struct grub_datetime *datetime);
+
+/* Set date and time.  */
+grub_err_t grub_set_datetime (struct grub_datetime *datetime);
+
+int grub_get_weekday (struct grub_datetime *datetime);
+char *grub_get_weekday_name (struct grub_datetime *datetime);
+
+void grub_unixtime2datetime (grub_int32_t nix,
+			     struct grub_datetime *datetime);
+
+
+#endif /* ! KERNEL_DATETIME_HEADER */
diff --git a/include/grub/device.h b/include/grub/device.h
new file mode 100644
index 0000000..f0e8a8c
--- /dev/null
+++ b/include/grub/device.h
@@ -0,0 +1,41 @@
+/* device.h - device manager */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_DEVICE_HEADER
+#define GRUB_DEVICE_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+
+struct grub_disk;
+struct grub_net;
+struct grub_fs;
+
+struct grub_device
+{
+  struct grub_disk *disk;
+  struct grub_net *net;
+};
+typedef struct grub_device *grub_device_t;
+
+grub_device_t EXPORT_FUNC(grub_device_open) (const char *name);
+grub_err_t EXPORT_FUNC(grub_device_close) (grub_device_t device);
+int EXPORT_FUNC(grub_device_iterate) (int (*hook) (const char *name));
+
+#endif /* ! GRUB_DEVICE_HEADER */
diff --git a/include/grub/disk.h b/include/grub/disk.h
new file mode 100644
index 0000000..de71bb5
--- /dev/null
+++ b/include/grub/disk.h
@@ -0,0 +1,176 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_DISK_HEADER
+#define GRUB_DISK_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/device.h>
+
+/* These are used to set a device id. When you add a new disk device,
+   you must define a new id for it here.  */
+enum grub_disk_dev_id
+  {
+    GRUB_DISK_DEVICE_BIOSDISK_ID,
+    GRUB_DISK_DEVICE_OFDISK_ID,
+    GRUB_DISK_DEVICE_LOOPBACK_ID,
+    GRUB_DISK_DEVICE_EFIDISK_ID,
+    GRUB_DISK_DEVICE_RAID_ID,
+    GRUB_DISK_DEVICE_LVM_ID,
+    GRUB_DISK_DEVICE_HOST_ID,
+    GRUB_DISK_DEVICE_ATA_ID,
+    GRUB_DISK_DEVICE_MEMDISK_ID,
+    GRUB_DISK_DEVICE_NAND_ID,
+    GRUB_DISK_DEVICE_UUID_ID,
+    GRUB_DISK_DEVICE_PXE_ID,
+    GRUB_DISK_DEVICE_SCSI_ID,
+    GRUB_DISK_DEVICE_FILE_ID,
+  };
+
+struct grub_disk;
+#ifdef GRUB_UTIL
+struct grub_disk_memberlist;
+#endif
+
+/* Disk device.  */
+struct grub_disk_dev
+{
+  /* The device name.  */
+  const char *name;
+
+  /* The device id used by the cache manager.  */
+  enum grub_disk_dev_id id;
+
+  /* Call HOOK with each device name, until HOOK returns non-zero.  */
+  int (*iterate) (int (*hook) (const char *name));
+
+  /* Open the device named NAME, and set up DISK.  */
+  grub_err_t (*open) (const char *name, struct grub_disk *disk);
+
+  /* Close the disk DISK.  */
+  void (*close) (struct grub_disk *disk);
+
+  /* Read SIZE sectors from the sector SECTOR of the disk DISK into BUF.  */
+  grub_err_t (*read) (struct grub_disk *disk, grub_disk_addr_t sector,
+		      grub_size_t size, char *buf);
+
+  /* Write SIZE sectors from BUF into the sector SECTOR of the disk DISK.  */
+  grub_err_t (*write) (struct grub_disk *disk, grub_disk_addr_t sector,
+		       grub_size_t size, const char *buf);
+
+#ifdef GRUB_UTIL
+  struct grub_disk_memberlist *(*memberlist) (struct grub_disk *disk);
+#endif
+
+  /* The next disk device.  */
+  struct grub_disk_dev *next;
+};
+typedef struct grub_disk_dev *grub_disk_dev_t;
+
+struct grub_partition;
+
+/* Disk.  */
+struct grub_disk
+{
+  /* The disk name.  */
+  const char *name;
+
+  /* The underlying disk device.  */
+  grub_disk_dev_t dev;
+
+  /* The total number of sectors.  */
+  grub_uint64_t total_sectors;
+
+  /* If partitions can be stored.  */
+  int has_partitions;
+
+  /* The id used by the disk cache manager.  */
+  unsigned long id;
+
+  /* The partition information. This is machine-specific.  */
+  struct grub_partition *partition;
+
+  /* Called when a sector was read. OFFSET is between 0 and
+     the sector size minus 1, and LENGTH is between 0 and the sector size.  */
+  void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+		     unsigned offset, unsigned length);
+
+  /* Device-specific data.  */
+  void *data;
+};
+typedef struct grub_disk *grub_disk_t;
+
+#ifdef GRUB_UTIL
+struct grub_disk_memberlist
+{
+  grub_disk_t disk;
+  struct grub_disk_memberlist *next;
+};
+typedef struct grub_disk_memberlist *grub_disk_memberlist_t;
+#endif
+
+/* The sector size.  */
+#define GRUB_DISK_SECTOR_SIZE	0x200
+#define GRUB_DISK_SECTOR_BITS	9
+
+/* The maximum number of disk caches.  */
+#define GRUB_DISK_CACHE_NUM	1021
+
+/* The size of a disk cache in sector units.  */
+#define GRUB_DISK_CACHE_SIZE	8
+#define GRUB_DISK_CACHE_BITS	3
+
+/* This is called from the memory manager.  */
+void grub_disk_cache_invalidate_all (void);
+
+void EXPORT_FUNC(grub_disk_dev_register) (grub_disk_dev_t dev);
+void EXPORT_FUNC(grub_disk_dev_unregister) (grub_disk_dev_t dev);
+int EXPORT_FUNC(grub_disk_dev_iterate) (int (*hook) (const char *name));
+
+grub_disk_t EXPORT_FUNC(grub_disk_open) (const char *name);
+void EXPORT_FUNC(grub_disk_close) (grub_disk_t disk);
+grub_err_t EXPORT_FUNC(grub_disk_read) (grub_disk_t disk,
+					grub_disk_addr_t sector,
+					grub_off_t offset,
+					grub_size_t size,
+					void *buf);
+grub_err_t EXPORT_FUNC(grub_disk_write) (grub_disk_t disk,
+					 grub_disk_addr_t sector,
+					 grub_off_t offset,
+					 grub_size_t size,
+					 const void *buf);
+
+grub_uint64_t EXPORT_FUNC(grub_disk_get_size) (grub_disk_t disk);
+
+extern void (* EXPORT_VAR(grub_disk_firmware_fini)) (void);
+extern int EXPORT_VAR(grub_disk_firmware_is_tainted);
+
+/* ATA pass through parameters and function.  */
+struct grub_disk_ata_pass_through_parms
+{
+  grub_uint8_t taskfile[8];
+  void * buffer;
+  int size;
+};
+
+extern grub_err_t (* EXPORT_VAR(grub_disk_ata_pass_through)) (grub_disk_t,
+		   struct grub_disk_ata_pass_through_parms *);
+
+#endif /* ! GRUB_DISK_HEADER */
diff --git a/include/grub/dl.h b/include/grub/dl.h
new file mode 100644
index 0000000..3f8b328
--- /dev/null
+++ b/include/grub/dl.h
@@ -0,0 +1,119 @@
+/* dl.h - types and prototypes for loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_DL_H
+#define GRUB_DL_H	1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/elf.h>
+
+#define GRUB_MOD_INIT(name)	\
+static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
+void grub_##name##_init (void); \
+void \
+grub_##name##_init (void) { grub_mod_init (0); } \
+static void \
+grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
+
+#define GRUB_MOD_FINI(name)	\
+static void grub_mod_fini (void) __attribute__ ((used)); \
+void grub_##name##_fini (void); \
+void \
+grub_##name##_fini (void) { grub_mod_fini (); } \
+static void \
+grub_mod_fini (void)
+
+#ifdef APPLE_CC
+#define GRUB_MOD_NAME(name)	\
+static char grub_modname[] __attribute__ ((section ("_modname, _modname"), used)) = #name;
+
+#define GRUB_MOD_DEP(name)	\
+__asm__ (".section _moddeps, _moddeps\n.asciz \"" #name "\"\n")
+#else
+#define GRUB_MOD_NAME(name)	\
+__asm__ (".section .modname\n.asciz \"" #name "\"\n")
+
+#define GRUB_MOD_DEP(name)	\
+__asm__ (".section .moddeps\n.asciz \"" #name "\"\n")
+#endif
+
+struct grub_dl_segment
+{
+  struct grub_dl_segment *next;
+  void *addr;
+  grub_size_t size;
+  unsigned section;
+};
+typedef struct grub_dl_segment *grub_dl_segment_t;
+
+struct grub_dl;
+
+struct grub_dl_dep
+{
+  struct grub_dl_dep *next;
+  struct grub_dl *mod;
+};
+typedef struct grub_dl_dep *grub_dl_dep_t;
+
+struct grub_dl
+{
+  char *name;
+  int ref_count;
+  grub_dl_dep_t dep;
+  grub_dl_segment_t segment;
+  Elf_Sym *symtab;
+  void (*init) (struct grub_dl *mod);
+  void (*fini) (void);
+};
+typedef struct grub_dl *grub_dl_t;
+
+grub_dl_t EXPORT_FUNC(grub_dl_load_file) (const char *filename);
+grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name);
+grub_dl_t grub_dl_load_core (void *addr, grub_size_t size);
+int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod);
+void grub_dl_unload_unneeded (void);
+void grub_dl_unload_all (void);
+#ifdef GRUB_UTIL
+static inline int
+grub_dl_ref (grub_dl_t mod)
+{
+  (void) mod;
+  return 0;
+}
+static inline int
+grub_dl_unref (grub_dl_t mod)
+{
+  (void) mod;
+  return 0;
+}
+#else
+int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod);
+int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod);
+#endif
+void EXPORT_FUNC(grub_dl_iterate) (int (*hook) (grub_dl_t mod));
+grub_dl_t EXPORT_FUNC(grub_dl_get) (const char *name);
+grub_err_t EXPORT_FUNC(grub_dl_register_symbol) (const char *name, void *addr,
+					    grub_dl_t mod);
+
+grub_err_t grub_arch_dl_check_header (void *ehdr);
+grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr);
+
+#endif /* ! GRUB_DL_H */
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
new file mode 100644
index 0000000..e870eab
--- /dev/null
+++ b/include/grub/efi/api.h
@@ -0,0 +1,1180 @@
+/* efi.h - declare EFI types and functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_API_HEADER
+#define GRUB_EFI_API_HEADER	1
+
+#include <grub/types.h>
+
+/* For consistency and safety, we name the EFI-defined types differently.
+   All names are transformed into lower case, _t appended, and
+   grub_efi_ prepended.  */
+
+/* Constants.  */
+#define GRUB_EFI_EVT_TIMER				0x80000000
+#define GRUB_EFI_EVT_RUNTIME				0x40000000
+#define GRUB_EFI_EVT_RUNTIME_CONTEXT			0x20000000
+#define GRUB_EFI_EVT_NOTIFY_WAIT			0x00000100
+#define GRUB_EFI_EVT_NOTIFY_SIGNAL			0x00000200
+#define GRUB_EFI_EVT_SIGNAL_EXIT_BOOT_SERVICES		0x00000201
+#define GRUB_EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE	0x60000202
+
+#define GRUB_EFI_TPL_APPLICATION	4
+#define GRUB_EFI_TPL_CALLBACK		8
+#define GRUB_EFI_TPL_NOTIFY		16
+#define GRUB_EFI_TPL_HIGH_LEVEL		31
+
+#define GRUB_EFI_MEMORY_UC	0x0000000000000001LL
+#define GRUB_EFI_MEMORY_WC	0x0000000000000002LL
+#define GRUB_EFI_MEMORY_WT	0x0000000000000004LL
+#define GRUB_EFI_MEMORY_WB	0x0000000000000008LL
+#define GRUB_EFI_MEMORY_UCE	0x0000000000000010LL
+#define GRUB_EFI_MEMORY_WP	0x0000000000001000LL
+#define GRUB_EFI_MEMORY_RP	0x0000000000002000LL
+#define GRUB_EFI_MEMORY_XP	0x0000000000004000LL
+#define GRUB_EFI_MEMORY_RUNTIME	0x8000000000000000LL
+
+#define GRUB_EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL	0x00000001
+#define GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL		0x00000002
+#define GRUB_EFI_OPEN_PROTOCOL_TEST_PROTOCOL		0x00000004
+#define GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER	0x00000008
+#define GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER		0x00000010
+#define GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE		0x00000020
+
+#define GRUB_EFI_VARIABLE_NON_VOLATILE		0x0000000000000001
+#define GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS	0x0000000000000002
+#define GRUB_EFI_VARIABLE_RUNTIME_ACCESS	0x0000000000000004
+
+#define GRUB_EFI_TIME_ADJUST_DAYLIGHT	0x01
+#define GRUB_EFI_TIME_IN_DAYLIGHT	0x02
+
+#define GRUB_EFI_UNSPECIFIED_TIMEZONE	0x07FF
+
+#define GRUB_EFI_OPTIONAL_PTR	0x00000001
+
+#define GRUB_EFI_LOADED_IMAGE_GUID	\
+  { 0x5b1b31a1, 0x9562, 0x11d2, \
+    { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+#define GRUB_EFI_DISK_IO_GUID	\
+  { 0xce345171, 0xba0b, 0x11d2, \
+    { 0x8e, 0x4f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+#define GRUB_EFI_BLOCK_IO_GUID	\
+  { 0x964e5b21, 0x6459, 0x11d2, \
+    { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+#define GRUB_EFI_DEVICE_PATH_GUID	\
+  { 0x09576e91, 0x6d3f, 0x11d2, \
+    { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+#define GRUB_EFI_MPS_TABLE_GUID	\
+  { 0xeb9d2d2f, 0x2d88, 0x11d3, \
+    { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+  }
+
+#define GRUB_EFI_ACPI_TABLE_GUID	\
+  { 0xeb9d2d30, 0x2d88, 0x11d3, \
+    { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+  }
+
+#define GRUB_EFI_ACPI_20_TABLE_GUID	\
+  { 0x8868e871, 0xe4f1, 0x11d3, \
+    { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
+  }
+
+#define GRUB_EFI_SMBIOS_TABLE_GUID	\
+  { 0xeb9d2d31, 0x2d88, 0x11d3, \
+    { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+  }
+
+/* Enumerations.  */
+enum grub_efi_timer_delay
+  {
+    GRUB_EFI_TIMER_CANCEL,
+    GRUB_EFI_TIMER_PERIODIC,
+    GRUB_EFI_TIMER_RELATIVE
+  };
+typedef enum grub_efi_timer_delay grub_efi_timer_delay_t;
+
+enum grub_efi_allocate_type
+  {
+    GRUB_EFI_ALLOCATE_ANY_PAGES,
+    GRUB_EFI_ALLOCATE_MAX_ADDRESS,
+    GRUB_EFI_ALLOCATE_ADDRESS,
+    GRUB_EFI_MAX_ALLOCATION_TYPE
+  };
+typedef enum grub_efi_allocate_type grub_efi_allocate_type_t;
+
+enum grub_efi_memory_type
+  {
+    GRUB_EFI_RESERVED_MEMORY_TYPE,
+    GRUB_EFI_LOADER_CODE,
+    GRUB_EFI_LOADER_DATA,
+    GRUB_EFI_BOOT_SERVICES_CODE,
+    GRUB_EFI_BOOT_SERVICES_DATA,
+    GRUB_EFI_RUNTIME_SERVICES_CODE,
+    GRUB_EFI_RUNTIME_SERVICES_DATA,
+    GRUB_EFI_CONVENTIONAL_MEMORY,
+    GRUB_EFI_UNUSABLE_MEMORY,
+    GRUB_EFI_ACPI_RECLAIM_MEMORY,
+    GRUB_EFI_ACPI_MEMORY_NVS,
+    GRUB_EFI_MEMORY_MAPPED_IO,
+    GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE,
+    GRUB_EFI_PAL_CODE,
+    GRUB_EFI_MAX_MEMORY_TYPE
+  };
+typedef enum grub_efi_memory_type grub_efi_memory_type_t;
+
+enum grub_efi_interface_type
+  {
+    GRUB_EFI_NATIVE_INTERFACE
+  };
+typedef enum grub_efi_interface_type grub_efi_interface_type_t;
+
+enum grub_efi_locate_search_type
+  {
+    GRUB_EFI_ALL_HANDLES,
+    GRUB_EFI_BY_REGISTER_NOTIFY,
+    GRUB_EFI_BY_PROTOCOL
+  };
+typedef enum grub_efi_locate_search_type grub_efi_locate_search_type_t;
+
+enum grub_efi_reset_type
+  {
+    GRUB_EFI_RESET_COLD,
+    GRUB_EFI_RESET_WARM,
+    GRUB_EFI_RESET_SHUTDOWN
+  };
+typedef enum grub_efi_reset_type grub_efi_reset_type_t;
+
+/* Types.  */
+typedef char grub_efi_boolean_t;
+typedef long grub_efi_intn_t;
+typedef unsigned long grub_efi_uintn_t;
+typedef grub_int8_t grub_efi_int8_t;
+typedef grub_uint8_t grub_efi_uint8_t;
+typedef grub_int16_t grub_efi_int16_t;
+typedef grub_uint16_t grub_efi_uint16_t;
+typedef grub_int32_t grub_efi_int32_t;
+typedef grub_uint32_t grub_efi_uint32_t;
+typedef grub_int64_t grub_efi_int64_t;
+typedef grub_uint64_t grub_efi_uint64_t;
+typedef grub_uint8_t grub_efi_char8_t;
+typedef grub_uint16_t grub_efi_char16_t;
+
+typedef grub_efi_intn_t grub_efi_status_t;
+
+#define GRUB_EFI_ERROR_CODE(value)	\
+  ((1L << (sizeof (grub_efi_status_t) * 8 - 1)) | (value))
+
+#define GRUB_EFI_WARNING_CODE(value)	(value)
+
+#define GRUB_EFI_SUCCESS		0
+
+#define GRUB_EFI_LOAD_ERROR		GRUB_EFI_ERROR_CODE (1)
+#define GRUB_EFI_INVALID_PARAMETER	GRUB_EFI_ERROR_CODE (2)
+#define GRUB_EFI_UNSUPPORTED		GRUB_EFI_ERROR_CODE (3)
+#define GRUB_EFI_BAD_BUFFER_SIZE	GRUB_EFI_ERROR_CODE (4)
+#define GRUB_EFI_BUFFER_TOO_SMALL	GRUB_EFI_ERROR_CODE (5)
+#define GRUB_EFI_NOT_READY		GRUB_EFI_ERROR_CODE (6)
+#define GRUB_EFI_DEVICE_ERROR		GRUB_EFI_ERROR_CODE (7)
+#define GRUB_EFI_WRITE_PROTECTED	GRUB_EFI_ERROR_CODE (8)
+#define GRUB_EFI_OUT_OF_RESOURCES	GRUB_EFI_ERROR_CODE (9)
+#define GRUB_EFI_VOLUME_CORRUPTED	GRUB_EFI_ERROR_CODE (10)
+#define GRUB_EFI_VOLUME_FULL		GRUB_EFI_ERROR_CODE (11)
+#define GRUB_EFI_NO_MEDIA		GRUB_EFI_ERROR_CODE (12)
+#define GRUB_EFI_MEDIA_CHANGED		GRUB_EFI_ERROR_CODE (13)
+#define GRUB_EFI_NOT_FOUND		GRUB_EFI_ERROR_CODE (14)
+#define GRUB_EFI_ACCESS_DENIED		GRUB_EFI_ERROR_CODE (15)
+#define GRUB_EFI_NO_RESPONSE		GRUB_EFI_ERROR_CODE (16)
+#define GRUB_EFI_NO_MAPPING		GRUB_EFI_ERROR_CODE (17)
+#define GRUB_EFI_TIMEOUT		GRUB_EFI_ERROR_CODE (18)
+#define GRUB_EFI_NOT_STARTED		GRUB_EFI_ERROR_CODE (19)
+#define GRUB_EFI_ALREADY_STARTED	GRUB_EFI_ERROR_CODE (20)
+#define GRUB_EFI_ABORTED		GRUB_EFI_ERROR_CODE (21)
+#define GRUB_EFI_ICMP_ERROR		GRUB_EFI_ERROR_CODE (22)
+#define GRUB_EFI_TFTP_ERROR		GRUB_EFI_ERROR_CODE (23)
+#define GRUB_EFI_PROTOCOL_ERROR		GRUB_EFI_ERROR_CODE (24)
+#define GRUB_EFI_INCOMPATIBLE_VERSION	GRUB_EFI_ERROR_CODE (25)
+#define GRUB_EFI_SECURITY_VIOLATION	GRUB_EFI_ERROR_CODE (26)
+#define GRUB_EFI_CRC_ERROR		GRUB_EFI_ERROR_CODE (27)
+
+#define GRUB_EFI_WARN_UNKNOWN_GLYPH	GRUB_EFI_WARNING_CODE (1)
+#define GRUB_EFI_WARN_DELETE_FAILURE	GRUB_EFI_WARNING_CODE (2)
+#define GRUB_EFI_WARN_WRITE_FAILURE	GRUB_EFI_WARNING_CODE (3)
+#define GRUB_EFI_WARN_BUFFER_TOO_SMALL	GRUB_EFI_WARNING_CODE (4)
+
+typedef void *grub_efi_handle_t;
+typedef void *grub_efi_event_t;
+typedef grub_efi_uint64_t grub_efi_lba_t;
+typedef grub_efi_uintn_t grub_efi_tpl_t;
+typedef grub_uint8_t grub_efi_mac_address_t[32];
+typedef grub_uint8_t grub_efi_ipv4_address_t[4];
+typedef grub_uint16_t grub_efi_ipv6_address_t[8];
+typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4)));
+typedef grub_efi_uint64_t grub_efi_physical_address_t;
+typedef grub_efi_uint64_t grub_efi_virtual_address_t;
+
+struct grub_efi_guid
+{
+  grub_uint32_t data1;
+  grub_uint16_t data2;
+  grub_uint16_t data3;
+  grub_uint8_t data4[8];
+} __attribute__ ((aligned(8)));
+typedef struct grub_efi_guid grub_efi_guid_t;
+
+/* XXX although the spec does not specify the padding, this actually
+   must have the padding!  */
+struct grub_efi_memory_descriptor
+{
+  grub_efi_uint32_t type;
+  grub_efi_uint32_t padding;
+  grub_efi_physical_address_t physical_start;
+  grub_efi_virtual_address_t virtual_start;
+  grub_efi_uint64_t num_pages;
+  grub_efi_uint64_t attribute;
+};
+typedef struct grub_efi_memory_descriptor grub_efi_memory_descriptor_t;
+
+/* Device Path definitions.  */
+struct grub_efi_device_path
+{
+  grub_efi_uint8_t type;
+  grub_efi_uint8_t subtype;
+  grub_efi_uint8_t length[2];
+};
+typedef struct grub_efi_device_path grub_efi_device_path_t;
+/* XXX EFI does not define EFI_DEVICE_PATH_PROTOCOL but uses it.
+   It seems to be identical to EFI_DEVICE_PATH.  */
+typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
+
+#define GRUB_EFI_DEVICE_PATH_TYPE(dp)		((dp)->type & 0x7f)
+#define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp)	((dp)->subtype)
+#define GRUB_EFI_DEVICE_PATH_LENGTH(dp)		\
+  ((dp)->length[0] | ((grub_efi_uint16_t) ((dp)->length[1]) << 8))
+
+/* The End of Device Path nodes.  */
+#define GRUB_EFI_END_DEVICE_PATH_TYPE			(0xff & 0x7f)
+
+#define GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE		0xff
+#define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE		0x01
+
+#define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp)	\
+  (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
+   && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
+       == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE))
+
+#define GRUB_EFI_NEXT_DEVICE_PATH(dp)	\
+  ((grub_efi_device_path_t *) ((char *) (dp) \
+                               + GRUB_EFI_DEVICE_PATH_LENGTH (dp)))
+
+/* Hardware Device Path.  */
+#define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE		1
+
+#define GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE		1
+
+struct grub_efi_pci_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint8_t function;
+  grub_efi_uint8_t device;
+};
+typedef struct grub_efi_pci_device_path grub_efi_pci_device_path_t;
+
+#define GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE		2
+
+struct grub_efi_pccard_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint8_t function;
+};
+typedef struct grub_efi_pccard_device_path grub_efi_pccard_device_path_t;
+
+#define GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE	3
+
+struct grub_efi_memory_mapped_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_memory_type_t memory_type;
+  grub_efi_physical_address_t start_address;
+  grub_efi_physical_address_t end_address;
+};
+typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_path_t;
+
+#define GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE		4
+
+struct grub_efi_vendor_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_guid_t vendor_guid;
+  grub_efi_uint8_t vendor_defined_data[0];
+};
+typedef struct grub_efi_vendor_device_path grub_efi_vendor_device_path_t;
+
+#define GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE		5
+
+struct grub_efi_controller_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t controller_number;
+};
+typedef struct grub_efi_controller_device_path grub_efi_controller_device_path_t;
+
+/* ACPI Device Path.  */
+#define GRUB_EFI_ACPI_DEVICE_PATH_TYPE			2
+
+#define GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE		1
+
+struct grub_efi_acpi_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t hid;
+  grub_efi_uint32_t uid;
+};
+typedef struct grub_efi_acpi_device_path grub_efi_acpi_device_path_t;
+
+#define GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE	2
+
+struct grub_efi_expanded_acpi_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t hid;
+  grub_efi_uint32_t uid;
+  grub_efi_uint32_t cid;
+  char hidstr[1];
+};
+typedef struct grub_efi_expanded_acpi_device_path grub_efi_expanded_acpi_device_path_t;
+
+#define GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp)	\
+  (((grub_efi_expanded_acpi_device_path_t *) dp)->hidstr)
+#define GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp)	\
+  (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \
+   + grub_strlen (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp)) + 1)
+#define GRUB_EFI_EXPANDED_ACPI_CIDSTR(dp)	\
+  (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \
+   + grub_strlen (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp)) + 1)
+
+/* Messaging Device Path.  */
+#define GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE		3
+
+#define GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE		1
+
+struct grub_efi_atapi_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint8_t primary_secondary;
+  grub_efi_uint8_t slave_master;
+  grub_efi_uint16_t lun;
+};
+typedef struct grub_efi_atapi_device_path grub_efi_atapi_device_path_t;
+
+#define GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE		2
+
+struct grub_efi_scsi_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint16_t pun;
+  grub_efi_uint16_t lun;
+};
+typedef struct grub_efi_scsi_device_path grub_efi_scsi_device_path_t;
+
+#define GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE	3
+
+struct grub_efi_fibre_channel_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t reserved;
+  grub_efi_uint64_t wwn;
+  grub_efi_uint64_t lun;
+};
+typedef struct grub_efi_fibre_channel_device_path grub_efi_fibre_channel_device_path_t;
+
+#define GRUB_EFI_1394_DEVICE_PATH_SUBTYPE		4
+
+struct grub_efi_1394_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t reserved;
+  grub_efi_uint64_t guid;
+};
+typedef struct grub_efi_1394_device_path grub_efi_1394_device_path_t;
+
+#define GRUB_EFI_USB_DEVICE_PATH_SUBTYPE		5
+
+struct grub_efi_usb_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint8_t parent_port_number;
+  grub_efi_uint8_t interface;
+};
+typedef struct grub_efi_usb_device_path grub_efi_usb_device_path_t;
+
+#define GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE		15
+
+struct grub_efi_usb_class_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint16_t vendor_id;
+  grub_efi_uint16_t product_id;
+  grub_efi_uint8_t device_class;
+  grub_efi_uint8_t device_subclass;
+  grub_efi_uint8_t device_protocol;
+};
+typedef struct grub_efi_usb_class_device_path grub_efi_usb_class_device_path_t;
+
+#define GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE		6
+
+struct grub_efi_i2o_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t tid;
+};
+typedef struct grub_efi_i2o_device_path grub_efi_i2o_device_path_t;
+
+#define GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE	11
+
+struct grub_efi_mac_address_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_mac_address_t mac_address;
+  grub_efi_uint8_t if_type;
+};
+typedef struct grub_efi_mac_address_device_path grub_efi_mac_address_device_path_t;
+
+#define GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE		12
+
+struct grub_efi_ipv4_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_ipv4_address_t local_ip_address;
+  grub_efi_ipv4_address_t remote_ip_address;
+  grub_efi_uint16_t local_port;
+  grub_efi_uint16_t remote_port;
+  grub_efi_uint16_t protocol;
+  grub_efi_uint8_t static_ip_address;
+};
+typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t;
+
+#define GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE		13
+
+struct grub_efi_ipv6_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_ipv6_address_t local_ip_address;
+  grub_efi_ipv6_address_t remote_ip_address;
+  grub_efi_uint16_t local_port;
+  grub_efi_uint16_t remote_port;
+  grub_efi_uint16_t protocol;
+  grub_efi_uint8_t static_ip_address;
+};
+typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t;
+
+#define GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE		9
+
+struct grub_efi_infiniband_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t resource_flags;
+  grub_efi_uint8_t port_gid[16];
+  grub_efi_uint64_t remote_id;
+  grub_efi_uint64_t target_port_id;
+  grub_efi_uint64_t device_id;
+};
+typedef struct grub_efi_infiniband_device_path grub_efi_infiniband_device_path_t;
+
+#define GRUB_EFI_UART_DEVICE_PATH_SUBTYPE		14
+
+struct grub_efi_uart_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t reserved;
+  grub_efi_uint64_t baud_rate;
+  grub_efi_uint8_t data_bits;
+  grub_efi_uint8_t parity;
+  grub_efi_uint8_t stop_bits;
+};
+typedef struct grub_efi_uart_device_path grub_efi_uart_device_path_t;
+
+#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE	10
+
+struct grub_efi_vendor_messaging_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_guid_t vendor_guid;
+  grub_efi_uint8_t vendor_defined_data[0];
+};
+typedef struct grub_efi_vendor_messaging_device_path grub_efi_vendor_messaging_device_path_t;
+
+/* Media Device Path.  */
+#define GRUB_EFI_MEDIA_DEVICE_PATH_TYPE			4
+
+#define GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE		1
+
+struct grub_efi_hard_drive_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t partition_number;
+  grub_efi_lba_t partition_start;
+  grub_efi_lba_t partition_size;
+  grub_efi_uint8_t partition_signature[8];
+  grub_efi_uint8_t mbr_type;
+  grub_efi_uint8_t signature_type;
+};
+typedef struct grub_efi_hard_drive_device_path grub_efi_hard_drive_device_path_t;
+
+#define GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE		2
+
+struct grub_efi_cdrom_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t boot_entry;
+  grub_efi_lba_t partition_start;
+  grub_efi_lba_t partition_size;
+};
+typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t;
+
+#define GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE	3
+
+struct grub_efi_vendor_media_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_guid_t vendor_guid;
+  grub_efi_uint8_t vendor_defined_data[0];
+};
+typedef struct grub_efi_vendor_media_device_path grub_efi_vendor_media_device_path_t;
+
+#define GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE		4
+
+struct grub_efi_file_path_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_char16_t path_name[0];
+};
+typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t;
+
+#define GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE		5
+
+struct grub_efi_protocol_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_guid_t guid;
+};
+typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t;
+
+/* BIOS Boot Specification Device Path.  */
+#define GRUB_EFI_BIOS_DEVICE_PATH_TYPE			5
+
+#define GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE		1
+
+struct grub_efi_bios_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint16_t device_type;
+  grub_efi_uint16_t status_flags;
+  char description[0];
+};
+typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t;
+
+struct grub_efi_open_protocol_information_entry
+{
+  grub_efi_handle_t agent_handle;
+  grub_efi_handle_t controller_handle;
+  grub_efi_uint32_t attributes;
+  grub_efi_uint32_t open_count;
+};
+typedef struct grub_efi_open_protocol_information_entry grub_efi_open_protocol_information_entry_t;
+
+struct grub_efi_time
+{
+  grub_efi_uint16_t year;
+  grub_efi_uint8_t month;
+  grub_efi_uint8_t day;
+  grub_efi_uint8_t hour;
+  grub_efi_uint8_t minute;
+  grub_efi_uint8_t second;
+  grub_efi_uint8_t pad1;
+  grub_efi_uint32_t nanosecond;
+  grub_efi_int16_t time_zone;
+  grub_efi_uint8_t daylight;
+  grub_efi_uint8_t pad2;
+} __attribute__ ((packed));
+typedef struct grub_efi_time grub_efi_time_t;
+
+struct grub_efi_time_capabilities
+{
+  grub_efi_uint32_t resolution;
+  grub_efi_uint32_t accuracy;
+  grub_efi_boolean_t sets_to_zero;
+};
+typedef struct grub_efi_time_capabilities grub_efi_time_capabilities_t;
+
+struct grub_efi_input_key
+{
+  grub_efi_uint16_t scan_code;
+  grub_efi_char16_t unicode_char;
+};
+typedef struct grub_efi_input_key grub_efi_input_key_t;
+
+struct grub_efi_simple_text_output_mode
+{
+  grub_efi_int32_t max_mode;
+  grub_efi_int32_t mode;
+  grub_efi_int32_t attribute;
+  grub_efi_int32_t cursor_column;
+  grub_efi_int32_t cursor_row;
+  grub_efi_boolean_t cursor_visible;
+};
+typedef struct grub_efi_simple_text_output_mode grub_efi_simple_text_output_mode_t;
+
+/* Tables.  */
+struct grub_efi_table_header
+{
+  grub_efi_uint64_t signature;
+  grub_efi_uint32_t revision;
+  grub_efi_uint32_t header_size;
+  grub_efi_uint32_t crc32;
+  grub_efi_uint32_t reserved;
+};
+typedef struct grub_efi_table_header grub_efi_table_header_t;
+
+struct grub_efi_boot_services
+{
+  grub_efi_table_header_t hdr;
+
+  grub_efi_tpl_t
+  (*raise_tpl) (grub_efi_tpl_t new_tpl);
+
+  void
+  (*restore_tpl) (grub_efi_tpl_t old_tpl);
+
+  grub_efi_status_t
+  (*allocate_pages) (grub_efi_allocate_type_t type,
+		     grub_efi_memory_type_t memory_type,
+		     grub_efi_uintn_t pages,
+		     grub_efi_physical_address_t *memory);
+
+  grub_efi_status_t
+  (*free_pages) (grub_efi_physical_address_t memory,
+		 grub_efi_uintn_t pages);
+
+  grub_efi_status_t
+  (*get_memory_map) (grub_efi_uintn_t *memory_map_size,
+		     grub_efi_memory_descriptor_t *memory_map,
+		     grub_efi_uintn_t *map_key,
+		     grub_efi_uintn_t *descriptor_size,
+		     grub_efi_uint32_t *descriptor_version);
+
+  grub_efi_status_t
+  (*allocate_pool) (grub_efi_memory_type_t pool_type,
+		    grub_efi_uintn_t size,
+		    void **buffer);
+
+  grub_efi_status_t
+  (*free_pool) (void *buffer);
+
+  grub_efi_status_t
+  (*create_event) (grub_efi_uint32_t type,
+		   grub_efi_tpl_t notify_tpl,
+		   void (*notify_function) (grub_efi_event_t event,
+					    void *context),
+		   void *notify_context,
+		   grub_efi_event_t *event);
+
+  grub_efi_status_t
+  (*set_timer) (grub_efi_event_t event,
+		grub_efi_timer_delay_t type,
+		grub_efi_uint64_t trigger_time);
+
+   grub_efi_status_t
+   (*wait_for_event) (grub_efi_uintn_t num_events,
+		      grub_efi_event_t *event,
+		      grub_efi_uintn_t *index);
+
+  grub_efi_status_t
+  (*signal_event) (grub_efi_event_t event);
+
+  grub_efi_status_t
+  (*close_event) (grub_efi_event_t event);
+
+  grub_efi_status_t
+  (*check_event) (grub_efi_event_t event);
+
+   grub_efi_status_t
+   (*install_protocol_interface) (grub_efi_handle_t *handle,
+				  grub_efi_guid_t *protocol,
+				  grub_efi_interface_type_t interface_type,
+				  void *interface);
+
+  grub_efi_status_t
+  (*reinstall_protocol_interface) (grub_efi_handle_t handle,
+				   grub_efi_guid_t *protocol,
+				   void *old_interface,
+				   void *new_interface);
+
+  grub_efi_status_t
+  (*uninstall_protocol_interface) (grub_efi_handle_t handle,
+				   grub_efi_guid_t *protocol,
+				   void *interface);
+
+  grub_efi_status_t
+  (*handle_protocol) (grub_efi_handle_t handle,
+		      grub_efi_guid_t *protocol,
+		      void **interface);
+
+  void *reserved;
+
+  grub_efi_status_t
+  (*register_protocol_notify) (grub_efi_guid_t *protocol,
+			       grub_efi_event_t event,
+			       void **registration);
+
+  grub_efi_status_t
+  (*locate_handle) (grub_efi_locate_search_type_t search_type,
+		    grub_efi_guid_t *protocol,
+		    void *search_key,
+		    grub_efi_uintn_t *buffer_size,
+		    grub_efi_handle_t *buffer);
+
+  grub_efi_status_t
+  (*locate_device_path) (grub_efi_guid_t *protocol,
+			 grub_efi_device_path_t **device_path,
+			 grub_efi_handle_t *device);
+
+  grub_efi_status_t
+  (*install_configuration_table) (grub_efi_guid_t *guid, void *table);
+
+  grub_efi_status_t
+  (*load_image) (grub_efi_boolean_t boot_policy,
+		 grub_efi_handle_t parent_image_handle,
+		 grub_efi_device_path_t *file_path,
+		 void *source_buffer,
+		 grub_efi_uintn_t source_size,
+		 grub_efi_handle_t *image_handle);
+
+  grub_efi_status_t
+  (*start_image) (grub_efi_handle_t image_handle,
+		  grub_efi_uintn_t *exit_data_size,
+		  grub_efi_char16_t **exit_data);
+
+  grub_efi_status_t
+  (*exit) (grub_efi_handle_t image_handle,
+	   grub_efi_status_t exit_status,
+	   grub_efi_uintn_t exit_data_size,
+	   grub_efi_char16_t *exit_data) __attribute__((noreturn));
+
+  grub_efi_status_t
+  (*unload_image) (grub_efi_handle_t image_handle);
+
+  grub_efi_status_t
+  (*exit_boot_services) (grub_efi_handle_t image_handle,
+			 grub_efi_uintn_t map_key);
+
+  grub_efi_status_t
+  (*get_next_monotonic_count) (grub_efi_uint64_t *count);
+
+  grub_efi_status_t
+  (*stall) (grub_efi_uintn_t microseconds);
+
+  grub_efi_status_t
+  (*set_watchdog_timer) (grub_efi_uintn_t timeout,
+			 grub_efi_uint64_t watchdog_code,
+			 grub_efi_uintn_t data_size,
+			 grub_efi_char16_t *watchdog_data);
+
+  grub_efi_status_t
+  (*connect_controller) (grub_efi_handle_t controller_handle,
+			 grub_efi_handle_t *driver_image_handle,
+			 grub_efi_device_path_protocol_t *remaining_device_path,
+			 grub_efi_boolean_t recursive);
+
+  grub_efi_status_t
+  (*disconnect_controller) (grub_efi_handle_t controller_handle,
+			    grub_efi_handle_t driver_image_handle,
+			    grub_efi_handle_t child_handle);
+
+  grub_efi_status_t
+  (*open_protocol) (grub_efi_handle_t handle,
+		    grub_efi_guid_t *protocol,
+		    void **interface,
+		    grub_efi_handle_t agent_handle,
+		    grub_efi_handle_t controller_handle,
+		    grub_efi_uint32_t attributes);
+
+  grub_efi_status_t
+  (*close_protocol) (grub_efi_handle_t handle,
+		     grub_efi_guid_t *protocol,
+		     grub_efi_handle_t agent_handle,
+		     grub_efi_handle_t controller_handle);
+
+  grub_efi_status_t
+  (*open_protocol_information) (grub_efi_handle_t handle,
+				grub_efi_guid_t *protocol,
+				grub_efi_open_protocol_information_entry_t **entry_buffer,
+				grub_efi_uintn_t *entry_count);
+
+  grub_efi_status_t
+  (*protocols_per_handle) (grub_efi_handle_t handle,
+			   grub_efi_guid_t ***protocol_buffer,
+			   grub_efi_uintn_t *protocol_buffer_count);
+
+  grub_efi_status_t
+  (*locate_handle_buffer) (grub_efi_locate_search_type_t search_type,
+			   grub_efi_guid_t *protocol,
+			   void *search_key,
+			   grub_efi_uintn_t *no_handles,
+			   grub_efi_handle_t **buffer);
+
+  grub_efi_status_t
+  (*locate_protocol) (grub_efi_guid_t *protocol,
+		      void *registration,
+		      void **interface);
+
+  grub_efi_status_t
+  (*install_multiple_protocol_interfaces) (grub_efi_handle_t *handle, ...);
+
+  grub_efi_status_t
+  (*uninstall_multiple_protocol_interfaces) (grub_efi_handle_t handle, ...);
+
+  grub_efi_status_t
+  (*calculate_crc32) (void *data,
+		      grub_efi_uintn_t data_size,
+		      grub_efi_uint32_t *crc32);
+
+  void
+  (*copy_mem) (void *destination, void *source, grub_efi_uintn_t length);
+
+  void
+  (*set_mem) (void *buffer, grub_efi_uintn_t size, grub_efi_uint8_t value);
+};
+typedef struct grub_efi_boot_services grub_efi_boot_services_t;
+
+struct grub_efi_runtime_services
+{
+  grub_efi_table_header_t hdr;
+
+  grub_efi_status_t
+  (*get_time) (grub_efi_time_t *time,
+	       grub_efi_time_capabilities_t *capabilities);
+
+  grub_efi_status_t
+  (*set_time) (grub_efi_time_t *time);
+
+  grub_efi_status_t
+  (*get_wakeup_time) (grub_efi_boolean_t *enabled,
+		      grub_efi_boolean_t *pending,
+		      grub_efi_time_t *time);
+
+  grub_efi_status_t
+  (*set_wakeup_time) (grub_efi_boolean_t enabled,
+		      grub_efi_time_t *time);
+
+  grub_efi_status_t
+  (*set_virtual_address_map) (grub_efi_uintn_t memory_map_size,
+			      grub_efi_uintn_t descriptor_size,
+			      grub_efi_uint32_t descriptor_version,
+			      grub_efi_memory_descriptor_t *virtual_map);
+
+  grub_efi_status_t
+  (*convert_pointer) (grub_efi_uintn_t debug_disposition, void **address);
+
+  grub_efi_status_t
+  (*get_variable) (grub_efi_char16_t *variable_name,
+		   grub_efi_guid_t *vendor_guid,
+		   grub_efi_uint32_t *attributes,
+		   grub_efi_uintn_t *data_size,
+		   void *data);
+
+  grub_efi_status_t
+  (*get_next_variable_name) (grub_efi_uintn_t *variable_name_size,
+			     grub_efi_char16_t *variable_name,
+			     grub_efi_guid_t *vendor_guid);
+
+  grub_efi_status_t
+  (*set_variable) (grub_efi_char16_t *variable_name,
+		   grub_efi_guid_t *vendor_guid,
+		   grub_efi_uint32_t attributes,
+		   grub_efi_uintn_t data_size,
+		   void *data);
+
+  grub_efi_status_t
+  (*get_next_high_monotonic_count) (grub_efi_uint32_t *high_count);
+
+  void
+  (*reset_system) (grub_efi_reset_type_t reset_type,
+		   grub_efi_status_t reset_status,
+		   grub_efi_uintn_t data_size,
+		   grub_efi_char16_t *reset_data);
+};
+typedef struct grub_efi_runtime_services grub_efi_runtime_services_t;
+
+struct grub_efi_configuration_table
+{
+  grub_efi_guid_t vendor_guid;
+  void *vendor_table;
+} __attribute__ ((packed));
+typedef struct grub_efi_configuration_table grub_efi_configuration_table_t;
+
+#define GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE 0x5453595320494249LL
+#define GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552LL
+
+struct grub_efi_simple_input_interface
+{
+  grub_efi_status_t
+  (*reset) (struct grub_efi_simple_input_interface *this,
+	    grub_efi_boolean_t extended_verification);
+
+  grub_efi_status_t
+  (*read_key_stroke) (struct grub_efi_simple_input_interface *this,
+		      grub_efi_input_key_t *key);
+
+  grub_efi_event_t wait_for_key;
+};
+typedef struct grub_efi_simple_input_interface grub_efi_simple_input_interface_t;
+
+struct grub_efi_simple_text_output_interface
+{
+  grub_efi_status_t
+  (*reset) (struct grub_efi_simple_text_output_interface *this,
+	    grub_efi_boolean_t extended_verification);
+
+  grub_efi_status_t
+  (*output_string) (struct grub_efi_simple_text_output_interface *this,
+		    grub_efi_char16_t *string);
+
+  grub_efi_status_t
+  (*test_string) (struct grub_efi_simple_text_output_interface *this,
+		  grub_efi_char16_t *string);
+
+  grub_efi_status_t
+  (*query_mode) (struct grub_efi_simple_text_output_interface *this,
+		 grub_efi_uintn_t mode_number,
+		 grub_efi_uintn_t *columns,
+		 grub_efi_uintn_t *rows);
+
+  grub_efi_status_t
+  (*set_mode) (struct grub_efi_simple_text_output_interface *this,
+	       grub_efi_uintn_t mode_number);
+
+  grub_efi_status_t
+  (*set_attributes) (struct grub_efi_simple_text_output_interface *this,
+		     grub_efi_uintn_t attribute);
+
+  grub_efi_status_t
+  (*clear_screen) (struct grub_efi_simple_text_output_interface *this);
+
+  grub_efi_status_t
+  (*set_cursor_position) (struct grub_efi_simple_text_output_interface *this,
+			  grub_efi_uintn_t column,
+			  grub_efi_uintn_t row);
+
+  grub_efi_status_t
+  (*enable_cursor) (struct grub_efi_simple_text_output_interface *this,
+		    grub_efi_boolean_t visible);
+
+  grub_efi_simple_text_output_mode_t *mode;
+};
+typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t;
+
+#define GRUB_EFI_BLACK		0x00
+#define GRUB_EFI_BLUE		0x01
+#define GRUB_EFI_GREEN		0x02
+#define GRUB_EFI_CYAN		0x03
+#define GRUB_EFI_RED		0x04
+#define GRUB_EFI_MAGENTA	0x05
+#define GRUB_EFI_BROWN		0x06
+#define GRUB_EFI_LIGHTGRAY	0x07
+#define GRUB_EFI_BRIGHT		0x08
+#define GRUB_EFI_DARKGRAY	0x08
+#define GRUB_EFI_LIGHTBLUE	0x09
+#define GRUB_EFI_LIGHTGREEN	0x0A
+#define GRUB_EFI_LIGHTCYAN	0x0B
+#define GRUB_EFI_LIGHTRED	0x0C
+#define GRUB_EFI_LIGHTMAGENTA	0x0D
+#define GRUB_EFI_YELLOW		0x0E
+#define GRUB_EFI_WHITE		0x0F
+
+#define GRUB_EFI_BACKGROUND_BLACK	0x00
+#define GRUB_EFI_BACKGROUND_BLUE	0x10
+#define GRUB_EFI_BACKGROUND_GREEN	0x20
+#define GRUB_EFI_BACKGROUND_CYAN	0x30
+#define GRUB_EFI_BACKGROUND_RED		0x40
+#define GRUB_EFI_BACKGROUND_MAGENTA	0x50
+#define GRUB_EFI_BACKGROUND_BROWN	0x60
+#define GRUB_EFI_BACKGROUND_LIGHTGRAY	0x70
+
+#define GRUB_EFI_TEXT_ATTR(fg, bg)	((fg) | ((bg)))
+
+struct grub_efi_system_table
+{
+  grub_efi_table_header_t hdr;
+  grub_efi_char16_t *firmware_vendor;
+  grub_efi_uint32_t firmware_revision;
+  grub_efi_handle_t console_in_handler;
+  grub_efi_simple_input_interface_t *con_in;
+  grub_efi_handle_t console_out_handler;
+  grub_efi_simple_text_output_interface_t *con_out;
+  grub_efi_handle_t standard_error_handle;
+  grub_efi_simple_text_output_interface_t *std_err;
+  grub_efi_runtime_services_t *runtime_services;
+  grub_efi_boot_services_t *boot_services;
+  grub_efi_uintn_t num_table_entries;
+  grub_efi_configuration_table_t *configuration_table;
+};
+typedef struct grub_efi_system_table  grub_efi_system_table_t;
+
+struct grub_efi_loaded_image
+{
+  grub_efi_uint32_t revision;
+  grub_efi_handle_t parent_handle;
+  grub_efi_system_table_t *system_table;
+
+  grub_efi_handle_t device_handle;
+  grub_efi_device_path_t *file_path;
+  void *reserved;
+
+  grub_efi_uint32_t load_options_size;
+  void *load_options;
+
+  void *image_base;
+  grub_efi_uint64_t image_size;
+  grub_efi_memory_type_t image_code_type;
+  grub_efi_memory_type_t image_data_type;
+
+  grub_efi_status_t (*unload) (grub_efi_handle_t image_handle);
+};
+typedef struct grub_efi_loaded_image grub_efi_loaded_image_t;
+
+struct grub_efi_disk_io
+{
+  grub_efi_uint64_t revision;
+  grub_efi_status_t (*read) (struct grub_efi_disk_io *this,
+			     grub_efi_uint32_t media_id,
+			     grub_efi_uint64_t offset,
+			     grub_efi_uintn_t buffer_size,
+			     void *buffer);
+  grub_efi_status_t (*write) (struct grub_efi_disk_io *this,
+			     grub_efi_uint32_t media_id,
+			     grub_efi_uint64_t offset,
+			     grub_efi_uintn_t buffer_size,
+			     void *buffer);
+};
+typedef struct grub_efi_disk_io grub_efi_disk_io_t;
+
+struct grub_efi_block_io_media
+{
+  grub_efi_uint32_t media_id;
+  grub_efi_boolean_t removable_media;
+  grub_efi_boolean_t media_present;
+  grub_efi_boolean_t logical_partition;
+  grub_efi_boolean_t read_only;
+  grub_efi_boolean_t write_caching;
+  grub_efi_uint8_t pad[3];
+  grub_efi_uint32_t block_size;
+  grub_efi_uint32_t io_align;
+  grub_efi_uint8_t pad2[4];
+  grub_efi_lba_t last_block;
+};
+typedef struct grub_efi_block_io_media grub_efi_block_io_media_t;
+
+struct grub_efi_block_io
+{
+  grub_efi_uint64_t revision;
+  grub_efi_block_io_media_t *media;
+  grub_efi_status_t (*reset) (struct grub_efi_block_io *this,
+			      grub_efi_boolean_t extended_verification);
+  grub_efi_status_t (*read_blocks) (struct grub_efi_block_io *this,
+				    grub_efi_uint32_t media_id,
+				    grub_efi_lba_t lba,
+				    grub_efi_uintn_t buffer_size,
+				    void *buffer);
+  grub_efi_status_t (*write_blocks) (struct grub_efi_block_io *this,
+				     grub_efi_uint32_t media_id,
+				     grub_efi_lba_t lba,
+				     grub_efi_uintn_t buffer_size,
+				     void *buffer);
+  grub_efi_status_t (*flush_blocks) (struct grub_efi_block_io *this);
+};
+typedef struct grub_efi_block_io grub_efi_block_io_t;
+
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+
+#define efi_call_0(func)		func()
+#define efi_call_1(func, a)		func(a)
+#define efi_call_2(func, a, b)		func(a, b)
+#define efi_call_3(func, a, b, c)	func(a, b, c)
+#define efi_call_4(func, a, b, c, d)	func(a, b, c, d)
+#define efi_call_5(func, a, b, c, d, e)	func(a, b, c, d, e)
+#define efi_call_6(func, a, b, c, d, e, f) func(a, b, c, d, e, f)
+#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j)	func(a, b, c, d, e, f, g, h, i, j)
+
+#else
+
+#define efi_call_0(func) \
+  efi_wrap_0(func)
+#define efi_call_1(func, a) \
+  efi_wrap_1(func, (grub_uint64_t) a)
+#define efi_call_2(func, a, b) \
+  efi_wrap_2(func, (grub_uint64_t) a, (grub_uint64_t) b)
+#define efi_call_3(func, a, b, c) \
+  efi_wrap_3(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c)
+#define efi_call_4(func, a, b, c, d) \
+  efi_wrap_4(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \
+  (grub_uint64_t) d)
+#define efi_call_5(func, a, b, c, d, e)	\
+  efi_wrap_5(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \
+  (grub_uint64_t) d, (grub_uint64_t) e)
+#define efi_call_6(func, a, b, c, d, e, f) \
+  efi_wrap_6(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \
+  (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f)
+#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) \
+  efi_wrap_10(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \
+  (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f, (grub_uint64_t) g, \
+  (grub_uint64_t) h, (grub_uint64_t) i, (grub_uint64_t) j)
+
+grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func);
+grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1);
+grub_uint64_t EXPORT_FUNC(efi_wrap_2) (void *func, grub_uint64_t arg1,
+                                       grub_uint64_t arg2);
+grub_uint64_t EXPORT_FUNC(efi_wrap_3) (void *func, grub_uint64_t arg1,
+                                       grub_uint64_t arg2, grub_uint64_t arg3);
+grub_uint64_t EXPORT_FUNC(efi_wrap_4) (void *func, grub_uint64_t arg1,
+                                       grub_uint64_t arg2, grub_uint64_t arg3,
+                                       grub_uint64_t arg4);
+grub_uint64_t EXPORT_FUNC(efi_wrap_5) (void *func, grub_uint64_t arg1,
+                                       grub_uint64_t arg2, grub_uint64_t arg3,
+                                       grub_uint64_t arg4, grub_uint64_t arg5);
+grub_uint64_t EXPORT_FUNC(efi_wrap_6) (void *func, grub_uint64_t arg1,
+                                       grub_uint64_t arg2, grub_uint64_t arg3,
+                                       grub_uint64_t arg4, grub_uint64_t arg5,
+                                       grub_uint64_t arg6);
+grub_uint64_t EXPORT_FUNC(efi_wrap_10) (void *func, grub_uint64_t arg1,
+                                        grub_uint64_t arg2, grub_uint64_t arg3,
+                                        grub_uint64_t arg4, grub_uint64_t arg5,
+                                        grub_uint64_t arg6, grub_uint64_t arg7,
+                                        grub_uint64_t arg8, grub_uint64_t arg9,
+                                        grub_uint64_t arg10);
+#endif
+
+#endif /* ! GRUB_EFI_API_HEADER */
diff --git a/include/grub/efi/console.h b/include/grub/efi/console.h
new file mode 100644
index 0000000..f90b5b7
--- /dev/null
+++ b/include/grub/efi/console.h
@@ -0,0 +1,31 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_CONSOLE_HEADER
+#define GRUB_EFI_CONSOLE_HEADER	1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+/* Initialize the console system.  */
+void grub_console_init (void);
+
+/* Finish the console system.  */
+void grub_console_fini (void);
+
+#endif /* ! GRUB_EFI_CONSOLE_HEADER */
diff --git a/include/grub/efi/console_control.h b/include/grub/efi/console_control.h
new file mode 100644
index 0000000..7c358fc
--- /dev/null
+++ b/include/grub/efi/console_control.h
@@ -0,0 +1,57 @@
+/* console_control.h - definitions of the console control protocol */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The console control protocol is not a part of the EFI spec,
+   but defined in Intel's Sample Implementation.  */
+
+#ifndef GRUB_EFI_CONSOLE_CONTROL_HEADER
+#define GRUB_EFI_CONSOLE_CONTROL_HEADER	1
+
+#define GRUB_EFI_CONSOLE_CONTROL_GUID	\
+  { 0xf42f7782, 0x12e, 0x4c12, \
+    { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } \
+  }
+
+enum grub_efi_screen_mode
+  {
+    GRUB_EFI_SCREEN_TEXT,
+    GRUB_EFI_SCREEN_GRAPHICS,
+    GRUB_EFI_SCREEN_TEXT_MAX_VALUE
+  };
+typedef enum grub_efi_screen_mode grub_efi_screen_mode_t;
+
+struct grub_efi_console_control_protocol
+{
+  grub_efi_status_t
+  (*get_mode) (struct grub_efi_console_control_protocol *this,
+	       grub_efi_screen_mode_t *mode,
+	       grub_efi_boolean_t *uga_exists,
+	       grub_efi_boolean_t *std_in_locked);
+
+  grub_efi_status_t
+  (*set_mode) (struct grub_efi_console_control_protocol *this,
+	       grub_efi_screen_mode_t mode);
+
+  grub_efi_status_t
+  (*lock_std_in) (struct grub_efi_console_control_protocol *this,
+		  grub_efi_char16_t *password);
+};
+typedef struct grub_efi_console_control_protocol grub_efi_console_control_protocol_t;
+
+#endif /* ! GRUB_EFI_CONSOLE_CONTROL_HEADER */
diff --git a/include/grub/efi/disk.h b/include/grub/efi/disk.h
new file mode 100644
index 0000000..254475c
--- /dev/null
+++ b/include/grub/efi/disk.h
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_DISK_HEADER
+#define GRUB_EFI_DISK_HEADER	1
+
+#include <grub/efi/api.h>
+#include <grub/symbol.h>
+#include <grub/disk.h>
+
+grub_efi_handle_t
+EXPORT_FUNC(grub_efidisk_get_device_handle) (grub_disk_t disk);
+char *EXPORT_FUNC(grub_efidisk_get_device_name) (grub_efi_handle_t *handle);
+
+void grub_efidisk_init (void);
+void grub_efidisk_fini (void);
+
+#endif /* ! GRUB_EFI_DISK_HEADER */
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
new file mode 100644
index 0000000..916f9d6
--- /dev/null
+++ b/include/grub/efi/efi.h
@@ -0,0 +1,71 @@
+/* efi.h - declare variables and functions for EFI support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_EFI_HEADER
+#define GRUB_EFI_EFI_HEADER	1
+
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/efi/api.h>
+
+/* Functions.  */
+void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_efi_guid_t *protocol,
+					     void *registration);
+grub_efi_handle_t *
+EXPORT_FUNC(grub_efi_locate_handle) (grub_efi_locate_search_type_t search_type,
+				     grub_efi_guid_t *protocol,
+				     void *search_key,
+				     grub_efi_uintn_t *num_handles);
+void *EXPORT_FUNC(grub_efi_open_protocol) (grub_efi_handle_t handle,
+					   grub_efi_guid_t *protocol,
+					   grub_efi_uint32_t attributes);
+int EXPORT_FUNC(grub_efi_set_text_mode) (int on);
+void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds);
+void *
+EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address,
+				      grub_efi_uintn_t pages);
+void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address,
+				       grub_efi_uintn_t pages);
+int
+EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size,
+				      grub_efi_memory_descriptor_t *memory_map,
+				      grub_efi_uintn_t *map_key,
+				      grub_efi_uintn_t *descriptor_size,
+				      grub_efi_uint32_t *descriptor_version);
+grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (grub_efi_handle_t image_handle);
+void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp);
+char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp);
+grub_efi_device_path_t *
+EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle);
+int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key);
+void EXPORT_FUNC (grub_reboot) (void);
+void EXPORT_FUNC (grub_halt) (void);
+int EXPORT_FUNC (grub_efi_finish_boot_services) (void);
+
+void grub_efi_mm_init (void);
+void grub_efi_mm_fini (void);
+void grub_efi_init (void);
+void grub_efi_fini (void);
+void grub_efi_set_prefix (void);
+
+/* Variables.  */
+extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table);
+extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle);
+
+#endif /* ! GRUB_EFI_EFI_HEADER */
diff --git a/include/grub/efi/memory.h b/include/grub/efi/memory.h
new file mode 100644
index 0000000..e5ea58d
--- /dev/null
+++ b/include/grub/efi/memory.h
@@ -0,0 +1,48 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_MACHINE_HEADER
+#define GRUB_MEMORY_MACHINE_HEADER	1
+
+#include <grub/err.h>
+#include <grub/types.h>
+
+#define GRUB_MMAP_REGISTER_BY_FIRMWARE  1
+
+#define GRUB_MACHINE_MEMORY_AVAILABLE	1
+#define GRUB_MACHINE_MEMORY_RESERVED	2
+#define GRUB_MACHINE_MEMORY_ACPI	3
+#define GRUB_MACHINE_MEMORY_NVS         4
+#define GRUB_MACHINE_MEMORY_CODE        5
+#define GRUB_MACHINE_MEMORY_MAX_TYPE 	5
+  /* This one is special: it's used internally but is never reported
+     by firmware. */
+#define GRUB_MACHINE_MEMORY_HOLE 	6
+
+
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
+(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size,
+				       int type, int handle);
+grub_err_t grub_machine_mmap_unregister (int handle);
+
+grub_uint64_t grub_mmap_get_post64 (void);
+grub_uint64_t grub_mmap_get_upper (void);
+grub_uint64_t grub_mmap_get_lower (void);
+
+#endif /* ! GRUB_MEMORY_MACHINE_HEADER */
diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
new file mode 100644
index 0000000..4fb8d09
--- /dev/null
+++ b/include/grub/efi/pe32.h
@@ -0,0 +1,276 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_PE32_HEADER
+#define GRUB_EFI_PE32_HEADER	1
+
+#include <grub/types.h>
+
+/* The MSDOS compatibility stub. This was copied from the output of
+   objcopy, and it is not necessary to care about what this means.  */
+#define GRUB_PE32_MSDOS_STUB \
+  { \
+    0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, \
+    0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, \
+    0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+    0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+    0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, \
+    0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, \
+    0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, \
+    0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, \
+    0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, \
+    0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, \
+    0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, \
+    0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, \
+    0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  \
+  }
+
+#define GRUB_PE32_MSDOS_STUB_SIZE	0x80
+
+/* According to the spec, the minimal alignment is 512 bytes...
+   But some examples (such as EFI drivers in the Intel
+   Sample Implementation) use 32 bytes (0x20) instead, and it seems
+   to be working. For now, GRUB uses 512 bytes for safety.  */
+#define GRUB_PE32_SECTION_ALIGNMENT	0x200
+#define GRUB_PE32_FILE_ALIGNMENT	GRUB_PE32_SECTION_ALIGNMENT
+
+struct grub_pe32_coff_header
+{
+  grub_uint16_t machine;
+  grub_uint16_t num_sections;
+  grub_uint32_t time;
+  grub_uint32_t symtab_offset;
+  grub_uint32_t num_symbols;
+  grub_uint16_t optional_header_size;
+  grub_uint16_t characteristics;
+};
+
+#define GRUB_PE32_MACHINE_I386		0x14c
+#define GRUB_PE32_MACHINE_X86_64	0x8664
+
+#define GRUB_PE32_RELOCS_STRIPPED		0x0001
+#define GRUB_PE32_EXECUTABLE_IMAGE		0x0002
+#define GRUB_PE32_LINE_NUMS_STRIPPED		0x0004
+#define GRUB_PE32_LOCAL_SYMS_STRIPPED		0x0008
+#define GRUB_PE32_AGGRESSIVE_WS_TRIM		0x0010
+#define GRUB_PE32_LARGE_ADDRESS_AWARE		0x0020
+#define GRUB_PE32_16BIT_MACHINE			0x0040
+#define GRUB_PE32_BYTES_REVERSED_LO		0x0080
+#define GRUB_PE32_32BIT_MACHINE			0x0100
+#define GRUB_PE32_DEBUG_STRIPPED		0x0200
+#define GRUB_PE32_REMOVABLE_RUN_FROM_SWAP	0x0400
+#define GRUB_PE32_SYSTEM			0x1000
+#define GRUB_PE32_DLL				0x2000
+#define GRUB_PE32_UP_SYSTEM_ONLY		0x4000
+#define GRUB_PE32_BYTES_REVERSED_HI		0x8000
+
+struct grub_pe32_data_directory
+{
+  grub_uint32_t rva;
+  grub_uint32_t size;
+};
+
+struct grub_pe32_optional_header
+{
+  grub_uint16_t magic;
+  grub_uint8_t major_linker_version;
+  grub_uint8_t minor_linker_version;
+  grub_uint32_t code_size;
+  grub_uint32_t data_size;
+  grub_uint32_t bss_size;
+  grub_uint32_t entry_addr;
+  grub_uint32_t code_base;
+
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+  grub_uint32_t data_base;
+  grub_uint32_t image_base;
+#else
+  grub_uint64_t image_base;
+#endif
+
+  grub_uint32_t section_alignment;
+  grub_uint32_t file_alignment;
+  grub_uint16_t major_os_version;
+  grub_uint16_t minor_os_version;
+  grub_uint16_t major_image_version;
+  grub_uint16_t minor_image_version;
+  grub_uint16_t major_subsystem_version;
+  grub_uint16_t minor_subsystem_version;
+  grub_uint32_t reserved;
+  grub_uint32_t image_size;
+  grub_uint32_t header_size;
+  grub_uint32_t checksum;
+  grub_uint16_t subsystem;
+  grub_uint16_t dll_characteristics;
+
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+
+  grub_uint32_t stack_reserve_size;
+  grub_uint32_t stack_commit_size;
+  grub_uint32_t heap_reserve_size;
+  grub_uint32_t heap_commit_size;
+
+#else
+
+  grub_uint64_t stack_reserve_size;
+  grub_uint64_t stack_commit_size;
+  grub_uint64_t heap_reserve_size;
+  grub_uint64_t heap_commit_size;
+
+#endif
+
+  grub_uint32_t loader_flags;
+  grub_uint32_t num_data_directories;
+
+  /* Data directories.  */
+  struct grub_pe32_data_directory export_table;
+  struct grub_pe32_data_directory import_table;
+  struct grub_pe32_data_directory resource_table;
+  struct grub_pe32_data_directory exception_table;
+  struct grub_pe32_data_directory certificate_table;
+  struct grub_pe32_data_directory base_relocation_table;
+  struct grub_pe32_data_directory debug;
+  struct grub_pe32_data_directory architecture;
+  struct grub_pe32_data_directory global_ptr;
+  struct grub_pe32_data_directory tls_table;
+  struct grub_pe32_data_directory load_config_table;
+  struct grub_pe32_data_directory bound_import;
+  struct grub_pe32_data_directory iat;
+  struct grub_pe32_data_directory delay_import_descriptor;
+  struct grub_pe32_data_directory com_runtime_header;
+  struct grub_pe32_data_directory reserved_entry;
+};
+
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+
+#define GRUB_PE32_PE32_MAGIC	0x10b
+
+#else
+
+#define GRUB_PE32_PE32_MAGIC	0x20b
+
+#endif
+
+#define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION	10
+
+#define GRUB_PE32_NUM_DATA_DIRECTORIES	16
+
+struct grub_pe32_section_table
+{
+  char name[8];
+  grub_uint32_t virtual_size;
+  grub_uint32_t virtual_address;
+  grub_uint32_t raw_data_size;
+  grub_uint32_t raw_data_offset;
+  grub_uint32_t relocations_offset;
+  grub_uint32_t line_numbers_offset;
+  grub_uint16_t num_relocations;
+  grub_uint16_t num_line_numbers;
+  grub_uint32_t characteristics;
+};
+
+#define GRUB_PE32_SCN_CNT_CODE			0x00000020
+#define GRUB_PE32_SCN_CNT_INITIALIZED_DATA	0x00000040
+#define GRUB_PE32_SCN_MEM_DISCARDABLE		0x02000000
+#define GRUB_PE32_SCN_MEM_EXECUTE		0x20000000
+#define GRUB_PE32_SCN_MEM_READ			0x40000000
+#define GRUB_PE32_SCN_MEM_WRITE			0x80000000
+
+#define GRUB_PE32_SCN_ALIGN_1BYTES		0x00100000
+#define GRUB_PE32_SCN_ALIGN_2BYTES		0x00200000
+#define GRUB_PE32_SCN_ALIGN_4BYTES		0x00300000
+#define GRUB_PE32_SCN_ALIGN_8BYTES		0x00400000
+#define GRUB_PE32_SCN_ALIGN_16BYTES		0x00500000
+#define GRUB_PE32_SCN_ALIGN_32BYTES		0x00600000
+#define GRUB_PE32_SCN_ALIGN_64BYTES		0x00700000
+
+#define GRUB_PE32_SCN_ALIGN_SHIFT		20
+#define GRUB_PE32_SCN_ALIGN_MASK		7
+
+
+struct grub_pe32_header
+{
+  /* This should be filled in with GRUB_PE32_MSDOS_STUB.  */
+  grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE];
+
+  /* This is always PE\0\0.  */
+  char signature[4];
+
+  /* The COFF file header.  */
+  struct grub_pe32_coff_header coff_header;
+
+  /* The Optional header.  */
+  struct grub_pe32_optional_header optional_header;
+};
+
+struct grub_pe32_fixup_block
+{
+  grub_uint32_t page_rva;
+  grub_uint32_t block_size;
+  grub_uint16_t entries[0];
+};
+
+#define GRUB_PE32_FIXUP_ENTRY(type, offset)	(((type) << 12) | (offset))
+
+#define GRUB_PE32_REL_BASED_ABSOLUTE	0
+#define GRUB_PE32_REL_BASED_HIGH	1
+#define GRUB_PE32_REL_BASED_LOW		2
+#define GRUB_PE32_REL_BASED_HIGHLOW	3
+#define GRUB_PE32_REL_BASED_HIGHADJ	4
+#define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5
+#define GRUB_PE32_REL_BASED_SECTION	6
+#define GRUB_PE32_REL_BASED_REL		7
+#define GRUB_PE32_REL_BASED_IA64_IMM64	9
+#define GRUB_PE32_REL_BASED_DIR64	10
+#define GRUB_PE32_REL_BASED_HIGH3ADJ	11
+
+struct grub_pe32_symbol
+{
+  union
+  {
+    char short_name[8];
+    grub_uint32_t long_name[2];
+  };
+
+  grub_uint32_t value;
+  grub_uint16_t section;
+  grub_uint16_t type;
+  grub_uint8_t storage_class;
+  grub_uint8_t num_aux;
+} __attribute__ ((packed));
+
+#define GRUB_PE32_SYM_CLASS_EXTERNAL	2
+#define GRUB_PE32_SYM_CLASS_STATIC	3
+#define GRUB_PE32_SYM_CLASS_FILE	0x67
+
+#define GRUB_PE32_DT_FUNCTION		0x20
+
+struct grub_pe32_reloc
+{
+  grub_uint32_t offset;
+  grub_uint32_t symtab_index;
+  grub_uint16_t type;
+} __attribute__ ((packed));
+
+#define GRUB_PE32_REL_I386_DIR32	0x6
+#define GRUB_PE32_REL_I386_REL32	0x14
+
+#endif /* ! GRUB_EFI_PE32_HEADER */
diff --git a/include/grub/efi/time.h b/include/grub/efi/time.h
new file mode 100644
index 0000000..540f6fc
--- /dev/null
+++ b/include/grub/efi/time.h
@@ -0,0 +1,30 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_TIME_HEADER
+#define GRUB_EFI_TIME_HEADER	1
+
+#include <grub/symbol.h>
+
+/* This is destined to overflow when one hour passes by.  */
+#define GRUB_TICKS_PER_SECOND	((1UL << 31) / 60 / 60 * 2)
+
+/* Return the real time in ticks.  */
+grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
+
+#endif /* ! GRUB_EFI_TIME_HEADER */
diff --git a/include/grub/efi/uga_draw.h b/include/grub/efi/uga_draw.h
new file mode 100644
index 0000000..9350430
--- /dev/null
+++ b/include/grub/efi/uga_draw.h
@@ -0,0 +1,76 @@
+/* uga_draw.h - definitions of the uga draw protocol */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The console control protocol is not a part of the EFI spec,
+   but defined in Intel's Sample Implementation.  */
+
+#ifndef GRUB_EFI_UGA_DRAW_HEADER
+#define GRUB_EFI_UGA_DRAW_HEADER	1
+
+#define GRUB_EFI_UGA_DRAW_GUID \
+  { 0x982c298b, 0xf4fa, 0x41cb, { 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 }}
+
+enum grub_efi_uga_blt_operation
+{
+  GRUB_EFI_UGA_VIDEO_FILL,
+  GRUB_EFI_UGA_VIDEO_TO_BLT,
+  GRUB_EFI_UGA_BLT_TO_VIDEO,
+  GRUB_EFI_UGA_VIDEO_TO_VIDEO,
+  GRUB_EFI_UGA_GLT_MAX
+};
+
+struct grub_efi_uga_pixel
+{
+  grub_uint8_t Blue;
+  grub_uint8_t Green;
+  grub_uint8_t Red;
+  grub_uint8_t Reserved;
+};
+
+struct grub_efi_uga_draw_protocol
+{
+  grub_efi_status_t
+  (*get_mode) (struct grub_efi_uga_draw_protocol *this,
+	       grub_uint32_t *width,
+	       grub_uint32_t *height,
+	       grub_uint32_t *depth,
+	       grub_uint32_t *refresh_rate);
+
+  grub_efi_status_t
+  (*set_mode) (struct grub_efi_uga_draw_protocol *this,
+	       grub_uint32_t width,
+	       grub_uint32_t height,
+	       grub_uint32_t depth,
+	       grub_uint32_t refresh_rate);
+
+  grub_efi_status_t
+  (*blt) (struct grub_efi_uga_draw_protocol *this,
+	  struct grub_efi_uga_pixel *blt_buffer,
+	  enum grub_efi_uga_blt_operation blt_operation,
+	  grub_efi_uintn_t src_x,
+	  grub_efi_uintn_t src_y,
+	  grub_efi_uintn_t dest_x,
+	  grub_efi_uintn_t dest_y,
+	  grub_efi_uintn_t width,
+	  grub_efi_uintn_t height,
+	  grub_efi_uintn_t delta);
+};
+typedef struct grub_efi_uga_draw_protocol grub_efi_uga_draw_protocol_t;
+
+#endif /* ! GRUB_EFI_UGA_DRAW_HEADER */
diff --git a/include/grub/efiemu/efiemu.h b/include/grub/efiemu/efiemu.h
new file mode 100644
index 0000000..20163dd
--- /dev/null
+++ b/include/grub/efiemu/efiemu.h
@@ -0,0 +1,276 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_EMU_HEADER
+#define GRUB_EFI_EMU_HEADER	1
+
+#include <grub/efi/api.h>
+#include <grub/file.h>
+
+#define GRUB_EFIEMU_PAGESIZE 4096
+
+/* EFI api defined in 32-bit and 64-bit version*/
+struct grub_efi_system_table32
+{
+  grub_efi_table_header_t hdr;
+  grub_efi_uint32_t firmware_vendor;
+  grub_efi_uint32_t firmware_revision;
+  grub_efi_uint32_t console_in_handler;
+  grub_efi_uint32_t con_in;
+  grub_efi_uint32_t console_out_handler;
+  grub_efi_uint32_t con_out;
+  grub_efi_uint32_t standard_error_handle;
+  grub_efi_uint32_t std_err;
+  grub_efi_uint32_t runtime_services;
+  grub_efi_uint32_t boot_services;
+  grub_efi_uint32_t num_table_entries;
+  grub_efi_uint32_t configuration_table;
+} __attribute__ ((packed));
+typedef struct grub_efi_system_table32  grub_efi_system_table32_t;
+
+struct grub_efi_system_table64
+{
+  grub_efi_table_header_t hdr;
+  grub_efi_uint64_t firmware_vendor;
+  grub_efi_uint32_t firmware_revision;
+  grub_efi_uint32_t pad;
+  grub_efi_uint64_t console_in_handler;
+  grub_efi_uint64_t con_in;
+  grub_efi_uint64_t console_out_handler;
+  grub_efi_uint64_t con_out;
+  grub_efi_uint64_t standard_error_handle;
+  grub_efi_uint64_t std_err;
+  grub_efi_uint64_t runtime_services;
+  grub_efi_uint64_t boot_services;
+  grub_efi_uint64_t num_table_entries;
+  grub_efi_uint64_t configuration_table;
+} __attribute__ ((packed));
+typedef struct grub_efi_system_table64  grub_efi_system_table64_t;
+
+struct grub_efiemu_runtime_services32
+{
+  grub_efi_table_header_t hdr;
+  grub_efi_uint32_t get_time;
+  grub_efi_uint32_t set_time;
+  grub_efi_uint32_t get_wakeup_time;
+  grub_efi_uint32_t set_wakeup_time;
+  grub_efi_uint32_t set_virtual_address_map;
+  grub_efi_uint32_t convert_pointer;
+  grub_efi_uint32_t get_variable;
+  grub_efi_uint32_t get_next_variable_name;
+  grub_efi_uint32_t set_variable;
+  grub_efi_uint32_t get_next_high_monotonic_count;
+  grub_efi_uint32_t reset_system;
+} __attribute__ ((packed));
+typedef struct grub_efiemu_runtime_services32 grub_efiemu_runtime_services32_t;
+
+struct grub_efiemu_runtime_services64
+{
+  grub_efi_table_header_t hdr;
+  grub_efi_uint64_t get_time;
+  grub_efi_uint64_t set_time;
+  grub_efi_uint64_t get_wakeup_time;
+  grub_efi_uint64_t set_wakeup_time;
+  grub_efi_uint64_t set_virtual_address_map;
+  grub_efi_uint64_t convert_pointer;
+  grub_efi_uint64_t get_variable;
+  grub_efi_uint64_t get_next_variable_name;
+  grub_efi_uint64_t set_variable;
+  grub_efi_uint64_t get_next_high_monotonic_count;
+  grub_efi_uint64_t reset_system;
+} __attribute__ ((packed));
+typedef struct grub_efiemu_runtime_services64 grub_efiemu_runtime_services64_t;
+
+extern grub_efi_system_table32_t *grub_efiemu_system_table32;
+extern grub_efi_system_table64_t *grub_efiemu_system_table64;
+
+/* Convenience macros to access currently loaded efiemu */
+#define grub_efiemu_system_table ((grub_efiemu_sizeof_uintn_t () == 8) \
+				  ? (void *) grub_efiemu_system_table64 \
+				  : (void *) grub_efiemu_system_table32)
+#define GRUB_EFIEMU_SIZEOF_OF_UINTN (grub_efiemu_sizeof_uintn_t ())
+#define GRUB_EFIEMU_SYSTEM_TABLE(x) ((grub_efiemu_sizeof_uintn_t () == 8) \
+				     ? grub_efiemu_system_table64->x \
+				     : grub_efiemu_system_table32->x)
+#define GRUB_EFIEMU_SYSTEM_TABLE_SET(x,y) ((grub_efiemu_sizeof_uintn_t () == 8)\
+					   ? (grub_efiemu_system_table64->x \
+					      = (y)) \
+					   : (grub_efiemu_system_table32->x \
+					      = (y)))
+#define GRUB_EFIEMU_SYSTEM_TABLE_PTR(x) ((grub_efiemu_sizeof_uintn_t () == 8)\
+					 ? UINT_TO_PTR \
+					 (grub_efiemu_system_table64->x) \
+					 : UINT_TO_PTR \
+					 (grub_efiemu_system_table32->x))
+#define GRUB_EFIEMU_SYSTEM_TABLE_VAR(x) ((grub_efiemu_sizeof_uintn_t () == 8) \
+					 ? (void *) \
+					 &(grub_efiemu_system_table64->x) \
+					 : (void *) \
+					 &(grub_efiemu_system_table32->x))
+#define GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF(x) \
+  ((grub_efiemu_sizeof_uintn_t () == 8) \
+   ? sizeof(grub_efiemu_system_table64->x)\
+   : sizeof(grub_efiemu_system_table32->x))
+#define GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF_TOTAL ((grub_efiemu_sizeof_uintn_t () == 8) ? sizeof(*grub_efiemu_system_table64):sizeof(*grub_efiemu_system_table32))
+
+/* ELF management definitions and functions */
+
+struct grub_efiemu_segment
+{
+  struct grub_efiemu_segment *next;
+  grub_size_t size;
+  unsigned section;
+  int handle;
+  int ptv_rel_needed;
+  grub_off_t off;
+  void *srcptr;
+};
+typedef struct grub_efiemu_segment *grub_efiemu_segment_t;
+
+struct grub_efiemu_elf_sym
+{
+  int handle;
+  grub_off_t off;
+  unsigned section;
+};
+
+int grub_efiemu_check_header32 (void *ehdr, grub_size_t size);
+int grub_efiemu_check_header64 (void *ehdr, grub_size_t size);
+grub_err_t grub_efiemu_loadcore_init32 (void *core, grub_size_t core_size,
+					grub_efiemu_segment_t *segments);
+grub_err_t grub_efiemu_loadcore_init64 (void *core, grub_size_t core_size,
+					grub_efiemu_segment_t *segments);
+grub_err_t grub_efiemu_loadcore_load32 (void *core,
+					grub_size_t core_size,
+					grub_efiemu_segment_t segments);
+grub_err_t grub_efiemu_loadcore_load64 (void *core,
+					grub_size_t core_size,
+					grub_efiemu_segment_t segments);
+grub_err_t grub_efiemu_loadcore_unload32 (void);
+grub_err_t grub_efiemu_loadcore_unload64 (void);
+grub_err_t grub_efiemu_loadcore_unload(void);
+grub_err_t grub_efiemu_loadcore_init (grub_file_t file);
+grub_err_t grub_efiemu_loadcore_load (void);
+
+/* Configuration tables manipulation. Definitions and functions */
+struct grub_efiemu_configuration_table
+{
+  struct grub_efiemu_configuration_table *next;
+  grub_efi_guid_t guid;
+  void * (*get_table) (void *data);
+  void (*unload) (void *data);
+  void *data;
+};
+struct grub_efiemu_configuration_table32
+{
+  grub_efi_guid_t vendor_guid;
+  grub_efi_uint32_t vendor_table;
+} __attribute__ ((packed));
+typedef struct grub_efiemu_configuration_table32 grub_efiemu_configuration_table32_t;
+struct grub_efiemu_configuration_table64
+{
+  grub_efi_guid_t vendor_guid;
+  grub_efi_uint64_t vendor_table;
+} __attribute__ ((packed));
+typedef struct grub_efiemu_configuration_table64 grub_efiemu_configuration_table64_t;
+grub_err_t grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid);
+grub_err_t
+grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
+					  void * (*get_table) (void *data),
+					  void (*unload) (void *data),
+					  void *data);
+
+/* Memory management functions */
+int grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
+				  grub_efi_memory_type_t type);
+void *grub_efiemu_mm_obtain_request (int handle);
+int grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
+				grub_efi_memory_descriptor_t *memory_map,
+				grub_efi_uintn_t *map_key,
+				grub_efi_uintn_t *descriptor_size,
+				grub_efi_uint32_t *descriptor_version);
+grub_err_t grub_efiemu_mm_unload (void);
+grub_err_t grub_efiemu_mm_do_alloc (void);
+grub_err_t grub_efiemu_mm_init (void);
+void *grub_efiemu_mm_obtain_request (int handle);
+void grub_efiemu_mm_return_request (int handle);
+grub_efi_memory_type_t grub_efiemu_mm_get_type (int handle);
+
+/* Drop-in replacements for grub_efi_* and grub_machine_* */
+int grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
+				grub_efi_memory_descriptor_t *memory_map,
+				grub_efi_uintn_t *map_key,
+				grub_efi_uintn_t *descriptor_size,
+				grub_efi_uint32_t *descriptor_version);
+grub_err_t
+grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+							grub_uint64_t,
+							grub_uint32_t));
+int grub_efiemu_sizeof_uintn_t (void);
+int grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key);
+int grub_efiemu_finish_boot_services (void);
+grub_err_t
+grub_efiemu_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper);
+#define GRUB_EFIEMU_MEMORY_AVAILABLE	1
+#define GRUB_EFIEMU_MEMORY_RESERVED	2
+#define GRUB_EFIEMU_MEMORY_ACPI	3
+#define GRUB_EFIEMU_MEMORY_NVS         4
+#define GRUB_EFIEMU_MEMORY_CODE         5
+
+/* efiemu main control definitions and functions*/
+typedef enum {GRUB_EFIEMU_NOTLOADED,
+	      GRUB_EFIEMU32, GRUB_EFIEMU64} grub_efiemu_mode_t;
+struct grub_efiemu_prepare_hook
+{
+  struct grub_efiemu_prepare_hook *next;
+  grub_err_t (*hook) (void *data);
+  void (*unload) (void *data);
+  void *data;
+};
+grub_err_t grub_efiemu_prepare32 (struct grub_efiemu_prepare_hook
+				  *prepare_hooks,
+				  struct grub_efiemu_configuration_table
+				  *config_tables);
+grub_err_t grub_efiemu_prepare64 (struct grub_efiemu_prepare_hook
+				  *prepare_hooks,
+				  struct grub_efiemu_configuration_table
+				  *config_tables);
+grub_err_t grub_efiemu_unload (void);
+grub_err_t grub_efiemu_prepare (void);
+grub_err_t
+grub_efiemu_register_prepare_hook (grub_err_t (*hook) (void *data),
+				   void (*unload) (void *data),
+				   void *data);
+
+/* symbols and pointers */
+grub_err_t grub_efiemu_alloc_syms (void);
+grub_err_t grub_efiemu_request_symbols (int num);
+grub_err_t grub_efiemu_resolve_symbol (const char *name,
+				       int *handle, grub_off_t *off);
+grub_err_t grub_efiemu_register_symbol (const char *name,
+					int handle, grub_off_t off);
+void grub_efiemu_free_syms (void);
+grub_err_t grub_efiemu_write_value (void * addr, grub_uint32_t value,
+				    int plus_handle,
+				    int minus_handle, int ptv_needed, int size);
+grub_err_t grub_efiemu_pnvram (void);
+grub_err_t grub_efiemu_prepare (void);
+char *grub_efiemu_get_default_core_name (void);
+void grub_efiemu_pnvram_cmd_unregister (void);
+grub_err_t grub_efiemu_autocore (void);
+#endif /* ! GRUB_EFI_EMU_HEADER */
diff --git a/include/grub/efiemu/runtime.h b/include/grub/efiemu/runtime.h
new file mode 100644
index 0000000..1eb474a
--- /dev/null
+++ b/include/grub/efiemu/runtime.h
@@ -0,0 +1,37 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_EMU_RUNTIME_HEADER
+#define GRUB_EFI_EMU_RUNTIME_HEADER	1
+
+struct grub_efiemu_ptv_rel
+{
+  grub_uint64_t addr;
+  grub_efi_memory_type_t plustype;
+  grub_efi_memory_type_t minustype;
+  grub_uint32_t size;
+} __attribute__ ((packed));
+
+struct efi_variable
+{
+  grub_efi_guid_t guid;
+  grub_uint32_t namelen;
+  grub_uint32_t size;
+  grub_efi_uint32_t attributes;
+} __attribute__ ((packed));
+#endif /* ! GRUB_EFI_EMU_RUNTIME_HEADER */
diff --git a/include/grub/elf.h b/include/grub/elf.h
new file mode 100644
index 0000000..1a1ec13
--- /dev/null
+++ b/include/grub/elf.h
@@ -0,0 +1,2377 @@
+/* This file defines standard ELF types, structures, and macros.
+   Copyright (C) 1995-1999, 2000, 2001, 2002,2008 Free Software Foundation, Inc.
+   This file was 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef GRUB_ELF_H
+#define	GRUB_ELF_H 1
+
+/* Standard ELF types.  */
+
+#include <grub/types.h>
+
+/* Type for a 16-bit quantity.  */
+typedef grub_uint16_t Elf32_Half;
+typedef grub_uint16_t Elf64_Half;
+
+/* Types for signed and unsigned 32-bit quantities.  */
+typedef grub_uint32_t Elf32_Word;
+typedef	grub_int32_t  Elf32_Sword;
+typedef grub_uint32_t Elf64_Word;
+typedef	grub_int32_t  Elf64_Sword;
+
+/* Types for signed and unsigned 64-bit quantities.  */
+typedef grub_uint64_t Elf32_Xword;
+typedef	grub_int64_t  Elf32_Sxword;
+typedef grub_uint64_t Elf64_Xword;
+typedef	grub_int64_t  Elf64_Sxword;
+
+/* Type of addresses.  */
+typedef grub_uint32_t Elf32_Addr;
+typedef grub_uint64_t Elf64_Addr;
+
+/* Type of file offsets.  */
+typedef grub_uint32_t Elf32_Off;
+typedef grub_uint64_t Elf64_Off;
+
+/* Type for section indices, which are 16-bit quantities.  */
+typedef grub_uint16_t Elf32_Section;
+typedef grub_uint16_t Elf64_Section;
+
+/* Type for version symbol information.  */
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+
+/* The ELF file header.  This appears at the start of every ELF file.  */
+
+#define EI_NIDENT (16)
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf32_Half	e_type;			/* Object file type */
+  Elf32_Half	e_machine;		/* Architecture */
+  Elf32_Word	e_version;		/* Object file version */
+  Elf32_Addr	e_entry;		/* Entry point virtual address */
+  Elf32_Off	e_phoff;		/* Program header table file offset */
+  Elf32_Off	e_shoff;		/* Section header table file offset */
+  Elf32_Word	e_flags;		/* Processor-specific flags */
+  Elf32_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf32_Half	e_phentsize;		/* Program header table entry size */
+  Elf32_Half	e_phnum;		/* Program header table entry count */
+  Elf32_Half	e_shentsize;		/* Section header table entry size */
+  Elf32_Half	e_shnum;		/* Section header table entry count */
+  Elf32_Half	e_shstrndx;		/* Section header string table index */
+} Elf32_Ehdr;
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf64_Half	e_type;			/* Object file type */
+  Elf64_Half	e_machine;		/* Architecture */
+  Elf64_Word	e_version;		/* Object file 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 */
+  Elf64_Word	e_flags;		/* Processor-specific flags */
+  Elf64_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf64_Half	e_phentsize;		/* Program header table entry size */
+  Elf64_Half	e_phnum;		/* Program header table entry count */
+  Elf64_Half	e_shentsize;		/* Section header table entry size */
+  Elf64_Half	e_shnum;		/* Section header table entry count */
+  Elf64_Half	e_shstrndx;		/* Section header string table index */
+} Elf64_Ehdr;
+
+/* Fields in the e_ident array.  The EI_* macros are indices into the
+   array.  The macros under each EI_* macro are the values the byte
+   may have.  */
+
+#define EI_MAG0		0		/* File identification byte 0 index */
+#define ELFMAG0		0x7f		/* Magic number byte 0 */
+
+#define EI_MAG1		1		/* File identification byte 1 index */
+#define ELFMAG1		'E'		/* Magic number byte 1 */
+
+#define EI_MAG2		2		/* File identification byte 2 index */
+#define ELFMAG2		'L'		/* Magic number byte 2 */
+
+#define EI_MAG3		3		/* File identification byte 3 index */
+#define ELFMAG3		'F'		/* Magic number byte 3 */
+
+/* Conglomeration of the identification bytes, for easy testing as a word.  */
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+#define EI_CLASS	4		/* File class byte index */
+#define ELFCLASSNONE	0		/* Invalid class */
+#define ELFCLASS32	1		/* 32-bit objects */
+#define ELFCLASS64	2		/* 64-bit objects */
+#define ELFCLASSNUM	3
+
+#define EI_DATA		5		/* Data encoding byte index */
+#define ELFDATANONE	0		/* Invalid data encoding */
+#define ELFDATA2LSB	1		/* 2's complement, little endian */
+#define ELFDATA2MSB	2		/* 2's complement, big endian */
+#define ELFDATANUM	3
+
+#define EI_VERSION	6		/* File version byte index */
+					/* Value must be EV_CURRENT */
+
+#define EI_OSABI	7		/* OS ABI identification */
+#define ELFOSABI_NONE		0	/* UNIX System V ABI */
+#define ELFOSABI_SYSV		0	/* Alias.  */
+#define ELFOSABI_HPUX		1	/* HP-UX */
+#define ELFOSABI_NETBSD		2	/* NetBSD.  */
+#define ELFOSABI_LINUX		3	/* Linux.  */
+#define ELFOSABI_SOLARIS	6	/* Sun Solaris.  */
+#define ELFOSABI_AIX		7	/* IBM AIX.  */
+#define ELFOSABI_IRIX		8	/* SGI Irix.  */
+#define ELFOSABI_FREEBSD	9	/* FreeBSD.  */
+#define ELFOSABI_TRU64		10	/* Compaq TRU64 UNIX.  */
+#define ELFOSABI_MODESTO	11	/* Novell Modesto.  */
+#define ELFOSABI_OPENBSD	12	/* OpenBSD.  */
+#define ELFOSABI_ARM		97	/* ARM */
+#define ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
+
+#define EI_ABIVERSION	8		/* ABI version */
+
+#define EI_PAD		9		/* Byte index of padding bytes */
+
+/* Legal values for e_type (object file type).  */
+
+#define ET_NONE		0		/* No file type */
+#define ET_REL		1		/* Relocatable file */
+#define ET_EXEC		2		/* Executable file */
+#define ET_DYN		3		/* Shared object file */
+#define ET_CORE		4		/* Core file */
+#define	ET_NUM		5		/* Number of defined types */
+#define ET_LOOS		0xfe00		/* OS-specific range start */
+#define ET_HIOS		0xfeff		/* OS-specific range end */
+#define ET_LOPROC	0xff00		/* Processor-specific range start */
+#define ET_HIPROC	0xffff		/* Processor-specific range end */
+
+/* Legal values for e_machine (architecture).  */
+
+#define EM_NONE		 0		/* No machine */
+#define EM_M32		 1		/* AT&T WE 32100 */
+#define EM_SPARC	 2		/* SUN SPARC */
+#define EM_386		 3		/* Intel 80386 */
+#define EM_68K		 4		/* Motorola m68k family */
+#define EM_88K		 5		/* Motorola m88k family */
+#define EM_860		 7		/* Intel 80860 */
+#define EM_MIPS		 8		/* MIPS R3000 big-endian */
+#define EM_S370		 9		/* IBM System/370 */
+#define EM_MIPS_RS3_LE	10		/* MIPS R3000 little-endian */
+
+#define EM_PARISC	15		/* HPPA */
+#define EM_VPP500	17		/* Fujitsu VPP500 */
+#define EM_SPARC32PLUS	18		/* Sun's "v8plus" */
+#define EM_960		19		/* Intel 80960 */
+#define EM_PPC		20		/* PowerPC */
+#define EM_PPC64	21		/* PowerPC 64-bit */
+#define EM_S390		22		/* IBM S390 */
+
+#define EM_V800		36		/* NEC V800 series */
+#define EM_FR20		37		/* Fujitsu FR20 */
+#define EM_RH32		38		/* TRW RH-32 */
+#define EM_RCE		39		/* Motorola RCE */
+#define EM_ARM		40		/* ARM */
+#define EM_FAKE_ALPHA	41		/* Digital Alpha */
+#define EM_SH		42		/* Hitachi SH */
+#define EM_SPARCV9	43		/* SPARC v9 64-bit */
+#define EM_TRICORE	44		/* Siemens Tricore */
+#define EM_ARC		45		/* Argonaut RISC Core */
+#define EM_H8_300	46		/* Hitachi H8/300 */
+#define EM_H8_300H	47		/* Hitachi H8/300H */
+#define EM_H8S		48		/* Hitachi H8S */
+#define EM_H8_500	49		/* Hitachi H8/500 */
+#define EM_IA_64	50		/* Intel Merced */
+#define EM_MIPS_X	51		/* Stanford MIPS-X */
+#define EM_COLDFIRE	52		/* Motorola Coldfire */
+#define EM_68HC12	53		/* Motorola M68HC12 */
+#define EM_MMA		54		/* Fujitsu MMA Multimedia Accelerator*/
+#define EM_PCP		55		/* Siemens PCP */
+#define EM_NCPU		56		/* Sony nCPU embedded RISC */
+#define EM_NDR1		57		/* Denso NDR1 microprocessor */
+#define EM_STARCORE	58		/* Motorola Start*Core processor */
+#define EM_ME16		59		/* Toyota ME16 processor */
+#define EM_ST100	60		/* STMicroelectronics ST100 processor */
+#define EM_TINYJ	61		/* Advanced Logic Corp. Tinyj emb.fam*/
+#define EM_X86_64	62		/* AMD x86-64 architecture */
+#define EM_PDSP		63		/* Sony DSP Processor */
+
+#define EM_FX66		66		/* Siemens FX66 microcontroller */
+#define EM_ST9PLUS	67		/* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7		68		/* STMicroelectronics ST7 8 bit mc */
+#define EM_68HC16	69		/* Motorola MC68HC16 microcontroller */
+#define EM_68HC11	70		/* Motorola MC68HC11 microcontroller */
+#define EM_68HC08	71		/* Motorola MC68HC08 microcontroller */
+#define EM_68HC05	72		/* Motorola MC68HC05 microcontroller */
+#define EM_SVX		73		/* Silicon Graphics SVx */
+#define EM_AT19		74		/* STMicroelectronics ST19 8 bit mc */
+#define EM_VAX		75		/* Digital VAX */
+#define EM_CRIS		76		/* Axis Communications 32-bit embedded processor */
+#define EM_JAVELIN	77		/* Infineon Technologies 32-bit embedded processor */
+#define EM_FIREPATH	78		/* Element 14 64-bit DSP Processor */
+#define EM_ZSP		79		/* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX		80		/* Donald Knuth's educational 64-bit processor */
+#define EM_HUANY	81		/* Harvard University machine-independent object files */
+#define EM_PRISM	82		/* SiTera Prism */
+#define EM_AVR		83		/* Atmel AVR 8-bit microcontroller */
+#define EM_FR30		84		/* Fujitsu FR30 */
+#define EM_D10V		85		/* Mitsubishi D10V */
+#define EM_D30V		86		/* Mitsubishi D30V */
+#define EM_V850		87		/* NEC v850 */
+#define EM_M32R		88		/* Mitsubishi M32R */
+#define EM_MN10300	89		/* Matsushita MN10300 */
+#define EM_MN10200	90		/* Matsushita MN10200 */
+#define EM_PJ		91		/* picoJava */
+#define EM_OPENRISC	92		/* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5	93		/* ARC Cores Tangent-A5 */
+#define EM_XTENSA	94		/* Tensilica Xtensa Architecture */
+#define EM_NUM		95
+
+/* If it is necessary to assign new unofficial EM_* values, please
+   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+   chances of collision with official or non-GNU unofficial values.  */
+
+#define EM_ALPHA	0x9026
+
+/* Legal values for e_version (version).  */
+
+#define EV_NONE		0		/* Invalid ELF version */
+#define EV_CURRENT	1		/* Current version */
+#define EV_NUM		2
+
+/* Section header.  */
+
+typedef struct
+{
+  Elf32_Word	sh_name;		/* Section name (string tbl index) */
+  Elf32_Word	sh_type;		/* Section type */
+  Elf32_Word	sh_flags;		/* Section flags */
+  Elf32_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf32_Off	sh_offset;		/* Section file offset */
+  Elf32_Word	sh_size;		/* Section size in bytes */
+  Elf32_Word	sh_link;		/* Link to another section */
+  Elf32_Word	sh_info;		/* Additional section information */
+  Elf32_Word	sh_addralign;		/* Section alignment */
+  Elf32_Word	sh_entsize;		/* Entry size if section holds table */
+} Elf32_Shdr;
+
+typedef struct
+{
+  Elf64_Word	sh_name;		/* Section name (string tbl index) */
+  Elf64_Word	sh_type;		/* Section type */
+  Elf64_Xword	sh_flags;		/* Section flags */
+  Elf64_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf64_Off	sh_offset;		/* Section file offset */
+  Elf64_Xword	sh_size;		/* Section size in bytes */
+  Elf64_Word	sh_link;		/* Link to another section */
+  Elf64_Word	sh_info;		/* Additional section information */
+  Elf64_Xword	sh_addralign;		/* Section alignment */
+  Elf64_Xword	sh_entsize;		/* Entry size if section holds table */
+} Elf64_Shdr;
+
+/* Special section indices.  */
+
+#define SHN_UNDEF	0		/* Undefined section */
+#define SHN_LORESERVE	0xff00		/* Start of reserved indices */
+#define SHN_LOPROC	0xff00		/* Start of processor-specific */
+#define SHN_HIPROC	0xff1f		/* End of processor-specific */
+#define SHN_LOOS	0xff20		/* Start of OS-specific */
+#define SHN_HIOS	0xff3f		/* End of OS-specific */
+#define SHN_ABS		0xfff1		/* Associated symbol is absolute */
+#define SHN_COMMON	0xfff2		/* Associated symbol is common */
+#define SHN_XINDEX	0xffff		/* Index is in extra table.  */
+#define SHN_HIRESERVE	0xffff		/* End of reserved indices */
+
+/* Legal values for sh_type (section type).  */
+
+#define SHT_NULL	  0		/* Section header table entry unused */
+#define SHT_PROGBITS	  1		/* Program data */
+#define SHT_SYMTAB	  2		/* Symbol table */
+#define SHT_STRTAB	  3		/* String table */
+#define SHT_RELA	  4		/* Relocation entries with addends */
+#define SHT_HASH	  5		/* Symbol hash table */
+#define SHT_DYNAMIC	  6		/* Dynamic linking information */
+#define SHT_NOTE	  7		/* Notes */
+#define SHT_NOBITS	  8		/* Program space with no data (bss) */
+#define SHT_REL		  9		/* Relocation entries, no addends */
+#define SHT_SHLIB	  10		/* Reserved */
+#define SHT_DYNSYM	  11		/* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY	  14		/* Array of constructors */
+#define SHT_FINI_ARRAY	  15		/* Array of destructors */
+#define SHT_PREINIT_ARRAY 16		/* Array of pre-constructors */
+#define SHT_GROUP	  17		/* Section group */
+#define SHT_SYMTAB_SHNDX  18		/* Extended section indices */
+#define	SHT_NUM		  19		/* Number of defined types.  */
+#define SHT_LOOS	  0x60000000	/* Start OS-specific */
+#define SHT_GNU_LIBLIST	  0x6ffffff7	/* Prelink library list */
+#define SHT_CHECKSUM	  0x6ffffff8	/* Checksum for DSO content.  */
+#define SHT_LOSUNW	  0x6ffffffa	/* Sun-specific low bound.  */
+#define SHT_SUNW_move	  0x6ffffffa
+#define SHT_SUNW_COMDAT   0x6ffffffb
+#define SHT_SUNW_syminfo  0x6ffffffc
+#define SHT_GNU_verdef	  0x6ffffffd	/* Version definition section.  */
+#define SHT_GNU_verneed	  0x6ffffffe	/* Version needs section.  */
+#define SHT_GNU_versym	  0x6fffffff	/* Version symbol table.  */
+#define SHT_HISUNW	  0x6fffffff	/* Sun-specific high bound.  */
+#define SHT_HIOS	  0x6fffffff	/* End OS-specific type */
+#define SHT_LOPROC	  0x70000000	/* Start of processor-specific */
+#define SHT_HIPROC	  0x7fffffff	/* End of processor-specific */
+#define SHT_LOUSER	  0x80000000	/* Start of application-specific */
+#define SHT_HIUSER	  0x8fffffff	/* End of application-specific */
+
+/* Legal values for sh_flags (section flags).  */
+
+#define SHF_WRITE	     (1 << 0)	/* Writable */
+#define SHF_ALLOC	     (1 << 1)	/* Occupies memory during execution */
+#define SHF_EXECINSTR	     (1 << 2)	/* Executable */
+#define SHF_MERGE	     (1 << 4)	/* Might be merged */
+#define SHF_STRINGS	     (1 << 5)	/* Contains nul-terminated strings */
+#define SHF_INFO_LINK	     (1 << 6)	/* `sh_info' contains SHT index */
+#define SHF_LINK_ORDER	     (1 << 7)	/* Preserve order after combining */
+#define SHF_OS_NONCONFORMING (1 << 8)	/* Non-standard OS specific handling
+					   required */
+#define SHF_GROUP	     (1 << 9)	/* Section is member of a group.  */
+#define SHF_TLS		     (1 << 10)	/* Section hold thread-local data.  */
+#define SHF_MASKOS	     0x0ff00000	/* OS-specific.  */
+#define SHF_MASKPROC	     0xf0000000	/* Processor-specific */
+
+/* Section group handling.  */
+#define GRP_COMDAT	0x1		/* Mark group as COMDAT.  */
+
+/* Symbol table entry.  */
+
+typedef struct
+{
+  Elf32_Word	st_name;		/* Symbol name (string tbl index) */
+  Elf32_Addr	st_value;		/* Symbol value */
+  Elf32_Word	st_size;		/* Symbol size */
+  unsigned char	st_info;		/* Symbol type and binding */
+  unsigned char	st_other;		/* Symbol visibility */
+  Elf32_Section	st_shndx;		/* Section index */
+} Elf32_Sym;
+
+typedef struct
+{
+  Elf64_Word	st_name;		/* Symbol name (string tbl index) */
+  unsigned char	st_info;		/* Symbol type and binding */
+  unsigned char st_other;		/* Symbol visibility */
+  Elf64_Section	st_shndx;		/* Section index */
+  Elf64_Addr	st_value;		/* Symbol value */
+  Elf64_Xword	st_size;		/* Symbol size */
+} Elf64_Sym;
+
+/* The syminfo section if available contains additional information about
+   every dynamic symbol.  */
+
+typedef struct
+{
+  Elf32_Half si_boundto;		/* Direct bindings, symbol bound to */
+  Elf32_Half si_flags;			/* Per symbol flags */
+} Elf32_Syminfo;
+
+typedef struct
+{
+  Elf64_Half si_boundto;		/* Direct bindings, symbol bound to */
+  Elf64_Half si_flags;			/* Per symbol flags */
+} Elf64_Syminfo;
+
+/* Possible values for si_boundto.  */
+#define SYMINFO_BT_SELF		0xffff	/* Symbol bound to self */
+#define SYMINFO_BT_PARENT	0xfffe	/* Symbol bound to parent */
+#define SYMINFO_BT_LOWRESERVE	0xff00	/* Beginning of reserved entries */
+
+/* Possible bitmasks for si_flags.  */
+#define SYMINFO_FLG_DIRECT	0x0001	/* Direct bound symbol */
+#define SYMINFO_FLG_PASSTHRU	0x0002	/* Pass-thru symbol for translator */
+#define SYMINFO_FLG_COPY	0x0004	/* Symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD	0x0008	/* Symbol bound to object to be lazy
+					   loaded */
+/* Syminfo version values.  */
+#define SYMINFO_NONE		0
+#define SYMINFO_CURRENT		1
+#define SYMINFO_NUM		2
+
+
+/* How to extract and insert information held in the st_info field.  */
+
+#define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)		((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)	(((bind) << 4) + ((type) & 0xf))
+
+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
+#define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type)	ELF32_ST_INFO ((bind), (type))
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
+
+#define STB_LOCAL	0		/* Local symbol */
+#define STB_GLOBAL	1		/* Global symbol */
+#define STB_WEAK	2		/* Weak symbol */
+#define	STB_NUM		3		/* Number of defined types.  */
+#define STB_LOOS	10		/* Start of OS-specific */
+#define STB_HIOS	12		/* End of OS-specific */
+#define STB_LOPROC	13		/* Start of processor-specific */
+#define STB_HIPROC	15		/* End of processor-specific */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_NOTYPE	0		/* Symbol type is unspecified */
+#define STT_OBJECT	1		/* Symbol is a data object */
+#define STT_FUNC	2		/* Symbol is a code object */
+#define STT_SECTION	3		/* Symbol associated with a section */
+#define STT_FILE	4		/* Symbol's name is file name */
+#define STT_COMMON	5		/* Symbol is a common data object */
+#define STT_TLS		6		/* Symbol is thread-local data object*/
+#define	STT_NUM		7		/* Number of defined types.  */
+#define STT_LOOS	10		/* Start of OS-specific */
+#define STT_HIOS	12		/* End of OS-specific */
+#define STT_LOPROC	13		/* Start of processor-specific */
+#define STT_HIPROC	15		/* End of processor-specific */
+
+
+/* Symbol table indices are found in the hash buckets and chain table
+   of a symbol hash table section.  This special index value indicates
+   the end of a chain, meaning no further symbols are found in that bucket.  */
+
+#define STN_UNDEF	0		/* End of a chain.  */
+#define STN_ABS		65521
+
+
+/* How to extract and insert information held in the st_other field.  */
+
+#define ELF32_ST_VISIBILITY(o)	((o) & 0x03)
+
+/* For ELF64 the definitions are the same.  */
+#define ELF64_ST_VISIBILITY(o)	ELF32_ST_VISIBILITY (o)
+
+/* Symbol visibility specification encoded in the st_other field.  */
+#define STV_DEFAULT	0		/* Default symbol visibility rules */
+#define STV_INTERNAL	1		/* Processor specific hidden class */
+#define STV_HIDDEN	2		/* Sym unavailable in other modules */
+#define STV_PROTECTED	3		/* Not preemptible, not exported */
+
+
+/* Relocation table entry without addend (in section of type SHT_REL).  */
+
+typedef struct
+{
+  Elf32_Addr	r_offset;		/* Address */
+  Elf32_Word	r_info;			/* Relocation type and symbol index */
+} Elf32_Rel;
+
+/* I have seen two different definitions of the Elf64_Rel and
+   Elf64_Rela structures, so we'll leave them out until Novell (or
+   whoever) gets their act together.  */
+/* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  Elf64_Xword	r_info;			/* Relocation type and symbol index */
+} Elf64_Rel;
+
+/* Relocation table entry with addend (in section of type SHT_RELA).  */
+
+typedef struct
+{
+  Elf32_Addr	r_offset;		/* Address */
+  Elf32_Word	r_info;			/* Relocation type and symbol index */
+  Elf32_Sword	r_addend;		/* Addend */
+} Elf32_Rela;
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  Elf64_Xword	r_info;			/* Relocation type and symbol index */
+  Elf64_Sxword	r_addend;		/* Addend */
+} Elf64_Rela;
+
+/* How to extract and insert information held in the r_info field.  */
+
+#define ELF32_R_SYM(val)		((val) >> 8)
+#define ELF32_R_TYPE(val)		((val) & 0xff)
+#define ELF32_R_INFO(sym, type)		(((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i)			((i) >> 32)
+#define ELF64_R_TYPE(i)			((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type)		((((Elf64_Xword) (sym)) << 32) + (type))
+
+/* Program segment header.  */
+
+typedef struct
+{
+  Elf32_Word	p_type;			/* Segment type */
+  Elf32_Off	p_offset;		/* Segment file offset */
+  Elf32_Addr	p_vaddr;		/* Segment virtual address */
+  Elf32_Addr	p_paddr;		/* Segment physical address */
+  Elf32_Word	p_filesz;		/* Segment size in file */
+  Elf32_Word	p_memsz;		/* Segment size in memory */
+  Elf32_Word	p_flags;		/* Segment flags */
+  Elf32_Word	p_align;		/* Segment alignment */
+} Elf32_Phdr;
+
+typedef struct
+{
+  Elf64_Word	p_type;			/* Segment type */
+  Elf64_Word	p_flags;		/* Segment flags */
+  Elf64_Off	p_offset;		/* Segment file offset */
+  Elf64_Addr	p_vaddr;		/* Segment virtual address */
+  Elf64_Addr	p_paddr;		/* Segment physical address */
+  Elf64_Xword	p_filesz;		/* Segment size in file */
+  Elf64_Xword	p_memsz;		/* Segment size in memory */
+  Elf64_Xword	p_align;		/* Segment alignment */
+} Elf64_Phdr;
+
+/* Legal values for p_type (segment type).  */
+
+#define	PT_NULL		0		/* Program header table entry unused */
+#define PT_LOAD		1		/* Loadable program segment */
+#define PT_DYNAMIC	2		/* Dynamic linking information */
+#define PT_INTERP	3		/* Program interpreter */
+#define PT_NOTE		4		/* Auxiliary information */
+#define PT_SHLIB	5		/* Reserved */
+#define PT_PHDR		6		/* Entry for header table itself */
+#define PT_TLS		7		/* Thread-local storage segment */
+#define	PT_NUM		8		/* Number of defined types */
+#define PT_LOOS		0x60000000	/* Start of OS-specific */
+#define PT_GNU_EH_FRAME	0x6474e550	/* GCC .eh_frame_hdr segment */
+#define PT_LOSUNW	0x6ffffffa
+#define PT_SUNWBSS	0x6ffffffa	/* Sun Specific segment */
+#define PT_SUNWSTACK	0x6ffffffb	/* Stack segment */
+#define PT_HISUNW	0x6fffffff
+#define PT_HIOS		0x6fffffff	/* End of OS-specific */
+#define PT_LOPROC	0x70000000	/* Start of processor-specific */
+#define PT_HIPROC	0x7fffffff	/* End of processor-specific */
+
+/* Legal values for p_flags (segment flags).  */
+
+#define PF_X		(1 << 0)	/* Segment is executable */
+#define PF_W		(1 << 1)	/* Segment is writable */
+#define PF_R		(1 << 2)	/* Segment is readable */
+#define PF_MASKOS	0x0ff00000	/* OS-specific */
+#define PF_MASKPROC	0xf0000000	/* Processor-specific */
+
+/* Legal values for note segment descriptor types for core files. */
+
+#define NT_PRSTATUS	1		/* Contains copy of prstatus struct */
+#define NT_FPREGSET	2		/* Contains copy of fpregset struct */
+#define NT_PRPSINFO	3		/* Contains copy of prpsinfo struct */
+#define NT_PRXREG	4		/* Contains copy of prxregset struct */
+#define NT_PLATFORM	5		/* String from sysinfo(SI_PLATFORM) */
+#define NT_AUXV		6		/* Contains copy of auxv array */
+#define NT_GWINDOWS	7		/* Contains copy of gwindows struct */
+#define NT_ASRS		8		/* Contains copy of asrset struct */
+#define NT_PSTATUS	10		/* Contains copy of pstatus struct */
+#define NT_PSINFO	13		/* Contains copy of psinfo struct */
+#define NT_PRCRED	14		/* Contains copy of prcred struct */
+#define NT_UTSNAME	15		/* Contains copy of utsname struct */
+#define NT_LWPSTATUS	16		/* Contains copy of lwpstatus struct */
+#define NT_LWPSINFO	17		/* Contains copy of lwpinfo struct */
+#define NT_PRFPXREG	20		/* Contains copy of fprxregset struct*/
+
+/* Legal values for the note segment descriptor types for object files.  */
+
+#define NT_VERSION	1		/* Contains a version string.  */
+
+
+/* Dynamic section entry.  */
+
+typedef struct
+{
+  Elf32_Sword	d_tag;			/* Dynamic entry type */
+  union
+    {
+      Elf32_Word d_val;			/* Integer value */
+      Elf32_Addr d_ptr;			/* Address value */
+    } d_un;
+} Elf32_Dyn;
+
+typedef struct
+{
+  Elf64_Sxword	d_tag;			/* Dynamic entry type */
+  union
+    {
+      Elf64_Xword d_val;		/* Integer value */
+      Elf64_Addr d_ptr;			/* Address value */
+    } d_un;
+} Elf64_Dyn;
+
+/* Legal values for d_tag (dynamic entry type).  */
+
+#define DT_NULL		0		/* Marks end of dynamic section */
+#define DT_NEEDED	1		/* Name of needed library */
+#define DT_PLTRELSZ	2		/* Size in bytes of PLT relocs */
+#define DT_PLTGOT	3		/* Processor defined value */
+#define DT_HASH		4		/* Address of symbol hash table */
+#define DT_STRTAB	5		/* Address of string table */
+#define DT_SYMTAB	6		/* Address of symbol table */
+#define DT_RELA		7		/* Address of Rela relocs */
+#define DT_RELASZ	8		/* Total size of Rela relocs */
+#define DT_RELAENT	9		/* Size of one Rela reloc */
+#define DT_STRSZ	10		/* Size of string table */
+#define DT_SYMENT	11		/* Size of one symbol table entry */
+#define DT_INIT		12		/* Address of init function */
+#define DT_FINI		13		/* Address of termination function */
+#define DT_SONAME	14		/* Name of shared object */
+#define DT_RPATH	15		/* Library search path (deprecated) */
+#define DT_SYMBOLIC	16		/* Start symbol search here */
+#define DT_REL		17		/* Address of Rel relocs */
+#define DT_RELSZ	18		/* Total size of Rel relocs */
+#define DT_RELENT	19		/* Size of one Rel reloc */
+#define DT_PLTREL	20		/* Type of reloc in PLT */
+#define DT_DEBUG	21		/* For debugging; unspecified */
+#define DT_TEXTREL	22		/* Reloc might modify .text */
+#define DT_JMPREL	23		/* Address of PLT relocs */
+#define	DT_BIND_NOW	24		/* Process relocations of object */
+#define	DT_INIT_ARRAY	25		/* Array with addresses of init fct */
+#define	DT_FINI_ARRAY	26		/* Array with addresses of fini fct */
+#define	DT_INIT_ARRAYSZ	27		/* Size in bytes of DT_INIT_ARRAY */
+#define	DT_FINI_ARRAYSZ	28		/* Size in bytes of DT_FINI_ARRAY */
+#define DT_RUNPATH	29		/* Library search path */
+#define DT_FLAGS	30		/* Flags for the object being loaded */
+#define DT_ENCODING	32		/* Start of encoded range */
+#define DT_PREINIT_ARRAY 32		/* Array with addresses of preinit fct*/
+#define DT_PREINIT_ARRAYSZ 33		/* size in bytes of DT_PREINIT_ARRAY */
+#define	DT_NUM		34		/* Number used */
+#define DT_LOOS		0x6000000d	/* Start of OS-specific */
+#define DT_HIOS		0x6ffff000	/* End of OS-specific */
+#define DT_LOPROC	0x70000000	/* Start of processor-specific */
+#define DT_HIPROC	0x7fffffff	/* End of processor-specific */
+#define	DT_PROCNUM	DT_MIPS_NUM	/* Most used by any processor */
+
+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+   Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
+   approach.  */
+#define DT_VALRNGLO	0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5	/* Prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6	/* Size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7	/* Size of library list */
+#define DT_CHECKSUM	0x6ffffdf8
+#define DT_PLTPADSZ	0x6ffffdf9
+#define DT_MOVEENT	0x6ffffdfa
+#define DT_MOVESZ	0x6ffffdfb
+#define DT_FEATURE_1	0x6ffffdfc	/* Feature selection (DTF_*).  */
+#define DT_POSFLAG_1	0x6ffffdfd	/* Flags for DT_* entries, effecting
+					   the following DT_* entry.  */
+#define DT_SYMINSZ	0x6ffffdfe	/* Size of syminfo table (in bytes) */
+#define DT_SYMINENT	0x6ffffdff	/* Entry size of syminfo */
+#define DT_VALRNGHI	0x6ffffdff
+#define DT_VALTAGIDX(tag)	(DT_VALRNGHI - (tag))	/* Reverse order! */
+#define DT_VALNUM 12
+
+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+   Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+
+   If any adjustment is made to the ELF object after it has been
+   built these entries will need to be adjusted.  */
+#define DT_ADDRRNGLO	0x6ffffe00
+#define DT_GNU_CONFLICT	0x6ffffef8	/* Start of conflict section */
+#define DT_GNU_LIBLIST	0x6ffffef9	/* Library list */
+#define DT_CONFIG	0x6ffffefa	/* Configuration information.  */
+#define DT_DEPAUDIT	0x6ffffefb	/* Dependency auditing.  */
+#define DT_AUDIT	0x6ffffefc	/* Object auditing.  */
+#define	DT_PLTPAD	0x6ffffefd	/* PLT padding.  */
+#define	DT_MOVETAB	0x6ffffefe	/* Move table.  */
+#define DT_SYMINFO	0x6ffffeff	/* Syminfo table.  */
+#define DT_ADDRRNGHI	0x6ffffeff
+#define DT_ADDRTAGIDX(tag)	(DT_ADDRRNGHI - (tag))	/* Reverse order! */
+#define DT_ADDRNUM 10
+
+/* The versioning entry types.  The next are defined as part of the
+   GNU extension.  */
+#define DT_VERSYM	0x6ffffff0
+
+#define DT_RELACOUNT	0x6ffffff9
+#define DT_RELCOUNT	0x6ffffffa
+
+/* These were chosen by Sun.  */
+#define DT_FLAGS_1	0x6ffffffb	/* State flags, see DF_1_* below.  */
+#define	DT_VERDEF	0x6ffffffc	/* Address of version definition
+					   table */
+#define	DT_VERDEFNUM	0x6ffffffd	/* Number of version definitions */
+#define	DT_VERNEED	0x6ffffffe	/* Address of table with needed
+					   versions */
+#define	DT_VERNEEDNUM	0x6fffffff	/* Number of needed versions */
+#define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))	/* Reverse order! */
+#define DT_VERSIONTAGNUM 16
+
+/* Sun added these machine-independent extensions in the "processor-specific"
+   range.  Be compatible.  */
+#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
+#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
+#define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM	3
+
+/* Values of `d_un.d_val' in the DT_FLAGS entry.  */
+#define DF_ORIGIN	0x00000001	/* Object may use DF_ORIGIN */
+#define DF_SYMBOLIC	0x00000002	/* Symbol resolutions starts here */
+#define DF_TEXTREL	0x00000004	/* Object contains text relocations */
+#define DF_BIND_NOW	0x00000008	/* No lazy binding for this object */
+#define DF_STATIC_TLS	0x00000010	/* Module uses the static TLS model */
+
+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
+   entry in the dynamic section.  */
+#define DF_1_NOW	0x00000001	/* Set RTLD_NOW for this object.  */
+#define DF_1_GLOBAL	0x00000002	/* Set RTLD_GLOBAL for this object.  */
+#define DF_1_GROUP	0x00000004	/* Set RTLD_GROUP for this object.  */
+#define DF_1_NODELETE	0x00000008	/* Set RTLD_NODELETE for this object.*/
+#define DF_1_LOADFLTR	0x00000010	/* Trigger filtee loading at runtime.*/
+#define DF_1_INITFIRST	0x00000020	/* Set RTLD_INITFIRST for this object*/
+#define DF_1_NOOPEN	0x00000040	/* Set RTLD_NOOPEN for this object.  */
+#define DF_1_ORIGIN	0x00000080	/* $ORIGIN must be handled.  */
+#define DF_1_DIRECT	0x00000100	/* Direct binding enabled.  */
+#define DF_1_TRANS	0x00000200
+#define DF_1_INTERPOSE	0x00000400	/* Object is used to interpose.  */
+#define DF_1_NODEFLIB	0x00000800	/* Ignore default lib search path.  */
+#define DF_1_NODUMP	0x00001000	/* Object can't be dldump'ed.  */
+#define DF_1_CONFALT	0x00002000	/* Configuration alternative created.*/
+#define DF_1_ENDFILTEE	0x00004000	/* Filtee terminates filters search. */
+#define	DF_1_DISPRELDNE	0x00008000	/* Disp reloc applied at build time. */
+#define	DF_1_DISPRELPND	0x00010000	/* Disp reloc applied at run-time.  */
+
+/* Flags for the feature selection in DT_FEATURE_1.  */
+#define DTF_1_PARINIT	0x00000001
+#define DTF_1_CONFEXP	0x00000002
+
+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry.  */
+#define DF_P1_LAZYLOAD	0x00000001	/* Lazyload following object.  */
+#define DF_P1_GROUPPERM	0x00000002	/* Symbols from next object are not
+					   generally available.  */
+
+/* Version definition sections.  */
+
+typedef struct
+{
+  Elf32_Half	vd_version;		/* Version revision */
+  Elf32_Half	vd_flags;		/* Version information */
+  Elf32_Half	vd_ndx;			/* Version Index */
+  Elf32_Half	vd_cnt;			/* Number of associated aux entries */
+  Elf32_Word	vd_hash;		/* Version name hash value */
+  Elf32_Word	vd_aux;			/* Offset in bytes to verdaux array */
+  Elf32_Word	vd_next;		/* Offset in bytes to next verdef
+					   entry */
+} Elf32_Verdef;
+
+typedef struct
+{
+  Elf64_Half	vd_version;		/* Version revision */
+  Elf64_Half	vd_flags;		/* Version information */
+  Elf64_Half	vd_ndx;			/* Version Index */
+  Elf64_Half	vd_cnt;			/* Number of associated aux entries */
+  Elf64_Word	vd_hash;		/* Version name hash value */
+  Elf64_Word	vd_aux;			/* Offset in bytes to verdaux array */
+  Elf64_Word	vd_next;		/* Offset in bytes to next verdef
+					   entry */
+} Elf64_Verdef;
+
+
+/* Legal values for vd_version (version revision).  */
+#define VER_DEF_NONE	0		/* No version */
+#define VER_DEF_CURRENT	1		/* Current version */
+#define VER_DEF_NUM	2		/* Given version number */
+
+/* Legal values for vd_flags (version information flags).  */
+#define VER_FLG_BASE	0x1		/* Version definition of file itself */
+#define VER_FLG_WEAK	0x2		/* Weak version identifier */
+
+/* Versym symbol index values.  */
+#define	VER_NDX_LOCAL		0	/* Symbol is local.  */
+#define	VER_NDX_GLOBAL		1	/* Symbol is global.  */
+#define	VER_NDX_LORESERVE	0xff00	/* Beginning of reserved entries.  */
+#define	VER_NDX_ELIMINATE	0xff01	/* Symbol is to be eliminated.  */
+
+/* Auxiliary version information.  */
+
+typedef struct
+{
+  Elf32_Word	vda_name;		/* Version or dependency names */
+  Elf32_Word	vda_next;		/* Offset in bytes to next verdaux
+					   entry */
+} Elf32_Verdaux;
+
+typedef struct
+{
+  Elf64_Word	vda_name;		/* Version or dependency names */
+  Elf64_Word	vda_next;		/* Offset in bytes to next verdaux
+					   entry */
+} Elf64_Verdaux;
+
+
+/* Version dependency section.  */
+
+typedef struct
+{
+  Elf32_Half	vn_version;		/* Version of structure */
+  Elf32_Half	vn_cnt;			/* Number of associated aux entries */
+  Elf32_Word	vn_file;		/* Offset of filename for this
+					   dependency */
+  Elf32_Word	vn_aux;			/* Offset in bytes to vernaux array */
+  Elf32_Word	vn_next;		/* Offset in bytes to next verneed
+					   entry */
+} Elf32_Verneed;
+
+typedef struct
+{
+  Elf64_Half	vn_version;		/* Version of structure */
+  Elf64_Half	vn_cnt;			/* Number of associated aux entries */
+  Elf64_Word	vn_file;		/* Offset of filename for this
+					   dependency */
+  Elf64_Word	vn_aux;			/* Offset in bytes to vernaux array */
+  Elf64_Word	vn_next;		/* Offset in bytes to next verneed
+					   entry */
+} Elf64_Verneed;
+
+
+/* Legal values for vn_version (version revision).  */
+#define VER_NEED_NONE	 0		/* No version */
+#define VER_NEED_CURRENT 1		/* Current version */
+#define VER_NEED_NUM	 2		/* Given version number */
+
+/* Auxiliary needed version information.  */
+
+typedef struct
+{
+  Elf32_Word	vna_hash;		/* Hash value of dependency name */
+  Elf32_Half	vna_flags;		/* Dependency specific information */
+  Elf32_Half	vna_other;		/* Unused */
+  Elf32_Word	vna_name;		/* Dependency name string offset */
+  Elf32_Word	vna_next;		/* Offset in bytes to next vernaux
+					   entry */
+} Elf32_Vernaux;
+
+typedef struct
+{
+  Elf64_Word	vna_hash;		/* Hash value of dependency name */
+  Elf64_Half	vna_flags;		/* Dependency specific information */
+  Elf64_Half	vna_other;		/* Unused */
+  Elf64_Word	vna_name;		/* Dependency name string offset */
+  Elf64_Word	vna_next;		/* Offset in bytes to next vernaux
+					   entry */
+} Elf64_Vernaux;
+
+
+/* Legal values for vna_flags.  */
+#define VER_FLG_WEAK	0x2		/* Weak version identifier */
+
+
+/* Auxiliary vector.  */
+
+/* This vector is normally only used by the program interpreter.  The
+   usual definition in an ABI supplement uses the name auxv_t.  The
+   vector is not usually defined in a standard <elf.h> file, but it
+   can't hurt.  We rename it to avoid conflicts.  The sizes of these
+   types are an arrangement between the exec server and the program
+   interpreter, so we don't fully specify them here.  */
+
+typedef struct
+{
+  int a_type;			/* Entry type */
+  union
+    {
+      long int a_val;		/* Integer value */
+      void *a_ptr;		/* Pointer value */
+      void (*a_fcn) (void);	/* Function pointer value */
+    } a_un;
+} Elf32_auxv_t;
+
+typedef struct
+{
+  long int a_type;		/* Entry type */
+  union
+    {
+      long int a_val;		/* Integer value */
+      void *a_ptr;		/* Pointer value */
+      void (*a_fcn) (void);	/* Function pointer value */
+    } a_un;
+} Elf64_auxv_t;
+
+/* Legal values for a_type (entry type).  */
+
+#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_CLKTCK	17		/* Frequency of times() */
+
+/* Some more special a_type values describing the hardware.  */
+#define AT_PLATFORM	15		/* String identifying platform.  */
+#define AT_HWCAP	16		/* Machine dependent hints about
+					   processor capabilities.  */
+
+/* This entry gives some information about the FPU initialization
+   performed by the kernel.  */
+#define AT_FPUCW	18		/* Used FPU control word.  */
+
+/* Cache block sizes.  */
+#define AT_DCACHEBSIZE	19		/* Data cache block size.  */
+#define AT_ICACHEBSIZE	20		/* Instruction cache block size.  */
+#define AT_UCACHEBSIZE	21		/* Unified cache block size.  */
+
+/* A special ignored value for PPC, used by the kernel to control the
+   interpretation of the AUXV. Must be > 16.  */
+#define AT_IGNOREPPC	22		/* Entry should be ignored */
+
+
+/* Note section contents.  Each entry in the note section begins with
+   a header of a fixed form.  */
+
+typedef struct
+{
+  Elf32_Word n_namesz;			/* Length of the note's name.  */
+  Elf32_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf32_Word n_type;			/* Type of the note.  */
+} Elf32_Nhdr;
+
+typedef struct
+{
+  Elf64_Word n_namesz;			/* Length of the note's name.  */
+  Elf64_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf64_Word n_type;			/* Type of the note.  */
+} Elf64_Nhdr;
+
+/* Known names of notes.  */
+
+/* Solaris entries in the note section have this name.  */
+#define ELF_NOTE_SOLARIS	"SUNW Solaris"
+
+/* Note entries for GNU systems have this name.  */
+#define ELF_NOTE_GNU		"GNU"
+
+
+/* Defined types of notes for Solaris.  */
+
+/* Value of descriptor (one word) is desired pagesize for the binary.  */
+#define ELF_NOTE_PAGESIZE_HINT	1
+
+
+/* Defined note types for GNU systems.  */
+
+/* ABI information.  The descriptor consists of words:
+   word 0: OS descriptor
+   word 1: major version of the ABI
+   word 2: minor version of the ABI
+   word 3: subminor version of the ABI
+*/
+#define ELF_NOTE_ABI		1
+
+/* Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
+   note section entry.  */
+#define ELF_NOTE_OS_LINUX	0
+#define ELF_NOTE_OS_GNU		1
+#define ELF_NOTE_OS_SOLARIS2	2
+
+
+/* Move records.  */
+typedef struct
+{
+  Elf32_Xword m_value;		/* Symbol value.  */
+  Elf32_Word m_info;		/* Size and index.  */
+  Elf32_Word m_poffset;		/* Symbol offset.  */
+  Elf32_Half m_repeat;		/* Repeat count.  */
+  Elf32_Half m_stride;		/* Stride info.  */
+} Elf32_Move;
+
+typedef struct
+{
+  Elf64_Xword m_value;		/* Symbol value.  */
+  Elf64_Xword m_info;		/* Size and index.  */
+  Elf64_Xword m_poffset;	/* Symbol offset.  */
+  Elf64_Half m_repeat;		/* Repeat count.  */
+  Elf64_Half m_stride;		/* Stride info.  */
+} Elf64_Move;
+
+/* Macro to construct move records.  */
+#define ELF32_M_SYM(info)	((info) >> 8)
+#define ELF32_M_SIZE(info)	((unsigned char) (info))
+#define ELF32_M_INFO(sym, size)	(((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info)	ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info)	ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size)	ELF32_M_INFO (sym, size)
+
+
+/* Motorola 68k specific definitions.  */
+
+/* Values for Elf32_Ehdr.e_flags.  */
+#define EF_CPU32	0x00810000
+
+/* m68k relocs.  */
+
+#define R_68K_NONE	0		/* No reloc */
+#define R_68K_32	1		/* Direct 32 bit  */
+#define R_68K_16	2		/* Direct 16 bit  */
+#define R_68K_8		3		/* Direct 8 bit  */
+#define R_68K_PC32	4		/* PC relative 32 bit */
+#define R_68K_PC16	5		/* PC relative 16 bit */
+#define R_68K_PC8	6		/* PC relative 8 bit */
+#define R_68K_GOT32	7		/* 32 bit PC relative GOT entry */
+#define R_68K_GOT16	8		/* 16 bit PC relative GOT entry */
+#define R_68K_GOT8	9		/* 8 bit PC relative GOT entry */
+#define R_68K_GOT32O	10		/* 32 bit GOT offset */
+#define R_68K_GOT16O	11		/* 16 bit GOT offset */
+#define R_68K_GOT8O	12		/* 8 bit GOT offset */
+#define R_68K_PLT32	13		/* 32 bit PC relative PLT address */
+#define R_68K_PLT16	14		/* 16 bit PC relative PLT address */
+#define R_68K_PLT8	15		/* 8 bit PC relative PLT address */
+#define R_68K_PLT32O	16		/* 32 bit PLT offset */
+#define R_68K_PLT16O	17		/* 16 bit PLT offset */
+#define R_68K_PLT8O	18		/* 8 bit PLT offset */
+#define R_68K_COPY	19		/* Copy symbol at runtime */
+#define R_68K_GLOB_DAT	20		/* Create GOT entry */
+#define R_68K_JMP_SLOT	21		/* Create PLT entry */
+#define R_68K_RELATIVE	22		/* Adjust by program base */
+/* Keep this the last entry.  */
+#define R_68K_NUM	23
+
+/* Intel 80386 specific definitions.  */
+
+/* i386 relocs.  */
+
+#define R_386_NONE	   0		/* No reloc */
+#define R_386_32	   1		/* Direct 32 bit  */
+#define R_386_PC32	   2		/* PC relative 32 bit */
+#define R_386_GOT32	   3		/* 32 bit GOT entry */
+#define R_386_PLT32	   4		/* 32 bit PLT address */
+#define R_386_COPY	   5		/* Copy symbol at runtime */
+#define R_386_GLOB_DAT	   6		/* Create GOT entry */
+#define R_386_JMP_SLOT	   7		/* Create PLT entry */
+#define R_386_RELATIVE	   8		/* Adjust by program base */
+#define R_386_GOTOFF	   9		/* 32 bit offset to GOT */
+#define R_386_GOTPC	   10		/* 32 bit PC relative offset to GOT */
+#define R_386_32PLT	   11
+#define R_386_TLS_TPOFF	   14		/* Offset in static TLS block */
+#define R_386_TLS_IE	   15		/* Address of GOT entry for static TLS
+					   block offset */
+#define R_386_TLS_GOTIE	   16		/* GOT entry for static TLS block
+					   offset */
+#define R_386_TLS_LE	   17		/* Offset relative to static TLS
+					   block */
+#define R_386_TLS_GD	   18		/* Direct 32 bit for GNU version of
+					   general dynamic thread local data */
+#define R_386_TLS_LDM	   19		/* Direct 32 bit for GNU version of
+					   local dynamic thread local data
+					   in LE code */
+#define R_386_16	   20
+#define R_386_PC16	   21
+#define R_386_8		   22
+#define R_386_PC8	   23
+#define R_386_TLS_GD_32	   24		/* Direct 32 bit for general dynamic
+					   thread local data */
+#define R_386_TLS_GD_PUSH  25		/* Tag for pushl in GD TLS code */
+#define R_386_TLS_GD_CALL  26		/* Relocation for call to
+					   __tls_get_addr() */
+#define R_386_TLS_GD_POP   27		/* Tag for popl in GD TLS code */
+#define R_386_TLS_LDM_32   28		/* Direct 32 bit for local dynamic
+					   thread local data in LE code */
+#define R_386_TLS_LDM_PUSH 29		/* Tag for pushl in LDM TLS code */
+#define R_386_TLS_LDM_CALL 30		/* Relocation for call to
+					   __tls_get_addr() in LDM code */
+#define R_386_TLS_LDM_POP  31		/* Tag for popl in LDM TLS code */
+#define R_386_TLS_LDO_32   32		/* Offset relative to TLS block */
+#define R_386_TLS_IE_32	   33		/* GOT entry for negated static TLS
+					   block offset */
+#define R_386_TLS_LE_32	   34		/* Negated offset relative to static
+					   TLS block */
+#define R_386_TLS_DTPMOD32 35		/* ID of module containing symbol */
+#define R_386_TLS_DTPOFF32 36		/* Offset in TLS block */
+#define R_386_TLS_TPOFF32  37		/* Negated offset in static TLS block */
+/* Keep this the last entry.  */
+#define R_386_NUM	   38
+
+
+/* SUN SPARC specific definitions.  */
+
+/* x86_64 specific definitions.  */
+#define R_X86_64_NONE		0
+#define R_X86_64_64		1
+#define R_X86_64_PC32		2
+#define R_X86_64_GOT32		3
+#define R_X86_64_PLT32		4
+#define R_X86_64_COPY		5
+#define R_X86_64_GLOB_DAT	6
+#define R_X86_64_JUMP_SLOT	7
+#define R_X86_64_RELATIVE	8
+#define R_X86_64_GOTPCREL	9
+#define R_X86_64_32		10
+#define R_X86_64_32S		11
+#define R_X86_64_16		12
+#define R_X86_64_PC16		13
+#define R_X86_64_8		14
+#define R_X86_64_PC8		15
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_REGISTER	13		/* Global register reserved to app. */
+
+/* Values for Elf64_Ehdr.e_flags.  */
+
+#define EF_SPARCV9_MM		3
+#define EF_SPARCV9_TSO		0
+#define EF_SPARCV9_PSO		1
+#define EF_SPARCV9_RMO		2
+#define EF_SPARC_LEDATA		0x800000 /* little endian data */
+#define EF_SPARC_EXT_MASK	0xFFFF00
+#define EF_SPARC_32PLUS		0x000100 /* generic V8+ features */
+#define EF_SPARC_SUN_US1	0x000200 /* Sun UltraSPARC1 extensions */
+#define EF_SPARC_HAL_R1		0x000400 /* HAL R1 extensions */
+#define EF_SPARC_SUN_US3	0x000800 /* Sun UltraSPARCIII extensions */
+
+/* SPARC relocs.  */
+
+#define R_SPARC_NONE		0	/* No reloc */
+#define R_SPARC_8		1	/* Direct 8 bit */
+#define R_SPARC_16		2	/* Direct 16 bit */
+#define R_SPARC_32		3	/* Direct 32 bit */
+#define R_SPARC_DISP8		4	/* PC relative 8 bit */
+#define R_SPARC_DISP16		5	/* PC relative 16 bit */
+#define R_SPARC_DISP32		6	/* PC relative 32 bit */
+#define R_SPARC_WDISP30		7	/* PC relative 30 bit shifted */
+#define R_SPARC_WDISP22		8	/* PC relative 22 bit shifted */
+#define R_SPARC_HI22		9	/* High 22 bit */
+#define R_SPARC_22		10	/* Direct 22 bit */
+#define R_SPARC_13		11	/* Direct 13 bit */
+#define R_SPARC_LO10		12	/* Truncated 10 bit */
+#define R_SPARC_GOT10		13	/* Truncated 10 bit GOT entry */
+#define R_SPARC_GOT13		14	/* 13 bit GOT entry */
+#define R_SPARC_GOT22		15	/* 22 bit GOT entry shifted */
+#define R_SPARC_PC10		16	/* PC relative 10 bit truncated */
+#define R_SPARC_PC22		17	/* PC relative 22 bit shifted */
+#define R_SPARC_WPLT30		18	/* 30 bit PC relative PLT address */
+#define R_SPARC_COPY		19	/* Copy symbol at runtime */
+#define R_SPARC_GLOB_DAT	20	/* Create GOT entry */
+#define R_SPARC_JMP_SLOT	21	/* Create PLT entry */
+#define R_SPARC_RELATIVE	22	/* Adjust by program base */
+#define R_SPARC_UA32		23	/* Direct 32 bit unaligned */
+
+/* Additional Sparc64 relocs.  */
+
+#define R_SPARC_PLT32		24	/* Direct 32 bit ref to PLT entry */
+#define R_SPARC_HIPLT22		25	/* High 22 bit PLT entry */
+#define R_SPARC_LOPLT10		26	/* Truncated 10 bit PLT entry */
+#define R_SPARC_PCPLT32		27	/* PC rel 32 bit ref to PLT entry */
+#define R_SPARC_PCPLT22		28	/* PC rel high 22 bit PLT entry */
+#define R_SPARC_PCPLT10		29	/* PC rel trunc 10 bit PLT entry */
+#define R_SPARC_10		30	/* Direct 10 bit */
+#define R_SPARC_11		31	/* Direct 11 bit */
+#define R_SPARC_64		32	/* Direct 64 bit */
+#define R_SPARC_OLO10		33	/* 10bit with secondary 13bit addend */
+#define R_SPARC_HH22		34	/* Top 22 bits of direct 64 bit */
+#define R_SPARC_HM10		35	/* High middle 10 bits of ... */
+#define R_SPARC_LM22		36	/* Low middle 22 bits of ... */
+#define R_SPARC_PC_HH22		37	/* Top 22 bits of pc rel 64 bit */
+#define R_SPARC_PC_HM10		38	/* High middle 10 bit of ... */
+#define R_SPARC_PC_LM22		39	/* Low middle 22 bits of ... */
+#define R_SPARC_WDISP16		40	/* PC relative 16 bit shifted */
+#define R_SPARC_WDISP19		41	/* PC relative 19 bit shifted */
+#define R_SPARC_7		43	/* Direct 7 bit */
+#define R_SPARC_5		44	/* Direct 5 bit */
+#define R_SPARC_6		45	/* Direct 6 bit */
+#define R_SPARC_DISP64		46	/* PC relative 64 bit */
+#define R_SPARC_PLT64		47	/* Direct 64 bit ref to PLT entry */
+#define R_SPARC_HIX22		48	/* High 22 bit complemented */
+#define R_SPARC_LOX10		49	/* Truncated 11 bit complemented */
+#define R_SPARC_H44		50	/* Direct high 12 of 44 bit */
+#define R_SPARC_M44		51	/* Direct mid 22 of 44 bit */
+#define R_SPARC_L44		52	/* Direct low 10 of 44 bit */
+#define R_SPARC_REGISTER	53	/* Global register usage */
+#define R_SPARC_UA64		54	/* Direct 64 bit unaligned */
+#define R_SPARC_UA16		55	/* Direct 16 bit unaligned */
+#define R_SPARC_TLS_GD_HI22	56
+#define R_SPARC_TLS_GD_LO10	57
+#define R_SPARC_TLS_GD_ADD	58
+#define R_SPARC_TLS_GD_CALL	59
+#define R_SPARC_TLS_LDM_HI22	60
+#define R_SPARC_TLS_LDM_LO10	61
+#define R_SPARC_TLS_LDM_ADD	62
+#define R_SPARC_TLS_LDM_CALL	63
+#define R_SPARC_TLS_LDO_HIX22	64
+#define R_SPARC_TLS_LDO_LOX10	65
+#define R_SPARC_TLS_LDO_ADD	66
+#define R_SPARC_TLS_IE_HI22	67
+#define R_SPARC_TLS_IE_LO10	68
+#define R_SPARC_TLS_IE_LD	69
+#define R_SPARC_TLS_IE_LDX	70
+#define R_SPARC_TLS_IE_ADD	71
+#define R_SPARC_TLS_LE_HIX22	72
+#define R_SPARC_TLS_LE_LOX10	73
+#define R_SPARC_TLS_DTPMOD32	74
+#define R_SPARC_TLS_DTPMOD64	75
+#define R_SPARC_TLS_DTPOFF32	76
+#define R_SPARC_TLS_DTPOFF64	77
+#define R_SPARC_TLS_TPOFF32	78
+#define R_SPARC_TLS_TPOFF64	79
+/* Keep this the last entry.  */
+#define R_SPARC_NUM		80
+
+/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM	2
+
+/* Bits present in AT_HWCAP, primarily for Sparc32.  */
+
+#define HWCAP_SPARC_FLUSH	1	/* The cpu supports flush insn.  */
+#define HWCAP_SPARC_STBAR	2
+#define HWCAP_SPARC_SWAP	4
+#define HWCAP_SPARC_MULDIV	8
+#define HWCAP_SPARC_V9		16	/* The cpu is v9, so v8plus is ok.  */
+#define HWCAP_SPARC_ULTRA3	32
+
+/* MIPS R3000 specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_MIPS_NOREORDER   1		/* A .noreorder directive was used */
+#define EF_MIPS_PIC	    2		/* Contains PIC code */
+#define EF_MIPS_CPIC	    4		/* Uses PIC calling sequence */
+#define EF_MIPS_XGOT	    8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2	    32
+#define EF_MIPS_ABI_ON32    64
+#define EF_MIPS_ARCH	    0xf0000000	/* MIPS architecture level */
+
+/* Legal values for MIPS architecture level.  */
+
+#define EF_MIPS_ARCH_1	    0x00000000	/* -mips1 code.  */
+#define EF_MIPS_ARCH_2	    0x10000000	/* -mips2 code.  */
+#define EF_MIPS_ARCH_3	    0x20000000	/* -mips3 code.  */
+#define EF_MIPS_ARCH_4	    0x30000000	/* -mips4 code.  */
+#define EF_MIPS_ARCH_5	    0x40000000	/* -mips5 code.  */
+#define EF_MIPS_ARCH_32	    0x60000000	/* MIPS32 code.  */
+#define EF_MIPS_ARCH_64	    0x70000000	/* MIPS64 code.  */
+
+/* The following are non-official names and should not be used.  */
+
+#define E_MIPS_ARCH_1	  0x00000000	/* -mips1 code.  */
+#define E_MIPS_ARCH_2	  0x10000000	/* -mips2 code.  */
+#define E_MIPS_ARCH_3	  0x20000000	/* -mips3 code.  */
+#define E_MIPS_ARCH_4	  0x30000000	/* -mips4 code.  */
+#define E_MIPS_ARCH_5	  0x40000000	/* -mips5 code.  */
+#define E_MIPS_ARCH_32	  0x60000000	/* MIPS32 code.  */
+#define E_MIPS_ARCH_64	  0x70000000	/* MIPS64 code.  */
+
+/* Special section indices.  */
+
+#define SHN_MIPS_ACOMMON    0xff00	/* Allocated common symbols */
+#define SHN_MIPS_TEXT	    0xff01	/* Allocated test symbols.  */
+#define SHN_MIPS_DATA	    0xff02	/* Allocated data symbols.  */
+#define SHN_MIPS_SCOMMON    0xff03	/* Small common symbols */
+#define SHN_MIPS_SUNDEFINED 0xff04	/* Small undefined symbols */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
+#define SHT_MIPS_MSYM	       0x70000001
+#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
+#define SHT_MIPS_GPTAB	       0x70000003 /* Global data area sizes */
+#define SHT_MIPS_UCODE	       0x70000004 /* Reserved for SGI/MIPS compilers */
+#define SHT_MIPS_DEBUG	       0x70000005 /* MIPS ECOFF debugging information*/
+#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
+#define SHT_MIPS_PACKAGE       0x70000007
+#define SHT_MIPS_PACKSYM       0x70000008
+#define SHT_MIPS_RELD	       0x70000009
+#define SHT_MIPS_IFACE         0x7000000b
+#define SHT_MIPS_CONTENT       0x7000000c
+#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
+#define SHT_MIPS_SHDR	       0x70000010
+#define SHT_MIPS_FDESC	       0x70000011
+#define SHT_MIPS_EXTSYM	       0x70000012
+#define SHT_MIPS_DENSE	       0x70000013
+#define SHT_MIPS_PDESC	       0x70000014
+#define SHT_MIPS_LOCSYM	       0x70000015
+#define SHT_MIPS_AUXSYM	       0x70000016
+#define SHT_MIPS_OPTSYM	       0x70000017
+#define SHT_MIPS_LOCSTR	       0x70000018
+#define SHT_MIPS_LINE	       0x70000019
+#define SHT_MIPS_RFDESC	       0x7000001a
+#define SHT_MIPS_DELTASYM      0x7000001b
+#define SHT_MIPS_DELTAINST     0x7000001c
+#define SHT_MIPS_DELTACLASS    0x7000001d
+#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
+#define SHT_MIPS_DELTADECL     0x7000001f
+#define SHT_MIPS_SYMBOL_LIB    0x70000020
+#define SHT_MIPS_EVENTS	       0x70000021 /* Event section.  */
+#define SHT_MIPS_TRANSLATE     0x70000022
+#define SHT_MIPS_PIXIE	       0x70000023
+#define SHT_MIPS_XLATE	       0x70000024
+#define SHT_MIPS_XLATE_DEBUG   0x70000025
+#define SHT_MIPS_WHIRL	       0x70000026
+#define SHT_MIPS_EH_REGION     0x70000027
+#define SHT_MIPS_XLATE_OLD     0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_MIPS_GPREL	 0x10000000	/* Must be part of global data area */
+#define SHF_MIPS_MERGE	 0x20000000
+#define SHF_MIPS_ADDR	 0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL	 0x04000000
+#define SHF_MIPS_NAMES	 0x02000000
+#define SHF_MIPS_NODUPE	 0x01000000
+
+
+/* Symbol tables.  */
+
+/* MIPS specific values for `st_other'.  */
+#define STO_MIPS_DEFAULT		0x0
+#define STO_MIPS_INTERNAL		0x1
+#define STO_MIPS_HIDDEN			0x2
+#define STO_MIPS_PROTECTED		0x3
+#define STO_MIPS_SC_ALIGN_UNUSED	0xff
+
+/* MIPS specific values for `st_info'.  */
+#define STB_MIPS_SPLIT_COMMON		13
+
+/* Entries found in sections of type SHT_MIPS_GPTAB.  */
+
+typedef union
+{
+  struct
+    {
+      Elf32_Word gt_current_g_value;	/* -G value used for compilation */
+      Elf32_Word gt_unused;		/* Not used */
+    } gt_header;			/* First entry in section */
+  struct
+    {
+      Elf32_Word gt_g_value;		/* If this value were used for -G */
+      Elf32_Word gt_bytes;		/* This many bytes would be used */
+    } gt_entry;				/* Subsequent entries in section */
+} Elf32_gptab;
+
+/* Entry found in sections of type SHT_MIPS_REGINFO.  */
+
+typedef struct
+{
+  Elf32_Word	ri_gprmask;		/* General registers used */
+  Elf32_Word	ri_cprmask[4];		/* Coprocessor registers used */
+  Elf32_Sword	ri_gp_value;		/* $gp register value */
+} Elf32_RegInfo;
+
+/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
+
+typedef struct
+{
+  unsigned char kind;		/* Determines interpretation of the
+				   variable part of descriptor.  */
+  unsigned char size;		/* Size of descriptor, including header.  */
+  Elf32_Section section;	/* Section header index of section affected,
+				   0 for global options.  */
+  Elf32_Word info;		/* Kind-specific information.  */
+} Elf_Options;
+
+/* Values for `kind' field in Elf_Options.  */
+
+#define ODK_NULL	0	/* Undefined.  */
+#define ODK_REGINFO	1	/* Register usage information.  */
+#define ODK_EXCEPTIONS	2	/* Exception processing options.  */
+#define ODK_PAD		3	/* Section padding options.  */
+#define ODK_HWPATCH	4	/* Hardware workarounds performed */
+#define ODK_FILL	5	/* record the fill value used by the linker. */
+#define ODK_TAGS	6	/* reserve space for desktop tools to write. */
+#define ODK_HWAND	7	/* HW workarounds.  'AND' bits when merging. */
+#define ODK_HWOR	8	/* HW workarounds.  'OR' bits when merging.  */
+
+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
+
+#define OEX_FPU_MIN	0x1f	/* FPE's which MUST be enabled.  */
+#define OEX_FPU_MAX	0x1f00	/* FPE's which MAY be enabled.  */
+#define OEX_PAGE0	0x10000	/* page zero must be mapped.  */
+#define OEX_SMM		0x20000	/* Force sequential memory mode?  */
+#define OEX_FPDBUG	0x40000	/* Force floating point debug mode?  */
+#define OEX_PRECISEFP	OEX_FPDBUG
+#define OEX_DISMISS	0x80000	/* Dismiss invalid address faults?  */
+
+#define OEX_FPU_INVAL	0x10
+#define OEX_FPU_DIV0	0x08
+#define OEX_FPU_OFLO	0x04
+#define OEX_FPU_UFLO	0x02
+#define OEX_FPU_INEX	0x01
+
+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
+
+#define OHW_R4KEOP	0x1	/* R4000 end-of-page patch.  */
+#define OHW_R8KPFETCH	0x2	/* may need R8000 prefetch patch.  */
+#define OHW_R5KEOP	0x4	/* R5000 end-of-page patch.  */
+#define OHW_R5KCVTL	0x8	/* R5000 cvt.[ds].l bug.  clean=1.  */
+
+#define OPAD_PREFIX	0x1
+#define OPAD_POSTFIX	0x2
+#define OPAD_SYMBOL	0x4
+
+/* Entry found in `.options' section.  */
+
+typedef struct
+{
+  Elf32_Word hwp_flags1;	/* Extra flags.  */
+  Elf32_Word hwp_flags2;	/* Extra flags.  */
+} Elf_Options_Hw;
+
+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
+
+#define OHWA0_R4KEOP_CHECKED	0x00000001
+#define OHWA1_R4KEOP_CLEAN	0x00000002
+
+/* MIPS relocs.  */
+
+#define R_MIPS_NONE		0	/* No reloc */
+#define R_MIPS_16		1	/* Direct 16 bit */
+#define R_MIPS_32		2	/* Direct 32 bit */
+#define R_MIPS_REL32		3	/* PC relative 32 bit */
+#define R_MIPS_26		4	/* Direct 26 bit shifted */
+#define R_MIPS_HI16		5	/* High 16 bit */
+#define R_MIPS_LO16		6	/* Low 16 bit */
+#define R_MIPS_GPREL16		7	/* GP relative 16 bit */
+#define R_MIPS_LITERAL		8	/* 16 bit literal entry */
+#define R_MIPS_GOT16		9	/* 16 bit GOT entry */
+#define R_MIPS_PC16		10	/* PC relative 16 bit */
+#define R_MIPS_CALL16		11	/* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32		12	/* GP relative 32 bit */
+
+#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
+#define R_MIPS_GOT_HI16		22
+#define R_MIPS_GOT_LO16		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
+#define R_MIPS_CALL_HI16	30
+#define R_MIPS_CALL_LO16	31
+#define R_MIPS_SCN_DISP		32
+#define R_MIPS_REL16		33
+#define R_MIPS_ADD_IMMEDIATE	34
+#define R_MIPS_PJUMP		35
+#define R_MIPS_RELGOT		36
+#define R_MIPS_JALR		37
+/* Keep this the last entry.  */
+#define R_MIPS_NUM		38
+
+/* Legal values for p_type field of Elf32_Phdr.  */
+
+#define PT_MIPS_REGINFO	0x70000000	/* Register usage information */
+#define PT_MIPS_RTPROC  0x70000001	/* Runtime procedure table. */
+#define PT_MIPS_OPTIONS 0x70000002
+
+/* Special program header types.  */
+
+#define PF_MIPS_LOCAL	0x10000000
+
+/* Legal values for d_tag field of Elf32_Dyn.  */
+
+#define DT_MIPS_RLD_VERSION  0x70000001	/* Runtime linker interface version */
+#define DT_MIPS_TIME_STAMP   0x70000002	/* Timestamp */
+#define DT_MIPS_ICHECKSUM    0x70000003	/* Checksum */
+#define DT_MIPS_IVERSION     0x70000004	/* Version string (string tbl index) */
+#define DT_MIPS_FLAGS	     0x70000005	/* Flags */
+#define DT_MIPS_BASE_ADDRESS 0x70000006	/* Base address */
+#define DT_MIPS_MSYM	     0x70000007
+#define DT_MIPS_CONFLICT     0x70000008	/* Address of CONFLICT section */
+#define DT_MIPS_LIBLIST	     0x70000009	/* Address of LIBLIST section */
+#define DT_MIPS_LOCAL_GOTNO  0x7000000a	/* Number of local GOT entries */
+#define DT_MIPS_CONFLICTNO   0x7000000b	/* Number of CONFLICT entries */
+#define DT_MIPS_LIBLISTNO    0x70000010	/* Number of LIBLIST entries */
+#define DT_MIPS_SYMTABNO     0x70000011	/* Number of DYNSYM entries */
+#define DT_MIPS_UNREFEXTNO   0x70000012	/* First external DYNSYM */
+#define DT_MIPS_GOTSYM	     0x70000013	/* First GOT entry in DYNSYM */
+#define DT_MIPS_HIPAGENO     0x70000014	/* Number of GOT page table entries */
+#define DT_MIPS_RLD_MAP	     0x70000016	/* Address of run time loader map.  */
+#define DT_MIPS_DELTA_CLASS  0x70000017	/* Delta C++ class definition.  */
+#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
+						DT_MIPS_DELTA_CLASS.  */
+#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
+						DT_MIPS_DELTA_INSTANCE.  */
+#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
+					     DT_MIPS_DELTA_RELOC.  */
+#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
+					   relocations refer to.  */
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
+					   DT_MIPS_DELTA_SYM.  */
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
+					     class declaration.  */
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
+						DT_MIPS_DELTA_CLASSSYM.  */
+#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
+#define DT_MIPS_PIXIE_INIT   0x70000023
+#define DT_MIPS_SYMBOL_LIB   0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS	     0x70000029 /* Address of .options.  */
+#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
+						    function stored in GOT.  */
+#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
+					   by rld on dlopen() calls.  */
+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
+#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
+#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
+#define DT_MIPS_NUM	     0x32
+
+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
+
+#define RHF_NONE		   0		/* No flags */
+#define RHF_QUICKSTART		   (1 << 0)	/* Use quickstart */
+#define RHF_NOTPOT		   (1 << 1)	/* Hash size not power of 2 */
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)	/* Ignore LD_LIBRARY_PATH */
+#define RHF_NO_MOVE		   (1 << 3)
+#define RHF_SGI_ONLY		   (1 << 4)
+#define RHF_GUARANTEE_INIT	   (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS	   (1 << 6)
+#define RHF_GUARANTEE_START_INIT   (1 << 7)
+#define RHF_PIXIE		   (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD	   (1 << 9)
+#define RHF_REQUICKSTART	   (1 << 10)
+#define RHF_REQUICKSTARTED	   (1 << 11)
+#define RHF_CORD		   (1 << 12)
+#define RHF_NO_UNRES_UNDEF	   (1 << 13)
+#define RHF_RLD_ORDER_SAFE	   (1 << 14)
+
+/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
+
+typedef struct
+{
+  Elf32_Word l_name;		/* Name (string table index) */
+  Elf32_Word l_time_stamp;	/* Timestamp */
+  Elf32_Word l_checksum;	/* Checksum */
+  Elf32_Word l_version;		/* Interface version */
+  Elf32_Word l_flags;		/* Flags */
+} Elf32_Lib;
+
+typedef struct
+{
+  Elf64_Word l_name;		/* Name (string table index) */
+  Elf64_Word l_time_stamp;	/* Timestamp */
+  Elf64_Word l_checksum;	/* Checksum */
+  Elf64_Word l_version;		/* Interface version */
+  Elf64_Word l_flags;		/* Flags */
+} Elf64_Lib;
+
+
+/* Legal values for l_flags.  */
+
+#define LL_NONE		  0
+#define LL_EXACT_MATCH	  (1 << 0)	/* Require exact match */
+#define LL_IGNORE_INT_VER (1 << 1)	/* Ignore interface version */
+#define LL_REQUIRE_MINOR  (1 << 2)
+#define LL_EXPORTS	  (1 << 3)
+#define LL_DELAY_LOAD	  (1 << 4)
+#define LL_DELTA	  (1 << 5)
+
+/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
+
+typedef Elf32_Addr Elf32_Conflict;
+
+
+/* HPPA specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_PARISC_TRAPNIL	0x00010000 /* Trap nil pointer dereference.  */
+#define EF_PARISC_EXT		0x00020000 /* Program uses arch. extensions. */
+#define EF_PARISC_LSB		0x00040000 /* Program expects little endian. */
+#define EF_PARISC_WIDE		0x00080000 /* Program expects wide mode.  */
+#define EF_PARISC_NO_KABP	0x00100000 /* No kernel assisted branch
+					      prediction.  */
+#define EF_PARISC_LAZYSWAP	0x00400000 /* Allow lazy swapping.  */
+#define EF_PARISC_ARCH		0x0000ffff /* Architecture version.  */
+
+/* Defined values for `e_flags & EF_PARISC_ARCH' are:  */
+
+#define EFA_PARISC_1_0		    0x020b /* PA-RISC 1.0 big-endian.  */
+#define EFA_PARISC_1_1		    0x0210 /* PA-RISC 1.1 big-endian.  */
+#define EFA_PARISC_2_0		    0x0214 /* PA-RISC 2.0 big-endian.  */
+
+/* Additional section indices.  */
+
+#define SHN_PARISC_ANSI_COMMON	0xff00	   /* Section for tentatively declared
+					      symbols in ANSI C.  */
+#define SHN_PARISC_HUGE_COMMON	0xff01	   /* Common blocks in huge model.  */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_PARISC_EXT		0x70000000 /* Contains product specific ext. */
+#define SHT_PARISC_UNWIND	0x70000001 /* Unwind information.  */
+#define SHT_PARISC_DOC		0x70000002 /* Debug info for optimized code. */
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_PARISC_SHORT	0x20000000 /* Section with short addressing. */
+#define SHF_PARISC_HUGE		0x40000000 /* Section far from gp.  */
+#define SHF_PARISC_SBP		0x80000000 /* Static branch prediction code. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_PARISC_MILLICODE	13	/* Millicode function entry point.  */
+
+#define STT_HP_OPAQUE		(STT_LOOS + 0x1)
+#define STT_HP_STUB		(STT_LOOS + 0x2)
+
+/* HPPA relocs.  */
+
+#define R_PARISC_NONE		0	/* No reloc.  */
+#define R_PARISC_DIR32		1	/* Direct 32-bit reference.  */
+#define R_PARISC_DIR21L		2	/* Left 21 bits of eff. address.  */
+#define R_PARISC_DIR17R		3	/* Right 17 bits of eff. address.  */
+#define R_PARISC_DIR17F		4	/* 17 bits of eff. address.  */
+#define R_PARISC_DIR14R		6	/* Right 14 bits of eff. address.  */
+#define R_PARISC_PCREL32	9	/* 32-bit rel. address.  */
+#define R_PARISC_PCREL21L	10	/* Left 21 bits of rel. address.  */
+#define R_PARISC_PCREL17R	11	/* Right 17 bits of rel. address.  */
+#define R_PARISC_PCREL17F	12	/* 17 bits of rel. address.  */
+#define R_PARISC_PCREL14R	14	/* Right 14 bits of rel. address.  */
+#define R_PARISC_DPREL21L	18	/* Left 21 bits of rel. address.  */
+#define R_PARISC_DPREL14R	22	/* Right 14 bits of rel. address.  */
+#define R_PARISC_GPREL21L	26	/* GP-relative, left 21 bits.  */
+#define R_PARISC_GPREL14R	30	/* GP-relative, right 14 bits.  */
+#define R_PARISC_LTOFF21L	34	/* LT-relative, left 21 bits.  */
+#define R_PARISC_LTOFF14R	38	/* LT-relative, right 14 bits.  */
+#define R_PARISC_SECREL32	41	/* 32 bits section rel. address.  */
+#define R_PARISC_SEGBASE	48	/* No relocation, set segment base.  */
+#define R_PARISC_SEGREL32	49	/* 32 bits segment rel. address.  */
+#define R_PARISC_PLTOFF21L	50	/* PLT rel. address, left 21 bits.  */
+#define R_PARISC_PLTOFF14R	54	/* PLT rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_FPTR32	57	/* 32 bits LT-rel. function pointer. */
+#define R_PARISC_LTOFF_FPTR21L	58	/* LT-rel. fct ptr, left 21 bits. */
+#define R_PARISC_LTOFF_FPTR14R	62	/* LT-rel. fct ptr, right 14 bits. */
+#define R_PARISC_FPTR64		64	/* 64 bits function address.  */
+#define R_PARISC_PLABEL32	65	/* 32 bits function address.  */
+#define R_PARISC_PCREL64	72	/* 64 bits PC-rel. address.  */
+#define R_PARISC_PCREL22F	74	/* 22 bits PC-rel. address.  */
+#define R_PARISC_PCREL14WR	75	/* PC-rel. address, right 14 bits.  */
+#define R_PARISC_PCREL14DR	76	/* PC rel. address, right 14 bits.  */
+#define R_PARISC_PCREL16F	77	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16WF	78	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16DF	79	/* 16 bits PC-rel. address.  */
+#define R_PARISC_DIR64		80	/* 64 bits of eff. address.  */
+#define R_PARISC_DIR14WR	83	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR14DR	84	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR16F		85	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16WF	86	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16DF	87	/* 16 bits of eff. address.  */
+#define R_PARISC_GPREL64	88	/* 64 bits of GP-rel. address.  */
+#define R_PARISC_GPREL14WR	91	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL14DR	92	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL16F	93	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16WF	94	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16DF	95	/* 16 bits GP-rel. address.  */
+#define R_PARISC_LTOFF64	96	/* 64 bits LT-rel. address.  */
+#define R_PARISC_LTOFF14WR	99	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF14DR	100	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF16F	101	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16WF	102	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16DF	103	/* 16 bits LT-rel. address.  */
+#define R_PARISC_SECREL64	104	/* 64 bits section rel. address.  */
+#define R_PARISC_SEGREL64	112	/* 64 bits segment rel. address.  */
+#define R_PARISC_PLTOFF14WR	115	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF14DR	116	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF16F	117	/* 16 bits LT-rel. address.  */
+#define R_PARISC_PLTOFF16WF	118	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_PLTOFF16DF	119	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_LTOFF_FPTR64	120	/* 64 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR14WR	123	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR14DR	124	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR16F	125	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16WF	126	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16DF	127	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LORESERVE	128
+#define R_PARISC_COPY		128	/* Copy relocation.  */
+#define R_PARISC_IPLT		129	/* Dynamic reloc, imported PLT */
+#define R_PARISC_EPLT		130	/* Dynamic reloc, exported PLT */
+#define R_PARISC_TPREL32	153	/* 32 bits TP-rel. address.  */
+#define R_PARISC_TPREL21L	154	/* TP-rel. address, left 21 bits.  */
+#define R_PARISC_TPREL14R	158	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_TP21L	162	/* LT-TP-rel. address, left 21 bits. */
+#define R_PARISC_LTOFF_TP14R	166	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14F	167	/* 14 bits LT-TP-rel. address.  */
+#define R_PARISC_TPREL64	216	/* 64 bits TP-rel. address.  */
+#define R_PARISC_TPREL14WR	219	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL14DR	220	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL16F	221	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16WF	222	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16DF	223	/* 16 bits TP-rel. address.  */
+#define R_PARISC_LTOFF_TP64	224	/* 64 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP14WR	227	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14DR	228	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP16F	229	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16WF	230	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16DF	231	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_HIRESERVE	255
+
+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PT_HP_TLS		(PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE		(PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION	(PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL	(PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM		(PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC		(PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE	(PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK	(PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM		(PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF		(PT_LOOS + 0x9)
+#define PT_HP_PARALLEL		(PT_LOOS + 0x10)
+#define PT_HP_FASTBIND		(PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT		(PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT		(PT_LOOS + 0x13)
+#define PT_HP_STACK		(PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT	0x70000000
+#define PT_PARISC_UNWIND	0x70000001
+
+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PF_PARISC_SBP		0x08000000
+
+#define PF_HP_PAGE_SIZE		0x00100000
+#define PF_HP_FAR_SHARED	0x00200000
+#define PF_HP_NEAR_SHARED	0x00400000
+#define PF_HP_CODE		0x01000000
+#define PF_HP_MODIFY		0x02000000
+#define PF_HP_LAZYSWAP		0x04000000
+#define PF_HP_SBP		0x08000000
+
+
+/* Alpha specific definitions.  */
+
+/* Legal values for e_flags field of Elf64_Ehdr.  */
+
+#define EF_ALPHA_32BIT		1	/* All addresses must be < 2GB.  */
+#define EF_ALPHA_CANRELAX	2	/* Relocations for relaxing exist.  */
+
+/* Legal values for sh_type field of Elf64_Shdr.  */
+
+/* These two are primarily concerned with ECOFF debugging info.  */
+#define SHT_ALPHA_DEBUG		0x70000001
+#define SHT_ALPHA_REGINFO	0x70000002
+
+/* Legal values for sh_flags field of Elf64_Shdr.  */
+
+#define SHF_ALPHA_GPREL		0x10000000
+
+/* Legal values for st_other field of Elf64_Sym.  */
+#define STO_ALPHA_NOPV		0x80	/* No PV required.  */
+#define STO_ALPHA_STD_GPLOAD	0x88	/* PV only used for initial ldgp.  */
+
+/* Alpha relocs.  */
+
+#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_GPRELHIGH	17	/* GP relative 32 bit, high 16 bits */
+#define R_ALPHA_GPRELLOW	18	/* GP relative 32 bit, low 16 bits */
+#define R_ALPHA_GPREL16		19	/* GP relative 16 bit */
+#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 */
+#define R_ALPHA_TLS_GD_HI	28
+#define R_ALPHA_TLSGD		29
+#define R_ALPHA_TLS_LDM		30
+#define R_ALPHA_DTPMOD64	31
+#define R_ALPHA_GOTDTPREL	32
+#define R_ALPHA_DTPREL64	33
+#define R_ALPHA_DTPRELHI	34
+#define R_ALPHA_DTPRELLO	35
+#define R_ALPHA_DTPREL16	36
+#define R_ALPHA_GOTTPREL	37
+#define R_ALPHA_TPREL64		38
+#define R_ALPHA_TPRELHI		39
+#define R_ALPHA_TPRELLO		40
+#define R_ALPHA_TPREL16		41
+/* Keep this the last entry.  */
+#define R_ALPHA_NUM		46
+
+/* Magic values of the LITUSE relocation addend.  */
+#define LITUSE_ALPHA_ADDR	0
+#define LITUSE_ALPHA_BASE	1
+#define LITUSE_ALPHA_BYTOFF	2
+#define LITUSE_ALPHA_JSR	3
+#define LITUSE_ALPHA_TLS_GD	4
+#define LITUSE_ALPHA_TLS_LDM	5
+
+
+/* PowerPC specific declarations */
+
+/* Values for Elf32/64_Ehdr.e_flags.  */
+#define EF_PPC_EMB		0x80000000	/* PowerPC embedded flag */
+
+/* Cygnus local bits below */
+#define EF_PPC_RELOCATABLE	0x00010000	/* PowerPC -mrelocatable flag*/
+#define EF_PPC_RELOCATABLE_LIB	0x00008000	/* PowerPC -mrelocatable-lib
+						   flag */
+
+/* PowerPC relocations defined by the ABIs */
+#define R_PPC_NONE		0
+#define R_PPC_ADDR32		1	/* 32bit absolute address */
+#define R_PPC_ADDR24		2	/* 26bit address, 2 bits ignored.  */
+#define R_PPC_ADDR16		3	/* 16bit absolute address */
+#define R_PPC_ADDR16_LO		4	/* lower 16bit of absolute address */
+#define R_PPC_ADDR16_HI		5	/* high 16bit of absolute address */
+#define R_PPC_ADDR16_HA		6	/* adjusted high 16bit */
+#define R_PPC_ADDR14		7	/* 16bit address, 2 bits ignored */
+#define R_PPC_ADDR14_BRTAKEN	8
+#define R_PPC_ADDR14_BRNTAKEN	9
+#define R_PPC_REL24		10	/* PC relative 26 bit */
+#define R_PPC_REL14		11	/* PC relative 16 bit */
+#define R_PPC_REL14_BRTAKEN	12
+#define R_PPC_REL14_BRNTAKEN	13
+#define R_PPC_GOT16		14
+#define R_PPC_GOT16_LO		15
+#define R_PPC_GOT16_HI		16
+#define R_PPC_GOT16_HA		17
+#define R_PPC_PLTREL24		18
+#define R_PPC_COPY		19
+#define R_PPC_GLOB_DAT		20
+#define R_PPC_JMP_SLOT		21
+#define R_PPC_RELATIVE		22
+#define R_PPC_LOCAL24PC		23
+#define R_PPC_UADDR32		24
+#define R_PPC_UADDR16		25
+#define R_PPC_REL32		26
+#define R_PPC_PLT32		27
+#define R_PPC_PLTREL32		28
+#define R_PPC_PLT16_LO		29
+#define R_PPC_PLT16_HI		30
+#define R_PPC_PLT16_HA		31
+#define R_PPC_SDAREL16		32
+#define R_PPC_SECTOFF		33
+#define R_PPC_SECTOFF_LO	34
+#define R_PPC_SECTOFF_HI	35
+#define R_PPC_SECTOFF_HA	36
+/* Keep this the last entry.  */
+#define R_PPC_NUM		37
+
+/* PowerPC64 relocations defined by the ABIs */
+#define R_PPC64_NONE    R_PPC_NONE
+#define R_PPC64_ADDR32  R_PPC_ADDR32  /* 32bit absolute address.  */
+#define R_PPC64_ADDR24  R_PPC_ADDR24  /* 26bit address, word aligned.  */
+#define R_PPC64_ADDR16  R_PPC_ADDR16  /* 16bit absolute address. */
+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address.  */
+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */
+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits.  */
+#define R_PPC64_ADDR14 R_PPC_ADDR14   /* 16bit address, word aligned.  */
+#define R_PPC64_ADDR14_BRTAKEN  R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24   R_PPC_REL24 /* PC relative 26 bit, word aligned.  */
+#define R_PPC64_REL14   R_PPC_REL14 /* PC relative 16 bit. */
+#define R_PPC64_REL14_BRTAKEN   R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN  R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16     R_PPC_GOT16
+#define R_PPC64_GOT16_LO  R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI  R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA  R_PPC_GOT16_HA
+
+#define R_PPC64_COPY      R_PPC_COPY
+#define R_PPC64_GLOB_DAT  R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT  R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE  R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32   R_PPC_UADDR32
+#define R_PPC64_UADDR16   R_PPC_UADDR16
+#define R_PPC64_REL32     R_PPC_REL32
+#define R_PPC64_PLT32     R_PPC_PLT32
+#define R_PPC64_PLTREL32  R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO  R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI  R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA  R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF     R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO  R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI  R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA  R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30          37  /* word30 (S + A - P) >> 2.  */
+#define R_PPC64_ADDR64          38  /* doubleword64 S + A.  */
+#define R_PPC64_ADDR16_HIGHER   39  /* half16 #higher(S + A).  */
+#define R_PPC64_ADDR16_HIGHERA  40  /* half16 #highera(S + A).  */
+#define R_PPC64_ADDR16_HIGHEST  41  /* half16 #highest(S + A).  */
+#define R_PPC64_ADDR16_HIGHESTA 42  /* half16 #highesta(S + A). */
+#define R_PPC64_UADDR64     43  /* doubleword64 S + A.  */
+#define R_PPC64_REL64       44  /* doubleword64 S + A - P.  */
+#define R_PPC64_PLT64       45  /* doubleword64 L + A.  */
+#define R_PPC64_PLTREL64    46  /* doubleword64 L + A - P.  */
+#define R_PPC64_TOC16       47  /* half16* S + A - .TOC.  */
+#define R_PPC64_TOC16_LO    48  /* half16 #lo(S + A - .TOC.).  */
+#define R_PPC64_TOC16_HI    49  /* half16 #hi(S + A - .TOC.).  */
+#define R_PPC64_TOC16_HA    50  /* half16 #ha(S + A - .TOC.).  */
+#define R_PPC64_TOC         51  /* doubleword64 .TOC. */
+#define R_PPC64_PLTGOT16    52  /* half16* M + A.  */
+#define R_PPC64_PLTGOT16_LO 53  /* half16 #lo(M + A).  */
+#define R_PPC64_PLTGOT16_HI 54  /* half16 #hi(M + A).  */
+#define R_PPC64_PLTGOT16_HA 55  /* half16 #ha(M + A).  */
+
+#define R_PPC64_ADDR16_DS      56 /* half16ds* (S + A) >> 2.  */
+#define R_PPC64_ADDR16_LO_DS   57 /* half16ds  #lo(S + A) >> 2.  */
+#define R_PPC64_GOT16_DS       58 /* half16ds* (G + A) >> 2.  */
+#define R_PPC64_GOT16_LO_DS    59 /* half16ds  #lo(G + A) >> 2.  */
+#define R_PPC64_PLT16_LO_DS    60 /* half16ds  #lo(L + A) >> 2.  */
+#define R_PPC64_SECTOFF_DS     61 /* half16ds* (R + A) >> 2.  */
+#define R_PPC64_SECTOFF_LO_DS  62 /* half16ds  #lo(R + A) >> 2.  */
+#define R_PPC64_TOC16_DS       63 /* half16ds* (S + A - .TOC.) >> 2.  */
+#define R_PPC64_TOC16_LO_DS    64 /* half16ds  #lo(S + A - .TOC.) >> 2.  */
+#define R_PPC64_PLTGOT16_DS    65 /* half16ds* (M + A) >> 2.  */
+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds  #lo(M + A) >> 2.  */
+/* Keep this the last entry.  */
+#define R_PPC64_NUM		67
+
+/* The remaining relocs are from the Embedded ELF ABI, and are not
+   in the SVR4 ELF ABI.  */
+#define R_PPC_EMB_NADDR32	101
+#define R_PPC_EMB_NADDR16	102
+#define R_PPC_EMB_NADDR16_LO	103
+#define R_PPC_EMB_NADDR16_HI	104
+#define R_PPC_EMB_NADDR16_HA	105
+#define R_PPC_EMB_SDAI16	106
+#define R_PPC_EMB_SDA2I16	107
+#define R_PPC_EMB_SDA2REL	108
+#define R_PPC_EMB_SDA21		109	/* 16 bit offset in SDA */
+#define R_PPC_EMB_MRKREF	110
+#define R_PPC_EMB_RELSEC16	111
+#define R_PPC_EMB_RELST_LO	112
+#define R_PPC_EMB_RELST_HI	113
+#define R_PPC_EMB_RELST_HA	114
+#define R_PPC_EMB_BIT_FLD	115
+#define R_PPC_EMB_RELSDA	116	/* 16 bit relative offset in SDA */
+
+/* Diab tool relocations.  */
+#define R_PPC_DIAB_SDA21_LO	180	/* like EMB_SDA21, but lower 16 bit */
+#define R_PPC_DIAB_SDA21_HI	181	/* like EMB_SDA21, but high 16 bit */
+#define R_PPC_DIAB_SDA21_HA	182	/* like EMB_SDA21, adjusted high 16 */
+#define R_PPC_DIAB_RELSDA_LO	183	/* like EMB_RELSDA, but lower 16 bit */
+#define R_PPC_DIAB_RELSDA_HI	184	/* like EMB_RELSDA, but high 16 bit */
+#define R_PPC_DIAB_RELSDA_HA	185	/* like EMB_RELSDA, adjusted high 16 */
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+   that may still be in object files.  */
+#define R_PPC_TOC16		255
+
+/* PowerPC64 specific values for the Dyn d_tag field.  */
+#define DT_PPC64_GLINK  (DT_LOPROC + 0)
+#define DT_PPC64_NUM    1
+
+/* ARM specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_ARM_RELEXEC     0x01
+#define EF_ARM_HASENTRY    0x02
+#define EF_ARM_INTERWORK   0x04
+#define EF_ARM_APCS_26     0x08
+#define EF_ARM_APCS_FLOAT  0x10
+#define EF_ARM_PIC         0x20
+#define EF_ARM_ALIGN8      0x40		/* 8-bit structure alignment is in use */
+#define EF_ARM_NEW_ABI     0x80
+#define EF_ARM_OLD_ABI     0x100
+
+/* Other constants defined in the ARM ELF spec. version B-01.  */
+/* NB. These conflict with values defined above.  */
+#define EF_ARM_SYMSARESORTED	0x04
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08
+#define EF_ARM_MAPSYMSFIRST	0x10
+#define EF_ARM_EABIMASK		0XFF000000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN  0x00000000
+#define EF_ARM_EABI_VER1     0x01000000
+#define EF_ARM_EABI_VER2     0x02000000
+
+/* Additional symbol types for Thumb */
+#define STT_ARM_TFUNC      0xd
+
+/* ARM-specific values for sh_flags */
+#define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
+#define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
+					   in the input to a link step */
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB          0x10000000   /* Segment contains the location
+					   addressed by the static base */
+
+/* ARM relocs.  */
+#define R_ARM_NONE		0	/* No reloc */
+#define R_ARM_PC24		1	/* PC relative 26 bit branch */
+#define R_ARM_ABS32		2	/* Direct 32 bit  */
+#define R_ARM_REL32		3	/* PC relative 32 bit */
+#define R_ARM_PC13		4
+#define R_ARM_ABS16		5	/* Direct 16 bit */
+#define R_ARM_ABS12		6	/* Direct 12 bit */
+#define R_ARM_THM_ABS5		7
+#define R_ARM_ABS8		8	/* Direct 8 bit */
+#define R_ARM_SBREL32		9
+#define R_ARM_THM_PC22		10
+#define R_ARM_THM_PC8		11
+#define R_ARM_AMP_VCALL9	12
+#define R_ARM_SWI24		13
+#define R_ARM_THM_SWI8		14
+#define R_ARM_XPC25		15
+#define R_ARM_THM_XPC22		16
+#define R_ARM_COPY		20	/* Copy symbol at runtime */
+#define R_ARM_GLOB_DAT		21	/* Create GOT entry */
+#define R_ARM_JUMP_SLOT		22	/* Create PLT entry */
+#define R_ARM_RELATIVE		23	/* Adjust by program base */
+#define R_ARM_GOTOFF		24	/* 32 bit offset to GOT */
+#define R_ARM_GOTPC		25	/* 32 bit PC relative offset to GOT */
+#define R_ARM_GOT32		26	/* 32 bit GOT entry */
+#define R_ARM_PLT32		27	/* 32 bit PLT address */
+#define R_ARM_ALU_PCREL_7_0	32
+#define R_ARM_ALU_PCREL_15_8	33
+#define R_ARM_ALU_PCREL_23_15	34
+#define R_ARM_LDR_SBREL_11_0	35
+#define R_ARM_ALU_SBREL_19_12	36
+#define R_ARM_ALU_SBREL_27_20	37
+#define R_ARM_GNU_VTENTRY	100
+#define R_ARM_GNU_VTINHERIT	101
+#define R_ARM_THM_PC11		102	/* thumb unconditional branch */
+#define R_ARM_THM_PC9		103	/* thumb conditional branch */
+#define R_ARM_RXPC25		249
+#define R_ARM_RSBREL32		250
+#define R_ARM_THM_RPC22		251
+#define R_ARM_RREL32		252
+#define R_ARM_RABS22		253
+#define R_ARM_RPC24		254
+#define R_ARM_RBASE		255
+/* Keep this the last entry.  */
+#define R_ARM_NUM		256
+
+/* IA-64 specific declarations.  */
+
+/* Processor specific flags for the Ehdr e_flags field.  */
+#define EF_IA_64_MASKOS		0x0000000f	/* os-specific flags */
+#define EF_IA_64_ABI64		0x00000010	/* 64-bit ABI */
+#define EF_IA_64_ARCH		0xff000000	/* arch. version mask */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_IA_64_ARCHEXT	(PT_LOPROC + 0)	/* arch extension bits */
+#define PT_IA_64_UNWIND		(PT_LOPROC + 1)	/* ia64 unwind bits */
+
+/* Processor specific flags for the Phdr p_flags field.  */
+#define PF_IA_64_NORECOV	0x80000000	/* spec insns w/o recovery */
+
+/* Processor specific values for the Shdr sh_type field.  */
+#define SHT_IA_64_EXT		(SHT_LOPROC + 0) /* extension bits */
+#define SHT_IA_64_UNWIND	(SHT_LOPROC + 1) /* unwind bits */
+
+/* Processor specific flags for the Shdr sh_flags field.  */
+#define SHF_IA_64_SHORT		0x10000000	/* section near gp */
+#define SHF_IA_64_NORECOV	0x20000000	/* spec insns w/o recovery */
+
+/* Processor specific values for the Dyn d_tag field.  */
+#define DT_IA_64_PLT_RESERVE	(DT_LOPROC + 0)
+#define DT_IA_64_NUM		1
+
+/* IA-64 relocations.  */
+#define R_IA64_NONE		0x00	/* none */
+#define R_IA64_IMM14		0x21	/* symbol + addend, add imm14 */
+#define R_IA64_IMM22		0x22	/* symbol + addend, add imm22 */
+#define R_IA64_IMM64		0x23	/* symbol + addend, mov imm64 */
+#define R_IA64_DIR32MSB		0x24	/* symbol + addend, data4 MSB */
+#define R_IA64_DIR32LSB		0x25	/* symbol + addend, data4 LSB */
+#define R_IA64_DIR64MSB		0x26	/* symbol + addend, data8 MSB */
+#define R_IA64_DIR64LSB		0x27	/* symbol + addend, data8 LSB */
+#define R_IA64_GPREL22		0x2a	/* @gprel(sym + add), add imm22 */
+#define R_IA64_GPREL64I		0x2b	/* @gprel(sym + add), mov imm64 */
+#define R_IA64_GPREL32MSB	0x2c	/* @gprel(sym + add), data4 MSB */
+#define R_IA64_GPREL32LSB	0x2d	/* @gprel(sym + add), data4 LSB */
+#define R_IA64_GPREL64MSB	0x2e	/* @gprel(sym + add), data8 MSB */
+#define R_IA64_GPREL64LSB	0x2f	/* @gprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF22		0x32	/* @ltoff(sym + add), add imm22 */
+#define R_IA64_LTOFF64I		0x33	/* @ltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF22		0x3a	/* @pltoff(sym + add), add imm22 */
+#define R_IA64_PLTOFF64I	0x3b	/* @pltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF64MSB	0x3e	/* @pltoff(sym + add), data8 MSB */
+#define R_IA64_PLTOFF64LSB	0x3f	/* @pltoff(sym + add), data8 LSB */
+#define R_IA64_FPTR64I		0x43	/* @fptr(sym + add), mov imm64 */
+#define R_IA64_FPTR32MSB	0x44	/* @fptr(sym + add), data4 MSB */
+#define R_IA64_FPTR32LSB	0x45	/* @fptr(sym + add), data4 LSB */
+#define R_IA64_FPTR64MSB	0x46	/* @fptr(sym + add), data8 MSB */
+#define R_IA64_FPTR64LSB	0x47	/* @fptr(sym + add), data8 LSB */
+#define R_IA64_PCREL60B		0x48	/* @pcrel(sym + add), brl */
+#define R_IA64_PCREL21B		0x49	/* @pcrel(sym + add), ptb, call */
+#define R_IA64_PCREL21M		0x4a	/* @pcrel(sym + add), chk.s */
+#define R_IA64_PCREL21F		0x4b	/* @pcrel(sym + add), fchkf */
+#define R_IA64_PCREL32MSB	0x4c	/* @pcrel(sym + add), data4 MSB */
+#define R_IA64_PCREL32LSB	0x4d	/* @pcrel(sym + add), data4 LSB */
+#define R_IA64_PCREL64MSB	0x4e	/* @pcrel(sym + add), data8 MSB */
+#define R_IA64_PCREL64LSB	0x4f	/* @pcrel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_FPTR22	0x52	/* @ltoff(@fptr(s+a)), imm22 */
+#define R_IA64_LTOFF_FPTR64I	0x53	/* @ltoff(@fptr(s+a)), imm64 */
+#define R_IA64_LTOFF_FPTR32MSB	0x54	/* @ltoff(@fptr(s+a)), data4 MSB */
+#define R_IA64_LTOFF_FPTR32LSB	0x55	/* @ltoff(@fptr(s+a)), data4 LSB */
+#define R_IA64_LTOFF_FPTR64MSB	0x56	/* @ltoff(@fptr(s+a)), data8 MSB */
+#define R_IA64_LTOFF_FPTR64LSB	0x57	/* @ltoff(@fptr(s+a)), data8 LSB */
+#define R_IA64_SEGREL32MSB	0x5c	/* @segrel(sym + add), data4 MSB */
+#define R_IA64_SEGREL32LSB	0x5d	/* @segrel(sym + add), data4 LSB */
+#define R_IA64_SEGREL64MSB	0x5e	/* @segrel(sym + add), data8 MSB */
+#define R_IA64_SEGREL64LSB	0x5f	/* @segrel(sym + add), data8 LSB */
+#define R_IA64_SECREL32MSB	0x64	/* @secrel(sym + add), data4 MSB */
+#define R_IA64_SECREL32LSB	0x65	/* @secrel(sym + add), data4 LSB */
+#define R_IA64_SECREL64MSB	0x66	/* @secrel(sym + add), data8 MSB */
+#define R_IA64_SECREL64LSB	0x67	/* @secrel(sym + add), data8 LSB */
+#define R_IA64_REL32MSB		0x6c	/* data 4 + REL */
+#define R_IA64_REL32LSB		0x6d	/* data 4 + REL */
+#define R_IA64_REL64MSB		0x6e	/* data 8 + REL */
+#define R_IA64_REL64LSB		0x6f	/* data 8 + REL */
+#define R_IA64_LTV32MSB		0x74	/* symbol + addend, data4 MSB */
+#define R_IA64_LTV32LSB		0x75	/* symbol + addend, data4 LSB */
+#define R_IA64_LTV64MSB		0x76	/* symbol + addend, data8 MSB */
+#define R_IA64_LTV64LSB		0x77	/* symbol + addend, data8 LSB */
+#define R_IA64_PCREL21BI	0x79	/* @pcrel(sym + add), 21bit inst */
+#define R_IA64_PCREL22		0x7a	/* @pcrel(sym + add), 22bit inst */
+#define R_IA64_PCREL64I		0x7b	/* @pcrel(sym + add), 64bit inst */
+#define R_IA64_IPLTMSB		0x80	/* dynamic reloc, imported PLT, MSB */
+#define R_IA64_IPLTLSB		0x81	/* dynamic reloc, imported PLT, LSB */
+#define R_IA64_COPY		0x84	/* copy relocation */
+#define R_IA64_SUB		0x85	/* Addend and symbol difference */
+#define R_IA64_LTOFF22X		0x86	/* LTOFF22, relaxable.  */
+#define R_IA64_LDXMOV		0x87	/* Use of LTOFF22X.  */
+#define R_IA64_TPREL14		0x91	/* @tprel(sym + add), imm14 */
+#define R_IA64_TPREL22		0x92	/* @tprel(sym + add), imm22 */
+#define R_IA64_TPREL64I		0x93	/* @tprel(sym + add), imm64 */
+#define R_IA64_TPREL64MSB	0x96	/* @tprel(sym + add), data8 MSB */
+#define R_IA64_TPREL64LSB	0x97	/* @tprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_TPREL22	0x9a	/* @ltoff(@tprel(s+a)), imm2 */
+#define R_IA64_DTPMOD64MSB	0xa6	/* @dtpmod(sym + add), data8 MSB */
+#define R_IA64_DTPMOD64LSB	0xa7	/* @dtpmod(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPMOD22	0xaa	/* @ltoff(@dtpmod(sym + add)), imm22 */
+#define R_IA64_DTPREL14		0xb1	/* @dtprel(sym + add), imm14 */
+#define R_IA64_DTPREL22		0xb2	/* @dtprel(sym + add), imm22 */
+#define R_IA64_DTPREL64I	0xb3	/* @dtprel(sym + add), imm64 */
+#define R_IA64_DTPREL32MSB	0xb4	/* @dtprel(sym + add), data4 MSB */
+#define R_IA64_DTPREL32LSB	0xb5	/* @dtprel(sym + add), data4 LSB */
+#define R_IA64_DTPREL64MSB	0xb6	/* @dtprel(sym + add), data8 MSB */
+#define R_IA64_DTPREL64LSB	0xb7	/* @dtprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPREL22	0xba	/* @ltoff(@dtprel(s+a)), imm22 */
+
+/* SH specific declarations */
+
+/* SH relocs.  */
+#define	R_SH_NONE		0
+#define	R_SH_DIR32		1
+#define	R_SH_REL32		2
+#define	R_SH_DIR8WPN		3
+#define	R_SH_IND12W		4
+#define	R_SH_DIR8WPL		5
+#define	R_SH_DIR8WPZ		6
+#define	R_SH_DIR8BP		7
+#define	R_SH_DIR8W		8
+#define	R_SH_DIR8L		9
+#define	R_SH_SWITCH16		25
+#define	R_SH_SWITCH32		26
+#define	R_SH_USES		27
+#define	R_SH_COUNT		28
+#define	R_SH_ALIGN		29
+#define	R_SH_CODE		30
+#define	R_SH_DATA		31
+#define	R_SH_LABEL		32
+#define	R_SH_SWITCH8		33
+#define	R_SH_GNU_VTINHERIT	34
+#define	R_SH_GNU_VTENTRY	35
+#define	R_SH_TLS_GD_32		144
+#define	R_SH_TLS_LD_32		145
+#define	R_SH_TLS_LDO_32		146
+#define	R_SH_TLS_IE_32		147
+#define	R_SH_TLS_LE_32		148
+#define	R_SH_TLS_DTPMOD32	149
+#define	R_SH_TLS_DTPOFF32	150
+#define	R_SH_TLS_TPOFF32	151
+#define	R_SH_TLS_GD_MOV		152
+#define	R_SH_TLS_LDM_MOV	153
+#define	R_SH_TLS_LDO_MOV	154
+#define	R_SH_TLS_IE_MOV		155
+#define	R_SH_TLS_LE_MOV		156
+#define	R_SH_GOT32		160
+#define	R_SH_PLT32		161
+#define	R_SH_COPY		162
+#define	R_SH_GLOB_DAT		163
+#define	R_SH_JMP_SLOT		164
+#define	R_SH_RELATIVE		165
+#define	R_SH_GOTOFF		166
+#define	R_SH_GOTPC		167
+/* Keep this the last entry.  */
+#define	R_SH_NUM		256
+
+/* Additional s390 relocs */
+
+#define R_390_NONE	0	       /* No reloc.  */
+#define R_390_8		1	       /* Direct 8 bit.	 */
+#define R_390_12	2	       /* Direct 12 bit.  */
+#define R_390_16	3	       /* Direct 16 bit.  */
+#define R_390_32	4	       /* Direct 32 bit.  */
+#define R_390_PC32	5	       /* PC relative 32 bit.  */
+#define R_390_GOT12	6	       /* 12 bit GOT offset.  */
+#define R_390_GOT32	7	       /* 32 bit GOT offset.  */
+#define R_390_PLT32	8	       /* 32 bit PC relative PLT address.  */
+#define R_390_COPY	9	       /* Copy symbol at runtime.  */
+#define R_390_GLOB_DAT	10	       /* Create GOT entry.  */
+#define R_390_JMP_SLOT	11	       /* Create PLT entry.  */
+#define R_390_RELATIVE	12	       /* Adjust by program base.  */
+#define R_390_GOTOFF	13	       /* 32 bit offset to GOT.	 */
+#define R_390_GOTPC	14	       /* 32 bit PC relative offset to GOT.  */
+#define R_390_GOT16	15	       /* 16 bit GOT offset.  */
+#define R_390_PC16	16	       /* PC relative 16 bit.  */
+#define R_390_PC16DBL	17	       /* PC relative 16 bit shifted by 1.  */
+#define R_390_PLT16DBL	18	       /* 16 bit PC rel. PLT shifted by 1.  */
+#define R_390_PC32DBL	19	       /* PC relative 32 bit shifted by 1.  */
+#define R_390_PLT32DBL	20	       /* 32 bit PC rel. PLT shifted by 1.  */
+#define R_390_GOTPCDBL	21	       /* 32 bit PC rel. GOT shifted by 1.  */
+#define R_390_64	22	       /* Direct 64 bit.  */
+#define R_390_PC64	23	       /* PC relative 64 bit.  */
+#define R_390_GOT64	24	       /* 64 bit GOT offset.  */
+#define R_390_PLT64	25	       /* 64 bit PC relative PLT address.  */
+#define R_390_GOTENT	26	       /* 32 bit PC rel. to GOT entry >> 1. */
+
+/* Keep this the last entry.  */
+#define R_390_NUM	27
+
+/* CRIS relocations.  */
+#define R_CRIS_NONE		0
+#define R_CRIS_8		1
+#define R_CRIS_16		2
+#define R_CRIS_32		3
+#define R_CRIS_8_PCREL		4
+#define R_CRIS_16_PCREL		5
+#define R_CRIS_32_PCREL		6
+#define R_CRIS_GNU_VTINHERIT	7
+#define R_CRIS_GNU_VTENTRY	8
+#define R_CRIS_COPY		9
+#define R_CRIS_GLOB_DAT		10
+#define R_CRIS_JUMP_SLOT	11
+#define R_CRIS_RELATIVE		12
+#define R_CRIS_16_GOT		13
+#define R_CRIS_32_GOT		14
+#define R_CRIS_16_GOTPLT	15
+#define R_CRIS_32_GOTPLT	16
+#define R_CRIS_32_GOTREL	17
+#define R_CRIS_32_PLT_GOTREL	18
+#define R_CRIS_32_PLT_PCREL	19
+
+#define R_CRIS_NUM		20
+
+/* AMD x86-64 relocations.  */
+#define R_X86_64_NONE		0	/* No reloc */
+#define R_X86_64_64		1	/* Direct 64 bit  */
+#define R_X86_64_PC32		2	/* PC relative 32 bit signed */
+#define R_X86_64_GOT32		3	/* 32 bit GOT entry */
+#define R_X86_64_PLT32		4	/* 32 bit PLT address */
+#define R_X86_64_COPY		5	/* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT	6	/* Create GOT entry */
+#define R_X86_64_JUMP_SLOT	7	/* Create PLT entry */
+#define R_X86_64_RELATIVE	8	/* Adjust by program base */
+#define R_X86_64_GOTPCREL	9	/* 32 bit signed PC relative
+					   offset to GOT */
+#define R_X86_64_32		10	/* Direct 32 bit zero extended */
+#define R_X86_64_32S		11	/* Direct 32 bit sign extended */
+#define R_X86_64_16		12	/* Direct 16 bit zero extended */
+#define R_X86_64_PC16		13	/* 16 bit sign extended pc relative */
+#define R_X86_64_8		14	/* Direct 8 bit sign extended  */
+#define R_X86_64_PC8		15	/* 8 bit sign extended pc relative */
+#define R_X86_64_DTPMOD64	16	/* ID of module containing symbol */
+#define R_X86_64_DTPOFF64	17	/* Offset in module's TLS block */
+#define R_X86_64_TPOFF64	18	/* Offset in initial TLS block */
+#define R_X86_64_TLSGD		19	/* 32 bit signed PC relative offset
+					   to two GOT entries for GD symbol */
+#define R_X86_64_TLSLD		20	/* 32 bit signed PC relative offset
+					   to two GOT entries for LD symbol */
+#define R_X86_64_DTPOFF32	21	/* Offset in TLS block */
+#define r_x86_64_GOTTPOFF	22	/* 32 bit signed PC relative offset
+					   to GOT entry for IE symbol */
+#define R_X86_64_TPOFF32	23	/* Offset in initial TLS block */
+
+#define R_X86_64_NUM		24
+
+#if GRUB_TARGET_WORDSIZE == 32
+
+typedef Elf32_Addr Elf_Addr;
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Half Elf_Half;
+typedef Elf32_Off Elf_Off;
+typedef Elf32_Rel Elf_Rel;
+typedef Elf32_Rela Elf_Rela;
+typedef Elf32_Section Elf_Section;
+typedef Elf32_Shdr Elf_Shdr;
+typedef Elf32_Sword Elf_Sword;
+typedef Elf32_Sym Elf_Sym;
+typedef Elf32_Word Elf_Word;
+typedef Elf32_Xword Elf_Xword;
+
+#define ELF_ST_BIND(val)	ELF32_ST_BIND(val)
+#define ELF_ST_TYPE(val)	ELF32_ST_TYPE(val)
+#define ELF_R_SYM(val)		ELF32_R_SYM(val)
+#define ELF_R_TYPE(val)		ELF32_R_TYPE(val)
+#define ELF_R_INFO(sym, type)	ELF32_R_INFO(sym, type)
+
+#elif GRUB_TARGET_WORDSIZE == 64
+
+typedef Elf64_Addr Elf_Addr;
+typedef Elf64_Ehdr Elf_Ehdr;
+typedef Elf64_Half Elf_Half;
+typedef Elf64_Off Elf_Off;
+typedef Elf64_Rel Elf_Rel;
+typedef Elf64_Rela Elf_Rela;
+typedef Elf64_Section Elf_Section;
+typedef Elf64_Shdr Elf_Shdr;
+typedef Elf64_Sword Elf_Sword;
+typedef Elf64_Sym Elf_Sym;
+typedef Elf64_Word Elf_Word;
+typedef Elf64_Xword Elf_Xword;
+
+#define ELF_ST_BIND(val)	ELF64_ST_BIND (val)
+#define ELF_ST_TYPE(val)	ELF64_ST_TYPE (val)
+#define ELF_R_SYM(val)		ELF64_R_SYM(val)
+#define ELF_R_TYPE(val)		ELF64_R_TYPE(val)
+#define ELF_R_INFO(sym, type)	ELF64_R_INFO(sym, type)
+
+#endif /* GRUB_TARGET_WORDSIZE == 64 */
+
+#endif /* ! GRUB_ELF_H */
diff --git a/include/grub/elfload.h b/include/grub/elfload.h
new file mode 100644
index 0000000..6e09e0d
--- /dev/null
+++ b/include/grub/elfload.h
@@ -0,0 +1,58 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ELFLOAD_HEADER
+#define GRUB_ELFLOAD_HEADER	1
+
+#include <grub/err.h>
+#include <grub/elf.h>
+#include <grub/file.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+struct grub_elf_file
+{
+  grub_file_t file;
+  union {
+    Elf64_Ehdr ehdr64;
+    Elf32_Ehdr ehdr32;
+  } ehdr;
+  void *phdrs;
+};
+typedef struct grub_elf_file *grub_elf_t;
+
+typedef grub_err_t (*grub_elf32_load_hook_t)
+  (Elf32_Phdr *phdr, grub_addr_t *addr, int *load);
+typedef grub_err_t (*grub_elf64_load_hook_t)
+  (Elf64_Phdr *phdr, grub_addr_t *addr, int *load);
+
+grub_elf_t grub_elf_open (const char *);
+grub_elf_t grub_elf_file (grub_file_t);
+grub_err_t grub_elf_close (grub_elf_t);
+
+int grub_elf_is_elf32 (grub_elf_t);
+grub_size_t grub_elf32_size (grub_elf_t);
+grub_err_t grub_elf32_load (grub_elf_t, grub_elf32_load_hook_t, grub_addr_t *,
+			    grub_size_t *);
+
+int grub_elf_is_elf64 (grub_elf_t);
+grub_size_t grub_elf64_size (grub_elf_t);
+grub_err_t grub_elf64_load (grub_elf_t, grub_elf64_load_hook_t, grub_addr_t *,
+			    grub_size_t *);
+
+#endif /* ! GRUB_ELFLOAD_HEADER */
diff --git a/include/grub/env.h b/include/grub/env.h
new file mode 100644
index 0000000..440185a
--- /dev/null
+++ b/include/grub/env.h
@@ -0,0 +1,72 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ENV_HEADER
+#define GRUB_ENV_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+
+struct grub_env_var;
+
+typedef char *(*grub_env_read_hook_t) (struct grub_env_var *var,
+				       const char *val);
+typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var,
+					const char *val);
+
+enum grub_env_var_type
+  {
+    /* The default variable type which is local in current context.  */
+    GRUB_ENV_VAR_LOCAL,
+
+    /* The exported type, which is passed to new contexts.  */
+    GRUB_ENV_VAR_GLOBAL,
+
+    /* The data slot type, which is used to store arbitrary data.  */
+    GRUB_ENV_VAR_DATA
+  };
+
+struct grub_env_var
+{
+  char *name;
+  char *value;
+  grub_env_read_hook_t read_hook;
+  grub_env_write_hook_t write_hook;
+  struct grub_env_var *next;
+  struct grub_env_var **prevp;
+  enum grub_env_var_type type;
+};
+
+grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val);
+char *EXPORT_FUNC(grub_env_get) (const char *name);
+void EXPORT_FUNC(grub_env_unset) (const char *name);
+void EXPORT_FUNC(grub_env_iterate) (int (*func) (struct grub_env_var *var));
+grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name,
+						     grub_env_read_hook_t read_hook,
+						     grub_env_write_hook_t write_hook);
+grub_err_t EXPORT_FUNC(grub_env_context_open) (int export);
+grub_err_t EXPORT_FUNC(grub_env_context_close) (void);
+grub_err_t EXPORT_FUNC(grub_env_export) (const char *name);
+
+grub_err_t EXPORT_FUNC(grub_env_set_data_slot) (const char *name,
+						const void *ptr);
+void *EXPORT_FUNC(grub_env_get_data_slot) (const char *name);
+void EXPORT_FUNC(grub_env_unset_data_slot) (const char *name);
+
+#endif /* ! GRUB_ENV_HEADER */
diff --git a/include/grub/err.h b/include/grub/err.h
new file mode 100644
index 0000000..7a5ce1a
--- /dev/null
+++ b/include/grub/err.h
@@ -0,0 +1,72 @@
+/* err.h - error numbers and prototypes */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ERR_HEADER
+#define GRUB_ERR_HEADER	1
+
+#include <grub/symbol.h>
+
+typedef enum
+  {
+    GRUB_ERR_NONE = 0,
+    GRUB_ERR_TEST_FAILURE,
+    GRUB_ERR_BAD_MODULE,
+    GRUB_ERR_OUT_OF_MEMORY,
+    GRUB_ERR_BAD_FILE_TYPE,
+    GRUB_ERR_FILE_NOT_FOUND,
+    GRUB_ERR_FILE_READ_ERROR,
+    GRUB_ERR_BAD_FILENAME,
+    GRUB_ERR_UNKNOWN_FS,
+    GRUB_ERR_BAD_FS,
+    GRUB_ERR_BAD_NUMBER,
+    GRUB_ERR_OUT_OF_RANGE,
+    GRUB_ERR_UNKNOWN_DEVICE,
+    GRUB_ERR_BAD_DEVICE,
+    GRUB_ERR_READ_ERROR,
+    GRUB_ERR_WRITE_ERROR,
+    GRUB_ERR_UNKNOWN_COMMAND,
+    GRUB_ERR_INVALID_COMMAND,
+    GRUB_ERR_BAD_ARGUMENT,
+    GRUB_ERR_BAD_PART_TABLE,
+    GRUB_ERR_UNKNOWN_OS,
+    GRUB_ERR_BAD_OS,
+    GRUB_ERR_NO_KERNEL,
+    GRUB_ERR_BAD_FONT,
+    GRUB_ERR_NOT_IMPLEMENTED_YET,
+    GRUB_ERR_SYMLINK_LOOP,
+    GRUB_ERR_BAD_GZIP_DATA,
+    GRUB_ERR_MENU,
+    GRUB_ERR_TIMEOUT,
+    GRUB_ERR_IO,
+    GRUB_ERR_ACCESS_DENIED
+  }
+grub_err_t;
+
+extern grub_err_t EXPORT_VAR(grub_errno);
+extern char EXPORT_VAR(grub_errmsg)[];
+
+grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...);
+void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn));
+void EXPORT_FUNC(grub_error_push) (void);
+int EXPORT_FUNC(grub_error_pop) (void);
+void EXPORT_FUNC(grub_print_error) (void);
+int EXPORT_FUNC(grub_err_printf) (const char *fmt, ...)
+__attribute__ ((format (printf, 1, 2)));
+
+#endif /* ! GRUB_ERR_HEADER */
diff --git a/include/grub/extcmd.h b/include/grub/extcmd.h
new file mode 100644
index 0000000..03eaba8
--- /dev/null
+++ b/include/grub/extcmd.h
@@ -0,0 +1,55 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EXTCMD_HEADER
+#define GRUB_EXTCMD_HEADER	1
+
+#include <grub/lib/arg.h>
+#include <grub/command.h>
+
+struct grub_extcmd;
+
+typedef grub_err_t (*grub_extcmd_func_t) (struct grub_extcmd *cmd,
+					  int argc, char **args);
+
+/* The argcmd description.  */
+struct grub_extcmd
+{
+  grub_command_t cmd;
+
+  grub_extcmd_func_t func;
+
+  /* The argument parser optionlist.  */
+  const struct grub_arg_option *options;
+
+  void *data;
+
+  struct grub_arg_list *state;
+};
+typedef struct grub_extcmd *grub_extcmd_t;
+
+grub_extcmd_t grub_register_extcmd (const char *name,
+				    grub_extcmd_func_t func,
+				    unsigned flags,
+				    const char *summary,
+				    const char *description,
+				    const struct grub_arg_option *parser);
+
+void grub_unregister_extcmd (grub_extcmd_t cmd);
+
+#endif /* ! GRUB_EXTCMD_HEADER */
diff --git a/include/grub/fbblit.h b/include/grub/fbblit.h
new file mode 100644
index 0000000..af97dfb
--- /dev/null
+++ b/include/grub/fbblit.h
@@ -0,0 +1,182 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FBBLIT_HEADER
+#define GRUB_FBBLIT_HEADER	1
+
+/* NOTE: This header is private header for fb driver and should not be used
+   in other parts of the code.  */
+
+struct grub_video_fbblit_info;
+
+void
+grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
+			   struct grub_video_fbblit_info *src,
+			   int x, int y, int width, int height,
+			   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
+				   struct grub_video_fbblit_info *src,
+				   int x, int y, int width, int height,
+				   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
+					     struct grub_video_fbblit_info *src,
+					     int x, int y, int width, int height,
+					     int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
+					 struct grub_video_fbblit_info *src,
+					 int x, int y,
+					 int width, int height,
+					 int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
+					  struct grub_video_fbblit_info *src,
+					  int x, int y,
+					  int width, int height,
+					  int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
+					struct grub_video_fbblit_info *src,
+					int x, int y, int width, int height,
+					int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
+			 struct grub_video_fbblit_info *src,
+			 int x, int y, int width, int height,
+			 int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					 struct grub_video_fbblit_info *src,
+					 int x, int y,
+					 int width, int height,
+					 int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					 struct grub_video_fbblit_info *src,
+					 int x, int y,
+					 int width, int height,
+					 int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
+					struct grub_video_fbblit_info *src,
+					int x, int y,
+					int width, int height,
+					int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst,
+				      struct grub_video_fbblit_info *src,
+				      int x, int y,
+				      int width, int height,
+				      int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_24bit_1bit (struct grub_video_fbblit_info *dst,
+				      struct grub_video_fbblit_info *src,
+				      int x, int y,
+				      int width, int height,
+				      int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst,
+				      struct grub_video_fbblit_info *src,
+				      int x, int y,
+				      int width, int height,
+				      int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_8bit_1bit (struct grub_video_fbblit_info *dst,
+				     struct grub_video_fbblit_info *src,
+				     int x, int y,
+				     int width, int height,
+				     int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst,
+				       struct grub_video_fbblit_info *src,
+				       int x, int y,
+				       int width, int height,
+				       int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst,
+				       struct grub_video_fbblit_info *src,
+				       int x, int y,
+				       int width, int height,
+				       int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst,
+				     struct grub_video_fbblit_info *src,
+				     int x, int y,
+				     int width, int height,
+				     int offset_x, int offset_y);
+#endif /* ! GRUB_FBBLIT_HEADER */
diff --git a/include/grub/fbfill.h b/include/grub/fbfill.h
new file mode 100644
index 0000000..c85fa12
--- /dev/null
+++ b/include/grub/fbfill.h
@@ -0,0 +1,75 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FBFILL_HEADER
+#define GRUB_FBFILL_HEADER	1
+
+/* NOTE: This header is private header for fb driver and should not be used
+   in other parts of the code.  */
+
+struct grub_video_fbblit_info;
+
+struct grub_video_fbrender_target
+{
+  /* Copy of the screen's mode info structure, except that width, height and
+     mode_type has been re-adjusted to requested render target settings.  */
+  struct grub_video_mode_info mode_info;
+
+  struct
+  {
+    unsigned int x;
+    unsigned int y;
+    unsigned int width;
+    unsigned int height;
+  } viewport;
+
+  /* Indicates whether the data has been allocated by us and must be freed
+     when render target is destroyed.  */
+  int is_allocated;
+
+  /* Pointer to data.  Can either be in video card memory or in local host's
+     memory.  */
+  grub_uint8_t *data;
+};
+
+void
+grub_video_fbfill (struct grub_video_fbblit_info *dst,
+		   grub_video_color_t color, int x, int y,
+		   int width, int height);
+
+void
+grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst,
+			    grub_video_color_t color,  int x, int y,
+			    int width, int height);
+
+void
+grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst,
+			    grub_video_color_t color, int x, int y,
+			    int width, int height);
+
+void
+grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
+			    grub_video_color_t color, int x, int y,
+			    int width, int height);
+
+void
+grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst,
+			   grub_video_color_t color, int x, int y,
+			   int width, int height);
+
+#endif /* ! GRUB_FBFILL_HEADER */
diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h
new file mode 100644
index 0000000..065ccf9
--- /dev/null
+++ b/include/grub/fbutil.h
@@ -0,0 +1,43 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* NOTE: This header is private header for vbe driver and should not be used
+   in other parts of the code.  */
+
+#ifndef GRUB_VBEUTIL_MACHINE_HEADER
+#define GRUB_VBEUTIL_MACHINE_HEADER	1
+
+#include <grub/types.h>
+#include <grub/video.h>
+
+struct grub_video_fbblit_info
+{
+  struct grub_video_mode_info *mode_info;
+  grub_uint8_t *data;
+};
+
+grub_uint8_t *grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
+                            unsigned int x, unsigned int y);
+
+grub_video_color_t get_pixel (struct grub_video_fbblit_info *source,
+                              unsigned int x, unsigned int y);
+
+void set_pixel (struct grub_video_fbblit_info *source,
+                unsigned int x, unsigned int y, grub_video_color_t color);
+
+#endif /* ! GRUB_VBEUTIL_MACHINE_HEADER */
diff --git a/include/grub/file.h b/include/grub/file.h
new file mode 100644
index 0000000..2aacf93
--- /dev/null
+++ b/include/grub/file.h
@@ -0,0 +1,72 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FILE_HEADER
+#define GRUB_FILE_HEADER	1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/device.h>
+#include <grub/fs.h>
+
+/* File description.  */
+struct grub_file
+{
+  /* The underlying device.  */
+  grub_device_t device;
+
+  /* The underlying filesystem.  */
+  grub_fs_t fs;
+
+  /* The current offset.  */
+  grub_off_t offset;
+
+  /* The file size.  */
+  grub_off_t size;
+
+  /* Filesystem-specific data.  */
+  void *data;
+
+  /* This is called when a sector is read. Used only for a disk device.  */
+  void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+		     unsigned offset, unsigned length);
+};
+typedef struct grub_file *grub_file_t;
+
+/* Get a device name from NAME.  */
+char *EXPORT_FUNC(grub_file_get_device_name) (const char *name);
+
+grub_file_t EXPORT_FUNC(grub_file_open) (const char *name);
+grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, void *buf,
+					  grub_size_t len);
+grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset);
+grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file);
+
+static inline grub_off_t
+grub_file_size (const grub_file_t file)
+{
+  return file->size;
+}
+
+static inline grub_off_t
+grub_file_tell (const grub_file_t file)
+{
+  return file->offset;
+}
+
+#endif /* ! GRUB_FILE_HEADER */
diff --git a/include/grub/font.h b/include/grub/font.h
new file mode 100644
index 0000000..8a5f3ac
--- /dev/null
+++ b/include/grub/font.h
@@ -0,0 +1,115 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FONT_HEADER
+#define GRUB_FONT_HEADER	1
+
+#include <grub/types.h>
+#include <grub/video.h>
+
+/* Forward declaration of opaque structure grub_font.
+   Users only pass struct grub_font pointers to the font module functions,
+   and do not have knowledge of the structure contents.  */
+struct grub_font;
+
+/* Font type used to access font functions.  */
+typedef struct grub_font *grub_font_t;
+
+struct grub_font_node
+{
+  struct grub_font_node *next;
+  grub_font_t value;
+};
+
+/* Global font registry.  */
+extern struct grub_font_node *grub_font_list;
+
+struct grub_font_glyph
+{
+  /* Reference to the font this glyph belongs to.  */
+  grub_font_t font;
+
+  /* Glyph bitmap width in pixels.  */
+  grub_uint16_t width;
+
+  /* Glyph bitmap height in pixels.  */
+  grub_uint16_t height;
+
+  /* Glyph bitmap x offset in pixels.  Add to screen coordinate.  */
+  grub_int16_t offset_x;
+
+  /* Glyph bitmap y offset in pixels.  Subtract from screen coordinate.  */
+  grub_int16_t offset_y;
+
+  /* Number of pixels to advance to start the next character.  */
+  grub_uint16_t device_width;
+
+  /* Row-major order, packed bits (no padding; rows can break within a byte).
+     The length of the array is (width * height + 7) / 8.  Within a
+     byte, the most significant bit is the first (leftmost/uppermost) pixel.
+     Pixels are coded as bits, value 1 meaning of opaque pixel and 0 is
+     transparent.  If the length of the array does not fit byte boundary, it
+     will be padded with 0 bits to make it fit.  */
+  grub_uint8_t bitmap[0];
+};
+
+/* Initialize the font loader.
+   Must be called before any fonts are loaded or used.  */
+void grub_font_loader_init (void);
+
+/* Load a font and add it to the beginning of the global font list.
+   Returns: 0 upon success; nonzero upon failure.  */
+int grub_font_load (const char *filename);
+
+/* Get the font that has the specified name.  Font names are in the form
+   "Family Name Bold Italic 14", where Bold and Italic are optional.
+   If no font matches the name specified, the most recently loaded font
+   is returned as a fallback.  */
+grub_font_t grub_font_get (const char *font_name);
+
+const char *grub_font_get_name (grub_font_t font);
+
+int grub_font_get_max_char_width (grub_font_t font);
+
+int grub_font_get_max_char_height (grub_font_t font);
+
+int grub_font_get_ascent (grub_font_t font);
+
+int grub_font_get_descent (grub_font_t font);
+
+int grub_font_get_leading (grub_font_t font);
+
+int grub_font_get_height (grub_font_t font);
+
+int grub_font_get_string_width (grub_font_t font, const char *str);
+
+struct grub_font_glyph *grub_font_get_glyph (grub_font_t font,
+                                             grub_uint32_t code);
+
+struct grub_font_glyph *grub_font_get_glyph_with_fallback (grub_font_t font,
+                                                           grub_uint32_t code);
+
+grub_err_t grub_font_draw_glyph (struct grub_font_glyph *glyph,
+                                        grub_video_color_t color,
+                                        int left_x, int baseline_y);
+
+grub_err_t grub_font_draw_string (const char *str, grub_font_t font,
+                                  grub_video_color_t color,
+                                  int left_x, int baseline_y);
+
+#endif /* ! GRUB_FONT_HEADER */
diff --git a/include/grub/fs.h b/include/grub/fs.h
new file mode 100644
index 0000000..132ab47
--- /dev/null
+++ b/include/grub/fs.h
@@ -0,0 +1,96 @@
+/* fs.h - filesystem manager */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FS_HEADER
+#define GRUB_FS_HEADER	1
+
+#include <grub/device.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+/* Forward declaration is required, because of mutual reference.  */
+struct grub_file;
+
+struct grub_dirhook_info
+{
+  int dir:1;
+  int mtimeset:1;
+  int case_insensitive:1;
+  grub_int32_t mtime;
+};
+
+/* Filesystem descriptor.  */
+struct grub_fs
+{
+  /* My name.  */
+  const char *name;
+
+  /* Call HOOK with each file under DIR.  */
+  grub_err_t (*dir) (grub_device_t device, const char *path,
+		     int (*hook) (const char *filename,
+				  const struct grub_dirhook_info *info));
+
+  /* Open a file named NAME and initialize FILE.  */
+  grub_err_t (*open) (struct grub_file *file, const char *name);
+
+  /* Read LEN bytes data from FILE into BUF.  */
+  grub_ssize_t (*read) (struct grub_file *file, char *buf, grub_size_t len);
+
+  /* Close the file FILE.  */
+  grub_err_t (*close) (struct grub_file *file);
+
+  /* Return the label of the device DEVICE in LABEL.  The label is
+     returned in a grub_malloc'ed buffer and should be freed by the
+     caller.  */
+  grub_err_t (*label) (grub_device_t device, char **label);
+
+  /* Return the uuid of the device DEVICE in UUID.  The uuid is
+     returned in a grub_malloc'ed buffer and should be freed by the
+     caller.  */
+  grub_err_t (*uuid) (grub_device_t device, char **uuid);
+
+  /* Get writing time of filesystem. */
+  grub_err_t (*mtime) (grub_device_t device, grub_int32_t *timebuf);
+
+#ifdef GRUB_UTIL
+  /* Whether this filesystem reserves first sector for DOS-style boot.  */
+  int reserved_first_sector;
+#endif
+
+  /* The next filesystem.  */
+  struct grub_fs *next;
+};
+typedef struct grub_fs *grub_fs_t;
+
+/* This is special, because block lists are not files in usual sense.  */
+extern struct grub_fs grub_fs_blocklist;
+
+/* This hook is used to automatically load filesystem modules.
+   If this hook loads a module, return non-zero. Otherwise return zero.
+   The newly loaded filesystem is assumed to be inserted into the head of
+   the linked list GRUB_FS_LIST through the function grub_fs_register.  */
+typedef int (*grub_fs_autoload_hook_t) (void);
+extern grub_fs_autoload_hook_t EXPORT_VAR(grub_fs_autoload_hook);
+
+void EXPORT_FUNC(grub_fs_register) (grub_fs_t fs);
+void EXPORT_FUNC(grub_fs_unregister) (grub_fs_t fs);
+void EXPORT_FUNC(grub_fs_iterate) (int (*hook) (const grub_fs_t fs));
+grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device);
+
+#endif /* ! GRUB_FS_HEADER */
diff --git a/include/grub/fshelp.h b/include/grub/fshelp.h
new file mode 100644
index 0000000..42d8da5
--- /dev/null
+++ b/include/grub/fshelp.h
@@ -0,0 +1,82 @@
+/* fshelp.h -- Filesystem helper functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FSHELP_HEADER
+#define GRUB_FSHELP_HEADER	1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/err.h>
+
+typedef struct grub_fshelp_node *grub_fshelp_node_t;
+
+#define GRUB_FSHELP_CASE_INSENSITIVE	0x100
+#define GRUB_FSHELP_TYPE_MASK	0xff
+#define GRUB_FSHELP_FLAGS_MASK	0x100
+
+enum grub_fshelp_filetype
+  {
+    GRUB_FSHELP_UNKNOWN,
+    GRUB_FSHELP_REG,
+    GRUB_FSHELP_DIR,
+    GRUB_FSHELP_SYMLINK
+  };
+
+/* Lookup the node PATH.  The node ROOTNODE describes the root of the
+   directory tree.  The node found is returned in FOUNDNODE, which is
+   either a ROOTNODE or a new malloc'ed node.  ITERATE_DIR is used to
+   iterate over all directory entries in the current node.
+   READ_SYMLINK is used to read the symlink if a node is a symlink.
+   EXPECTTYPE is the type node that is expected by the called, an
+   error is generated if the node is not of the expected type.  Make
+   sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required
+   because GCC has a nasty bug when using regparm=3.  */
+grub_err_t
+EXPORT_FUNC(grub_fshelp_find_file) (const char *path,
+				    grub_fshelp_node_t rootnode,
+				    grub_fshelp_node_t *foundnode,
+				    int (*iterate_dir) (grub_fshelp_node_t dir,
+							int NESTED_FUNC_ATTR
+							(*hook) (const char *filename,
+								 enum grub_fshelp_filetype filetype,
+								 grub_fshelp_node_t node)),
+				    char *(*read_symlink) (grub_fshelp_node_t node),
+				    enum grub_fshelp_filetype expect);
+
+
+/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
+   beginning with the block POS.  READ_HOOK should be set before
+   reading a block from the file.  GET_BLOCK is used to translate file
+   blocks to disk blocks.  The file is FILESIZE bytes big and the
+   blocks have a size of LOG2BLOCKSIZE (in log2).  */
+grub_ssize_t
+EXPORT_FUNC(grub_fshelp_read_file) (grub_disk_t disk, grub_fshelp_node_t node,
+				    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                                                        unsigned offset,
+                                                                        unsigned length),
+				    grub_off_t pos, grub_size_t len, char *buf,
+				    grub_disk_addr_t (*get_block) (grub_fshelp_node_t node,
+                                                                   grub_disk_addr_t block),
+				    grub_off_t filesize, int log2blocksize);
+
+unsigned int
+EXPORT_FUNC(grub_fshelp_log2blksize) (unsigned int blksize,
+				      unsigned int *pow);
+
+#endif /* ! GRUB_FSHELP_HEADER */
diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h
new file mode 100644
index 0000000..428ceb1
--- /dev/null
+++ b/include/grub/gpt_partition.h
@@ -0,0 +1,71 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_GPT_PARTITION_HEADER
+#define GRUB_GPT_PARTITION_HEADER	1
+
+#include <grub/types.h>
+
+struct grub_gpt_part_type
+{
+  grub_uint32_t data1;
+  grub_uint16_t data2;
+  grub_uint16_t data3;
+  grub_uint8_t data4[8];
+} __attribute__ ((aligned(8)));
+typedef struct grub_gpt_part_type grub_gpt_part_type_t;
+
+#define GRUB_GPT_PARTITION_TYPE_EMPTY \
+  { 0x0, 0x0, 0x0, \
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } \
+  }
+
+#define GRUB_GPT_PARTITION_TYPE_BIOS_BOOT \
+  { grub_cpu_to_le32 (0x21686148), grub_cpu_to_le16 (0x6449), grub_cpu_to_le16 (0x6e6f), \
+    { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } \
+  }
+
+struct grub_gpt_header
+{
+  grub_uint8_t magic[8];
+  grub_uint32_t version;
+  grub_uint32_t headersize;
+  grub_uint32_t crc32;
+  grub_uint32_t unused1;
+  grub_uint64_t primary;
+  grub_uint64_t backup;
+  grub_uint64_t start;
+  grub_uint64_t end;
+  grub_uint8_t guid[16];
+  grub_uint64_t partitions;
+  grub_uint32_t maxpart;
+  grub_uint32_t partentry_size;
+  grub_uint32_t partentry_crc32;
+} __attribute__ ((packed));
+
+struct grub_gpt_partentry
+{
+  grub_gpt_part_type_t type;
+  grub_uint8_t guid[16];
+  grub_uint64_t start;
+  grub_uint64_t end;
+  grub_uint64_t attrib;
+  char name[72];
+} __attribute__ ((packed));
+
+#endif /* ! GRUB_GPT_PARTITION_HEADER */
diff --git a/include/grub/gzio.h b/include/grub/gzio.h
new file mode 100644
index 0000000..cd7f397
--- /dev/null
+++ b/include/grub/gzio.h
@@ -0,0 +1,28 @@
+/* gzio.h - prototypes for gzio */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_GZIO_H
+#define GRUB_GZIO_H	1
+
+#include <grub/file.h>
+
+grub_file_t grub_gzio_open (grub_file_t io, int transparent);
+grub_file_t grub_gzfile_open (const char *name, int transparent);
+
+#endif /* ! GRUB_GZIO_H */
diff --git a/include/grub/handler.h b/include/grub/handler.h
new file mode 100644
index 0000000..3331bb4
--- /dev/null
+++ b/include/grub/handler.h
@@ -0,0 +1,60 @@
+/* handler.h - header for grub handler */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_HANDLER_HEADER
+#define GRUB_HANDLER_HEADER 1
+
+#include <grub/list.h>
+#include <grub/err.h>
+
+struct grub_handler
+{
+  struct grub_handler *next;
+  const char *name;
+  grub_err_t (*init) (void);
+  grub_err_t (*fini) (void);
+};
+typedef struct grub_handler *grub_handler_t;
+
+struct grub_handler_class
+{
+  struct grub_handler_class *next;
+  const char *name;
+  grub_handler_t handler_list;
+  grub_handler_t cur_handler;
+};
+typedef struct grub_handler_class *grub_handler_class_t;
+
+extern grub_handler_class_t EXPORT_VAR(grub_handler_class_list);
+
+void EXPORT_FUNC(grub_handler_register) (grub_handler_class_t class,
+					 grub_handler_t handler);
+void EXPORT_FUNC(grub_handler_unregister) (grub_handler_class_t class,
+					   grub_handler_t handler);
+grub_err_t EXPORT_FUNC(grub_handler_set_current) (grub_handler_class_t class,
+						  grub_handler_t handler);
+
+#define GRUB_AS_HANDLER(ptr) \
+  ((GRUB_FIELD_MATCH (ptr, grub_handler_t, next) && \
+    GRUB_FIELD_MATCH (ptr, grub_handler_t, name) && \
+    GRUB_FIELD_MATCH (ptr, grub_handler_t, init) && \
+    GRUB_FIELD_MATCH (ptr, grub_handler_t, fini)) ? \
+   (grub_handler_t) ptr : grub_assert_fail ())
+
+#endif /* ! GRUB_HANDLER_HEADER */
diff --git a/include/grub/hfs.h b/include/grub/hfs.h
new file mode 100644
index 0000000..08b947c
--- /dev/null
+++ b/include/grub/hfs.h
@@ -0,0 +1,60 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_HFS_HEADER
+#define GRUB_HFS_HEADER	1
+
+#include <grub/types.h>
+
+#define GRUB_HFS_MAGIC		0x4244
+
+/* A single extent.  A file consists of one or more extents.  */
+struct grub_hfs_extent
+{
+  /* The first physical block.  */
+  grub_uint16_t first_block;
+  grub_uint16_t count;
+};
+
+/* HFS stores extents in groups of 3.  */
+typedef struct grub_hfs_extent grub_hfs_datarecord_t[3];
+
+/* The HFS superblock (The official name is `Master Directory
+   Block').  */
+struct grub_hfs_sblock
+{
+  grub_uint16_t magic;
+  grub_uint8_t unused[18];
+  grub_uint32_t blksz;
+  grub_uint8_t unused2[4];
+  grub_uint16_t first_block;
+  grub_uint8_t unused4[6];
+
+  /* A pascal style string that holds the volumename.  */
+  grub_uint8_t volname[28];
+
+  grub_uint8_t unused5[60];
+  grub_uint16_t embed_sig;
+  struct grub_hfs_extent embed_extent;
+  grub_uint8_t unused6[4];
+  grub_hfs_datarecord_t extent_recs;
+  grub_uint32_t catalog_size;
+  grub_hfs_datarecord_t catalog_recs;
+} __attribute__ ((packed));
+
+#endif /* ! GRUB_HFS_HEADER */
diff --git a/include/grub/i386/at_keyboard.h b/include/grub/i386/at_keyboard.h
new file mode 100644
index 0000000..96b2162
--- /dev/null
+++ b/include/grub/i386/at_keyboard.h
@@ -0,0 +1,57 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CPU_AT_KEYBOARD_HEADER
+#define GRUB_CPU_AT_KEYBOARD_HEADER	1
+
+#include <grub/machine/machine.h>
+
+#define SHIFT_L		0x2a
+#define SHIFT_R		0x36
+#define CTRL		0x1d
+#define ALT		0x38
+#define CAPS_LOCK	0x3a
+
+#define KEYBOARD_REG_DATA	0x60
+#define KEYBOARD_REG_STATUS	0x64
+
+/* Used for sending commands to the controller.  */
+#define KEYBOARD_COMMAND_ISREADY(x)	!((x) & 0x02)
+#define KEYBOARD_COMMAND_READ		0x20
+#define KEYBOARD_COMMAND_WRITE		0x60
+#define KEYBOARD_COMMAND_REBOOT		0xfe
+
+#define KEYBOARD_SCANCODE_SET1		0x40
+
+#define KEYBOARD_ISMAKE(x)	!((x) & 0x80)
+#define KEYBOARD_ISREADY(x)	((x) & 0x01)
+#define KEYBOARD_SCANCODE(x)	((x) & 0x7f)
+
+#ifdef GRUB_MACHINE_IEEE1275
+#define OLPC_UP		GRUB_TERM_UP
+#define OLPC_DOWN	GRUB_TERM_DOWN
+#define OLPC_LEFT	GRUB_TERM_LEFT
+#define OLPC_RIGHT	GRUB_TERM_RIGHT
+#else
+#define OLPC_UP		'\0'
+#define OLPC_DOWN	'\0'
+#define OLPC_LEFT	'\0'
+#define OLPC_RIGHT	'\0'
+#endif
+
+#endif
diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h
new file mode 100644
index 0000000..8ffaf7d
--- /dev/null
+++ b/include/grub/i386/bsd.h
@@ -0,0 +1,278 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BSD_CPU_HEADER
+#define GRUB_BSD_CPU_HEADER	1
+
+#include <grub/types.h>
+
+enum bsd_kernel_types
+  {
+    KERNEL_TYPE_NONE,
+    KERNEL_TYPE_FREEBSD,
+    KERNEL_TYPE_OPENBSD,
+    KERNEL_TYPE_NETBSD,
+  };
+
+#define GRUB_BSD_TEMP_BUFFER   0x80000
+
+#define FREEBSD_RB_ASKNAME	(1 << 0)  /* ask for file name to reboot from */
+#define FREEBSD_RB_SINGLE       (1 << 1)  /* reboot to single user only */
+#define FREEBSD_RB_NOSYNC       (1 << 2)  /* dont sync before reboot */
+#define FREEBSD_RB_HALT         (1 << 3)  /* don't reboot, just halt */
+#define FREEBSD_RB_INITNAME     (1 << 4)  /* name given for /etc/init (unused) */
+#define FREEBSD_RB_DFLTROOT     (1 << 5)  /* use compiled-in rootdev */
+#define FREEBSD_RB_KDB          (1 << 6)  /* give control to kernel debugger */
+#define FREEBSD_RB_RDONLY       (1 << 7)  /* mount root fs read-only */
+#define FREEBSD_RB_DUMP         (1 << 8)  /* dump kernel memory before reboot */
+#define FREEBSD_RB_MINIROOT     (1 << 9)  /* mini-root present in memory at boot time */
+#define FREEBSD_RB_CONFIG       (1 << 10) /* invoke user configuration routing */
+#define FREEBSD_RB_VERBOSE      (1 << 11) /* print all potentially useful info */
+#define FREEBSD_RB_SERIAL       (1 << 12) /* user serial port as console */
+#define FREEBSD_RB_CDROM        (1 << 13) /* use cdrom as root */
+#define FREEBSD_RB_GDB		(1 << 15) /* use GDB remote debugger instead of DDB */
+#define FREEBSD_RB_MUTE		(1 << 16) /* Come up with the console muted */
+#define FREEBSD_RB_PAUSE	(1 << 20)
+#define FREEBSD_RB_QUIET	(1 << 21)
+#define FREEBSD_RB_NOINTR	(1 << 28)
+#define FREENSD_RB_MULTIPLE	(1 << 29)  /* Use multiple consoles */
+#define FREEBSD_RB_DUAL		FREENSD_RB_MULTIPLE
+#define FREEBSD_RB_BOOTINFO     (1 << 31) /* have `struct bootinfo *' arg */
+
+#define FREEBSD_B_DEVMAGIC	0xa0000000
+#define FREEBSD_B_SLICESHIFT	20
+#define FREEBSD_B_UNITSHIFT	16
+#define FREEBSD_B_PARTSHIFT	8
+#define FREEBSD_B_TYPESHIFT	0
+
+#define FREEBSD_BOOTINFO_VERSION 1
+#define FREEBSD_N_BIOS_GEOM	8
+
+#define FREEBSD_MODINFO_END		0x0000	/* End of list */
+#define FREEBSD_MODINFO_NAME		0x0001	/* Name of module (string) */
+#define FREEBSD_MODINFO_TYPE		0x0002	/* Type of module (string) */
+#define FREEBSD_MODINFO_ADDR		0x0003	/* Loaded address */
+#define FREEBSD_MODINFO_SIZE		0x0004	/* Size of module */
+#define FREEBSD_MODINFO_EMPTY		0x0005	/* Has been deleted */
+#define FREEBSD_MODINFO_ARGS		0x0006	/* Parameters string */
+#define FREEBSD_MODINFO_METADATA	0x8000	/* Module-specfic */
+
+#define FREEBSD_MODINFOMD_AOUTEXEC	0x0001	/* a.out exec header */
+#define FREEBSD_MODINFOMD_ELFHDR	0x0002	/* ELF header */
+#define FREEBSD_MODINFOMD_SSYM		0x0003	/* start of symbols */
+#define FREEBSD_MODINFOMD_ESYM		0x0004	/* end of symbols */
+#define FREEBSD_MODINFOMD_DYNAMIC	0x0005	/* _DYNAMIC pointer */
+#define FREEBSD_MODINFOMD_ENVP		0x0006	/* envp[] */
+#define FREEBSD_MODINFOMD_HOWTO		0x0007	/* boothowto */
+#define FREEBSD_MODINFOMD_KERNEND	0x0008	/* kernend */
+#define FREEBSD_MODINFOMD_SHDR		0x0009	/* section header table */
+#define FREEBSD_MODINFOMD_NOCOPY	0x8000	/* don't copy this metadata to the kernel */
+
+#define FREEBSD_MODINFOMD_SMAP		0x1001
+
+#define FREEBSD_MODINFOMD_DEPLIST	(0x4001 | FREEBSD_MODINFOMD_NOCOPY)  /* depends on */
+
+#define FREEBSD_MODTYPE_KERNEL		"elf kernel"
+#define FREEBSD_MODTYPE_KERNEL64	"elf64 kernel"
+#define FREEBSD_MODTYPE_ELF_MODULE	"elf module"
+#define FREEBSD_MODTYPE_ELF_MODULE_OBJ	"elf obj module"
+#define FREEBSD_MODTYPE_RAW		"raw"
+
+struct grub_freebsd_bootinfo
+{
+  grub_uint32_t bi_version;
+  grub_uint8_t *bi_kernelname;
+  struct nfs_diskless *bi_nfs_diskless;
+  grub_uint32_t bi_n_bios_used;
+  grub_uint32_t bi_bios_geom[FREEBSD_N_BIOS_GEOM];
+  grub_uint32_t bi_size;
+  grub_uint8_t bi_memsizes_valid;
+  grub_uint8_t bi_bios_dev;
+  grub_uint8_t bi_pad[2];
+  grub_uint32_t bi_basemem;
+  grub_uint32_t bi_extmem;
+  grub_uint32_t bi_symtab;
+  grub_uint32_t bi_esymtab;
+  grub_uint32_t bi_kernend;
+  grub_uint32_t bi_envp;
+  grub_uint32_t bi_modulep;
+} __attribute__ ((packed));
+
+#define OPENBSD_RB_ASKNAME	(1 << 0)  /* ask for file name to reboot from */
+#define OPENBSD_RB_SINGLE	(1 << 1)  /* reboot to single user only */
+#define OPENBSD_RB_NOSYNC	(1 << 2)  /* dont sync before reboot */
+#define OPENBSD_RB_HALT		(1 << 3)  /* don't reboot, just halt */
+#define OPENBSD_RB_INITNAME	(1 << 4)  /* name given for /etc/init (unused) */
+#define OPENBSD_RB_DFLTROOT	(1 << 5)  /* use compiled-in rootdev */
+#define OPENBSD_RB_KDB		(1 << 6)  /* give control to kernel debugger */
+#define OPENBSD_RB_RDONLY	(1 << 7)  /* mount root fs read-only */
+#define OPENBSD_RB_DUMP		(1 << 8)  /* dump kernel memory before reboot */
+#define OPENBSD_RB_MINIROOT	(1 << 9)  /* mini-root present in memory at boot time */
+#define OPENBSD_RB_CONFIG	(1 << 10) /* change configured devices */
+#define OPENBSD_RB_TIMEBAD	(1 << 11) /* don't call resettodr() in boot() */
+#define OPENBSD_RB_POWERDOWN	(1 << 12) /* attempt to power down machine */
+#define OPENBSD_RB_SERCONS	(1 << 13) /* use serial console if available */
+#define OPENBSD_RB_USERREQ	(1 << 14) /* boot() called at user request (e.g. ddb) */
+
+#define OPENBSD_B_DEVMAGIC	0xa0000000
+#define OPENBSD_B_ADAPTORSHIFT	24
+#define OPENBSD_B_CTRLSHIFT	20
+#define OPENBSD_B_UNITSHIFT	16
+#define OPENBSD_B_PARTSHIFT	8
+#define OPENBSD_B_TYPESHIFT	0
+
+#define OPENBSD_BOOTARG_APIVER	(OPENBSD_BAPIV_VECTOR | \
+                                 OPENBSD_BAPIV_ENV | \
+                                 OPENBSD_BAPIV_BMEMMAP)
+
+#define OPENBSD_BAPIV_ANCIENT	0x0  /* MD old i386 bootblocks */
+#define OPENBSD_BAPIV_VARS	0x1  /* MD structure w/ add info passed */
+#define OPENBSD_BAPIV_VECTOR	0x2  /* MI vector of MD structures passed */
+#define OPENBSD_BAPIV_ENV	0x4  /* MI environment vars vector */
+#define OPENBSD_BAPIV_BMEMMAP	0x8  /* MI memory map passed is in bytes */
+
+#define OPENBSD_BOOTARG_ENV	0x1000
+#define OPENBSD_BOOTARG_END	-1
+
+#define	OPENBSD_BOOTARG_MMAP	0
+
+struct grub_openbsd_bios_mmap
+{
+  grub_uint64_t addr;
+  grub_uint64_t len;
+#define	OPENBSD_MMAP_AVAILABLE	1
+#define	OPENBSD_MMAP_RESERVED 2
+#define	OPENBSD_MMAP_ACPI	3
+#define	OPENBSD_MMAP_NVS 	4
+  grub_uint32_t type;
+};
+
+struct grub_openbsd_bootargs
+{
+  int ba_type;
+  int ba_size;
+  struct grub_openbsd_bootargs *ba_next;
+} __attribute__ ((packed));
+
+#define NETBSD_RB_AUTOBOOT	0  /* flags for system auto-booting itself */
+
+#define NETBSD_RB_ASKNAME	(1 << 0)  /* ask for file name to reboot from */
+#define NETBSD_RB_SINGLE	(1 << 1)  /* reboot to single user only */
+#define NETBSD_RB_NOSYNC	(1 << 2)  /* dont sync before reboot */
+#define NETBSD_RB_HALT		(1 << 3)  /* don't reboot, just halt */
+#define NETBSD_RB_INITNAME	(1 << 4)  /* name given for /etc/init (unused) */
+#define NETBSD_RB_UNUSED1	(1 << 5)  /* was RB_DFLTROOT, obsolete */
+#define NETBSD_RB_KDB		(1 << 6)  /* give control to kernel debugger */
+#define NETBSD_RB_RDONLY	(1 << 7)  /* mount root fs read-only */
+#define NETBSD_RB_DUMP		(1 << 8)  /* dump kernel memory before reboot */
+#define NETBSD_RB_MINIROOT	(1 << 9)  /* mini-root present in memory at boot time */
+#define NETBSD_RB_STRING	(1 << 10) /* use provided bootstr */
+#define NETBSD_RB_POWERDOWN     ((1 << 11) | RB_HALT) /* turn power off (or at least halt) */
+#define NETBSD_RB_USERCONFIG	(1 << 12) /* change configured devices */
+
+#define NETBSD_AB_NORMAL	0  /* boot normally (default) */
+
+#define NETBSD_AB_QUIET		(1 << 16) /* boot quietly */
+#define NETBSD_AB_VERBOSE	(1 << 17) /* boot verbosely */
+#define NETBSD_AB_SILENT	(1 << 18) /* boot silently */
+#define NETBSD_AB_DEBUG		(1 << 19) /* boot with debug messages */
+#define NETBSD_AB_NOSMP		(1 << 28) /* Boot without SMP support.  */
+#define NETBSD_AB_NOACPI        (1 << 29) /* Boot without ACPI support.  */
+
+struct grub_netbsd_bootinfo
+{
+  grub_uint32_t bi_count;
+  void *bi_data[1];
+};
+
+#define NETBSD_BTINFO_BOOTPATH		0
+#define NETBSD_BTINFO_ROOTDEVICE	1
+#define NETBSD_BTINFO_BOOTDISK		3
+#define NETBSD_BTINFO_MEMMAP		9
+
+struct grub_netbsd_btinfo_common
+{
+  int len;
+  int type;
+};
+
+struct grub_netbsd_btinfo_mmap_header
+{
+  struct grub_netbsd_btinfo_common common;
+  grub_uint32_t count;
+};
+
+struct grub_netbsd_btinfo_mmap_entry
+{
+  grub_uint64_t addr;
+  grub_uint64_t len;
+#define	NETBSD_MMAP_AVAILABLE	1
+#define	NETBSD_MMAP_RESERVED 	2
+#define	NETBSD_MMAP_ACPI	3
+#define	NETBSD_MMAP_NVS 	4
+  grub_uint32_t type;
+};
+
+struct grub_netbsd_btinfo_bootpath
+{
+  struct grub_netbsd_btinfo_common common;
+  char bootpath[80];
+};
+
+struct grub_netbsd_btinfo_rootdevice
+{
+  struct grub_netbsd_btinfo_common common;
+  char devname[16];
+};
+
+struct grub_netbsd_btinfo_bootdisk
+{
+  struct grub_netbsd_btinfo_common common;
+  int labelsector;  /* label valid if != -1 */
+  struct
+    {
+      grub_uint16_t type, checksum;
+      char packname[16];
+    } label;
+  int biosdev;
+  int partition;
+};
+
+void grub_unix_real_boot (grub_addr_t entry, ...)
+     __attribute__ ((cdecl,noreturn));
+grub_err_t grub_freebsd_load_elfmodule32 (grub_file_t file, int argc,
+					  char *argv[], grub_addr_t *kern_end);
+grub_err_t grub_freebsd_load_elfmodule_obj64 (grub_file_t file, int argc,
+					      char *argv[],
+					      grub_addr_t *kern_end);
+grub_err_t grub_freebsd_load_elf_meta32 (grub_file_t file,
+					 grub_addr_t *kern_end);
+grub_err_t grub_freebsd_load_elf_meta64 (grub_file_t file,
+					 grub_addr_t *kern_end);
+
+grub_err_t grub_freebsd_add_meta (grub_uint32_t type, void *data,
+				  grub_uint32_t len);
+grub_err_t grub_freebsd_add_meta_module (char *filename, char *type,
+					 int argc, char **argv,
+					 grub_addr_t addr, grub_uint32_t size);
+
+extern grub_uint8_t grub_bsd64_trampoline_start, grub_bsd64_trampoline_end;
+extern grub_uint32_t grub_bsd64_trampoline_selfjump;
+extern grub_uint32_t grub_bsd64_trampoline_gdt;
+
+#endif /* ! GRUB_BSD_CPU_HEADER */
diff --git a/include/grub/i386/cmos.h b/include/grub/i386/cmos.h
new file mode 100644
index 0000000..1c0530d
--- /dev/null
+++ b/include/grub/i386/cmos.h
@@ -0,0 +1,74 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef	GRUB_CPU_CMOS_H
+#define	GRUB_CPU_CMOS_H	1
+
+#include <grub/types.h>
+#include <grub/i386/io.h>
+
+#define GRUB_CMOS_ADDR_REG	0x70
+#define GRUB_CMOS_DATA_REG	0x71
+
+#define GRUB_CMOS_INDEX_SECOND		0
+#define GRUB_CMOS_INDEX_SECOND_ALARM	1
+#define GRUB_CMOS_INDEX_MINUTE		2
+#define GRUB_CMOS_INDEX_MINUTE_ALARM	3
+#define GRUB_CMOS_INDEX_HOUR		4
+#define GRUB_CMOS_INDEX_HOUR_ALARM	5
+#define GRUB_CMOS_INDEX_DAY_OF_WEEK	6
+#define GRUB_CMOS_INDEX_DAY_OF_MONTH	7
+#define GRUB_CMOS_INDEX_MONTH		8
+#define GRUB_CMOS_INDEX_YEAR		9
+
+#define GRUB_CMOS_INDEX_STATUS_A	0xA
+#define GRUB_CMOS_INDEX_STATUS_B	0xB
+#define GRUB_CMOS_INDEX_STATUS_C	0xC
+#define GRUB_CMOS_INDEX_STATUS_D	0xD
+
+#define GRUB_CMOS_STATUS_B_DAYLIGHT	1
+#define GRUB_CMOS_STATUS_B_24HOUR	2
+#define GRUB_CMOS_STATUS_B_BINARY	4
+
+static inline grub_uint8_t
+grub_bcd_to_num (grub_uint8_t a)
+{
+  return ((a >> 4) * 10 + (a & 0xF));
+}
+
+static inline grub_uint8_t
+grub_num_to_bcd (grub_uint8_t a)
+{
+  return (((a / 10) << 4) + (a % 10));
+}
+
+static inline grub_uint8_t
+grub_cmos_read (grub_uint8_t index)
+{
+  grub_outb (index, GRUB_CMOS_ADDR_REG);
+  return grub_inb (GRUB_CMOS_DATA_REG);
+}
+
+static inline void
+grub_cmos_write (grub_uint8_t index, grub_uint8_t value)
+{
+  grub_outb (index, GRUB_CMOS_ADDR_REG);
+  grub_outb (value, GRUB_CMOS_DATA_REG);
+}
+
+#endif /* GRUB_CPU_CMOS_H */
diff --git a/include/grub/i386/coreboot/boot.h b/include/grub/i386/coreboot/boot.h
new file mode 100644
index 0000000..6cd23aa
--- /dev/null
+++ b/include/grub/i386/coreboot/boot.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/boot.h>
diff --git a/include/grub/i386/coreboot/console.h b/include/grub/i386/coreboot/console.h
new file mode 100644
index 0000000..2ffef73
--- /dev/null
+++ b/include/grub/i386/coreboot/console.h
@@ -0,0 +1,25 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_CONSOLE_HEADER
+#define GRUB_MACHINE_CONSOLE_HEADER	1
+
+void grub_vga_text_init (void);
+void grub_vga_text_fini (void);
+
+#endif /* ! GRUB_MACHINE_CONSOLE_HEADER */
diff --git a/include/grub/i386/coreboot/init.h b/include/grub/i386/coreboot/init.h
new file mode 100644
index 0000000..e670074
--- /dev/null
+++ b/include/grub/i386/coreboot/init.h
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_INIT_I386_LINUXBIOS_HEADER
+#define GRUB_INIT_I386_LINUXBIOS_HEADER		1
+
+#include <grub/symbol.h>
+#include <grub/i386/pc/memory.h>
+
+void EXPORT_FUNC(grub_stop) (void) __attribute__ ((noreturn));
+void EXPORT_FUNC(grub_stop_floppy) (void);
+
+#endif
diff --git a/include/grub/i386/coreboot/kernel.h b/include/grub/i386/coreboot/kernel.h
new file mode 100644
index 0000000..fb60668
--- /dev/null
+++ b/include/grub/i386/coreboot/kernel.h
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER	1
+
+#include <grub/symbol.h>
+
+#ifndef ASM_FILE
+extern char grub_prefix[];
+#endif
+
+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/include/grub/i386/coreboot/loader.h b/include/grub/i386/coreboot/loader.h
new file mode 100644
index 0000000..d3f36bb
--- /dev/null
+++ b/include/grub/i386/coreboot/loader.h
@@ -0,0 +1 @@
+#include <grub/cpu/loader.h>
diff --git a/include/grub/i386/coreboot/machine.h b/include/grub/i386/coreboot/machine.h
new file mode 100644
index 0000000..8b70590
--- /dev/null
+++ b/include/grub/i386/coreboot/machine.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_MACHINE_HEADER
+#define GRUB_MACHINE_MACHINE_HEADER	1
+
+#define GRUB_MACHINE_COREBOOT	1
+
+#endif /* ! GRUB_MACHINE_MACHINE_HEADER */
diff --git a/include/grub/i386/coreboot/memory.h b/include/grub/i386/coreboot/memory.h
new file mode 100644
index 0000000..434ae62
--- /dev/null
+++ b/include/grub/i386/coreboot/memory.h
@@ -0,0 +1,70 @@
+/* memory.h - describe the memory map */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GRUB_MEMORY_MACHINE_LB_HEADER
+#define _GRUB_MEMORY_MACHINE_LB_HEADER      1
+
+#include <grub/symbol.h>
+#include <grub/i386/pc/memory.h>
+
+#ifndef ASM_FILE
+#include <grub/err.h>
+#include <grub/types.h>
+#endif
+
+#define GRUB_MEMORY_MACHINE_LOWER_USABLE		0x9fc00		/* 640 kiB - 1 kiB */
+
+#define GRUB_MEMORY_MACHINE_UPPER_START			0x100000	/* 1 MiB */
+#define GRUB_MEMORY_MACHINE_LOWER_SIZE			GRUB_MEMORY_MACHINE_UPPER_START
+
+#ifndef ASM_FILE
+
+struct grub_linuxbios_table_header
+{
+  char signature[4];
+  grub_uint32_t size;
+};
+typedef struct grub_linuxbios_table_header *grub_linuxbios_table_header_t;
+
+struct grub_linuxbios_table_item
+{
+#define GRUB_LINUXBIOS_MEMBER_UNUSED		0
+#define GRUB_LINUXBIOS_MEMBER_MEMORY		1
+  grub_uint32_t tag;
+  grub_uint32_t size;
+};
+typedef struct grub_linuxbios_table_item *grub_linuxbios_table_item_t;
+
+struct grub_linuxbios_mem_region
+{
+  grub_uint64_t addr;
+  grub_uint64_t size;
+#define GRUB_MACHINE_MEMORY_AVAILABLE		1
+  grub_uint32_t type;
+};
+typedef struct grub_linuxbios_mem_region *mem_region_t;
+
+void grub_machine_mmap_init (void);
+
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
+     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+
+#endif
+
+#endif /* ! _GRUB_MEMORY_MACHINE_HEADER */
diff --git a/include/grub/i386/coreboot/serial.h b/include/grub/i386/coreboot/serial.h
new file mode 100644
index 0000000..2c527f6
--- /dev/null
+++ b/include/grub/i386/coreboot/serial.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/serial.h>
diff --git a/include/grub/i386/coreboot/time.h b/include/grub/i386/coreboot/time.h
new file mode 100644
index 0000000..2298ee8
--- /dev/null
+++ b/include/grub/i386/coreboot/time.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/time.h>
diff --git a/include/grub/i386/cpuid.h b/include/grub/i386/cpuid.h
new file mode 100644
index 0000000..09b313b
--- /dev/null
+++ b/include/grub/i386/cpuid.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CPU_CPUID_HEADER
+#define GRUB_CPU_CPUID_HEADER 1
+
+extern unsigned char grub_cpuid_has_longmode;
+
+#endif
diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h
new file mode 100644
index 0000000..c0549f4
--- /dev/null
+++ b/include/grub/i386/efi/kernel.h
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_KERNEL_HEADER
+#define GRUB_MACHINE_KERNEL_HEADER   1
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+/* The offset of GRUB_PREFIX.  */
+#define GRUB_KERNEL_MACHINE_PREFIX		0x8
+
+/* End of the data section. */
+#define GRUB_KERNEL_MACHINE_DATA_END		0x50
+
+#endif /* ! GRUB_MACHINE_KERNEL_HEADER */
+
diff --git a/include/grub/i386/efi/loader.h b/include/grub/i386/efi/loader.h
new file mode 100644
index 0000000..222dae8
--- /dev/null
+++ b/include/grub/i386/efi/loader.h
@@ -0,0 +1,22 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER	1
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/include/grub/i386/efi/machine.h b/include/grub/i386/efi/machine.h
new file mode 100644
index 0000000..1600768
--- /dev/null
+++ b/include/grub/i386/efi/machine.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_MACHINE_HEADER
+#define GRUB_MACHINE_MACHINE_HEADER	1
+
+#define GRUB_MACHINE_EFI	1
+
+#endif /* ! GRUB_MACHINE_MACHINE_HEADER */
diff --git a/include/grub/i386/efi/memory.h b/include/grub/i386/efi/memory.h
new file mode 100644
index 0000000..c9a61bb
--- /dev/null
+++ b/include/grub/i386/efi/memory.h
@@ -0,0 +1 @@
+#include <grub/efi/memory.h>
diff --git a/include/grub/i386/efi/time.h b/include/grub/i386/efi/time.h
new file mode 100644
index 0000000..7a9241f
--- /dev/null
+++ b/include/grub/i386/efi/time.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_TIME_HEADER
+#define GRUB_MACHINE_TIME_HEADER	1
+
+#include <grub/efi/time.h>
+
+#endif /* ! GRUB_MACHINE_TIME_HEADER */
diff --git a/include/grub/i386/efiemu.h b/include/grub/i386/efiemu.h
new file mode 100644
index 0000000..edb13ff
--- /dev/null
+++ b/include/grub/i386/efiemu.h
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ARCH_EFI_EMU_HEADER
+#define GRUB_ARCH_EFI_EMU_HEADER	1
+
+grub_err_t
+grub_arch_efiemu_relocate_symbols32 (grub_efiemu_segment_t segs,
+				     struct grub_efiemu_elf_sym *elfsyms,
+				     void *ehdr);
+grub_err_t
+grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
+				     struct grub_efiemu_elf_sym *elfsyms,
+				     void *ehdr);
+
+int grub_arch_efiemu_check_header32 (void *ehdr);
+int grub_arch_efiemu_check_header64 (void *ehdr);
+#endif
diff --git a/include/grub/i386/halt.h b/include/grub/i386/halt.h
new file mode 100644
index 0000000..1c403a7
--- /dev/null
+++ b/include/grub/i386/halt.h
@@ -0,0 +1,19 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+extern void grub_halt (void);
diff --git a/include/grub/i386/ieee1275/console.h b/include/grub/i386/ieee1275/console.h
new file mode 100644
index 0000000..854724a
--- /dev/null
+++ b/include/grub/i386/ieee1275/console.h
@@ -0,0 +1,30 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CONSOLE_MACHINE_HEADER
+#define GRUB_CONSOLE_MACHINE_HEADER 1
+
+#include <grub/symbol.h>
+
+/* Initialize the console system.  */
+void grub_console_init (void);
+
+/* Finish the console system.  */
+void grub_console_fini (void);
+
+#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
diff --git a/include/grub/i386/ieee1275/ieee1275.h b/include/grub/i386/ieee1275/ieee1275.h
new file mode 100644
index 0000000..2625f02
--- /dev/null
+++ b/include/grub/i386/ieee1275/ieee1275.h
@@ -0,0 +1 @@
+#include <grub/powerpc/ieee1275/ieee1275.h>
diff --git a/include/grub/i386/ieee1275/kernel.h b/include/grub/i386/ieee1275/kernel.h
new file mode 100644
index 0000000..dccf8cb
--- /dev/null
+++ b/include/grub/i386/ieee1275/kernel.h
@@ -0,0 +1 @@
+#include <grub/powerpc/ieee1275/kernel.h>
diff --git a/include/grub/i386/ieee1275/loader.h b/include/grub/i386/ieee1275/loader.h
new file mode 100644
index 0000000..20df2e1
--- /dev/null
+++ b/include/grub/i386/ieee1275/loader.h
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER	1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/multiboot.h>
+
+void grub_rescue_cmd_linux (int argc, char *argv[]);
+void grub_rescue_cmd_initrd (int argc, char *argv[]);
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/include/grub/i386/ieee1275/machine.h b/include/grub/i386/ieee1275/machine.h
new file mode 100644
index 0000000..755eb33
--- /dev/null
+++ b/include/grub/i386/ieee1275/machine.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_MACHINE_HEADER
+#define GRUB_MACHINE_MACHINE_HEADER	1
+
+#define GRUB_MACHINE_IEEE1275	1
+
+#endif /* ! GRUB_MACHINE_MACHINE_HEADER */
diff --git a/include/grub/i386/ieee1275/memory.h b/include/grub/i386/ieee1275/memory.h
new file mode 100644
index 0000000..386ee4a
--- /dev/null
+++ b/include/grub/i386/ieee1275/memory.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/memory.h>
diff --git a/include/grub/i386/ieee1275/serial.h b/include/grub/i386/ieee1275/serial.h
new file mode 100644
index 0000000..2c527f6
--- /dev/null
+++ b/include/grub/i386/ieee1275/serial.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/serial.h>
diff --git a/include/grub/i386/ieee1275/time.h b/include/grub/i386/ieee1275/time.h
new file mode 100644
index 0000000..6f474ba
--- /dev/null
+++ b/include/grub/i386/ieee1275/time.h
@@ -0,0 +1 @@
+#include <grub/powerpc/ieee1275/time.h>
diff --git a/include/grub/i386/io.h b/include/grub/i386/io.h
new file mode 100644
index 0000000..0e56776
--- /dev/null
+++ b/include/grub/i386/io.h
@@ -0,0 +1,70 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1996,2000,2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Based on sys/io.h from GNU libc. */
+
+#ifndef	GRUB_IO_H
+#define	GRUB_IO_H	1
+
+static __inline unsigned char
+grub_inb (unsigned short int port)
+{
+  unsigned char _v;
+
+  __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
+  return _v;
+}
+
+static __inline unsigned short int
+grub_inw (unsigned short int port)
+{
+  unsigned short _v;
+
+  __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port));
+  return _v;
+}
+
+static __inline unsigned int
+grub_inl (unsigned short int port)
+{
+  unsigned int _v;
+
+  __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port));
+  return _v;
+}
+
+static __inline void
+grub_outb (unsigned char value, unsigned short int port)
+{
+  __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port));
+}
+
+static __inline void
+grub_outw (unsigned short int value, unsigned short int port)
+{
+  __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port));
+
+}
+
+static __inline void
+grub_outl (unsigned int value, unsigned short int port)
+{
+  __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port));
+}
+
+#endif /* _SYS_IO_H */
diff --git a/include/grub/i386/kernel.h b/include/grub/i386/kernel.h
new file mode 100644
index 0000000..74715e1
--- /dev/null
+++ b/include/grub/i386/kernel.h
@@ -0,0 +1,36 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_CPU_HEADER
+#define GRUB_KERNEL_CPU_HEADER	1
+
+#include <grub/machine/machine.h>
+
+#ifdef GRUB_MACHINE_IEEE1275
+#define GRUB_MOD_ALIGN	0x1000
+#else
+#define GRUB_MOD_ALIGN	0x1
+#endif
+
+/* Non-zero value is only needed for PowerMacs.  */
+#define GRUB_MOD_GAP 0x0
+
+#define GRUB_KERNEL_CPU_PREFIX	0x2
+#define GRUB_KERNEL_CPU_DATA_END	0x42
+
+#endif
diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
new file mode 100644
index 0000000..8a5a84d
--- /dev/null
+++ b/include/grub/i386/linux.h
@@ -0,0 +1,281 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LINUX_MACHINE_HEADER
+#define GRUB_LINUX_MACHINE_HEADER	1
+
+#define GRUB_LINUX_MAGIC_SIGNATURE	0x53726448      /* "HdrS" */
+#define GRUB_LINUX_DEFAULT_SETUP_SECTS	4
+#define GRUB_LINUX_INITRD_MAX_ADDRESS	0x37FFFFFF
+#define GRUB_LINUX_MAX_SETUP_SECTS	64
+#define GRUB_LINUX_BOOT_LOADER_TYPE	0x72
+#define GRUB_LINUX_HEAP_END_OFFSET	(0x9000 - 0x200)
+
+#define GRUB_LINUX_BZIMAGE_ADDR		0x100000
+#define GRUB_LINUX_ZIMAGE_ADDR		0x10000
+#define GRUB_LINUX_OLD_REAL_MODE_ADDR	0x90000
+#define GRUB_LINUX_SETUP_STACK		0x9000
+
+#define GRUB_LINUX_FLAG_BIG_KERNEL	0x1
+#define GRUB_LINUX_FLAG_QUIET		0x20
+#define GRUB_LINUX_FLAG_CAN_USE_HEAP	0x80
+
+/* Linux's video mode selection support. Actually I hate it!  */
+#define GRUB_LINUX_VID_MODE_NORMAL	0xFFFF
+#define GRUB_LINUX_VID_MODE_EXTENDED	0xFFFE
+#define GRUB_LINUX_VID_MODE_ASK		0xFFFD
+#define GRUB_LINUX_VID_MODE_VESA_START	0x0300
+
+#define GRUB_LINUX_SETUP_MOVE_SIZE	0x9100
+#define GRUB_LINUX_CL_MAGIC		0xA33F
+
+#ifdef __x86_64__
+
+#define GRUB_LINUX_EFI_SIGNATURE	\
+  ('4' << 24 | '6' << 16 | 'L' << 8 | 'E')
+
+#else
+
+#define GRUB_LINUX_EFI_SIGNATURE	\
+  ('2' << 24 | '3' << 16 | 'L' << 8 | 'E')
+
+#endif
+
+#define GRUB_LINUX_EFI_SIGNATURE_0204	\
+  ('L' << 24 | 'I' << 16 | 'F' << 8 | 'E')
+
+#define GRUB_LINUX_OFW_SIGNATURE	\
+  (' ' << 24 | 'W' << 16 | 'F' << 8 | 'O')
+
+#ifndef ASM_FILE
+
+#define GRUB_E820_RAM        1
+#define GRUB_E820_RESERVED   2
+#define GRUB_E820_ACPI       3
+#define GRUB_E820_NVS        4
+#define GRUB_E820_EXEC_CODE  5
+
+#define GRUB_E820_MAX_ENTRY  128
+
+struct grub_e820_mmap
+{
+  grub_uint64_t addr;
+  grub_uint64_t size;
+  grub_uint32_t type;
+} __attribute__((packed));
+
+#define GRUB_VIDEO_TYPE_TEXT	0x01
+#define GRUB_VIDEO_TYPE_VLFB	0x23    /* VESA VGA in graphic mode     */
+#define GRUB_VIDEO_TYPE_EFI	0x70
+
+/* For the Linux/i386 boot protocol version 2.03.  */
+struct linux_kernel_header
+{
+  grub_uint8_t code1[0x0020];
+  grub_uint16_t cl_magic;		/* Magic number 0xA33F */
+  grub_uint16_t cl_offset;		/* The offset of command line */
+  grub_uint8_t code2[0x01F1 - 0x0020 - 2 - 2];
+  grub_uint8_t setup_sects;		/* The size of the setup in sectors */
+  grub_uint16_t root_flags;		/* If the root is mounted readonly */
+  grub_uint16_t syssize;		/* obsolete */
+  grub_uint16_t swap_dev;		/* obsolete */
+  grub_uint16_t ram_size;		/* obsolete */
+  grub_uint16_t vid_mode;		/* Video mode control */
+  grub_uint16_t root_dev;		/* Default root device number */
+  grub_uint16_t boot_flag;		/* 0xAA55 magic number */
+  grub_uint16_t jump;			/* Jump instruction */
+  grub_uint32_t header;			/* Magic signature "HdrS" */
+  grub_uint16_t version;		/* Boot protocol version supported */
+  grub_uint32_t realmode_swtch;		/* Boot loader hook */
+  grub_uint16_t start_sys;		/* The load-low segment (obsolete) */
+  grub_uint16_t kernel_version;		/* Points to kernel version string */
+  grub_uint8_t type_of_loader;		/* Boot loader identifier */
+#define LINUX_LOADER_ID_LILO		0x0
+#define LINUX_LOADER_ID_LOADLIN		0x1
+#define LINUX_LOADER_ID_BOOTSECT	0x2
+#define LINUX_LOADER_ID_SYSLINUX	0x3
+#define LINUX_LOADER_ID_ETHERBOOT	0x4
+#define LINUX_LOADER_ID_ELILO		0x5
+#define LINUX_LOADER_ID_GRUB		0x7
+#define LINUX_LOADER_ID_UBOOT		0x8
+#define LINUX_LOADER_ID_XEN		0x9
+#define LINUX_LOADER_ID_GUJIN		0xa
+#define LINUX_LOADER_ID_QEMU		0xb
+  grub_uint8_t loadflags;		/* Boot protocol option flags */
+  grub_uint16_t setup_move_size;	/* Move to high memory size */
+  grub_uint32_t code32_start;		/* Boot loader hook */
+  grub_uint32_t ramdisk_image;		/* initrd load address */
+  grub_uint32_t ramdisk_size;		/* initrd size */
+  grub_uint32_t bootsect_kludge;	/* obsolete */
+  grub_uint16_t heap_end_ptr;		/* Free memory after setup end */
+  grub_uint16_t pad1;			/* Unused */
+  char *cmd_line_ptr;			/* Points to the kernel command line */
+  grub_uint32_t initrd_addr_max;        /* Highest address for initrd */
+} __attribute__ ((packed));
+
+/* Boot parameters for Linux based on 2.6.12. This is used by the setup
+   sectors of Linux, and must be simulated by GRUB on EFI, because
+   the setup sectors depend on BIOS.  */
+struct linux_kernel_params
+{
+  grub_uint8_t video_cursor_x;		/* 0 */
+  grub_uint8_t video_cursor_y;
+
+  grub_uint16_t ext_mem;		/* 2 */
+
+  grub_uint16_t video_page;		/* 4 */
+  grub_uint8_t video_mode;		/* 6 */
+  grub_uint8_t video_width;		/* 7 */
+
+  grub_uint8_t padding1[0xa - 0x8];
+
+  grub_uint16_t video_ega_bx;		/* a */
+
+  grub_uint8_t padding2[0xe - 0xc];
+
+  grub_uint8_t video_height;		/* e */
+  grub_uint8_t have_vga;		/* f */
+  grub_uint16_t font_size;		/* 10 */
+
+  grub_uint16_t lfb_width;		/* 12 */
+  grub_uint16_t lfb_height;		/* 14 */
+  grub_uint16_t lfb_depth;		/* 16 */
+  grub_uint32_t lfb_base;		/* 18 */
+  grub_uint32_t lfb_size;		/* 1c */
+
+  grub_uint16_t cl_magic;		/* 20 */
+  grub_uint16_t cl_offset;
+
+  grub_uint16_t lfb_line_len;		/* 24 */
+  grub_uint8_t red_mask_size;		/* 26 */
+  grub_uint8_t red_field_pos;
+  grub_uint8_t green_mask_size;
+  grub_uint8_t green_field_pos;
+  grub_uint8_t blue_mask_size;
+  grub_uint8_t blue_field_pos;
+  grub_uint8_t reserved_mask_size;
+  grub_uint8_t reserved_field_pos;
+  grub_uint16_t vesapm_segment;		/* 2e */
+  grub_uint16_t vesapm_offset;		/* 30 */
+  grub_uint16_t lfb_pages;		/* 32 */
+  grub_uint16_t vesa_attrib;		/* 34 */
+  grub_uint32_t capabilities;		/* 36 */
+
+  grub_uint8_t padding3[0x40 - 0x3a];
+
+  grub_uint16_t apm_version;		/* 40 */
+  grub_uint16_t apm_code_segment;	/* 42 */
+  grub_uint32_t apm_entry;		/* 44 */
+  grub_uint16_t apm_16bit_code_segment;	/* 48 */
+  grub_uint16_t apm_data_segment;	/* 4a */
+  grub_uint16_t apm_flags;		/* 4c */
+  grub_uint32_t apm_code_len;		/* 4e */
+  grub_uint16_t apm_data_len;		/* 52 */
+
+  grub_uint8_t padding4[0x60 - 0x54];
+
+  grub_uint32_t ist_signature;		/* 60 */
+  grub_uint32_t ist_command;		/* 64 */
+  grub_uint32_t ist_event;		/* 68 */
+  grub_uint32_t ist_perf_level;		/* 6c */
+
+  grub_uint8_t padding5[0x80 - 0x70];
+
+  grub_uint8_t hd0_drive_info[0x10];	/* 80 */
+  grub_uint8_t hd1_drive_info[0x10];	/* 90 */
+  grub_uint16_t rom_config_len;		/* a0 */
+
+  grub_uint8_t padding6[0xb0 - 0xa2];
+
+  grub_uint32_t ofw_signature;		/* b0 */
+  grub_uint32_t ofw_num_items;		/* b4 */
+  grub_uint32_t ofw_cif_handler;	/* b8 */
+  grub_uint32_t ofw_idt;		/* bc */
+
+  grub_uint8_t padding7[0x1b8 - 0xc0];
+
+  union
+    {
+      struct
+        {
+          grub_uint32_t efi_system_table;	/* 1b8 */
+          grub_uint32_t padding7_1;		/* 1bc */
+          grub_uint32_t efi_signature;		/* 1c0 */
+          grub_uint32_t efi_mem_desc_size;	/* 1c4 */
+          grub_uint32_t efi_mem_desc_version;	/* 1c8 */
+          grub_uint32_t efi_mmap_size;		/* 1cc */
+          grub_uint32_t efi_mmap;		/* 1d0 */
+        } v0204;
+      struct
+        {
+          grub_uint32_t padding7_1;		/* 1b8 */
+          grub_uint32_t padding7_2;		/* 1bc */
+          grub_uint32_t efi_signature;		/* 1c0 */
+          grub_uint32_t efi_system_table;	/* 1c4 */
+          grub_uint32_t efi_mem_desc_size;	/* 1c8 */
+          grub_uint32_t efi_mem_desc_version;	/* 1cc */
+          grub_uint32_t efi_mmap;		/* 1d0 */
+          grub_uint32_t efi_mmap_size;		/* 1d4 */
+          grub_uint32_t efi_system_table_hi;	/* 1d8 */
+          grub_uint32_t efi_mmap_hi;		/* 1dc */
+        } v0206;
+    };
+
+  grub_uint32_t alt_mem;		/* 1e0 */
+
+  grub_uint8_t padding8[0x1e8 - 0x1e4];
+
+  grub_uint8_t mmap_size;		/* 1e8 */
+
+  grub_uint8_t padding9[0x1f1 - 0x1e9];
+
+  grub_uint8_t setup_sects;		/* The size of the setup in sectors */
+  grub_uint16_t root_flags;		/* If the root is mounted readonly */
+  grub_uint16_t syssize;		/* obsolete */
+  grub_uint16_t swap_dev;		/* obsolete */
+  grub_uint16_t ram_size;		/* obsolete */
+  grub_uint16_t vid_mode;		/* Video mode control */
+  grub_uint16_t root_dev;		/* Default root device number */
+
+  grub_uint8_t padding10;		/* 1fe */
+  grub_uint8_t ps_mouse;		/* 1ff */
+
+  grub_uint16_t jump;			/* Jump instruction */
+  grub_uint32_t header;			/* Magic signature "HdrS" */
+  grub_uint16_t version;		/* Boot protocol version supported */
+  grub_uint32_t realmode_swtch;		/* Boot loader hook */
+  grub_uint16_t start_sys;		/* The load-low segment (obsolete) */
+  grub_uint16_t kernel_version;		/* Points to kernel version string */
+  grub_uint8_t type_of_loader;		/* Boot loader identifier */
+  grub_uint8_t loadflags;		/* Boot protocol option flags */
+  grub_uint16_t setup_move_size;	/* Move to high memory size */
+  grub_uint32_t code32_start;		/* Boot loader hook */
+  grub_uint32_t ramdisk_image;		/* initrd load address */
+  grub_uint32_t ramdisk_size;		/* initrd size */
+  grub_uint32_t bootsect_kludge;	/* obsolete */
+  grub_uint16_t heap_end_ptr;		/* Free memory after setup end */
+  grub_uint16_t pad1;			/* Unused */
+  grub_uint32_t cmd_line_ptr;		/* Points to the kernel command line */
+
+  grub_uint8_t pad2[164];		/* 22c */
+  struct grub_e820_mmap e820_map[GRUB_E820_MAX_ENTRY];	/* 2d0 */
+
+} __attribute__ ((packed));
+#endif /* ! ASM_FILE */
+
+#endif /* ! GRUB_LINUX_MACHINE_HEADER */
diff --git a/include/grub/i386/loader.h b/include/grub/i386/loader.h
new file mode 100644
index 0000000..b7fa413
--- /dev/null
+++ b/include/grub/i386/loader.h
@@ -0,0 +1,38 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_CPU_HEADER
+#define GRUB_LOADER_CPU_HEADER	1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/symbol.h>
+#include <grub/machine/machine.h>
+
+extern grub_addr_t EXPORT_VAR(grub_os_area_addr);
+extern grub_size_t EXPORT_VAR(grub_os_area_size);
+
+#ifdef GRUB_MACHINE_PCBIOS
+extern grub_uint32_t EXPORT_VAR(grub_linux_prot_size);
+extern char *EXPORT_VAR(grub_linux_tmp_addr);
+extern char *EXPORT_VAR(grub_linux_real_addr);
+extern grub_int32_t EXPORT_VAR(grub_linux_is_bzimage);
+grub_err_t EXPORT_FUNC(grub_linux16_boot) (void);
+#endif
+
+#endif /* ! GRUB_LOADER_CPU_HEADER */
diff --git a/include/grub/i386/macho.h b/include/grub/i386/macho.h
new file mode 100644
index 0000000..61e72a7
--- /dev/null
+++ b/include/grub/i386/macho.h
@@ -0,0 +1,11 @@
+#define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x)==0x00000007)
+#define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x)==0x01000007)
+
+struct grub_macho_thread32
+{
+  grub_uint32_t cmd;
+  grub_uint32_t cmdsize;
+  grub_uint8_t unknown1[48];
+  grub_uint32_t entry_point;
+  grub_uint8_t unknown2[20];
+} __attribute__ ((packed));
diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h
new file mode 100644
index 0000000..2dd7ec0
--- /dev/null
+++ b/include/grub/i386/multiboot.h
@@ -0,0 +1,42 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MULTIBOOT_CPU_HEADER
+#define GRUB_MULTIBOOT_CPU_HEADER	1
+
+/* The asm part of the multiboot loader.  */
+void grub_multiboot_real_boot (grub_addr_t entry,
+			       struct grub_multiboot_info *mbi)
+     __attribute__ ((noreturn));
+void grub_multiboot2_real_boot (grub_addr_t entry,
+				struct grub_multiboot_info *mbi)
+     __attribute__ ((noreturn));
+
+extern grub_addr_t grub_multiboot_payload_orig;
+extern grub_addr_t grub_multiboot_payload_dest;
+extern grub_size_t grub_multiboot_payload_size;
+extern grub_uint32_t grub_multiboot_payload_entry_offset;
+
+extern grub_uint8_t grub_multiboot_forward_relocator;
+extern grub_uint8_t grub_multiboot_forward_relocator_end;
+extern grub_uint8_t grub_multiboot_backward_relocator;
+extern grub_uint8_t grub_multiboot_backward_relocator_end;
+
+#define RELOCATOR_SIZEOF(x)	(&grub_multiboot_##x##_relocator_end - &grub_multiboot_##x##_relocator)
+
+#endif /* ! GRUB_MULTIBOOT_CPU_HEADER */
diff --git a/include/grub/i386/pc/biosdisk.h b/include/grub/i386/pc/biosdisk.h
new file mode 100644
index 0000000..b87e0e4
--- /dev/null
+++ b/include/grub/i386/pc/biosdisk.h
@@ -0,0 +1,126 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BIOSDISK_MACHINE_HEADER
+#define GRUB_BIOSDISK_MACHINE_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+#define GRUB_BIOSDISK_FLAG_LBA	1
+#define GRUB_BIOSDISK_FLAG_CDROM 2
+
+#define GRUB_BIOSDISK_CDTYPE_NO_EMUL	0
+#define GRUB_BIOSDISK_CDTYPE_1_2_M	1
+#define GRUB_BIOSDISK_CDTYPE_1_44_M	2
+#define GRUB_BIOSDISK_CDTYPE_2_88_M	3
+#define GRUB_BIOSDISK_CDTYPE_HARDDISK	4
+
+#define GRUB_BIOSDISK_CDTYPE_MASK	0xF
+
+struct grub_biosdisk_data
+{
+  int drive;
+  unsigned long cylinders;
+  unsigned long heads;
+  unsigned long sectors;
+  unsigned long flags;
+};
+
+/* Drive Parameters.  */
+struct grub_biosdisk_drp
+{
+  grub_uint16_t size;
+  grub_uint16_t flags;
+  grub_uint32_t cylinders;
+  grub_uint32_t heads;
+  grub_uint32_t sectors;
+  grub_uint64_t total_sectors;
+  grub_uint16_t bytes_per_sector;
+  /* ver 2.0 or higher */
+
+  union
+  {
+    grub_uint32_t EDD_configuration_parameters;
+
+    /* Pointer to the Device Parameter Table Extension (ver 3.0+).  */
+    grub_uint32_t dpte_pointer;
+  };
+
+  /* ver 3.0 or higher */
+  grub_uint16_t signature_dpi;
+  grub_uint8_t length_dpi;
+  grub_uint8_t reserved[3];
+  grub_uint8_t name_of_host_bus[4];
+  grub_uint8_t name_of_interface_type[8];
+  grub_uint8_t interface_path[8];
+  grub_uint8_t device_path[8];
+  grub_uint8_t reserved2;
+  grub_uint8_t checksum;
+
+  /* XXX: This is necessary, because the BIOS of Thinkpad X20
+     writes a garbage to the tail of drive parameters,
+     regardless of a size specified in a caller.  */
+  grub_uint8_t dummy[16];
+} __attribute__ ((packed));
+
+struct grub_biosdisk_cdrp
+{
+  grub_uint8_t size;
+  grub_uint8_t media_type;
+  grub_uint8_t drive_no;
+  grub_uint8_t controller_no;
+  grub_uint32_t image_lba;
+  grub_uint16_t device_spec;
+  grub_uint16_t cache_seg;
+  grub_uint16_t load_seg;
+  grub_uint16_t length_sec512;
+  grub_uint8_t cylinders;
+  grub_uint8_t sectors;
+  grub_uint8_t heads;
+  grub_uint8_t dummy[16];
+} __attribute__ ((packed));
+
+/* Disk Address Packet.  */
+struct grub_biosdisk_dap
+{
+  grub_uint8_t length;
+  grub_uint8_t reserved;
+  grub_uint16_t blocks;
+  grub_uint32_t buffer;
+  grub_uint64_t block;
+} __attribute__ ((packed));
+
+int EXPORT_FUNC(grub_biosdisk_rw_int13_extensions) (int ah, int drive, void *dap);
+int EXPORT_FUNC(grub_biosdisk_rw_standard) (int ah, int drive, int coff, int hoff,
+			       int soff, int nsec, int segment);
+int EXPORT_FUNC(grub_biosdisk_check_int13_extensions) (int drive);
+int EXPORT_FUNC(grub_biosdisk_get_diskinfo_int13_extensions) (int drive,
+           void *drp);
+int EXPORT_FUNC(grub_biosdisk_get_cdinfo_int13_extensions) (int drive,
+           void *cdrp);
+int EXPORT_FUNC(grub_biosdisk_get_diskinfo_standard) (int drive,
+					 unsigned long *cylinders,
+					 unsigned long *heads,
+					 unsigned long *sectors);
+int EXPORT_FUNC(grub_biosdisk_get_num_floppies) (void);
+
+void grub_biosdisk_init (void);
+void grub_biosdisk_fini (void);
+
+#endif /* ! GRUB_BIOSDISK_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/biosnum.h b/include/grub/i386/pc/biosnum.h
new file mode 100644
index 0000000..29c8ecc
--- /dev/null
+++ b/include/grub/i386/pc/biosnum.h
@@ -0,0 +1,6 @@
+#ifndef GRUB_BIOSNUM_MACHINE_HEADER
+#define GRUB_BIOSNUM_MACHINE_HEADER	1
+
+extern int (*grub_get_root_biosnumber) (void);
+
+#endif
diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h
new file mode 100644
index 0000000..f45fe6d
--- /dev/null
+++ b/include/grub/i386/pc/boot.h
@@ -0,0 +1,69 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2002,2005,2006,2007,2008   Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BOOT_MACHINE_HEADER
+#define GRUB_BOOT_MACHINE_HEADER	1
+
+/* The signature for bootloader.  */
+#define GRUB_BOOT_MACHINE_SIGNATURE	0xaa55
+
+/* The offset of the start of BPB (BIOS Parameter Block).  */
+#define GRUB_BOOT_MACHINE_BPB_START	0x3
+
+/* The offset of the end of BPB (BIOS Parameter Block).  */
+#define GRUB_BOOT_MACHINE_BPB_END	0x5a
+
+/* The offset of KERNEL_SECTOR.  */
+#define GRUB_BOOT_MACHINE_KERNEL_SECTOR	0x5c
+
+/* The offset of BOOT_DRIVE.  */
+#define GRUB_BOOT_MACHINE_BOOT_DRIVE	0x64
+
+/* The offset of BOOT_DRIVE_CHECK.  */
+#define GRUB_BOOT_MACHINE_DRIVE_CHECK	0x66
+
+/* The offset of a magic number used by Windows NT.  */
+#define GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC	0x1b8
+
+/* The offset of the start of the partition table.  */
+#define GRUB_BOOT_MACHINE_PART_START	0x1be
+
+/* The offset of the end of the partition table.  */
+#define GRUB_BOOT_MACHINE_PART_END	0x1fe
+
+/* The stack segment.  */
+#define GRUB_BOOT_MACHINE_STACK_SEG	0x2000
+
+/* The segment of disk buffer. The disk buffer MUST be 32K long and
+   cannot straddle a 64K boundary.  */
+#define GRUB_BOOT_MACHINE_BUFFER_SEG	0x7000
+
+/* The flag for BIOS drive number to designate a hard disk vs. a
+   floppy.  */
+#define GRUB_BOOT_MACHINE_BIOS_HD_FLAG	0x80
+
+/* The segment where the kernel is loaded.  */
+#define GRUB_BOOT_MACHINE_KERNEL_SEG	0x800
+
+/* The address where the kernel is loaded.  */
+#define GRUB_BOOT_MACHINE_KERNEL_ADDR	(GRUB_BOOT_MACHINE_KERNEL_SEG << 4)
+
+/* The size of a block list used in the kernel startup code.  */
+#define GRUB_BOOT_MACHINE_LIST_SIZE	12
+
+#endif /* ! BOOT_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/chainloader.h b/include/grub/i386/pc/chainloader.h
new file mode 100644
index 0000000..ca1da23
--- /dev/null
+++ b/include/grub/i386/pc/chainloader.h
@@ -0,0 +1,30 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CHAINLOADER_MACHINE_HEADER
+#define GRUB_CHAINLOADER_MACHINE_HEADER	1
+
+#include <grub/dl.h>
+
+/* Common function for normal and rescue mode commands. */
+typedef enum
+  {
+    GRUB_CHAINLOADER_FORCE = 0x1
+  } grub_chainloader_flags_t;
+
+#endif /* GRUB_CHAINLOADER_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h
new file mode 100644
index 0000000..2a74d15
--- /dev/null
+++ b/include/grub/i386/pc/console.h
@@ -0,0 +1,58 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CONSOLE_MACHINE_HEADER
+#define GRUB_CONSOLE_MACHINE_HEADER	1
+
+/* Define scan codes.  */
+#define GRUB_CONSOLE_KEY_LEFT		0x4B00
+#define GRUB_CONSOLE_KEY_RIGHT		0x4D00
+#define GRUB_CONSOLE_KEY_UP		0x4800
+#define GRUB_CONSOLE_KEY_DOWN		0x5000
+#define GRUB_CONSOLE_KEY_IC		0x5200
+#define GRUB_CONSOLE_KEY_DC		0x5300
+#define GRUB_CONSOLE_KEY_BACKSPACE	0x0008
+#define GRUB_CONSOLE_KEY_HOME		0x4700
+#define GRUB_CONSOLE_KEY_END		0x4F00
+#define GRUB_CONSOLE_KEY_NPAGE		0x5100
+#define GRUB_CONSOLE_KEY_PPAGE		0x4900
+
+#ifndef ASM_FILE
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/term.h>
+#include <grub/i386/vga_common.h>
+
+/* These are global to share code between C and asm.  */
+int grub_console_checkkey (void);
+int grub_console_getkey (void);
+grub_uint16_t grub_console_getxy (void);
+void grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y);
+void grub_console_cls (void);
+void grub_console_setcursor (int on);
+
+/* Initialize the console system.  */
+void grub_console_init (void);
+
+/* Finish the console system.  */
+void grub_console_fini (void);
+
+#endif
+
+#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/efiemu.h b/include/grub/i386/pc/efiemu.h
new file mode 100644
index 0000000..f269dd0
--- /dev/null
+++ b/include/grub/i386/pc/efiemu.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_EFI_EMU_HEADER
+#define GRUB_MACHINE_EFI_EMU_HEADER	1
+
+grub_err_t grub_machine_efiemu_init_tables (void);
+
+#endif
diff --git a/include/grub/i386/pc/init.h b/include/grub/i386/pc/init.h
new file mode 100644
index 0000000..0029959
--- /dev/null
+++ b/include/grub/i386/pc/init.h
@@ -0,0 +1,51 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_INIT_MACHINE_HEADER
+#define GRUB_INIT_MACHINE_HEADER	1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+
+/* Get the memory size in KB. If EXTENDED is zero, return conventional
+   memory, otherwise return extended memory.  */
+grub_uint16_t grub_get_memsize (int extended);
+
+/* Get a packed EISA memory map. Lower 16 bits are between 1MB and 16MB
+   in 1KB parts, and upper 16 bits are above 16MB in 64KB parts.  */
+grub_uint32_t grub_get_eisa_mmap (void);
+
+/* Get a memory map entry. Return next continuation value. Zero means
+   the end.  */
+grub_uint32_t EXPORT_FUNC(grub_get_mmap_entry) (struct grub_machine_mmap_entry *entry,
+				   grub_uint32_t cont);
+
+/* Turn on/off Gate A20.  */
+void grub_gate_a20 (int on);
+
+/* Reboot the machine.  */
+void EXPORT_FUNC (grub_reboot) (void);
+
+/* Halt the system, using APM if possible. If NO_APM is true, don't
+ * use APM even if it is available.  */
+void EXPORT_FUNC (grub_halt) (int no_apm);
+
+void EXPORT_FUNC(grub_stop_floppy) (void);
+
+#endif /* ! GRUB_INIT_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h
new file mode 100644
index 0000000..e830afa
--- /dev/null
+++ b/include/grub/i386/pc/kernel.h
@@ -0,0 +1,75 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_MACHINE_HEADER
+#define KERNEL_MACHINE_HEADER	1
+
+/* The offset of GRUB_TOTAL_MODULE_SIZE.  */
+#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE	0x8
+
+/* The offset of GRUB_KERNEL_IMAGE_SIZE.  */
+#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE	0xc
+
+/* The offset of GRUB_COMPRESSED_SIZE.  */
+#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE	0x10
+
+/* The offset of GRUB_INSTALL_DOS_PART.  */
+#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART	0x14
+
+/* The offset of GRUB_INSTALL_BSD_PART.  */
+#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART	0x18
+
+/* The offset of GRUB_PREFIX.  */
+#define GRUB_KERNEL_MACHINE_PREFIX		0x1c
+
+/* End of the data section. */
+#define GRUB_KERNEL_MACHINE_DATA_END		0x5c
+
+/* The size of the first region which won't be compressed.  */
+#define GRUB_KERNEL_MACHINE_RAW_SIZE		(GRUB_KERNEL_MACHINE_DATA_END + 0x5F0)
+
+/* Enable LZMA compression */
+#define ENABLE_LZMA	1
+
+#ifndef ASM_FILE
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+/* The size of kernel image.  */
+extern grub_int32_t grub_kernel_image_size;
+
+/* The total size of module images following the kernel.  */
+extern grub_int32_t grub_total_module_size;
+
+/* The DOS partition number of the installed partition.  */
+extern grub_int32_t grub_install_dos_part;
+
+/* The BSD partition number of the installed partition.  */
+extern grub_int32_t grub_install_bsd_part;
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+/* The boot BIOS drive number.  */
+extern grub_uint8_t EXPORT_VAR(grub_boot_drive);
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! KERNEL_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/loader.h b/include/grub/i386/pc/loader.h
new file mode 100644
index 0000000..3e03141
--- /dev/null
+++ b/include/grub/i386/pc/loader.h
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/cpu/loader.h>
+
+/* This is an asm part of the chainloader.  */
+void EXPORT_FUNC(grub_chainloader_real_boot) (int drive, void *part_addr) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/machine.h b/include/grub/i386/pc/machine.h
new file mode 100644
index 0000000..e6de728
--- /dev/null
+++ b/include/grub/i386/pc/machine.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_MACHINE_HEADER
+#define GRUB_MACHINE_MACHINE_HEADER	1
+
+#define GRUB_MACHINE_PCBIOS	1
+
+#endif /* ! GRUB_MACHINE_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h
new file mode 100644
index 0000000..8153904
--- /dev/null
+++ b/include/grub/i386/pc/memory.h
@@ -0,0 +1,142 @@
+/* memory.h - describe the memory map */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_MACHINE_HEADER
+#define GRUB_MEMORY_MACHINE_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/machine/machine.h>
+#ifndef ASM_FILE
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/memory.h>
+#endif
+
+/* The scratch buffer used in real mode code.  */
+#define GRUB_MEMORY_MACHINE_SCRATCH_ADDR	0x68000
+#define GRUB_MEMORY_MACHINE_SCRATCH_SEG	(GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4)
+#define GRUB_MEMORY_MACHINE_SCRATCH_SIZE	0x10000
+
+/* The real mode stack.  */
+#define GRUB_MEMORY_MACHINE_REAL_STACK	(0x2000 - 0x10)
+
+/* The size of the protect mode stack.  */
+#define GRUB_MEMORY_MACHINE_PROT_STACK_SIZE	0x8000
+
+/* The upper memory area (starting at 640 kiB).  */
+#define GRUB_MEMORY_MACHINE_UPPER		0xa0000
+
+/* The protected mode stack.  */
+#define GRUB_MEMORY_MACHINE_PROT_STACK	\
+	(GRUB_MEMORY_MACHINE_SCRATCH_ADDR + GRUB_MEMORY_MACHINE_SCRATCH_SIZE \
+	 + GRUB_MEMORY_MACHINE_PROT_STACK_SIZE - 0x10)
+
+/* The memory area where GRUB uses its own purpose. This part is not added
+   into free memory for dynamic allocations.  */
+#define GRUB_MEMORY_MACHINE_RESERVED_START	\
+	GRUB_MEMORY_MACHINE_SCRATCH_ADDR
+#define GRUB_MEMORY_MACHINE_RESERVED_END	\
+	(GRUB_MEMORY_MACHINE_PROT_STACK + 0x10)
+
+/* The area where GRUB is decompressed at early startup.  */
+#define GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR	0x100000
+
+/* The address of a partition table passed to another boot loader.  */
+#define GRUB_MEMORY_MACHINE_PART_TABLE_ADDR	0x7be
+
+/* The address where another boot loader is loaded.  */
+#define GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR	0x7c00
+
+/* The flag for protected mode.  */
+#define GRUB_MEMORY_MACHINE_CR0_PE_ON		0x1
+
+/* The code segment of the protected mode.  */
+#define GRUB_MEMORY_MACHINE_PROT_MODE_CSEG	0x8
+
+/* The data segment of the protected mode.  */
+#define GRUB_MEMORY_MACHINE_PROT_MODE_DSEG	0x10
+
+/* The code segment of the pseudo real mode.  */
+#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG	0x18
+
+/* The data segment of the pseudo real mode.  */
+#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG	0x20
+
+#define GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR	0x400
+
+#ifndef ASM_FILE
+
+/* See http://heim.ifi.uio.no/~stanisls/helppc/bios_data_area.html for a
+   description of the BIOS Data Area layout.  */
+struct grub_machine_bios_data_area
+{
+  grub_uint8_t unused1[0x17];
+  grub_uint8_t keyboard_flag_lower; /* 0x17 */ 
+  grub_uint8_t unused2[0xf0 - 0x18];
+};
+
+struct grub_machine_mmap_entry
+{
+  grub_uint32_t size;
+  grub_uint64_t addr;
+  grub_uint64_t len;
+#define GRUB_MACHINE_MEMORY_AVAILABLE	1
+#define GRUB_MACHINE_MEMORY_RESERVED	2
+#define GRUB_MACHINE_MEMORY_ACPI	3
+#define GRUB_MACHINE_MEMORY_NVS 	4
+#define GRUB_MACHINE_MEMORY_MAX_TYPE 	4
+  /* This one is special: it's used internally but is never reported
+     by firmware. */
+#define GRUB_MACHINE_MEMORY_HOLE 	5
+
+  grub_uint32_t type;
+} __attribute__((packed));
+
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
+     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+
+grub_uint64_t grub_mmap_get_post64 (void);
+grub_uint64_t grub_mmap_get_upper (void);
+grub_uint64_t grub_mmap_get_lower (void);
+
+#define GRUB_MMAP_MALLOC_LOW 1
+
+#ifdef GRUB_MACHINE_PCBIOS
+grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size,
+				       int type, int handle);
+grub_err_t grub_machine_mmap_unregister (int handle);
+#else
+static inline grub_err_t
+grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
+			    grub_uint64_t size __attribute__ ((unused)),
+			    int type __attribute__ ((unused)),
+			    int handle __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+static inline grub_err_t
+grub_machine_mmap_unregister (int handle  __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+#endif
+
+#endif
+
+#endif /* ! GRUB_MEMORY_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/pxe.h b/include/grub/i386/pc/pxe.h
new file mode 100644
index 0000000..4821328
--- /dev/null
+++ b/include/grub/i386/pc/pxe.h
@@ -0,0 +1,318 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CPU_PXE_H
+#define GRUB_CPU_PXE_H
+
+#include <grub/types.h>
+
+#define GRUB_PXENV_TFTP_OPEN			0x0020
+#define GRUB_PXENV_TFTP_CLOSE			0x0021
+#define GRUB_PXENV_TFTP_READ			0x0022
+#define GRUB_PXENV_TFTP_READ_FILE		0x0023
+#define GRUB_PXENV_TFTP_READ_FILE_PMODE		0x0024
+#define GRUB_PXENV_TFTP_GET_FSIZE		0x0025
+
+#define GRUB_PXENV_UDP_OPEN			0x0030
+#define GRUB_PXENV_UDP_CLOSE			0x0031
+#define GRUB_PXENV_UDP_READ			0x0032
+#define GRUB_PXENV_UDP_WRITE			0x0033
+
+#define GRUB_PXENV_START_UNDI			0x0000
+#define GRUB_PXENV_UNDI_STARTUP			0x0001
+#define GRUB_PXENV_UNDI_CLEANUP			0x0002
+#define GRUB_PXENV_UNDI_INITIALIZE		0x0003
+#define GRUB_PXENV_UNDI_RESET_NIC		0x0004
+#define GRUB_PXENV_UNDI_SHUTDOWN		0x0005
+#define GRUB_PXENV_UNDI_OPEN			0x0006
+#define GRUB_PXENV_UNDI_CLOSE			0x0007
+#define GRUB_PXENV_UNDI_TRANSMIT		0x0008
+#define GRUB_PXENV_UNDI_SET_MCAST_ADDR		0x0009
+#define GRUB_PXENV_UNDI_SET_STATION_ADDR	0x000A
+#define GRUB_PXENV_UNDI_SET_PACKET_FILTER	0x000B
+#define GRUB_PXENV_UNDI_GET_INFORMATION		0x000C
+#define GRUB_PXENV_UNDI_GET_STATISTICS		0x000D
+#define GRUB_PXENV_UNDI_CLEAR_STATISTICS	0x000E
+#define GRUB_PXENV_UNDI_INITIATE_DIAGS		0x000F
+#define GRUB_PXENV_UNDI_FORCE_INTERRUPT		0x0010
+#define GRUB_PXENV_UNDI_GET_MCAST_ADDR		0x0011
+#define GRUB_PXENV_UNDI_GET_NIC_TYPE		0x0012
+#define GRUB_PXENV_UNDI_GET_IFACE_INFO		0x0013
+#define GRUB_PXENV_UNDI_ISR			0x0014
+#define	GRUB_PXENV_STOP_UNDI			0x0015
+#define GRUB_PXENV_UNDI_GET_STATE		0x0015
+
+#define GRUB_PXENV_UNLOAD_STACK			0x0070
+#define GRUB_PXENV_GET_CACHED_INFO		0x0071
+#define GRUB_PXENV_RESTART_DHCP			0x0072
+#define GRUB_PXENV_RESTART_TFTP			0x0073
+#define GRUB_PXENV_MODE_SWITCH			0x0074
+#define GRUB_PXENV_START_BASE			0x0075
+#define GRUB_PXENV_STOP_BASE			0x0076
+
+#define GRUB_PXENV_EXIT_SUCCESS			0x0000
+#define GRUB_PXENV_EXIT_FAILURE			0x0001
+
+#define GRUB_PXENV_STATUS_SUCCESS				0x00
+#define GRUB_PXENV_STATUS_FAILURE				0x01
+#define GRUB_PXENV_STATUS_BAD_FUNC				0x02
+#define GRUB_PXENV_STATUS_UNSUPPORTED				0x03
+#define GRUB_PXENV_STATUS_KEEP_UNDI				0x04
+#define GRUB_PXENV_STATUS_KEEP_ALL				0x05
+#define GRUB_PXENV_STATUS_OUT_OF_RESOURCES			0x06
+#define GRUB_PXENV_STATUS_ARP_TIMEOUT				0x11
+#define GRUB_PXENV_STATUS_UDP_CLOSED				0x18
+#define GRUB_PXENV_STATUS_UDP_OPEN				0x19
+#define GRUB_PXENV_STATUS_TFTP_CLOSED				0x1A
+#define GRUB_PXENV_STATUS_TFTP_OPEN				0x1B
+#define GRUB_PXENV_STATUS_MCOPY_PROBLEM				0x20
+#define GRUB_PXENV_STATUS_BIS_INTEGRITY_FAILURE			0x21
+#define GRUB_PXENV_STATUS_BIS_VALIDATE_FAILURE			0x22
+#define GRUB_PXENV_STATUS_BIS_INIT_FAILURE			0x23
+#define GRUB_PXENV_STATUS_BIS_SHUTDOWN_FAILURE			0x24
+#define GRUB_PXENV_STATUS_BIS_GBOA_FAILURE			0x25
+#define GRUB_PXENV_STATUS_BIS_FREE_FAILURE			0x26
+#define GRUB_PXENV_STATUS_BIS_GSI_FAILURE			0x27
+#define GRUB_PXENV_STATUS_BIS_BAD_CKSUM				0x28
+#define GRUB_PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS		0x30
+#define GRUB_PXENV_STATUS_TFTP_OPEN_TIMEOUT			0x32
+
+#define GRUB_PXENV_STATUS_TFTP_UNKNOWN_OPCODE			0x33
+#define GRUB_PXENV_STATUS_TFTP_READ_TIMEOUT			0x35
+#define GRUB_PXENV_STATUS_TFTP_ERROR_OPCODE			0x36
+#define GRUB_PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION		0x38
+#define GRUB_PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION	0x39
+#define GRUB_PXENV_STATUS_TFTP_TOO_MANY_PACKAGES		0x3A
+#define GRUB_PXENV_STATUS_TFTP_FILE_NOT_FOUND			0x3B
+#define GRUB_PXENV_STATUS_TFTP_ACCESS_VIOLATION			0x3C
+#define GRUB_PXENV_STATUS_TFTP_NO_MCAST_ADDRESS			0x3D
+#define GRUB_PXENV_STATUS_TFTP_NO_FILESIZE			0x3E
+#define GRUB_PXENV_STATUS_TFTP_INVALID_PACKET_SIZE		0x3F
+#define GRUB_PXENV_STATUS_DHCP_TIMEOUT				0x51
+#define GRUB_PXENV_STATUS_DHCP_NO_IP_ADDRESS			0x52
+#define GRUB_PXENV_STATUS_DHCP_NO_BOOTFILE_NAME			0x53
+#define GRUB_PXENV_STATUS_DHCP_BAD_IP_ADDRESS			0x54
+#define GRUB_PXENV_STATUS_UNDI_INVALID_FUNCTION			0x60
+#define GRUB_PXENV_STATUS_UNDI_MEDIATEST_FAILED			0x61
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST	0x62
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC		0x63
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY		0x64
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA		0x65
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA		0x66
+#define GRUB_PXENV_STATUS_UNDI_BAD_MAC_ADDRESS			0x67
+#define GRUB_PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM		0x68
+#define GRUB_PXENV_STATUS_UNDI_ERROR_SETTING_ISR		0x69
+#define GRUB_PXENV_STATUS_UNDI_INVALID_STATE			0x6A
+#define GRUB_PXENV_STATUS_UNDI_TRANSMIT_ERROR			0x6B
+#define GRUB_PXENV_STATUS_UNDI_INVALID_PARAMETER		0x6C
+#define GRUB_PXENV_STATUS_BSTRAP_PROMPT_MENU			0x74
+#define GRUB_PXENV_STATUS_BSTRAP_MCAST_ADDR			0x76
+#define GRUB_PXENV_STATUS_BSTRAP_MISSING_LIST			0x77
+#define GRUB_PXENV_STATUS_BSTRAP_NO_RESPONSE			0x78
+#define GRUB_PXENV_STATUS_BSTRAP_FILE_TOO_BIG			0x79
+#define GRUB_PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE		0xA0
+#define GRUB_PXENV_STATUS_BINL_NO_PXE_SERVER			0xA1
+#define GRUB_PXENV_STATUS_NOT_AVAILABLE_IN_PMODE		0xA2
+#define GRUB_PXENV_STATUS_NOT_AVAILABLE_IN_RMODE		0xA3
+#define GRUB_PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED		0xB0
+#define GRUB_PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY		0xC0
+#define GRUB_PXENV_STATUS_LOADER_NO_BC_ROMID			0xC1
+#define GRUB_PXENV_STATUS_LOADER_BAD_BC_ROMID			0xC2
+#define GRUB_PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE		0xC3
+#define GRUB_PXENV_STATUS_LOADER_NO_UNDI_ROMID			0xC4
+#define GRUB_PXENV_STATUS_LOADER_BAD_UNDI_ROMID			0xC5
+#define GRUB_PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE		0xC6
+#define GRUB_PXENV_STATUS_LOADER_NO_PXE_STRUCT			0xC8
+#define GRUB_PXENV_STATUS_LOADER_NO_PXENV_STRUCT		0xC9
+#define GRUB_PXENV_STATUS_LOADER_UNDI_START			0xCA
+#define GRUB_PXENV_STATUS_LOADER_BC_START			0xCB
+
+#define GRUB_PXENV_PACKET_TYPE_DHCP_DISCOVER	1
+#define GRUB_PXENV_PACKET_TYPE_DHCP_ACK		2
+#define GRUB_PXENV_PACKET_TYPE_CACHED_REPLY	3
+
+#define GRUB_PXE_BOOTP_REQ	1
+#define GRUB_PXE_BOOTP_REP	2
+
+#define GRUB_PXE_BOOTP_BCAST	0x8000
+
+#if 1
+#define GRUB_PXE_BOOTP_DHCPVEND	1024	/* DHCP extended vendor field size.  */
+#else
+#define GRUB_PXE_BOOTP_DHCPVEND	312	/* DHCP standard vendor field size.  */
+#endif
+
+#define GRUB_PXE_MIN_BLKSIZE	512
+#define GRUB_PXE_MAX_BLKSIZE	1432
+
+#define GRUB_PXE_TFTP_PORT	69
+
+#define	GRUB_PXE_VM_RFC1048	0x63825363L
+
+#define GRUB_PXE_ERR_LEN	0xFFFFFFFF
+
+#ifndef ASM_FILE
+
+struct grub_pxenv
+{
+  grub_uint8_t signature[6];	/* 'PXENV+'.  */
+  grub_uint16_t version;	/* MSB = major, LSB = minor.  */
+  grub_uint8_t length;		/* structure length.  */
+  grub_uint8_t checksum;	/* checksum pad.  */
+  grub_uint32_t rm_entry;	/* SEG:OFF to PXE entry point.  */
+  grub_uint32_t	pm_offset;	/* Protected mode entry.  */
+  grub_uint16_t pm_selector;	/* Protected mode selector.  */
+  grub_uint16_t stack_seg;	/* Stack segment address.  */
+  grub_uint16_t	stack_size;	/* Stack segment size (bytes).  */
+  grub_uint16_t bc_code_seg;	/* BC Code segment address.  */
+  grub_uint16_t	bc_code_size;	/* BC Code segment size (bytes).  */
+  grub_uint16_t	bc_data_seg;	/* BC Data segment address.  */
+  grub_uint16_t	bc_data_size;	/* BC Data segment size (bytes).  */
+  grub_uint16_t	undi_data_seg;	/* UNDI Data segment address.  */
+  grub_uint16_t	undi_data_size;	/* UNDI Data segment size (bytes).  */
+  grub_uint16_t	undi_code_seg;	/* UNDI Code segment address.  */
+  grub_uint16_t	undi_code_size;	/* UNDI Code segment size (bytes).  */
+  grub_uint32_t pxe_ptr;	/* SEG:OFF to !PXE struct.  */
+} __attribute__ ((packed));
+
+struct grub_pxenv_get_cached_info
+{
+  grub_uint16_t status;
+  grub_uint16_t packet_type;
+  grub_uint16_t buffer_size;
+  grub_uint32_t buffer;
+  grub_uint16_t buffer_limit;
+} __attribute__ ((packed));
+
+#define GRUB_PXE_MAC_ADDR_LEN	16
+
+typedef grub_uint8_t grub_pxe_mac_addr[GRUB_PXE_MAC_ADDR_LEN];
+
+struct grub_pxenv_boot_player
+{
+  grub_uint8_t opcode;
+  grub_uint8_t hw_type;		/* hardware type.  */
+  grub_uint8_t hw_len;		/* hardware addr len.  */
+  grub_uint8_t gate_hops;	/* zero it.  */
+  grub_uint32_t ident;		/* random number chosen by client.  */
+  grub_uint16_t seconds;	/* seconds since did initial bootstrap.  */
+  grub_uint16_t flags;
+  grub_uint32_t	client_ip;
+  grub_uint32_t your_ip;
+  grub_uint32_t	server_ip;
+  grub_uint32_t	gateway_ip;
+  grub_pxe_mac_addr mac_addr;
+  grub_uint8_t server_name[64];
+  grub_uint8_t boot_file[128];
+  union
+  {
+    grub_uint8_t d[GRUB_PXE_BOOTP_DHCPVEND];	/* raw array of vendor/dhcp options.  */
+    struct
+    {
+      grub_uint32_t magic;	/* DHCP magic cookie.  */
+      grub_uint32_t flags;	/* bootp flags/opcodes.  */
+      grub_uint8_t padding[56];
+    } v;
+  } vendor;
+} __attribute__ ((packed));
+
+struct grub_pxenv_tftp_open
+{
+  grub_uint16_t status;
+  grub_uint32_t server_ip;
+  grub_uint32_t gateway_ip;
+  grub_uint8_t filename[128];
+  grub_uint16_t tftp_port;
+  grub_uint16_t packet_size;
+} __attribute__ ((packed));
+
+struct grub_pxenv_tftp_close
+{
+  grub_uint16_t status;
+} __attribute__ ((packed));
+
+struct grub_pxenv_tftp_read
+{
+  grub_uint16_t status;
+  grub_uint16_t packet_number;
+  grub_uint16_t buffer_size;
+  grub_uint32_t buffer;
+} __attribute__ ((packed));
+
+struct grub_pxenv_tftp_get_fsize
+{
+  grub_uint16_t status;
+  grub_uint32_t server_ip;
+  grub_uint32_t gateway_ip;
+  grub_uint8_t filename[128];
+  grub_uint32_t file_size;
+} __attribute__ ((packed));
+
+struct grub_pxenv_udp_open
+{
+  grub_uint16_t status;
+  grub_uint32_t src_ip;
+} __attribute__ ((packed));
+
+struct grub_pxenv_udp_close
+{
+  grub_uint16_t status;
+} __attribute__ ((packed));
+
+struct grub_pxenv_udp_write
+{
+  grub_uint16_t status;
+  grub_uint32_t ip;
+  grub_uint32_t gateway;
+  grub_uint16_t src_port;
+  grub_uint16_t dst_port;
+  grub_uint16_t buffer_size;
+  grub_uint32_t buffer;
+} __attribute__ ((packed));
+
+struct grub_pxenv_udp_read
+{
+  grub_uint16_t status;
+  grub_uint32_t src_ip;
+  grub_uint32_t dst_ip;
+  grub_uint16_t src_port;
+  grub_uint16_t dst_port;
+  grub_uint16_t buffer_size;
+  grub_uint32_t buffer;
+} __attribute__ ((packed));
+
+struct grub_pxenv_unload_stack
+{
+  grub_uint16_t status;
+  grub_uint8_t reserved[10];
+} __attribute__ ((packed));
+
+struct grub_pxenv * EXPORT_FUNC(grub_pxe_scan) (void);
+int EXPORT_FUNC(grub_pxe_call) (int func, void * data);
+
+extern struct grub_pxenv *grub_pxe_pxenv;
+extern grub_uint32_t grub_pxe_your_ip;
+extern grub_uint32_t grub_pxe_server_ip;
+extern grub_uint32_t grub_pxe_gateway_ip;
+extern int grub_pxe_blksize;
+
+void grub_pxe_unload (void);
+
+#endif
+
+#endif /* GRUB_CPU_PXE_H */
diff --git a/include/grub/i386/pc/serial.h b/include/grub/i386/pc/serial.h
new file mode 100644
index 0000000..0632ff7
--- /dev/null
+++ b/include/grub/i386/pc/serial.h
@@ -0,0 +1,67 @@
+/* serial.h - serial device interface */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SERIAL_MACHINE_HEADER
+#define GRUB_SERIAL_MACHINE_HEADER	1
+
+/* Macros.  */
+
+/* The offsets of UART registers.  */
+#define UART_TX		0
+#define UART_RX		0
+#define UART_DLL	0
+#define UART_IER	1
+#define UART_DLH	1
+#define UART_IIR	2
+#define UART_FCR	2
+#define UART_LCR	3
+#define UART_MCR	4
+#define UART_LSR	5
+#define UART_MSR	6
+#define UART_SR		7
+
+/* For LSR bits.  */
+#define UART_DATA_READY		0x01
+#define UART_EMPTY_TRANSMITTER	0x20
+
+/* The type of parity.  */
+#define UART_NO_PARITY		0x00
+#define UART_ODD_PARITY		0x08
+#define UART_EVEN_PARITY	0x18
+
+/* The type of word length.  */
+#define UART_5BITS_WORD	0x00
+#define UART_6BITS_WORD	0x01
+#define UART_7BITS_WORD	0x02
+#define UART_8BITS_WORD	0x03
+
+/* The type of the length of stop bit.  */
+#define UART_1_STOP_BIT		0x00
+#define UART_2_STOP_BITS	0x04
+
+/* the switch of DLAB.  */
+#define UART_DLAB	0x80
+
+/* Enable the FIFO.  */
+#define UART_ENABLE_FIFO	0xC7
+
+/* Turn on DTR, RTS, and OUT2.  */
+#define UART_ENABLE_MODEM	0x0B
+
+#endif /* ! GRUB_SERIAL_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/time.h b/include/grub/i386/pc/time.h
new file mode 100644
index 0000000..98399b6
--- /dev/null
+++ b/include/grub/i386/pc/time.h
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_MACHINE_TIME_HEADER
+#define KERNEL_MACHINE_TIME_HEADER	1
+
+#include <grub/symbol.h>
+
+#define GRUB_TICKS_PER_SECOND	18
+
+/* Return the real time in ticks.  */
+grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
+
+#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/include/grub/i386/pc/vbe.h b/include/grub/i386/pc/vbe.h
new file mode 100644
index 0000000..3242767
--- /dev/null
+++ b/include/grub/i386/pc/vbe.h
@@ -0,0 +1,232 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VBE_MACHINE_HEADER
+#define GRUB_VBE_MACHINE_HEADER	1
+
+#include <grub/video_fb.h>
+
+/* Default video mode to be used.  */
+#define GRUB_VBE_DEFAULT_VIDEO_MODE     0x101
+
+/* VBE status codes.  */
+#define GRUB_VBE_STATUS_OK		0x004f
+
+#define GRUB_VBE_CAPABILITY_DACWIDTH	(1 << 0)
+
+/* Bits from the GRUB_VBE "mode_attributes" field in the mode info struct.  */
+#define GRUB_VBE_MODEATTR_SUPPORTED                 (1 << 0)
+#define GRUB_VBE_MODEATTR_RESERVED_1                (1 << 1)
+#define GRUB_VBE_MODEATTR_BIOS_TTY_OUTPUT_SUPPORT   (1 << 2)
+#define GRUB_VBE_MODEATTR_COLOR                     (1 << 3)
+#define GRUB_VBE_MODEATTR_GRAPHICS                  (1 << 4)
+#define GRUB_VBE_MODEATTR_VGA_COMPATIBLE            (1 << 5)
+#define GRUB_VBE_MODEATTR_VGA_WINDOWED_AVAIL        (1 << 6)
+#define GRUB_VBE_MODEATTR_LFB_AVAIL                 (1 << 7)
+#define GRUB_VBE_MODEATTR_DOUBLE_SCAN_AVAIL         (1 << 8)
+#define GRUB_VBE_MODEATTR_INTERLACED_AVAIL          (1 << 9)
+#define GRUB_VBE_MODEATTR_TRIPLE_BUF_AVAIL          (1 << 10)
+#define GRUB_VBE_MODEATTR_STEREO_AVAIL              (1 << 11)
+#define GRUB_VBE_MODEATTR_DUAL_DISPLAY_START        (1 << 12)
+
+/* Values for the GRUB_VBE memory_model field in the mode info struct.  */
+#define GRUB_VBE_MEMORY_MODEL_TEXT           0x00
+#define GRUB_VBE_MEMORY_MODEL_CGA            0x01
+#define GRUB_VBE_MEMORY_MODEL_HERCULES       0x02
+#define GRUB_VBE_MEMORY_MODEL_PLANAR         0x03
+#define GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL   0x04
+#define GRUB_VBE_MEMORY_MODEL_NONCHAIN4_256  0x05
+#define GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR   0x06
+#define GRUB_VBE_MEMORY_MODEL_YUV            0x07
+
+/* Note:
+
+   Please refer to VESA BIOS Extension 3.0 Specification for more descriptive
+   meanings of following structures and how they should be used.
+
+   I have tried to maintain field name compatibility against specification
+   while following naming conventions used in GRUB.  */
+
+typedef grub_uint32_t grub_vbe_farptr_t;
+typedef grub_uint32_t grub_vbe_physptr_t;
+typedef grub_uint32_t grub_vbe_status_t;
+
+struct grub_vbe_info_block
+{
+  grub_uint8_t signature[4];
+  grub_uint16_t version;
+
+  grub_vbe_farptr_t oem_string_ptr;
+  grub_uint32_t capabilities;
+  grub_vbe_farptr_t video_mode_ptr;
+  grub_uint16_t total_memory;
+
+  grub_uint16_t oem_software_rev;
+  grub_vbe_farptr_t oem_vendor_name_ptr;
+  grub_vbe_farptr_t oem_product_name_ptr;
+  grub_vbe_farptr_t oem_product_rev_ptr;
+
+  grub_uint8_t reserved[222];
+
+  grub_uint8_t oem_data[256];
+} __attribute__ ((packed));
+
+struct grub_vbe_mode_info_block
+{
+  /* Mandatory information for all VBE revisions.  */
+  grub_uint16_t mode_attributes;
+  grub_uint8_t win_a_attributes;
+  grub_uint8_t win_b_attributes;
+  grub_uint16_t win_granularity;
+  grub_uint16_t win_size;
+  grub_uint16_t win_a_segment;
+  grub_uint16_t win_b_segment;
+  grub_vbe_farptr_t win_func_ptr;
+  grub_uint16_t bytes_per_scan_line;
+
+  /* Mandatory information for VBE 1.2 and above.  */
+  grub_uint16_t x_resolution;
+  grub_uint16_t y_resolution;
+  grub_uint8_t x_char_size;
+  grub_uint8_t y_char_size;
+  grub_uint8_t number_of_planes;
+  grub_uint8_t bits_per_pixel;
+  grub_uint8_t number_of_banks;
+  grub_uint8_t memory_model;
+  grub_uint8_t bank_size;
+  grub_uint8_t number_of_image_pages;
+  grub_uint8_t reserved;
+
+  /* Direct Color fields (required for direct/6 and YUV/7 memory models).  */
+  grub_uint8_t red_mask_size;
+  grub_uint8_t red_field_position;
+  grub_uint8_t green_mask_size;
+  grub_uint8_t green_field_position;
+  grub_uint8_t blue_mask_size;
+  grub_uint8_t blue_field_position;
+  grub_uint8_t rsvd_mask_size;
+  grub_uint8_t rsvd_field_position;
+  grub_uint8_t direct_color_mode_info;
+
+  /* Mandatory information for VBE 2.0 and above.  */
+  grub_vbe_physptr_t phys_base_addr;
+  grub_uint32_t reserved2;
+  grub_uint16_t reserved3;
+
+  /* Mandatory information for VBE 3.0 and above.  */
+  grub_uint16_t lin_bytes_per_scan_line;
+  grub_uint8_t bnk_number_of_image_pages;
+  grub_uint8_t lin_number_of_image_pages;
+  grub_uint8_t lin_red_mask_size;
+  grub_uint8_t lin_red_field_position;
+  grub_uint8_t lin_green_mask_size;
+  grub_uint8_t lin_green_field_position;
+  grub_uint8_t lin_blue_mask_size;
+  grub_uint8_t lin_blue_field_position;
+  grub_uint8_t lin_rsvd_mask_size;
+  grub_uint8_t lin_rsvd_field_position;
+  grub_uint32_t max_pixel_clock;
+
+  /* Reserved field to make structure to be 256 bytes long, VESA BIOS
+     Extension 3.0 Specification says to reserve 189 bytes here but
+     that doesn't make structure to be 256 bytes.  So additional one is
+     added here.  */
+  grub_uint8_t reserved4[189 + 1];
+} __attribute__ ((packed));
+
+struct grub_vbe_crtc_info_block
+{
+  grub_uint16_t horizontal_total;
+  grub_uint16_t horizontal_sync_start;
+  grub_uint16_t horizontal_sync_end;
+  grub_uint16_t vertical_total;
+  grub_uint16_t vertical_sync_start;
+  grub_uint16_t vertical_sync_end;
+  grub_uint8_t flags;
+  grub_uint32_t pixel_clock;
+  grub_uint16_t refresh_rate;
+  grub_uint8_t reserved[40];
+} __attribute__ ((packed));
+
+struct grub_vbe_palette_data
+{
+  grub_uint8_t blue;
+  grub_uint8_t green;
+  grub_uint8_t red;
+  grub_uint8_t alignment;
+} __attribute__ ((packed));
+
+/* Prototypes for kernel real mode thunks.  */
+
+/* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_controller_info) (struct grub_vbe_info_block *controller_info);
+
+/* Call VESA BIOS 0x4f01 to get VBE Mode Information, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_mode_info) (grub_uint32_t mode,
+                                                            struct grub_vbe_mode_info_block *mode_info);
+
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_getset_dac_palette_width) (int set, int *width);
+
+#define grub_vbe_bios_get_dac_palette_width(width)	grub_vbe_bios_getset_dac_palette_width(0, (width))
+#define grub_vbe_bios_set_dac_palette_width(width)	grub_vbe_bios_getset_dac_palette_width(1, (width))
+
+/* Call VESA BIOS 0x4f02 to set video mode, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_mode) (grub_uint32_t mode,
+                                                       struct grub_vbe_crtc_info_block *crtc_info);
+
+/* Call VESA BIOS 0x4f03 to return current VBE Mode, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_mode) (grub_uint32_t *mode);
+
+/* Call VESA BIOS 0x4f05 to set memory window, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_memory_window) (grub_uint32_t window,
+                                                                grub_uint32_t position);
+
+/* Call VESA BIOS 0x4f05 to return memory window, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_memory_window) (grub_uint32_t window,
+                                                                grub_uint32_t *position);
+
+/* Call VESA BIOS 0x4f06 to set scanline length (in bytes), return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_scanline_length) (grub_uint32_t length);
+
+/* Call VESA BIOS 0x4f06 to return scanline length (in bytes), return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_scanline_length) (grub_uint32_t *length);
+
+/* Call VESA BIOS 0x4f07 to set display start, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_display_start) (grub_uint32_t x,
+                                                                grub_uint32_t y);
+
+/* Call VESA BIOS 0x4f07 to get display start, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_display_start) (grub_uint32_t *x,
+                                                                grub_uint32_t *y);
+
+/* Call VESA BIOS 0x4f09 to set palette data, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_palette_data) (grub_uint32_t color_count,
+                                                               grub_uint32_t start_index,
+                                                               struct grub_vbe_palette_data *palette_data);
+
+/* Prototypes for helper functions.  */
+
+grub_err_t grub_vbe_probe (struct grub_vbe_info_block *info_block);
+grub_err_t grub_vbe_set_video_mode (grub_uint32_t mode,
+                                    struct grub_vbe_mode_info_block *mode_info);
+grub_err_t grub_vbe_get_video_mode (grub_uint32_t *mode);
+grub_err_t grub_vbe_get_video_mode_info (grub_uint32_t mode,
+                                         struct grub_vbe_mode_info_block *mode_info);
+
+
+#endif /* ! GRUB_VBE_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/vga.h b/include/grub/i386/pc/vga.h
new file mode 100644
index 0000000..b982239
--- /dev/null
+++ b/include/grub/i386/pc/vga.h
@@ -0,0 +1,34 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VGA_MACHINE_HEADER
+#define GRUB_VGA_MACHINE_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+
+/* The VGA (at the beginning of upper memory).  */
+#define GRUB_MEMORY_MACHINE_VGA_ADDR		GRUB_MEMORY_MACHINE_UPPER
+
+/* Set the video mode to MODE and return the previous mode.  */
+unsigned char EXPORT_FUNC(grub_vga_set_mode) (unsigned char mode);
+
+/* Return a pointer to the ROM font table.  */
+unsigned char *EXPORT_FUNC(grub_vga_get_font) (void);
+
+#endif /* ! GRUB_VGA_MACHINE_HEADER */
diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h
new file mode 100644
index 0000000..996f642
--- /dev/null
+++ b/include/grub/i386/pci.h
@@ -0,0 +1,70 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef	GRUB_CPU_PCI_H
+#define	GRUB_CPU_PCI_H	1
+
+#include <grub/types.h>
+#include <grub/i386/io.h>
+
+#define GRUB_PCI_ADDR_REG	0xcf8
+#define GRUB_PCI_DATA_REG	0xcfc
+
+static inline grub_uint32_t
+grub_pci_read (grub_pci_address_t addr)
+{
+  grub_outl (addr, GRUB_PCI_ADDR_REG);
+  return grub_inl (GRUB_PCI_DATA_REG);
+}
+
+static inline grub_uint16_t
+grub_pci_read_word (grub_pci_address_t addr)
+{
+  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
+  return grub_inw (GRUB_PCI_DATA_REG + (addr & 3));
+}
+
+static inline grub_uint8_t
+grub_pci_read_byte (grub_pci_address_t addr)
+{
+  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
+  return grub_inb (GRUB_PCI_DATA_REG + (addr & 3));
+}
+
+static inline void
+grub_pci_write (grub_pci_address_t addr, grub_uint32_t data)
+{
+  grub_outl (addr, GRUB_PCI_ADDR_REG);
+  grub_outl (data, GRUB_PCI_DATA_REG);
+}
+
+static inline void
+grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data)
+{
+  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
+  grub_outw (data, GRUB_PCI_DATA_REG + (addr & 3));
+}
+
+static inline void
+grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data)
+{
+  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
+  grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3));
+}
+
+#endif /* GRUB_CPU_PCI_H */
diff --git a/include/grub/i386/pit.h b/include/grub/i386/pit.h
new file mode 100644
index 0000000..ff9b9a6
--- /dev/null
+++ b/include/grub/i386/pit.h
@@ -0,0 +1,27 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_PIT_HEADER
+#define KERNEL_CPU_PIT_HEADER   1
+
+#include <grub/types.h>
+#include <grub/err.h>
+
+void EXPORT_FUNC(grub_pit_wait) (grub_uint16_t tics);
+
+#endif /* ! KERNEL_CPU_PIT_HEADER */
diff --git a/include/grub/i386/qemu/boot.h b/include/grub/i386/qemu/boot.h
new file mode 100644
index 0000000..6fbb577
--- /dev/null
+++ b/include/grub/i386/qemu/boot.h
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BOOT_MACHINE_HEADER
+#define GRUB_BOOT_MACHINE_HEADER	1
+
+/* The size of boot.img.  */
+#define GRUB_BOOT_MACHINE_SIZE			(0x100000 - GRUB_BOOT_MACHINE_LINK_ADDR)
+
+/* The offset of GRUB_CORE_ENTRY_ADDR.  */
+#define GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR	0x4
+
+#endif
diff --git a/include/grub/i386/qemu/console.h b/include/grub/i386/qemu/console.h
new file mode 100644
index 0000000..774399a
--- /dev/null
+++ b/include/grub/i386/qemu/console.h
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/console.h>
diff --git a/include/grub/i386/qemu/init.h b/include/grub/i386/qemu/init.h
new file mode 100644
index 0000000..fd935c3
--- /dev/null
+++ b/include/grub/i386/qemu/init.h
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/init.h>
diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h
new file mode 100644
index 0000000..bc0b93d
--- /dev/null
+++ b/include/grub/i386/qemu/kernel.h
@@ -0,0 +1,53 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER	1
+
+/* The offset of GRUB_CORE_ENTRY_ADDR.  */
+#define GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR	0x8
+
+/* The offset of GRUB_KERNEL_IMAGE_SIZE.  */
+#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE	0xc
+
+/* The offset of GRUB_PREFIX.  */
+#define GRUB_KERNEL_MACHINE_PREFIX		0x10
+
+/* End of the data section. */
+#define GRUB_KERNEL_MACHINE_DATA_END		0x50
+
+#ifndef ASM_FILE
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+extern grub_addr_t grub_core_entry_addr;
+
+/* The size of kernel image.  */
+extern grub_int32_t grub_kernel_image_size;
+
+/* The total size of module images following the kernel.  */
+extern grub_int32_t grub_total_module_size;
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/include/grub/i386/qemu/loader.h b/include/grub/i386/qemu/loader.h
new file mode 100644
index 0000000..d3f36bb
--- /dev/null
+++ b/include/grub/i386/qemu/loader.h
@@ -0,0 +1 @@
+#include <grub/cpu/loader.h>
diff --git a/include/grub/i386/qemu/machine.h b/include/grub/i386/qemu/machine.h
new file mode 100644
index 0000000..b57932b
--- /dev/null
+++ b/include/grub/i386/qemu/machine.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_MACHINE_HEADER
+#define GRUB_MACHINE_MACHINE_HEADER	1
+
+#define GRUB_MACHINE_QEMU	1
+
+#endif /* ! GRUB_MACHINE_MACHINE_HEADER */
diff --git a/include/grub/i386/qemu/memory.h b/include/grub/i386/qemu/memory.h
new file mode 100644
index 0000000..de55944
--- /dev/null
+++ b/include/grub/i386/qemu/memory.h
@@ -0,0 +1,45 @@
+/* memory.h - describe the memory map */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GRUB_MEMORY_MACHINE_HEADER
+#define _GRUB_MEMORY_MACHINE_HEADER      1
+
+#include <grub/symbol.h>
+#include <grub/i386/pc/memory.h>
+
+#ifndef ASM_FILE
+#include <grub/err.h>
+#include <grub/types.h>
+#endif
+
+#define GRUB_MEMORY_MACHINE_LOWER_USABLE		0x9fc00		/* 640 kiB - 1 kiB */
+
+#define GRUB_MEMORY_MACHINE_UPPER_START			0x100000	/* 1 MiB */
+#define GRUB_MEMORY_MACHINE_LOWER_SIZE			GRUB_MEMORY_MACHINE_UPPER_START
+
+#ifndef ASM_FILE
+
+void grub_machine_mmap_init (void);
+
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
+     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+
+#endif
+
+#endif /* ! _GRUB_MEMORY_MACHINE_HEADER */
diff --git a/include/grub/i386/qemu/serial.h b/include/grub/i386/qemu/serial.h
new file mode 100644
index 0000000..2d85634
--- /dev/null
+++ b/include/grub/i386/qemu/serial.h
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/serial.h>
diff --git a/include/grub/i386/qemu/time.h b/include/grub/i386/qemu/time.h
new file mode 100644
index 0000000..7177c74
--- /dev/null
+++ b/include/grub/i386/qemu/time.h
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/time.h>
diff --git a/include/grub/i386/reboot.h b/include/grub/i386/reboot.h
new file mode 100644
index 0000000..5bcbb5d
--- /dev/null
+++ b/include/grub/i386/reboot.h
@@ -0,0 +1,19 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+extern void grub_reboot (void);
diff --git a/include/grub/i386/setjmp.h b/include/grub/i386/setjmp.h
new file mode 100644
index 0000000..6b6b6fd
--- /dev/null
+++ b/include/grub/i386/setjmp.h
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER	1
+
+typedef unsigned long grub_jmp_buf[6];
+
+#ifdef __MINGW32__
+int grub_setjmp (grub_jmp_buf env) __attribute__ ((cdecl, regparm (3)));
+#else
+int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice, cdecl,
+						   regparm (3)));
+#endif
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn, cdecl,
+							      regparm (3)));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/include/grub/i386/time.h b/include/grub/i386/time.h
new file mode 100644
index 0000000..842882c
--- /dev/null
+++ b/include/grub/i386/time.h
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER	1
+
+static __inline void
+grub_cpu_idle (void)
+{
+  /* FIXME: this can't work until we handle interrupts.  */
+/*  __asm__ __volatile__ ("hlt"); */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/include/grub/i386/tsc.h b/include/grub/i386/tsc.h
new file mode 100644
index 0000000..46041c2
--- /dev/null
+++ b/include/grub/i386/tsc.h
@@ -0,0 +1,141 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TSC_HEADER
+#define KERNEL_CPU_TSC_HEADER   1
+
+#include <grub/types.h>
+
+/* Read the TSC value, which increments with each CPU clock cycle. */
+static __inline grub_uint64_t
+grub_get_tsc (void)
+{
+  grub_uint32_t lo, hi;
+
+  /* The CPUID instruction is a 'serializing' instruction, and
+     avoids out-of-order execution of the RDTSC instruction. */
+#ifdef APPLE_CC
+  __asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
+#ifdef __x86_64__
+			"push %%rbx\n"
+#else
+			"push %%ebx\n"
+#endif
+			"cpuid\n"
+#ifdef __x86_64__
+			"pop %%rbx\n"
+#else
+			"pop %%ebx\n"
+#endif
+			:::"%rax", "%rcx", "%rdx");
+#else
+  __asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
+			"cpuid":::"%rax", "%rbx", "%rcx", "%rdx");
+#endif
+  /* Read TSC value.  We cannot use "=A", since this would use
+     %rax on x86_64. */
+  __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi));
+
+  return (((grub_uint64_t) hi) << 32) | lo;
+}
+
+#ifdef __x86_64__
+
+static __inline int
+grub_cpu_is_cpuid_supported (void)
+{
+  grub_uint64_t id_supported;
+
+  __asm__ ("pushfq\n\t"
+           "popq %%rax             /* Get EFLAGS into EAX */\n\t"
+           "movq %%rax, %%rcx      /* Save original flags in ECX */\n\t"
+           "xorq $0x200000, %%rax  /* Flip ID bit in EFLAGS */\n\t"
+           "pushq %%rax            /* Store modified EFLAGS on stack */\n\t"
+           "popfq                  /* Replace current EFLAGS */\n\t"
+           "pushfq                 /* Read back the EFLAGS */\n\t"
+           "popq %%rax             /* Get EFLAGS into EAX */\n\t"
+           "xorq %%rcx, %%rax      /* Check if flag could be modified */\n\t"
+           : "=a" (id_supported)
+           : /* No inputs.  */
+           : /* Clobbered:  */ "%rcx");
+
+  return id_supported != 0;
+}
+
+#else
+
+static __inline int
+grub_cpu_is_cpuid_supported (void)
+{
+  grub_uint32_t id_supported;
+
+  __asm__ ("pushfl\n\t"
+           "popl %%eax             /* Get EFLAGS into EAX */\n\t"
+           "movl %%eax, %%ecx      /* Save original flags in ECX */\n\t"
+           "xorl $0x200000, %%eax  /* Flip ID bit in EFLAGS */\n\t"
+           "pushl %%eax            /* Store modified EFLAGS on stack */\n\t"
+           "popfl                  /* Replace current EFLAGS */\n\t"
+           "pushfl                 /* Read back the EFLAGS */\n\t"
+           "popl %%eax             /* Get EFLAGS into EAX */\n\t"
+           "xorl %%ecx, %%eax      /* Check if flag could be modified */\n\t"
+           : "=a" (id_supported)
+           : /* No inputs.  */
+           : /* Clobbered:  */ "%rcx");
+
+  return id_supported != 0;
+}
+
+#endif
+
+static __inline int
+grub_cpu_is_tsc_supported (void)
+{
+  if (! grub_cpu_is_cpuid_supported ())
+    return 0;
+
+  grub_uint32_t features;
+#ifdef APPLE_CC
+  __asm__ ("movl $1, %%eax\n\t"
+#ifdef __x86_64__
+	   "push %%rbx\n"
+#else
+	   "push %%ebx\n"
+#endif
+	   "cpuid\n"
+#ifdef __x86_64__
+	   "pop %%rbx\n"
+#else
+	   "pop %%ebx\n"
+#endif
+           : "=d" (features)
+           : /* No inputs.  */
+	   : /* Clobbered:  */ "%rax", "%rcx");
+#else
+  __asm__ ("movl $1, %%eax\n\t"
+           "cpuid\n"
+           : "=d" (features)
+           : /* No inputs.  */
+           : /* Clobbered:  */ "%rax", "%rbx", "%rcx");
+#endif
+  return (features & (1 << 4)) != 0;
+}
+
+void grub_tsc_init (void);
+grub_uint64_t grub_tsc_get_time_ms (void);
+
+#endif /* ! KERNEL_CPU_TSC_HEADER */
diff --git a/include/grub/i386/types.h b/include/grub/i386/types.h
new file mode 100644
index 0000000..0ac6473
--- /dev/null
+++ b/include/grub/i386/types.h
@@ -0,0 +1,31 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER	1
+
+/* The size of void *.  */
+#define GRUB_TARGET_SIZEOF_VOID_P	4
+
+/* The size of long.  */
+#define GRUB_TARGET_SIZEOF_LONG		4
+
+/* i386 is little-endian.  */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/include/grub/i386/vga_common.h b/include/grub/i386/vga_common.h
new file mode 100644
index 0000000..f17fc01
--- /dev/null
+++ b/include/grub/i386/vga_common.h
@@ -0,0 +1,40 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VGA_COMMON_CPU_HEADER
+#define GRUB_VGA_COMMON_CPU_HEADER	1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/term.h>
+
+extern grub_uint8_t grub_console_cur_color;
+
+void grub_console_putchar (grub_uint32_t c);
+grub_ssize_t grub_console_getcharwidth (grub_uint32_t c);
+grub_uint16_t grub_console_getwh (void);
+void grub_console_setcolorstate (grub_term_color_state state);
+void grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color);
+void grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color);
+
+/* Implemented in both kern/i386/pc/startup.S and vga_text.c;  this symbol
+   is not exported, so there's no collision, but vga_common.c expects this
+   prototype to be the same.  */
+void grub_console_real_putchar (int c);
+
+#endif /* ! GRUB_VGA_COMMON_CPU_HEADER */
diff --git a/include/grub/i386/xnu.h b/include/grub/i386/xnu.h
new file mode 100644
index 0000000..68674e6
--- /dev/null
+++ b/include/grub/i386/xnu.h
@@ -0,0 +1,80 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CPU_XNU_H
+#define GRUB_CPU_XNU_H 1
+
+#include <grub/err.h>
+
+#define GRUB_XNU_PAGESIZE 4096
+typedef grub_uint32_t grub_xnu_ptr_t;
+
+struct grub_xnu_boot_params
+{
+  grub_uint16_t verminor;
+  grub_uint16_t vermajor;
+  /* Command line passed to xnu. */
+  grub_uint8_t cmdline[1024];
+
+  /* Later are the same as EFI's get_memory_map (). */
+  grub_xnu_ptr_t efi_mmap;
+  grub_uint32_t efi_mmap_size;
+  grub_uint32_t efi_mem_desc_size;
+  grub_uint32_t efi_mem_desc_version;
+
+  /* Later are video parameters. */
+  grub_xnu_ptr_t lfb_base;
+#define GRUB_XNU_VIDEO_SPLASH 1
+#define GRUB_XNU_VIDEO_TEXT_IN_VIDEO 2
+  grub_uint32_t lfb_mode;
+  grub_uint32_t lfb_line_len;
+  grub_uint32_t lfb_width;
+  grub_uint32_t lfb_height;
+  grub_uint32_t lfb_depth;
+
+  /* Pointer to device tree and its len. */
+  grub_xnu_ptr_t devtree;
+  grub_uint32_t devtreelen;
+
+  /* First used address by kernel or boot structures. */
+  grub_xnu_ptr_t heap_start;
+  /* Last used address by kernel or boot structures minus previous value. */
+  grub_uint32_t heap_size;
+
+  /* First memory page containing runtime code or data. */
+  grub_uint32_t efi_runtime_first_page;
+  /* First memory page containing runtime code or data minus previous value. */
+  grub_uint32_t efi_runtime_npages;
+  grub_uint32_t efi_system_table;
+  /* Size of grub_efi_uintn_t in bits. */
+  grub_uint8_t efi_uintnbits;
+} __attribute__ ((packed));
+#define GRUB_XNU_BOOTARGS_VERMINOR 4
+#define GRUB_XNU_BOOTARGS_VERMAJOR 1
+
+extern grub_uint32_t grub_xnu_entry_point;
+extern grub_uint32_t grub_xnu_stack;
+extern grub_uint32_t grub_xnu_arg1;
+extern char grub_xnu_cmdline[1024];
+grub_err_t grub_xnu_boot (void);
+grub_err_t grub_cpu_xnu_fill_devicetree (void);
+grub_err_t grub_xnu_set_video (struct grub_xnu_boot_params *bootparams_relloc);
+extern grub_uint32_t grub_xnu_heap_will_be_at;
+extern grub_uint8_t grub_xnu_launcher_start[];
+extern grub_uint8_t grub_xnu_launcher_end[];
+#endif
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
new file mode 100644
index 0000000..0e6aae5
--- /dev/null
+++ b/include/grub/ieee1275/ieee1275.h
@@ -0,0 +1,179 @@
+/* ieee1275.h - Access the Open Firmware client interface.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_IEEE1275_HEADER
+#define GRUB_IEEE1275_HEADER	1
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/machine/ieee1275.h>
+
+/* Maps a device alias to a pathname.  */
+struct grub_ieee1275_devalias
+{
+  char *name;
+  char *path;
+  char *type;
+};
+
+struct grub_ieee1275_mem_region
+{
+  unsigned int start;
+  unsigned int size;
+};
+
+#define IEEE1275_MAX_PROP_LEN	8192
+#define IEEE1275_MAX_PATH_LEN	256
+
+#ifndef IEEE1275_CALL_ENTRY_FN
+#define IEEE1275_CALL_ENTRY_FN(args) (*grub_ieee1275_entry_fn) (args)
+#endif
+
+/* All backcalls to the firmware is done by calling an entry function
+   which was passed to us from the bootloader.  When doing the backcall,
+   a structure is passed which specifies what the firmware should do.
+   NAME is the requested service.  NR_INS and NR_OUTS is the number of
+   passed arguments and the expected number of return values, resp. */
+struct grub_ieee1275_common_hdr
+{
+  grub_ieee1275_cell_t name;
+  grub_ieee1275_cell_t nr_ins;
+  grub_ieee1275_cell_t nr_outs;
+};
+
+#define INIT_IEEE1275_COMMON(p, xname, xins, xouts) \
+  (p)->name = (grub_ieee1275_cell_t) xname; \
+  (p)->nr_ins = (grub_ieee1275_cell_t) xins; \
+  (p)->nr_outs = (grub_ieee1275_cell_t) xouts
+
+typedef grub_uint32_t grub_ieee1275_ihandle_t;
+typedef grub_uint32_t grub_ieee1275_phandle_t;
+
+extern grub_ieee1275_phandle_t EXPORT_VAR(grub_ieee1275_chosen);
+extern grub_ieee1275_ihandle_t EXPORT_VAR(grub_ieee1275_mmu);
+extern int (* EXPORT_VAR(grub_ieee1275_entry_fn)) (void *);
+
+enum grub_ieee1275_flag
+{
+  /* Old World Macintosh firmware fails seek when "dev:0" is opened.  */
+  GRUB_IEEE1275_FLAG_NO_PARTITION_0,
+
+  /* Apple firmware runs in translated mode and requires use of the "map"
+     method.  Other firmware runs in untranslated mode and doesn't like "map"
+     calls.  */
+  GRUB_IEEE1275_FLAG_REAL_MODE,
+
+  /* CHRP specifies partitions are numbered from 1 (partition 0 refers to the
+     whole disk). However, CodeGen firmware numbers partitions from 0.  */
+  GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS,
+
+  /* CodeGen firmware does not correctly implement "output-device output" */
+  GRUB_IEEE1275_FLAG_BROKEN_OUTPUT,
+
+  /* OLPC / XO firmware hangs when accessing USB devices.  */
+  GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY,
+
+  /* Open Hack'Ware stops when trying to set colors */
+  GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS,
+
+  /* Open Hack'Ware stops when grub_ieee1275_interpret is used.  */
+  GRUB_IEEE1275_FLAG_CANNOT_INTERPRET,
+
+  /* Open Hack'Ware has no memory map, just claim what we need.  */
+  GRUB_IEEE1275_FLAG_FORCE_CLAIM,
+
+  /* Open Hack'Ware don't support the ANSI sequence.  */
+  GRUB_IEEE1275_FLAG_NO_ANSI,
+};
+
+extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag);
+extern void EXPORT_FUNC(grub_ieee1275_set_flag) (enum grub_ieee1275_flag flag);
+
+
+
+
+void EXPORT_FUNC(grub_ieee1275_init) (void);
+int EXPORT_FUNC(grub_ieee1275_finddevice) (char *name,
+					   grub_ieee1275_phandle_t *phandlep);
+int EXPORT_FUNC(grub_ieee1275_get_property) (grub_ieee1275_phandle_t phandle,
+					     const char *property, void *buf,
+					     grub_size_t size,
+					     grub_ssize_t *actual);
+int EXPORT_FUNC(grub_ieee1275_get_integer_property) (grub_ieee1275_phandle_t phandle,
+						     const char *property, grub_uint32_t *buf,
+						     grub_size_t size,
+						     grub_ssize_t *actual);
+int EXPORT_FUNC(grub_ieee1275_next_property) (grub_ieee1275_phandle_t phandle,
+					      char *prev_prop, char *prop);
+int EXPORT_FUNC(grub_ieee1275_get_property_length)
+     (grub_ieee1275_phandle_t phandle, const char *prop, grub_ssize_t *length);
+int EXPORT_FUNC(grub_ieee1275_instance_to_package)
+     (grub_ieee1275_ihandle_t ihandle, grub_ieee1275_phandle_t *phandlep);
+int EXPORT_FUNC(grub_ieee1275_package_to_path) (grub_ieee1275_phandle_t phandle,
+						char *path, grub_size_t len,
+						grub_ssize_t *actual);
+int EXPORT_FUNC(grub_ieee1275_instance_to_path)
+     (grub_ieee1275_ihandle_t ihandle, char *path, grub_size_t len,
+      grub_ssize_t *actual);
+int EXPORT_FUNC(grub_ieee1275_write) (grub_ieee1275_ihandle_t ihandle,
+				      void *buffer, grub_size_t len,
+				      grub_ssize_t *actualp);
+int EXPORT_FUNC(grub_ieee1275_read) (grub_ieee1275_ihandle_t ihandle,
+				     void *buffer, grub_size_t len,
+				     grub_ssize_t *actualp);
+int EXPORT_FUNC(grub_ieee1275_seek) (grub_ieee1275_ihandle_t ihandle,
+				     int pos_hi, int pos_lo,
+				     grub_ssize_t *result);
+int EXPORT_FUNC(grub_ieee1275_peer) (grub_ieee1275_phandle_t node,
+				     grub_ieee1275_phandle_t *result);
+int EXPORT_FUNC(grub_ieee1275_child) (grub_ieee1275_phandle_t node,
+				      grub_ieee1275_phandle_t *result);
+int EXPORT_FUNC(grub_ieee1275_parent) (grub_ieee1275_phandle_t node,
+				       grub_ieee1275_phandle_t *result);
+int EXPORT_FUNC(grub_ieee1275_interpret) (const char *command,
+					  grub_ieee1275_cell_t *catch);
+int EXPORT_FUNC(grub_ieee1275_enter) (void);
+void EXPORT_FUNC(grub_ieee1275_exit) (void) __attribute__ ((noreturn));
+int EXPORT_FUNC(grub_ieee1275_open) (const char *node,
+				     grub_ieee1275_ihandle_t *result);
+int EXPORT_FUNC(grub_ieee1275_close) (grub_ieee1275_ihandle_t ihandle);
+int EXPORT_FUNC(grub_ieee1275_claim) (grub_addr_t addr, grub_size_t size,
+				      unsigned int align, grub_addr_t *result);
+int EXPORT_FUNC(grub_ieee1275_release) (grub_addr_t addr, grub_size_t size);
+int EXPORT_FUNC(grub_ieee1275_set_property) (grub_ieee1275_phandle_t phandle,
+					     const char *propname, void *buf,
+					     grub_size_t size,
+					     grub_ssize_t *actual);
+int EXPORT_FUNC(grub_ieee1275_set_color) (grub_ieee1275_ihandle_t ihandle,
+					  int index, int r, int g, int b);
+int EXPORT_FUNC(grub_ieee1275_milliseconds) (grub_uint32_t *msecs);
+
+
+int EXPORT_FUNC(grub_devalias_iterate)
+     (int (*hook) (struct grub_ieee1275_devalias *alias));
+int EXPORT_FUNC(grub_children_iterate) (char *devpath,
+     int (*hook) (struct grub_ieee1275_devalias *alias));
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
+     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
+
+char *EXPORT_FUNC(grub_ieee1275_encode_devname) (const char *path);
+char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path);
+
+#endif /* ! GRUB_IEEE1275_HEADER */
diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h
new file mode 100644
index 0000000..2f69e3f
--- /dev/null
+++ b/include/grub/ieee1275/ofdisk.h
@@ -0,0 +1,25 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_OFDISK_HEADER
+#define GRUB_OFDISK_HEADER	1
+
+extern void grub_ofdisk_init (void);
+extern void grub_ofdisk_fini (void);
+
+#endif /* ! GRUB_INIT_HEADER */
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
new file mode 100644
index 0000000..75ec77c
--- /dev/null
+++ b/include/grub/kernel.h
@@ -0,0 +1,76 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_HEADER
+#define GRUB_KERNEL_HEADER	1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+enum
+{
+  OBJ_TYPE_ELF,
+  OBJ_TYPE_MEMDISK,
+  OBJ_TYPE_CONFIG
+};
+
+/* The module header.  */
+struct grub_module_header
+{
+  /* The type of object.  */
+  grub_uint8_t type;
+  /* The size of object (including this header).  */
+  grub_uint32_t size;
+};
+
+/* "gmim" (GRUB Module Info Magic).  */
+#define GRUB_MODULE_MAGIC 0x676d696d
+
+struct grub_module_info
+{
+  /* Magic number so we know we have modules present.  */
+  grub_uint32_t magic;
+#if GRUB_TARGET_SIZEOF_VOID_P == 8
+  grub_uint32_t padding;
+#endif
+  /* The offset of the modules.  */
+  grub_target_off_t offset;
+  /* The size of all modules plus this header.  */
+  grub_target_size_t size;
+};
+
+extern grub_addr_t grub_arch_modules_addr (void);
+
+extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *));
+
+/* The start point of the C code.  */
+void grub_main (void);
+
+/* The machine-specific initialization. This must initialize memory.  */
+void grub_machine_init (void);
+
+/* The machine-specific finalization.  */
+void EXPORT_FUNC(grub_machine_fini) (void);
+
+/* The machine-specific prefix initialization.  */
+void grub_machine_set_prefix (void);
+
+/* Register all the exported symbols. This is automatically generated.  */
+void grub_register_exported_symbols (void);
+
+#endif /* ! GRUB_KERNEL_HEADER */
diff --git a/include/grub/lib/LzFind.h b/include/grub/lib/LzFind.h
new file mode 100644
index 0000000..69447b6
--- /dev/null
+++ b/include/grub/lib/LzFind.h
@@ -0,0 +1,130 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#ifndef __LZFIND_H
+#define __LZFIND_H
+
+#include <grub/lib/LzmaTypes.h>
+
+typedef UInt32 CLzRef;
+
+typedef struct _CMatchFinder
+{
+  Byte *buffer;
+  UInt32 pos;
+  UInt32 posLimit;
+  UInt32 streamPos;
+  UInt32 lenLimit;
+
+  UInt32 cyclicBufferPos;
+  UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
+
+  UInt32 matchMaxLen;
+  CLzRef *hash;
+  CLzRef *son;
+  UInt32 hashMask;
+  UInt32 cutValue;
+
+  Byte *bufferBase;
+  ISeqInStream *stream;
+  int streamEndWasReached;
+
+  UInt32 blockSize;
+  UInt32 keepSizeBefore;
+  UInt32 keepSizeAfter;
+
+  UInt32 numHashBytes;
+  int directInput;
+  int btMode;
+  /* int skipModeBits; */
+  int bigHash;
+  UInt32 historySize;
+  UInt32 fixedHashSize;
+  UInt32 hashSizeSum;
+  UInt32 numSons;
+  SRes result;
+  UInt32 crc[256];
+} CMatchFinder;
+
+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
+
+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
+
+int MatchFinder_NeedMove(CMatchFinder *p);
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
+void MatchFinder_MoveBlock(CMatchFinder *p);
+void MatchFinder_ReadIfRequired(CMatchFinder *p);
+
+void MatchFinder_Construct(CMatchFinder *p);
+
+/* Conditions:
+     historySize <= 3 GB
+     keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
+*/
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+    ISzAlloc *alloc);
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
+    UInt32 *distances, UInt32 maxLen);
+
+/*
+Conditions:
+  Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
+  Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
+*/
+
+typedef void (*Mf_Init_Func)(void *object);
+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
+typedef void (*Mf_Skip_Func)(void *object, UInt32);
+
+typedef struct _IMatchFinder
+{
+  Mf_Init_Func Init;
+  Mf_GetIndexByte_Func GetIndexByte;
+  Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
+  Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
+  Mf_GetMatches_Func GetMatches;
+  Mf_Skip_Func Skip;
+} IMatchFinder;
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
+
+void MatchFinder_Init(CMatchFinder *p);
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+
+#endif
diff --git a/include/grub/lib/LzHash.h b/include/grub/lib/LzHash.h
new file mode 100644
index 0000000..c3d5586
--- /dev/null
+++ b/include/grub/lib/LzHash.h
@@ -0,0 +1,77 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#ifndef __LZHASH_H
+#define __LZHASH_H
+
+#define kHash2Size (1 << 10)
+#define kHash3Size (1 << 16)
+#define kHash4Size (1 << 20)
+
+#define kFix3HashSize (kHash2Size)
+#define kFix4HashSize (kHash2Size + kHash3Size)
+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
+
+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
+
+#define HASH3_CALC { \
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
+
+#define HASH4_CALC { \
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+  hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
+
+#define HASH5_CALC { \
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
+  hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
+  hash4Value &= (kHash4Size - 1); }
+
+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
+
+
+#define MT_HASH2_CALC \
+  hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
+
+#define MT_HASH3_CALC { \
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
+
+#define MT_HASH4_CALC { \
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
+
+#endif
diff --git a/include/grub/lib/LzmaDec.h b/include/grub/lib/LzmaDec.h
new file mode 100644
index 0000000..1e66b74
--- /dev/null
+++ b/include/grub/lib/LzmaDec.h
@@ -0,0 +1,246 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#ifndef __LZMADEC_H
+#define __LZMADEC_H
+
+#include "Types.h"
+
+/* #define _LZMA_PROB32 */
+/* _LZMA_PROB32 can increase the speed on some CPUs,
+   but memory usage for CLzmaDec::probs will be doubled in that case */
+
+#ifdef _LZMA_PROB32
+#define CLzmaProb UInt32
+#else
+#define CLzmaProb UInt16
+#endif
+
+
+/* ---------- LZMA Properties ---------- */
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaProps
+{
+  unsigned lc, lp, pb;
+  UInt32 dicSize;
+} CLzmaProps;
+
+/* LzmaProps_Decode - decodes properties
+Returns:
+  SZ_OK
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
+
+
+/* ---------- LZMA Decoder state ---------- */
+
+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
+   Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
+
+#define LZMA_REQUIRED_INPUT_MAX 20
+
+typedef struct
+{
+  CLzmaProps prop;
+  CLzmaProb *probs;
+  Byte *dic;
+  const Byte *buf;
+  UInt32 range, code;
+  SizeT dicPos;
+  SizeT dicBufSize;
+  UInt32 processedPos;
+  UInt32 checkDicSize;
+  unsigned state;
+  UInt32 reps[4];
+  unsigned remainLen;
+  int needFlush;
+  int needInitState;
+  UInt32 numProbs;
+  unsigned tempBufSize;
+  Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
+} CLzmaDec;
+
+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
+
+void LzmaDec_Init(CLzmaDec *p);
+
+/* There are two types of LZMA streams:
+     0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
+     1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
+
+typedef enum
+{
+  LZMA_FINISH_ANY,   /* finish at any point */
+  LZMA_FINISH_END    /* block must be finished at the end */
+} ELzmaFinishMode;
+
+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
+
+   You must use LZMA_FINISH_END, when you know that current output buffer
+   covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
+
+   If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
+   and output value of destLen will be less than output buffer size limit.
+   You can check status result also.
+
+   You can use multiple checks to test data integrity after full decompression:
+     1) Check Result and "status" variable.
+     2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
+     3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
+        You must use correct finish mode in that case. */
+
+typedef enum
+{
+  LZMA_STATUS_NOT_SPECIFIED,               /* use main error code instead */
+  LZMA_STATUS_FINISHED_WITH_MARK,          /* stream was finished with end mark. */
+  LZMA_STATUS_NOT_FINISHED,                /* stream was not finished */
+  LZMA_STATUS_NEEDS_MORE_INPUT,            /* you must provide more input bytes */
+  LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK  /* there is probability that stream was finished without end mark */
+} ELzmaStatus;
+
+/* ELzmaStatus is used only as output value for function call */
+
+
+/* ---------- Interfaces ---------- */
+
+/* There are 3 levels of interfaces:
+     1) Dictionary Interface
+     2) Buffer Interface
+     3) One Call Interface
+   You can select any of these interfaces, but don't mix functions from different
+   groups for same object. */
+
+
+/* There are two variants to allocate state for Dictionary Interface:
+     1) LzmaDec_Allocate / LzmaDec_Free
+     2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
+   You can use variant 2, if you set dictionary buffer manually.
+   For Buffer Interface you must always use variant 1.
+
+LzmaDec_Allocate* can return:
+  SZ_OK
+  SZ_ERROR_MEM         - Memory allocation error
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
+
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
+
+/* ---------- Dictionary Interface ---------- */
+
+/* You can use it, if you want to eliminate the overhead for data copying from
+   dictionary to some other external buffer.
+   You must work with CLzmaDec variables directly in this interface.
+
+   STEPS:
+     LzmaDec_Constr()
+     LzmaDec_Allocate()
+     for (each new stream)
+     {
+       LzmaDec_Init()
+       while (it needs more decompression)
+       {
+         LzmaDec_DecodeToDic()
+         use data from CLzmaDec::dic and update CLzmaDec::dicPos
+       }
+     }
+     LzmaDec_Free()
+*/
+
+/* LzmaDec_DecodeToDic
+
+   The decoding to internal dictionary buffer (CLzmaDec::dic).
+   You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (dicLimit).
+  LZMA_FINISH_ANY - Decode just dicLimit bytes.
+  LZMA_FINISH_END - Stream must be finished after dicLimit.
+
+Returns:
+  SZ_OK
+    status:
+      LZMA_STATUS_FINISHED_WITH_MARK
+      LZMA_STATUS_NOT_FINISHED
+      LZMA_STATUS_NEEDS_MORE_INPUT
+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+  SZ_ERROR_DATA - Data error
+*/
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- Buffer Interface ---------- */
+
+/* It's zlib-like interface.
+   See LzmaDec_DecodeToDic description for information about STEPS and return results,
+   but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
+   to work with CLzmaDec variables manually.
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (*destLen).
+  LZMA_FINISH_ANY - Decode just destLen bytes.
+  LZMA_FINISH_END - Stream must be finished after (*destLen).
+*/
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- One Call Interface ---------- */
+
+/* LzmaDecode
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (*destLen).
+  LZMA_FINISH_ANY - Decode just destLen bytes.
+  LZMA_FINISH_END - Stream must be finished after (*destLen).
+
+Returns:
+  SZ_OK
+    status:
+      LZMA_STATUS_FINISHED_WITH_MARK
+      LZMA_STATUS_NOT_FINISHED
+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+  SZ_ERROR_DATA - Data error
+  SZ_ERROR_MEM  - Memory allocation error
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+  SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+*/
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+    ELzmaStatus *status, ISzAlloc *alloc);
+
+#endif
diff --git a/include/grub/lib/LzmaEnc.h b/include/grub/lib/LzmaEnc.h
new file mode 100644
index 0000000..fc156a4
--- /dev/null
+++ b/include/grub/lib/LzmaEnc.h
@@ -0,0 +1,95 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#ifndef __LZMAENC_H
+#define __LZMAENC_H
+
+#include "LzmaTypes.h"
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaEncProps
+{
+  int level;       /*  0 <= level <= 9 */
+  UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
+                      (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
+                       default = (1 << 24) */
+  int lc;          /* 0 <= lc <= 8, default = 3 */
+  int lp;          /* 0 <= lp <= 4, default = 0 */
+  int pb;          /* 0 <= pb <= 4, default = 2 */
+  int algo;        /* 0 - fast, 1 - normal, default = 1 */
+  int fb;          /* 5 <= fb <= 273, default = 32 */
+  int btMode;      /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
+  int numHashBytes; /* 2, 3 or 4, default = 4 */
+  UInt32 mc;        /* 1 <= mc <= (1 << 30), default = 32 */
+  unsigned writeEndMark;  /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
+  int numThreads;  /* 1 or 2, default = 2 */
+} CLzmaEncProps;
+
+void LzmaEncProps_Init(CLzmaEncProps *p);
+void LzmaEncProps_Normalize(CLzmaEncProps *p);
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
+
+
+/* ---------- CLzmaEncHandle Interface ---------- */
+
+/* LzmaEnc_* functions can return the following exit codes:
+Returns:
+  SZ_OK           - OK
+  SZ_ERROR_MEM    - Memory allocation error
+  SZ_ERROR_PARAM  - Incorrect parameter in props
+  SZ_ERROR_WRITE  - Write callback error.
+  SZ_ERROR_PROGRESS - some break from progress callback
+  SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
+*/
+
+typedef void * CLzmaEncHandle;
+
+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+
+/* ---------- One Call Interface ---------- */
+
+/* LzmaEncode
+Return code:
+  SZ_OK               - OK
+  SZ_ERROR_MEM        - Memory allocation error
+  SZ_ERROR_PARAM      - Incorrect parameter
+  SZ_ERROR_OUTPUT_EOF - output buffer overflow
+  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)
+*/
+
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+
+#endif
diff --git a/include/grub/lib/LzmaTypes.h b/include/grub/lib/LzmaTypes.h
new file mode 100644
index 0000000..1e783a2
--- /dev/null
+++ b/include/grub/lib/LzmaTypes.h
@@ -0,0 +1,151 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#ifndef __7Z_TYPES_H
+#define __7Z_TYPES_H
+
+#define SZ_OK 0
+
+#define SZ_ERROR_DATA 1
+#define SZ_ERROR_MEM 2
+#define SZ_ERROR_CRC 3
+#define SZ_ERROR_UNSUPPORTED 4
+#define SZ_ERROR_PARAM 5
+#define SZ_ERROR_INPUT_EOF 6
+#define SZ_ERROR_OUTPUT_EOF 7
+#define SZ_ERROR_READ 8
+#define SZ_ERROR_WRITE 9
+#define SZ_ERROR_PROGRESS 10
+#define SZ_ERROR_FAIL 11
+#define SZ_ERROR_THREAD 12
+
+#define SZ_ERROR_ARCHIVE 16
+#define SZ_ERROR_NO_ARCHIVE 17
+
+typedef int SRes;
+
+#ifndef RINOK
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
+#endif
+
+typedef unsigned char Byte;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef long Int32;
+typedef unsigned long UInt32;
+#else
+typedef int Int32;
+typedef unsigned int UInt32;
+#endif
+
+/* #define _SZ_NO_INT_64 */
+/* define it if your compiler doesn't support 64-bit integers */
+
+#ifdef _SZ_NO_INT_64
+
+typedef long Int64;
+typedef unsigned long UInt64;
+
+#else
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#else
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#endif
+
+#endif
+
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+#include <stddef.h>
+typedef size_t SizeT;
+#endif
+
+typedef int Bool;
+#define True 1
+#define False 0
+
+
+#ifdef _MSC_VER
+
+#if _MSC_VER >= 1300
+#define MY_NO_INLINE __declspec(noinline)
+#else
+#define MY_NO_INLINE
+#endif
+
+#define MY_CDECL __cdecl
+#define MY_STD_CALL __stdcall
+#define MY_FAST_CALL MY_NO_INLINE __fastcall
+
+#else
+
+#define MY_CDECL
+#define MY_STD_CALL
+#define MY_FAST_CALL
+
+#endif
+
+
+/* The following interfaces use first parameter as pointer to structure */
+
+typedef struct
+{
+  SRes (*Read)(void *p, void *buf, size_t *size);
+    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+       (output(*size) < input(*size)) is allowed */
+} ISeqInStream;
+
+typedef struct
+{
+  size_t (*Write)(void *p, const void *buf, size_t size);
+    /* Returns: result - the number of actually written bytes.
+      (result < size) means error */
+} ISeqOutStream;
+
+typedef struct
+{
+  SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
+    /* Returns: result. (result != SZ_OK) means break.
+       Value (UInt64)(Int64)-1 for size means unknown value. */
+} ICompressProgress;
+
+typedef struct
+{
+  void *(*Alloc)(void *p, size_t size);
+  void (*Free)(void *p, void *address); /* address can be 0 */
+} ISzAlloc;
+
+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
+#define IAlloc_Free(p, a) (p)->Free((p), a)
+
+#endif
diff --git a/include/grub/lib/arg.h b/include/grub/lib/arg.h
new file mode 100644
index 0000000..e6af60c
--- /dev/null
+++ b/include/grub/lib/arg.h
@@ -0,0 +1,72 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ARG_HEADER
+#define GRUB_ARG_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+
+enum grub_arg_type
+  {
+    ARG_TYPE_NONE,
+    ARG_TYPE_STRING,
+    ARG_TYPE_INT,
+    ARG_TYPE_DEVICE,
+    ARG_TYPE_FILE,
+    ARG_TYPE_DIR,
+    ARG_TYPE_PATHNAME
+  };
+
+typedef enum grub_arg_type grub_arg_type_t;
+
+/* Flags for the option field op grub_arg_option.  */
+#define GRUB_ARG_OPTION_OPTIONAL	(1 << 1)
+
+enum grub_key_type
+  {
+    GRUB_KEY_ARG = -1,
+    GRUB_KEY_END = -2
+  };
+typedef enum grub_key_type grub_arg_key_type_t;
+
+struct grub_arg_option
+{
+  const char *longarg;
+  int shortarg;
+  int flags;
+  char *doc;
+  char *arg;
+  grub_arg_type_t type;
+};
+
+struct grub_arg_list
+{
+  int set;
+  char *arg;
+};
+
+struct grub_extcmd;
+
+int grub_arg_parse (struct grub_extcmd *cmd, int argc, char **argv,
+		    struct grub_arg_list *usr, char ***args, int *argnum);
+
+void grub_arg_show_help (struct grub_extcmd *cmd);
+
+#endif /* ! GRUB_ARG_HEADER */
diff --git a/include/grub/lib/crc.h b/include/grub/lib/crc.h
new file mode 100644
index 0000000..ff7284d
--- /dev/null
+++ b/include/grub/lib/crc.h
@@ -0,0 +1,25 @@
+/* crc.h - prototypes for crc */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CRC_H
+#define GRUB_CRC_H	1
+
+grub_uint32_t grub_getcrc32 (grub_uint32_t crc, void *buf, int size);
+
+#endif /* ! GRUB_CRC_H */
diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h
new file mode 100644
index 0000000..368ba53
--- /dev/null
+++ b/include/grub/lib/envblk.h
@@ -0,0 +1,55 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ENVBLK_HEADER
+#define GRUB_ENVBLK_HEADER	1
+
+#define GRUB_ENVBLK_SIGNATURE	"# GRUB Environment Block\n"
+#define GRUB_ENVBLK_DEFCFG	"grubenv"
+
+#ifndef ASM_FILE
+
+struct grub_envblk
+{
+  char *buf;
+  grub_size_t size;
+};
+typedef struct grub_envblk *grub_envblk_t;
+
+grub_envblk_t grub_envblk_open (char *buf, grub_size_t size);
+int grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value);
+void grub_envblk_delete (grub_envblk_t envblk, const char *name);
+void grub_envblk_iterate (grub_envblk_t envblk,
+                          int hook (const char *name, const char *value));
+void grub_envblk_close (grub_envblk_t envblk);
+
+static inline char *
+grub_envblk_buffer (const grub_envblk_t envblk)
+{
+  return envblk->buf;
+}
+
+static inline grub_size_t
+grub_envblk_size (const grub_envblk_t envblk)
+{
+  return envblk->size;
+}
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! GRUB_ENVBLK_HEADER */
diff --git a/include/grub/lib/hexdump.h b/include/grub/lib/hexdump.h
new file mode 100644
index 0000000..23c6fa6
--- /dev/null
+++ b/include/grub/lib/hexdump.h
@@ -0,0 +1,25 @@
+/* hexdump.h - prototypes for dump */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_HEXDUMP_H
+#define GRUB_HEXDUMP_H	1
+
+void hexdump (unsigned long bse,char* buf,int len);
+
+#endif /* ! GRUB_HEXDUMP_H */
diff --git a/include/grub/list.h b/include/grub/list.h
new file mode 100644
index 0000000..6e03492
--- /dev/null
+++ b/include/grub/list.h
@@ -0,0 +1,122 @@
+/* list.h - header for grub list */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LIST_HEADER
+#define GRUB_LIST_HEADER 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+struct grub_list
+{
+  struct grub_list *next;
+};
+typedef struct grub_list *grub_list_t;
+
+typedef int (*grub_list_hook_t) (grub_list_t item);
+typedef int (*grub_list_test_t) (grub_list_t new_item, grub_list_t item);
+
+void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item);
+void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head);
+void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item);
+int EXPORT_FUNC(grub_list_iterate) (grub_list_t head, grub_list_hook_t hook);
+void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item,
+				    grub_list_test_t test);
+
+/* This function doesn't exist, so if assertion is false for some reason, the
+   linker would fail.  */
+#ifdef APPLE_CC
+/* This approach fails with Apple's gcc. Use grub_abort.  */
+#include <grub/misc.h>
+static inline void *
+grub_assert_fail (void)
+{
+	grub_abort ();
+	return 0;
+}
+#else
+extern void* grub_assert_fail (void);
+#endif
+
+#define GRUB_FIELD_MATCH(ptr, type, field) \
+  ((char *) &(ptr)->field == (char *) &((type) (ptr))->field)
+
+#define GRUB_AS_LIST(ptr) \
+  (GRUB_FIELD_MATCH (ptr, grub_list_t, next) ? \
+   (grub_list_t) ptr : grub_assert_fail ())
+
+#define GRUB_AS_LIST_P(pptr) \
+  (GRUB_FIELD_MATCH (*pptr, grub_list_t, next) ? \
+   (grub_list_t *) (void *) pptr : grub_assert_fail ())
+
+struct grub_named_list
+{
+  struct grub_named_list *next;
+  const char *name;
+};
+typedef struct grub_named_list *grub_named_list_t;
+
+void * EXPORT_FUNC(grub_named_list_find) (grub_named_list_t head,
+					  const char *name);
+
+#define GRUB_AS_NAMED_LIST(ptr) \
+  ((GRUB_FIELD_MATCH (ptr, grub_named_list_t, next) && \
+    GRUB_FIELD_MATCH (ptr, grub_named_list_t, name))? \
+   (grub_named_list_t) ptr : grub_assert_fail ())
+
+#define GRUB_AS_NAMED_LIST_P(pptr) \
+  ((GRUB_FIELD_MATCH (*pptr, grub_named_list_t, next) && \
+    GRUB_FIELD_MATCH (*pptr, grub_named_list_t, name))? \
+   (grub_named_list_t *) (void *) pptr : grub_assert_fail ())
+
+#define GRUB_PRIO_LIST_PRIO_MASK	0xff
+#define GRUB_PRIO_LIST_FLAG_ACTIVE	0x100
+
+struct grub_prio_list
+{
+  struct grub_prio_list *next;
+  const char *name;
+  int prio;
+};
+typedef struct grub_prio_list *grub_prio_list_t;
+
+void EXPORT_FUNC(grub_prio_list_insert) (grub_prio_list_t *head,
+					 grub_prio_list_t item);
+
+static inline void
+grub_prio_list_remove (grub_prio_list_t *head, grub_prio_list_t item)
+{
+  if ((item->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) && (item->next))
+    item->next->prio |= GRUB_PRIO_LIST_FLAG_ACTIVE;
+  grub_list_remove (GRUB_AS_LIST_P (head), GRUB_AS_LIST (item));
+}
+
+#define GRUB_AS_PRIO_LIST(ptr) \
+  ((GRUB_FIELD_MATCH (ptr, grub_prio_list_t, next) && \
+    GRUB_FIELD_MATCH (ptr, grub_prio_list_t, name) && \
+    GRUB_FIELD_MATCH (ptr, grub_prio_list_t, prio))? \
+   (grub_prio_list_t) ptr : grub_assert_fail ())
+
+#define GRUB_AS_PRIO_LIST_P(pptr) \
+  ((GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, next) && \
+    GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, name) && \
+    GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, prio))? \
+   (grub_prio_list_t *) (void *) pptr : grub_assert_fail ())
+
+#endif /* ! GRUB_LIST_HEADER */
diff --git a/include/grub/loader.h b/include/grub/loader.h
new file mode 100644
index 0000000..319f3c5
--- /dev/null
+++ b/include/grub/loader.h
@@ -0,0 +1,66 @@
+/* loader.h - OS loaders */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_HEADER
+#define GRUB_LOADER_HEADER	1
+
+#include <grub/file.h>
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+
+/* Check if a loader is loaded.  */
+int grub_loader_is_loaded (void);
+
+/* Set loader functions. NORETURN must be set to true, if BOOT won't return
+   to the original state.  */
+void grub_loader_set (grub_err_t (*boot) (void),
+		      grub_err_t (*unload) (void),
+		      int noreturn);
+
+/* Unset current loader, if any.  */
+void grub_loader_unset (void);
+
+/* Call the boot hook in current loader. This may or may not return,
+   depending on the setting by grub_loader_set.  */
+grub_err_t grub_loader_boot (void);
+
+/* The space between numbers is intentional for the simplicity of adding new
+   values even if external modules use them. */
+typedef enum {
+  /* A preboot hook which can use everything and turns nothing off. */
+  GRUB_LOADER_PREBOOT_HOOK_PRIO_NORMAL = 400,
+  /* A preboot hook which can't use disks and may stop disks. */
+  GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK = 300,
+  /* A preboot hook which can't use disks or console and may stop console. */
+  GRUB_LOADER_PREBOOT_HOOK_PRIO_CONSOLE = 200,
+  /* A preboot hook which can't use disks or console, can't modify memory map
+     and may stop memory services or finalize memory map. */
+  GRUB_LOADER_PREBOOT_HOOK_PRIO_MEMORY = 100,
+} grub_loader_preboot_hook_prio_t;
+
+/* Register a preboot hook. */
+void *grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noret),
+					 grub_err_t (*preboot_rest_func) (void),
+					 grub_loader_preboot_hook_prio_t prio);
+
+/* Unregister given preboot hook. */
+void grub_loader_unregister_preboot_hook (void *hnd);
+
+#endif /* ! GRUB_LOADER_HEADER */
diff --git a/include/grub/lvm.h b/include/grub/lvm.h
new file mode 100644
index 0000000..a4bf3b2
--- /dev/null
+++ b/include/grub/lvm.h
@@ -0,0 +1,129 @@
+/* lvm.h - On disk structures for LVM. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LVM_H
+#define GRUB_LVM_H	1
+
+#include <grub/types.h>
+
+/* Length of ID string, excluding terminating zero. */
+#define GRUB_LVM_ID_STRLEN 38
+
+struct grub_lvm_vg {
+  char id[GRUB_LVM_ID_STRLEN+1];
+  char *name;
+  int extent_size;
+  struct grub_lvm_pv *pvs;
+  struct grub_lvm_lv *lvs;
+  struct grub_lvm_vg *next;
+};
+
+struct grub_lvm_pv {
+  char id[GRUB_LVM_ID_STRLEN+1];
+  char *name;
+  grub_disk_t disk;
+  int start; /* Sector number where the data area starts. */
+  struct grub_lvm_pv *next;
+};
+
+struct grub_lvm_lv {
+  char *name;
+  unsigned int number;
+  unsigned int segment_count;
+  grub_uint64_t size;
+  struct grub_lvm_segment *segments; /* Pointer to segment_count segments. */
+  struct grub_lvm_vg *vg;
+  struct grub_lvm_lv *next;
+};
+
+struct grub_lvm_segment {
+  unsigned int start_extent;
+  unsigned int extent_count;
+  unsigned int stripe_count;
+  unsigned int stripe_size;
+  struct grub_lvm_stripe *stripes; /* Pointer to stripe_count stripes. */
+};
+
+struct grub_lvm_stripe {
+  int start;
+  struct grub_lvm_pv *pv;
+};
+
+#define GRUB_LVM_LABEL_SIZE GRUB_DISK_SECTOR_SIZE
+#define GRUB_LVM_LABEL_SCAN_SECTORS 4L
+
+#define GRUB_LVM_LABEL_ID "LABELONE"
+#define GRUB_LVM_LVM2_LABEL "LVM2 001"
+
+#define GRUB_LVM_ID_LEN 32
+
+/* On disk - 32 bytes */
+struct grub_lvm_label_header {
+  grub_int8_t id[8];		/* LABELONE */
+  grub_uint64_t sector_xl;	/* Sector number of this label */
+  grub_uint32_t crc_xl;		/* From next field to end of sector */
+  grub_uint32_t offset_xl;	/* Offset from start of struct to contents */
+  grub_int8_t type[8];		/* LVM2 001 */
+} __attribute__ ((packed));
+
+/* On disk */
+struct grub_lvm_disk_locn {
+  grub_uint64_t offset;		/* Offset in bytes to start sector */
+  grub_uint64_t size;		/* Bytes */
+} __attribute__ ((packed));
+
+/* Fields with the suffix _xl should be xlate'd wherever they appear */
+/* On disk */
+struct grub_lvm_pv_header {
+  grub_int8_t pv_uuid[GRUB_LVM_ID_LEN];
+
+  /* This size can be overridden if PV belongs to a VG */
+  grub_uint64_t device_size_xl;	/* Bytes */
+
+  /* NULL-terminated list of data areas followed by */
+  /* NULL-terminated list of metadata area headers */
+  struct grub_lvm_disk_locn disk_areas_xl[0];	/* Two lists */
+} __attribute__ ((packed));
+
+#define GRUB_LVM_FMTT_MAGIC "\040\114\126\115\062\040\170\133\065\101\045\162\060\116\052\076"
+#define GRUB_LVM_FMTT_VERSION 1
+#define GRUB_LVM_MDA_HEADER_SIZE 512
+
+/* On disk */
+struct grub_lvm_raw_locn {
+  grub_uint64_t offset;		/* Offset in bytes to start sector */
+  grub_uint64_t size;		/* Bytes */
+  grub_uint32_t checksum;
+  grub_uint32_t filler;
+} __attribute__ ((packed));
+
+/* On disk */
+/* Structure size limited to one sector */
+struct grub_lvm_mda_header {
+  grub_uint32_t checksum_xl;	/* Checksum of rest of mda_header */
+  grub_int8_t magic[16];	/* To aid scans for metadata */
+  grub_uint32_t version;
+  grub_uint64_t start;		/* Absolute start byte of mda_header */
+  grub_uint64_t size;		/* Size of metadata area */
+
+  struct grub_lvm_raw_locn raw_locns[0];	/* NULL-terminated list */
+} __attribute__ ((packed));
+
+
+#endif /* ! GRUB_LVM_H */
diff --git a/include/grub/macho.h b/include/grub/macho.h
new file mode 100644
index 0000000..0604100
--- /dev/null
+++ b/include/grub/macho.h
@@ -0,0 +1,107 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHO_H
+#define GRUB_MACHO_H 1
+#include <grub/types.h>
+
+/* Multi-architecture header. Always in big-endian. */
+struct grub_macho_fat_header
+{
+  grub_uint32_t magic;
+  grub_uint32_t nfat_arch;
+} __attribute__ ((packed));
+#define GRUB_MACHO_FAT_MAGIC 0xcafebabe
+
+typedef grub_uint32_t grub_macho_cpu_type_t;
+typedef grub_uint32_t grub_macho_cpu_subtype_t;
+
+/* Architecture descriptor. Always in big-endian. */
+struct grub_macho_fat_arch
+{
+  grub_macho_cpu_type_t cputype;
+  grub_macho_cpu_subtype_t cpusubtype;
+  grub_uint32_t offset;
+  grub_uint32_t size;
+  grub_uint32_t align;
+} __attribute__ ((packed));
+
+/* File header for 32-bit. Always in native-endian. */
+struct grub_macho_header32
+{
+#define GRUB_MACHO_MAGIC32 0xfeedface
+  grub_uint32_t magic;
+  grub_macho_cpu_type_t cputype;
+  grub_macho_cpu_subtype_t cpusubtype;
+  grub_uint32_t filetype;
+  grub_uint32_t ncmds;
+  grub_uint32_t sizeofcmds;
+  grub_uint32_t flags;
+} __attribute__ ((packed));
+
+/* File header for 64-bit. Always in native-endian. */
+struct grub_macho_header64
+{
+#define GRUB_MACHO_MAGIC64 0xfeedfacf
+  grub_uint32_t magic;
+  grub_macho_cpu_type_t cputype;
+  grub_macho_cpu_subtype_t cpusubtype;
+  grub_uint32_t filetype;
+  grub_uint32_t ncmds;
+  grub_uint32_t sizeofcmds;
+  grub_uint32_t flags;
+  grub_uint32_t reserved;
+} __attribute__ ((packed));
+
+/* Convenience union. What do we need to load to identify the file type. */
+union grub_macho_filestart
+{
+  struct grub_macho_fat_header fat;
+  struct grub_macho_header32 thin32;
+  struct grub_macho_header64 thin64;
+} __attribute__ ((packed));
+
+/* Common header of Mach-O commands. */
+struct grub_macho_cmd
+{
+  grub_uint32_t cmd;
+  grub_uint32_t cmdsize;
+} __attribute__ ((packed));
+
+typedef grub_uint32_t grub_macho_vmprot_t;
+
+/* 32-bit segment command. */
+struct grub_macho_segment32
+{
+#define GRUB_MACHO_CMD_SEGMENT32  1
+  grub_uint32_t cmd;
+  grub_uint32_t cmdsize;
+  grub_uint8_t segname[16];
+  grub_uint32_t vmaddr;
+  grub_uint32_t vmsize;
+  grub_uint32_t fileoff;
+  grub_uint32_t filesize;
+  grub_macho_vmprot_t maxprot;
+  grub_macho_vmprot_t initprot;
+  grub_uint32_t nsects;
+  grub_uint32_t flags;
+} __attribute__ ((packed));
+
+#define GRUB_MACHO_CMD_THREAD     5
+
+#endif
diff --git a/include/grub/machoload.h b/include/grub/machoload.h
new file mode 100644
index 0000000..a80bac6
--- /dev/null
+++ b/include/grub/machoload.h
@@ -0,0 +1,62 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHOLOAD_HEADER
+#define GRUB_MACHOLOAD_HEADER	1
+
+#include <grub/err.h>
+#include <grub/elf.h>
+#include <grub/file.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+struct grub_macho_file
+{
+  grub_file_t file;
+  grub_ssize_t offset32;
+  grub_ssize_t end32;
+  int ncmds32;
+  grub_size_t cmdsize32;
+  grub_uint8_t *cmds32;
+  grub_ssize_t offset64;
+  grub_ssize_t end64;
+  int ncmds64;
+  grub_size_t cmdsize64;
+  grub_uint8_t *cmds64;
+};
+typedef struct grub_macho_file *grub_macho_t;
+
+grub_macho_t grub_macho_open (const char *);
+grub_macho_t grub_macho_file (grub_file_t);
+grub_err_t grub_macho_close (grub_macho_t);
+
+int grub_macho_contains_macho32 (grub_macho_t);
+grub_err_t grub_macho32_size (grub_macho_t macho, grub_addr_t *segments_start,
+			      grub_addr_t *segments_end, int flags);
+grub_uint32_t grub_macho32_get_entry_point (grub_macho_t macho);
+
+/* Ignore BSS segments when loading. */
+#define GRUB_MACHO_NOBSS 0x1
+grub_err_t grub_macho32_load (grub_macho_t macho, char *offset, int flags);
+
+/* Like filesize and file_read but take only 32-bit part
+   for current architecture. */
+grub_size_t grub_macho32_filesize (grub_macho_t macho);
+grub_err_t grub_macho32_readfile (grub_macho_t macho, void *dest);
+
+#endif /* ! GRUB_MACHOLOAD_HEADER */
diff --git a/include/grub/memory.h b/include/grub/memory.h
new file mode 100644
index 0000000..43f90e1
--- /dev/null
+++ b/include/grub/memory.h
@@ -0,0 +1,52 @@
+/* memory.h - describe the memory map */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_HEADER
+#define GRUB_MEMORY_HEADER	1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/machine/memory.h>
+
+grub_err_t grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+							    grub_uint64_t,
+							    grub_uint32_t));
+int grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type);
+grub_err_t grub_mmap_unregister (int handle);
+
+void *grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size,
+				     int *handle, int type, int flags);
+
+void grub_mmap_free_and_unregister (int handle);
+
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+
+struct grub_mmap_region
+{
+  struct grub_mmap_region *next;
+  grub_uint64_t start;
+  grub_uint64_t end;
+  int type;
+  int handle;
+};
+
+extern struct grub_mmap_region *grub_mmap_overlays;
+#endif
+
+#endif /* ! GRUB_MEMORY_HEADER */
diff --git a/include/grub/menu.h b/include/grub/menu.h
new file mode 100644
index 0000000..c7114a9
--- /dev/null
+++ b/include/grub/menu.h
@@ -0,0 +1,97 @@
+/* menu.h - Menu model function prototypes and data structures. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MENU_HEADER
+#define GRUB_MENU_HEADER 1
+
+struct grub_menu_entry_class
+{
+  char *name;
+  struct grub_menu_entry_class *next;
+};
+
+/* The menu entry.  */
+struct grub_menu_entry
+{
+  /* The title name.  */
+  const char *title;
+
+  /* If set means not everybody is allowed to boot this entry.  */
+  int restricted;
+
+  /* Allowed users.  */
+  const char *users;
+
+  /* The classes associated with the menu entry:
+     used to choose an icon or other style attributes.
+     This is a dummy head node for the linked list, so for an entry E,
+     E.classes->next is the first class if it is not NULL.  */
+  struct grub_menu_entry_class *classes;
+
+  /* The sourcecode of the menu entry, used by the editor.  */
+  const char *sourcecode;
+
+  /* The next element.  */
+  struct grub_menu_entry *next;
+};
+typedef struct grub_menu_entry *grub_menu_entry_t;
+
+/* The menu.  */
+struct grub_menu
+{
+  /* The size of a menu.  */
+  int size;
+
+  /* The list of menu entries.  */
+  grub_menu_entry_t entry_list;
+};
+typedef struct grub_menu *grub_menu_t;
+
+/* Callback structure menu viewers can use to provide user feedback when
+   default entries are executed, possibly including fallback entries.  */
+typedef struct grub_menu_execute_callback
+{
+  /* Called immediately before ENTRY is booted.  */
+  void (*notify_booting) (grub_menu_entry_t entry, void *userdata);
+
+  /* Called when executing one entry has failed, and another entry, ENTRY, will
+     be executed as a fallback.  The implementation of this function should
+     delay for a period of at least 2 seconds before returning in order to
+     allow the user time to read the information before it can be lost by
+     executing ENTRY.  */
+  void (*notify_fallback) (grub_menu_entry_t entry, void *userdata);
+
+  /* Called when an entry has failed to execute and there is no remaining
+     fallback entry to attempt.  */
+  void (*notify_failure) (void *userdata);
+}
+*grub_menu_execute_callback_t;
+
+
+grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no);
+int grub_menu_get_timeout (void);
+void grub_menu_set_timeout (int timeout);
+void grub_menu_execute_entry (grub_menu_entry_t entry);
+void grub_menu_execute_with_fallback (grub_menu_t menu,
+				      grub_menu_entry_t entry,
+				      grub_menu_execute_callback_t callback,
+				      void *callback_data);
+void grub_menu_entry_run (grub_menu_entry_t entry);
+
+#endif /* GRUB_MENU_HEADER */
diff --git a/include/grub/menu_viewer.h b/include/grub/menu_viewer.h
new file mode 100644
index 0000000..725c975
--- /dev/null
+++ b/include/grub/menu_viewer.h
@@ -0,0 +1,43 @@
+/* menu_viewer.h - Interface to menu viewer implementations. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MENU_VIEWER_HEADER
+#define GRUB_MENU_VIEWER_HEADER 1
+
+#include <grub/err.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/menu.h>
+
+struct grub_menu_viewer
+{
+  /* The menu viewer name.  */
+  const char *name;
+
+  grub_err_t (*show_menu) (grub_menu_t menu, int nested);
+
+  struct grub_menu_viewer *next;
+};
+typedef struct grub_menu_viewer *grub_menu_viewer_t;
+
+void grub_menu_viewer_register (grub_menu_viewer_t viewer);
+
+grub_err_t grub_menu_viewer_show_menu (grub_menu_t menu, int nested);
+
+#endif /* GRUB_MENU_VIEWER_HEADER */
diff --git a/include/grub/misc.h b/include/grub/misc.h
new file mode 100644
index 0000000..7589f43
--- /dev/null
+++ b/include/grub/misc.h
@@ -0,0 +1,224 @@
+/* misc.h - prototypes for misc functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MISC_HEADER
+#define GRUB_MISC_HEADER	1
+
+#include <stdarg.h>
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/err.h>
+
+#define ALIGN_UP(addr, align) \
+	((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1))
+#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))
+
+#define grub_dprintf(condition, fmt, args...) grub_real_dprintf(__FILE__, __LINE__, condition, fmt, ## args)
+/* XXX: If grub_memmove is too slow, we must implement grub_memcpy.  */
+#define grub_memcpy(d,s,n)	grub_memmove ((d), (s), (n))
+
+void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n);
+char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src);
+char *EXPORT_FUNC(grub_strncpy) (char *dest, const char *src, int c);
+char *EXPORT_FUNC(grub_stpcpy) (char *dest, const char *src);
+
+static inline char *
+grub_strcat (char *dest, const char *src)
+{
+  char *p = dest;
+
+  while (*p)
+    p++;
+
+  while ((*p = *src) != '\0')
+    {
+      p++;
+      src++;
+    }
+
+  return dest;
+}
+
+static inline char *
+grub_strncat (char *dest, const char *src, int c)
+{
+  char *p = dest;
+
+  while (*p)
+    p++;
+
+  while ((*p = *src) != '\0' && c--)
+    {
+      p++;
+      src++;
+    }
+
+  *p = '\0';
+
+  return dest;
+}
+
+/* Prototypes for aliases.  */
+#if !defined (GRUB_UTIL) && !defined (APPLE_CC)
+int EXPORT_FUNC(memcmp) (const void *s1, const void *s2, grub_size_t n);
+void *EXPORT_FUNC(memmove) (void *dest, const void *src, grub_size_t n);
+void *EXPORT_FUNC(memcpy) (void *dest, const void *src, grub_size_t n);
+void *EXPORT_FUNC(memset) (void *s, int c, grub_size_t n);
+#endif
+
+int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n);
+int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2);
+int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n);
+
+char *EXPORT_FUNC(grub_strchr) (const char *s, int c);
+char *EXPORT_FUNC(grub_strrchr) (const char *s, int c);
+int EXPORT_FUNC(grub_strword) (const char *s, const char *w);
+char *EXPORT_FUNC(grub_strstr) (const char *haystack, const char *needle);
+int EXPORT_FUNC(grub_isspace) (int c);
+int EXPORT_FUNC(grub_isprint) (int c);
+
+static inline int
+grub_isalpha (int c)
+{
+  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+
+static inline int
+grub_isgraph (int c)
+{
+  return (c >= '!' && c <= '~');
+}
+
+static inline int
+grub_isdigit (int c)
+{
+  return (c >= '0' && c <= '9');
+}
+
+static inline int
+grub_tolower (int c)
+{
+  if (c >= 'A' && c <= 'Z')
+    return c - 'A' + 'a';
+
+  return c;
+}
+
+static inline int
+grub_toupper (int c)
+{
+  if (c >= 'a' && c <= 'z')
+    return c - 'a' + 'A';
+
+  return c;
+}
+
+static inline int
+grub_strcasecmp (const char *s1, const char *s2)
+{
+  while (*s1 && *s2)
+    {
+      if (grub_tolower (*s1) != grub_tolower (*s2))
+	break;
+
+      s1++;
+      s2++;
+    }
+
+  return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
+}
+
+static inline int
+grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
+{
+  if (n == 0)
+    return 0;
+
+  while (*s1 && *s2 && --n)
+    {
+      if (grub_tolower (*s1) != grub_tolower (*s2))
+	break;
+
+      s1++;
+      s2++;
+    }
+
+  return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
+}
+
+
+unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base);
+unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base);
+char *EXPORT_FUNC(grub_strdup) (const char *s);
+char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n);
+void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n);
+grub_size_t EXPORT_FUNC(grub_strlen) (const char *s);
+int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+void EXPORT_FUNC(grub_real_dprintf) (const char *file,
+                                     const int line,
+                                     const char *condition,
+                                     const char *fmt, ...) __attribute__ ((format (printf, 4, 5)));
+int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args);
+int EXPORT_FUNC(grub_sprintf) (char *str, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+int EXPORT_FUNC(grub_vsprintf) (char *str, const char *fmt, va_list args);
+void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
+void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn));
+grub_uint8_t *EXPORT_FUNC(grub_utf16_to_utf8) (grub_uint8_t *dest,
+					       grub_uint16_t *src,
+					       grub_size_t size);
+grub_ssize_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest,
+					     grub_size_t destsize,
+					     const grub_uint8_t *src,
+					     grub_size_t srcsize,
+					     const grub_uint8_t **srcend);
+grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
+					  grub_uint32_t d, grub_uint32_t *r);
+
+#ifdef NEED_ENABLE_EXECUTE_STACK
+void EXPORT_FUNC(__enable_execute_stack) (void *addr);
+#endif
+
+/* Inline functions.  */
+
+static inline unsigned int
+grub_abs (int x)
+{
+  if (x < 0)
+    return (unsigned int) (-x);
+  else
+    return (unsigned int) x;
+}
+
+static inline long
+grub_max (long x, long y)
+{
+  if (x > y)
+    return x;
+  else
+    return y;
+}
+
+/* Rounded-up division */
+static inline unsigned int
+grub_div_roundup (unsigned int x, unsigned int y)
+{
+  return (x + y - 1) / y;
+}
+
+#endif /* ! GRUB_MISC_HEADER */
diff --git a/include/grub/mm.h b/include/grub/mm.h
new file mode 100644
index 0000000..4caf805
--- /dev/null
+++ b/include/grub/mm.h
@@ -0,0 +1,72 @@
+/* mm.h - prototypes and declarations for memory manager */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MM_H
+#define GRUB_MM_H	1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <config.h>
+
+#ifndef NULL
+# define NULL	((void *) 0)
+#endif
+
+void grub_mm_init_region (void *addr, grub_size_t size);
+void *EXPORT_FUNC(grub_malloc) (grub_size_t size);
+void *EXPORT_FUNC(grub_zalloc) (grub_size_t size);
+void EXPORT_FUNC(grub_free) (void *ptr);
+void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size);
+void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size);
+
+/* For debugging.  */
+#if defined(MM_DEBUG) && !defined(GRUB_UTIL)
+/* Set this variable to 1 when you want to trace all memory function calls.  */
+extern int EXPORT_VAR(grub_mm_debug);
+
+void grub_mm_dump_free (void);
+void grub_mm_dump (unsigned lineno);
+
+#define grub_malloc(size)	\
+  grub_debug_malloc (__FILE__, __LINE__, size)
+
+#define grub_zalloc(size)	\
+  grub_debug_zalloc (__FILE__, __LINE__, size)
+
+#define grub_realloc(ptr,size)	\
+  grub_debug_realloc (__FILE__, __LINE__, ptr, size)
+
+#define grub_memalign(align,size)	\
+  grub_debug_memalign (__FILE__, __LINE__, align, size)
+
+#define grub_free(ptr)	\
+  grub_debug_free (__FILE__, __LINE__, ptr)
+
+void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line,
+				      grub_size_t size);
+void *EXPORT_FUNC(grub_debug_zalloc) (const char *file, int line,
+				       grub_size_t size);
+void EXPORT_FUNC(grub_debug_free) (const char *file, int line, void *ptr);
+void *EXPORT_FUNC(grub_debug_realloc) (const char *file, int line, void *ptr,
+				       grub_size_t size);
+void *EXPORT_FUNC(grub_debug_memalign) (const char *file, int line,
+					grub_size_t align, grub_size_t size);
+#endif /* MM_DEBUG && ! GRUB_UTIL */
+
+#endif /* ! GRUB_MM_H */
diff --git a/include/grub/msdos_partition.h b/include/grub/msdos_partition.h
new file mode 100644
index 0000000..273d8c9
--- /dev/null
+++ b/include/grub/msdos_partition.h
@@ -0,0 +1,211 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_PC_PARTITION_HEADER
+#define GRUB_PC_PARTITION_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/err.h>
+
+/* The signature.  */
+#define GRUB_PC_PARTITION_SIGNATURE		0xaa55
+
+/* This is not a flag actually, but used as if it were a flag.  */
+#define GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG	0x10
+
+/* DOS partition types.  */
+#define GRUB_PC_PARTITION_TYPE_NONE		0
+#define GRUB_PC_PARTITION_TYPE_FAT12		1
+#define GRUB_PC_PARTITION_TYPE_FAT16_LT32M	4
+#define GRUB_PC_PARTITION_TYPE_EXTENDED		5
+#define GRUB_PC_PARTITION_TYPE_FAT16_GT32M	6
+#define GRUB_PC_PARTITION_TYPE_NTFS	        7
+#define GRUB_PC_PARTITION_TYPE_FAT32		0xb
+#define GRUB_PC_PARTITION_TYPE_FAT32_LBA	0xc
+#define GRUB_PC_PARTITION_TYPE_FAT16_LBA	0xe
+#define GRUB_PC_PARTITION_TYPE_WIN95_EXTENDED	0xf
+#define GRUB_PC_PARTITION_TYPE_EZD		0x55
+#define GRUB_PC_PARTITION_TYPE_MINIX		0x80
+#define GRUB_PC_PARTITION_TYPE_LINUX_MINIX	0x81
+#define GRUB_PC_PARTITION_TYPE_EXT2FS		0x83
+#define GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED	0x85
+#define GRUB_PC_PARTITION_TYPE_VSTAFS		0x9e
+#define GRUB_PC_PARTITION_TYPE_FREEBSD		0xa5
+#define GRUB_PC_PARTITION_TYPE_OPENBSD		0xa6
+#define GRUB_PC_PARTITION_TYPE_NETBSD		0xa9
+#define GRUB_PC_PARTITION_TYPE_HFS		0xaf
+#define GRUB_PC_PARTITION_TYPE_GPT_DISK		0xee
+#define GRUB_PC_PARTITION_TYPE_LINUX_RAID	0xfd
+
+/* Constants for BSD disk label.  */
+#define GRUB_PC_PARTITION_BSD_LABEL_SECTOR	1
+#define GRUB_PC_PARTITION_BSD_LABEL_MAGIC	0x82564557
+#define GRUB_PC_PARTITION_BSD_MAX_ENTRIES	8
+
+/* BSD partition types.  */
+#define GRUB_PC_PARTITION_BSD_TYPE_UNUSED	0
+#define GRUB_PC_PARTITION_BSD_TYPE_SWAP		1
+#define GRUB_PC_PARTITION_BSD_TYPE_V6		2
+#define GRUB_PC_PARTITION_BSD_TYPE_V7		3
+#define GRUB_PC_PARTITION_BSD_TYPE_SYSV		4
+#define GRUB_PC_PARTITION_BSD_TYPE_V71K		5
+#define GRUB_PC_PARTITION_BSD_TYPE_V8		6
+#define GRUB_PC_PARTITION_BSD_TYPE_BSDFFS	7
+#define GRUB_PC_PARTITION_BSD_TYPE_MSDOS	8
+#define GRUB_PC_PARTITION_BSD_TYPE_BSDLFS	9
+#define GRUB_PC_PARTITION_BSD_TYPE_OTHER	10
+#define GRUB_PC_PARTITION_BSD_TYPE_HPFS		11
+#define GRUB_PC_PARTITION_BSD_TYPE_ISO9660	12
+#define GRUB_PC_PARTITION_BSD_TYPE_BOOT		13
+
+/* FreeBSD-specific types.  */
+#define GRUB_PC_PARTITION_FREEBSD_TYPE_VINUM	14
+#define GRUB_PC_PARTITION_FREEBSD_TYPE_RAID	15
+#define GRUB_PC_PARTITION_FREEBSD_TYPE_JFS2	21
+
+/* NetBSD-specific types.  */
+#define	GRUB_PC_PARTITION_NETBSD_TYPE_ADOS	14
+#define	GRUB_PC_PARTITION_NETBSD_TYPE_HFS	15
+#define	GRUB_PC_PARTITION_NETBSD_TYPE_FILECORE	16
+#define	GRUB_PC_PARTITION_NETBSD_TYPE_EXT2FS	17
+#define	GRUB_PC_PARTITION_NETBSD_TYPE_NTFS	18
+#define	GRUB_PC_PARTITION_NETBSD_TYPE_RAID	19
+#define	GRUB_PC_PARTITION_NETBSD_TYPE_CCD	20
+#define	GRUB_PC_PARTITION_NETBSD_TYPE_JFS2	21
+#define	GRUB_PC_PARTITION_NETBSD_TYPE_APPLEUFS	22
+
+/* OpenBSD-specific types.  */
+#define	GRUB_PC_PARTITION_OPENBSD_TYPE_ADOS	14
+#define	GRUB_PC_PARTITION_OPENBSD_TYPE_HFS	15
+#define	GRUB_PC_PARTITION_OPENBSD_TYPE_FILECORE	16
+#define	GRUB_PC_PARTITION_OPENBSD_TYPE_EXT2FS	17
+#define	GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS	18
+#define	GRUB_PC_PARTITION_OPENBSD_TYPE_RAID	19
+
+/* The BSD partition entry.  */
+struct grub_msdos_partition_bsd_entry
+{
+  grub_uint32_t size;
+  grub_uint32_t offset;
+  grub_uint32_t fragment_size;
+  grub_uint8_t fs_type;
+  grub_uint8_t fs_fragments;
+  grub_uint16_t fs_cylinders;
+} __attribute__ ((packed));
+
+/* The BSD disk label. Only define members useful for GRUB.  */
+struct grub_msdos_partition_disk_label
+{
+  grub_uint32_t magic;
+  grub_uint8_t padding[128];
+  grub_uint32_t magic2;
+  grub_uint16_t checksum;
+  grub_uint16_t num_partitions;
+  grub_uint32_t boot_size;
+  grub_uint32_t superblock_size;
+  struct grub_msdos_partition_bsd_entry entries[GRUB_PC_PARTITION_BSD_MAX_ENTRIES];
+} __attribute__ ((packed));
+
+/* The partition entry.  */
+struct grub_msdos_partition_entry
+{
+  /* If active, 0x80, otherwise, 0x00.  */
+  grub_uint8_t flag;
+
+  /* The head of the start.  */
+  grub_uint8_t start_head;
+
+  /* (S | ((C >> 2) & 0xC0)) where S is the sector of the start and C
+     is the cylinder of the start. Note that S is counted from one.  */
+  grub_uint8_t start_sector;
+
+  /* (C & 0xFF) where C is the cylinder of the start.  */
+  grub_uint8_t start_cylinder;
+
+  /* The partition type.  */
+  grub_uint8_t type;
+
+  /* The end versions of start_head, start_sector and start_cylinder,
+     respectively.  */
+  grub_uint8_t end_head;
+  grub_uint8_t end_sector;
+  grub_uint8_t end_cylinder;
+
+  /* The start sector. Note that this is counted from zero.  */
+  grub_uint32_t start;
+
+  /* The length in sector units.  */
+  grub_uint32_t length;
+} __attribute__ ((packed));
+
+/* The structure of MBR.  */
+struct grub_msdos_partition_mbr
+{
+  /* The code area (actually, including BPB).  */
+  grub_uint8_t code[446];
+
+  /* Four partition entries.  */
+  struct grub_msdos_partition_entry entries[4];
+
+  /* The signature 0xaa55.  */
+  grub_uint16_t signature;
+} __attribute__ ((packed));
+
+
+struct grub_msdos_partition
+{
+    /* The DOS partition number.  */
+  int dos_part;
+
+  /* The BSD partition number (a == 0).  */
+  int bsd_part;
+
+  /* The DOS partition type.  */
+  int dos_type;
+
+  /* The BSD partition type.  */
+  int bsd_type;
+
+  /* The offset of the extended partition.  */
+  unsigned long ext_offset;
+};
+
+static inline int
+grub_msdos_partition_is_empty (int type)
+{
+  return (type == GRUB_PC_PARTITION_TYPE_NONE);
+}
+
+static inline int
+grub_msdos_partition_is_extended (int type)
+{
+  return (type == GRUB_PC_PARTITION_TYPE_EXTENDED
+	  || type == GRUB_PC_PARTITION_TYPE_WIN95_EXTENDED
+	  || type == GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED);
+}
+
+static inline int
+grub_msdos_partition_is_bsd (int type)
+{
+  return (type == GRUB_PC_PARTITION_TYPE_FREEBSD
+	  || type == GRUB_PC_PARTITION_TYPE_OPENBSD
+	  || type == GRUB_PC_PARTITION_TYPE_NETBSD);
+}
+
+#endif /* ! GRUB_PC_PARTITION_HEADER */
diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h
new file mode 100644
index 0000000..2cb00a0
--- /dev/null
+++ b/include/grub/multiboot.h
@@ -0,0 +1,129 @@
+/* multiboot.h - multiboot header file with grub definitions. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MULTIBOOT_HEADER
+#define GRUB_MULTIBOOT_HEADER 1
+
+#include <multiboot.h>
+
+void grub_multiboot (int argc, char *argv[]);
+void grub_module (int argc, char *argv[]);
+
+#ifndef ASM_FILE
+
+#include <grub/types.h>
+
+struct grub_multiboot_header
+{
+  /* Must be MULTIBOOT_MAGIC - see above.  */
+  grub_uint32_t magic;
+
+  /* Feature flags.  */
+  grub_uint32_t flags;
+
+  /* The above fields plus this one must equal 0 mod 2^32. */
+  grub_uint32_t checksum;
+
+  /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set.  */
+  grub_uint32_t header_addr;
+  grub_uint32_t load_addr;
+  grub_uint32_t load_end_addr;
+  grub_uint32_t bss_end_addr;
+  grub_uint32_t entry_addr;
+
+  /* These are only valid if MULTIBOOT_VIDEO_MODE is set.  */
+  grub_uint32_t mode_type;
+  grub_uint32_t width;
+  grub_uint32_t height;
+  grub_uint32_t depth;
+};
+
+struct grub_multiboot_info
+{
+  /* Multiboot info version number */
+  grub_uint32_t flags;
+
+  /* Available memory from BIOS */
+  grub_uint32_t mem_lower;
+  grub_uint32_t mem_upper;
+
+  /* "root" partition */
+  grub_uint32_t boot_device;
+
+  /* Kernel command line */
+  grub_uint32_t cmdline;
+
+  /* Boot-Module list */
+  grub_uint32_t mods_count;
+  grub_uint32_t mods_addr;
+
+  grub_uint32_t syms[4];
+
+  /* Memory Mapping buffer */
+  grub_uint32_t mmap_length;
+  grub_uint32_t mmap_addr;
+
+  /* Drive Info buffer */
+  grub_uint32_t drives_length;
+  grub_uint32_t drives_addr;
+
+  /* ROM configuration table */
+  grub_uint32_t config_table;
+
+  /* Boot Loader Name */
+  grub_uint32_t boot_loader_name;
+
+  /* APM table */
+  grub_uint32_t apm_table;
+
+  /* Video */
+  grub_uint32_t vbe_control_info;
+  grub_uint32_t vbe_mode_info;
+  grub_uint16_t vbe_mode;
+  grub_uint16_t vbe_interface_seg;
+  grub_uint16_t vbe_interface_off;
+  grub_uint16_t vbe_interface_len;
+};
+
+struct grub_multiboot_mmap_entry
+{
+  grub_uint32_t size;
+  grub_uint64_t addr;
+  grub_uint64_t len;
+#define GRUB_MULTIBOOT_MEMORY_AVAILABLE		1
+#define GRUB_MULTIBOOT_MEMORY_RESERVED		2
+  grub_uint32_t type;
+} __attribute__((packed));
+
+struct grub_mod_list
+{
+  /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
+  grub_uint32_t mod_start;
+  grub_uint32_t mod_end;
+
+  /* Module command line */
+  grub_uint32_t cmdline;
+
+  /* padding to take it to 16 bytes (must be zero) */
+  grub_uint32_t pad;
+};
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! GRUB_MULTIBOOT_HEADER */
diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h
new file mode 100644
index 0000000..2c97809
--- /dev/null
+++ b/include/grub/multiboot2.h
@@ -0,0 +1,70 @@
+/* multiboot2.h - multiboot2 header file with grub definitions. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MULTIBOOT2_HEADER
+#define GRUB_MULTIBOOT2_HEADER 1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/elf.h>
+
+#ifndef GRUB_UTIL
+typedef grub_uint32_t uint32_t;
+typedef grub_uint64_t uint64_t;
+#define __WORDSIZE GRUB_TARGET_WORDSIZE
+#endif
+
+struct multiboot_tag_header;
+
+grub_err_t
+grub_mb2_tag_alloc (grub_addr_t *addr, int key, grub_size_t len);
+
+grub_err_t
+grub_mb2_tags_arch_create (void);
+
+void
+grub_mb2_arch_boot (grub_addr_t entry, void *tags);
+
+void
+grub_mb2_arch_unload (struct multiboot_tag_header *tags);
+
+grub_err_t
+grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load);
+
+grub_err_t
+grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load);
+
+grub_err_t
+grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr);
+
+grub_err_t
+grub_mb2_arch_module_free (grub_addr_t addr, grub_size_t size);
+
+void
+grub_multiboot2 (int argc, char *argv[]);
+
+void
+grub_module2 (int argc, char *argv[]);
+
+#define for_each_tag(tag, tags) \
+  for (tag = tags; \
+       tag && tag->key != MULTIBOOT2_TAG_END; \
+       tag = (struct multiboot_tag_header *)((char *)tag + tag->len))
+
+#endif /* ! GRUB_MULTIBOOT2_HEADER */
diff --git a/include/grub/multiboot_loader.h b/include/grub/multiboot_loader.h
new file mode 100644
index 0000000..bf1c130
--- /dev/null
+++ b/include/grub/multiboot_loader.h
@@ -0,0 +1,28 @@
+/* multiboot_loader.h - multiboot loader header file. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef GRUB_MULTIBOOT_LOADER_HEADER
+#define GRUB_MULTIBOOT_LOADER_HEADER 1
+
+/* Provided by the core ("rescue mode").  */
+void grub_rescue_cmd_multiboot_loader (int argc, char *argv[]);
+void grub_rescue_cmd_module_loader (int argc, char *argv[]);
+
+#endif /* ! GRUB_MULTIBOOT_LOADER_HEADER */
diff --git a/include/grub/net.h b/include/grub/net.h
new file mode 100644
index 0000000..c6d71d5
--- /dev/null
+++ b/include/grub/net.h
@@ -0,0 +1,72 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_NET_HEADER
+#define GRUB_NET_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+
+struct grub_net;
+
+struct grub_net_dev
+{
+  /* The device name.  */
+  const char *name;
+
+  /* FIXME: Just a template.  */
+  int (*probe) (struct grub_net *net, const void *addr);
+  void (*reset) (struct grub_net *net);
+  int (*poll) (struct grub_net *net);
+  void (*transmit) (struct grub_net *net, const void *destip,
+		    unsigned srcsock, unsigned destsock, const void *packet);
+  void (*disable) (struct grub_net *net);
+
+  /* The next net device.  */
+  struct grub_net_dev *next;
+};
+typedef struct grub_net_dev *grub_net_dev_t;
+
+struct grub_fs;
+
+struct grub_net
+{
+  /* The net name.  */
+  const char *name;
+
+  /* The underlying disk device.  */
+  grub_net_dev_t dev;
+
+  /* The binding filesystem.  */
+  struct grub_fs *fs;
+
+  /* FIXME: More data would be required, such as an IP address, a mask,
+     a gateway, etc.  */
+
+  /* Device-specific data.  */
+  void *data;
+};
+typedef struct grub_net *grub_net_t;
+
+/* FIXME: How to abstract networks? More consideration is necessary.  */
+
+/* Note: Networks are very different from disks, because networks must
+   be initialized before used, and the status is persistent.  */
+
+#endif /* ! GRUB_NET_HEADER */
diff --git a/include/grub/normal.h b/include/grub/normal.h
new file mode 100644
index 0000000..feebc85
--- /dev/null
+++ b/include/grub/normal.h
@@ -0,0 +1,121 @@
+/* normal.h - prototypes for the normal mode */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_NORMAL_HEADER
+#define GRUB_NORMAL_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/env.h>
+#include <grub/menu.h>
+#include <grub/command.h>
+#include <grub/file.h>
+
+/* The maximum size of a command-line.  */
+#define GRUB_MAX_CMDLINE	1600
+
+/* The type of a completion item.  */
+enum grub_completion_type
+  {
+    GRUB_COMPLETION_TYPE_COMMAND,
+    GRUB_COMPLETION_TYPE_DEVICE,
+    GRUB_COMPLETION_TYPE_PARTITION,
+    GRUB_COMPLETION_TYPE_FILE,
+    GRUB_COMPLETION_TYPE_ARGUMENT
+  };
+typedef enum grub_completion_type grub_completion_type_t;
+
+extern struct grub_menu_viewer grub_normal_text_menu_viewer;
+
+
+/* Defined in `main.c'.  */
+void grub_enter_normal_mode (const char *config);
+void grub_normal_execute (const char *config, int nested, int batch);
+void grub_normal_init_page (void);
+void grub_menu_init_page (int nested, int edit);
+grub_err_t grub_normal_add_menu_entry (int argc, const char **args,
+				       const char *sourcecode);
+char *grub_file_getline (grub_file_t file);
+void grub_cmdline_run (int nested);
+
+/* Defined in `cmdline.c'.  */
+int grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
+		      int echo_char, int readline, int history);
+grub_err_t grub_set_history (int newsize);
+
+/* Defined in `completion.c'.  */
+char *grub_normal_do_completion (char *buf, int *restore,
+				 void (*hook) (const char *item, grub_completion_type_t type, int count));
+
+/* Defined in `misc.c'.  */
+grub_err_t grub_normal_print_device_info (const char *name);
+
+/* Defined in `color.c'.  */
+char *grub_env_write_color_normal (struct grub_env_var *var, const char *val);
+char *grub_env_write_color_highlight (struct grub_env_var *var, const char *val);
+void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name);
+
+/* Defined in `menu_text.c'.  */
+void grub_wait_after_message (void);
+
+/* Defined in `handler.c'.  */
+void read_handler_list (void);
+void free_handler_list (void);
+
+/* Defined in `dyncmd.c'.  */
+void read_command_list (void);
+
+/* Defined in `autofs.c'.  */
+void read_fs_list (void);
+
+
+#ifdef GRUB_UTIL
+void grub_normal_init (void);
+void grub_normal_fini (void);
+void grub_hello_init (void);
+void grub_hello_fini (void);
+void grub_ls_init (void);
+void grub_ls_fini (void);
+void grub_cat_init (void);
+void grub_cat_fini (void);
+void grub_boot_init (void);
+void grub_boot_fini (void);
+void grub_cmp_init (void);
+void grub_cmp_fini (void);
+void grub_terminal_init (void);
+void grub_terminal_fini (void);
+void grub_loop_init (void);
+void grub_loop_fini (void);
+void grub_help_init (void);
+void grub_help_fini (void);
+void grub_halt_init (void);
+void grub_halt_fini (void);
+void grub_reboot_init (void);
+void grub_reboot_fini (void);
+void grub_configfile_init (void);
+void grub_configfile_fini (void);
+void grub_search_init (void);
+void grub_search_fini (void);
+void grub_test_init (void);
+void grub_test_fini (void);
+void grub_blocklist_init (void);
+void grub_blocklist_fini (void);
+#endif
+
+#endif /* ! GRUB_NORMAL_HEADER */
diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h
new file mode 100644
index 0000000..6482e96
--- /dev/null
+++ b/include/grub/ntfs.h
@@ -0,0 +1,182 @@
+/* ntfs.h - header for the NTFS filesystem */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_NTFS_H
+#define GRUB_NTFS_H	1
+
+#define FILE_MFT      0
+#define FILE_MFTMIRR  1
+#define FILE_LOGFILE  2
+#define FILE_VOLUME   3
+#define FILE_ATTRDEF  4
+#define FILE_ROOT     5
+#define FILE_BITMAP   6
+#define FILE_BOOT     7
+#define FILE_BADCLUS  8
+#define FILE_QUOTA    9
+#define FILE_UPCASE  10
+
+#define AT_STANDARD_INFORMATION	0x10
+#define AT_ATTRIBUTE_LIST	0x20
+#define AT_FILENAME		0x30
+#define AT_OBJECT_ID		0x40
+#define AT_SECURITY_DESCRIPTOR	0x50
+#define AT_VOLUME_NAME		0x60
+#define AT_VOLUME_INFORMATION	0x70
+#define AT_DATA			0x80
+#define AT_INDEX_ROOT		0x90
+#define AT_INDEX_ALLOCATION	0xA0
+#define AT_BITMAP		0xB0
+#define AT_SYMLINK		0xC0
+#define AT_EA_INFORMATION	0xD0
+#define AT_EA			0xE0
+
+#define ATTR_READ_ONLY		0x1
+#define ATTR_HIDDEN		0x2
+#define ATTR_SYSTEM		0x4
+#define ATTR_ARCHIVE		0x20
+#define ATTR_DEVICE		0x40
+#define ATTR_NORMAL		0x80
+#define ATTR_TEMPORARY		0x100
+#define ATTR_SPARSE		0x200
+#define ATTR_REPARSE		0x400
+#define ATTR_COMPRESSED		0x800
+#define ATTR_OFFLINE		0x1000
+#define ATTR_NOT_INDEXED	0x2000
+#define ATTR_ENCRYPTED		0x4000
+#define ATTR_DIRECTORY		0x10000000
+#define ATTR_INDEX_VIEW		0x20000000
+
+#define FLAG_COMPRESSED		1
+#define FLAG_ENCRYPTED		0x4000
+#define FLAG_SPARSE		0x8000
+
+#define BLK_SHR		GRUB_DISK_SECTOR_BITS
+
+#define MAX_MFT		(1024 >> BLK_SHR)
+#define MAX_IDX		(16384 >> BLK_SHR)
+
+#define COM_LEN		4096
+#define COM_SEC		(COM_LEN >> BLK_SHR)
+
+#define AF_ALST		1
+#define AF_MMFT		2
+#define AF_GPOS		4
+
+#define RF_COMP		1
+#define RF_CBLK		2
+#define RF_BLNK		4
+
+#define valueat(buf,ofs,type)	*((type*)(((char*)buf)+ofs))
+
+#define u16at(buf,ofs)	grub_le_to_cpu16(valueat(buf,ofs,grub_uint16_t))
+#define u32at(buf,ofs)	grub_le_to_cpu32(valueat(buf,ofs,grub_uint32_t))
+#define u64at(buf,ofs)	grub_le_to_cpu64(valueat(buf,ofs,grub_uint64_t))
+
+#define v16at(buf,ofs)	valueat(buf,ofs,grub_uint16_t)
+#define v32at(buf,ofs)	valueat(buf,ofs,grub_uint32_t)
+#define v64at(buf,ofs)	valueat(buf,ofs,grub_uint64_t)
+
+struct grub_ntfs_bpb
+{
+  grub_uint8_t jmp_boot[3];
+  grub_uint8_t oem_name[8];
+  grub_uint16_t bytes_per_sector;
+  grub_uint8_t sectors_per_cluster;
+  grub_uint8_t reserved_1[7];
+  grub_uint8_t media;
+  grub_uint16_t reserved_2;
+  grub_uint16_t sectors_per_track;
+  grub_uint16_t num_heads;
+  grub_uint32_t num_hidden_sectors;
+  grub_uint32_t reserved_3[2];
+  grub_uint64_t num_total_sectors;
+  grub_uint64_t mft_lcn;
+  grub_uint64_t mft_mirr_lcn;
+  grub_int8_t clusters_per_mft;
+  grub_int8_t reserved_4[3];
+  grub_int8_t clusters_per_index;
+  grub_int8_t reserved_5[3];
+  grub_uint64_t num_serial;
+  grub_uint32_t checksum;
+} __attribute__ ((packed));
+
+#define grub_ntfs_file grub_fshelp_node
+
+struct grub_ntfs_attr
+{
+  int flags;
+  char *emft_buf, *edat_buf;
+  char *attr_cur, *attr_nxt, *attr_end;
+  grub_uint32_t save_pos;
+  char *sbuf;
+  struct grub_ntfs_file *mft;
+};
+
+struct grub_fshelp_node
+{
+  struct grub_ntfs_data *data;
+  char *buf;
+  grub_uint64_t size;
+  grub_uint32_t ino;
+  int inode_read;
+  struct grub_ntfs_attr attr;
+};
+
+struct grub_ntfs_data
+{
+  struct grub_ntfs_file cmft;
+  struct grub_ntfs_file mmft;
+  grub_disk_t disk;
+  grub_uint32_t mft_size;
+  grub_uint32_t idx_size;
+  grub_uint32_t spc;
+  grub_uint32_t blocksize;
+  grub_uint32_t mft_start;
+  grub_uint64_t uuid;
+};
+
+struct grub_ntfs_comp
+{
+  grub_disk_t disk;
+  int comp_head, comp_tail;
+  grub_uint32_t comp_table[16][2];
+  grub_uint32_t cbuf_ofs, cbuf_vcn, spc;
+  char *cbuf;
+};
+
+struct grub_ntfs_rlst
+{
+  int flags;
+  grub_uint32_t target_vcn, curr_vcn, next_vcn, curr_lcn;
+  char *cur_run;
+  struct grub_ntfs_attr *attr;
+  struct grub_ntfs_comp comp;
+};
+
+typedef grub_err_t (*ntfscomp_func_t) (struct grub_ntfs_attr * at, char *dest,
+				       grub_uint32_t ofs, grub_uint32_t len,
+				       struct grub_ntfs_rlst * ctx,
+				       grub_uint32_t vcn);
+
+extern ntfscomp_func_t EXPORT_VAR (grub_ntfscomp_func);
+
+grub_err_t EXPORT_FUNC(grub_ntfs_read_run_list) (struct grub_ntfs_rlst *ctx);
+
+#endif /* ! GRUB_NTFS_H */
diff --git a/include/grub/parser.h b/include/grub/parser.h
new file mode 100644
index 0000000..4ee0e83
--- /dev/null
+++ b/include/grub/parser.h
@@ -0,0 +1,117 @@
+/* parser.h - prototypes for the command line parser.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_PARSER_HEADER
+#define GRUB_PARSER_HEADER	1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/reader.h>
+
+/* All the states for the command line.  */
+typedef enum
+  {
+    GRUB_PARSER_STATE_TEXT = 1,
+    GRUB_PARSER_STATE_ESC,
+    GRUB_PARSER_STATE_QUOTE,
+    GRUB_PARSER_STATE_DQUOTE,
+    GRUB_PARSER_STATE_VAR,
+    GRUB_PARSER_STATE_VARNAME,
+    GRUB_PARSER_STATE_VARNAME2,
+    GRUB_PARSER_STATE_QVAR,
+    GRUB_PARSER_STATE_QVARNAME,
+    GRUB_PARSER_STATE_QVARNAME2
+  } grub_parser_state_t;
+
+/* A single state transition.  */
+struct grub_parser_state_transition
+{
+  /* The state that is looked up.  */
+  grub_parser_state_t from_state;
+
+  /* The next state, determined by FROM_STATE and INPUT.  */
+  grub_parser_state_t to_state;
+
+  /* The input that will determine the next state from FROM_STATE.  */
+  char input;
+
+  /* If set to 1, the input is valid and should be used.  */
+  int keep_value;
+};
+
+/* Determines the state following STATE, determined by C.  */
+grub_parser_state_t
+EXPORT_FUNC (grub_parser_cmdline_state) (grub_parser_state_t state,
+					 char c, char *result);
+
+grub_err_t
+EXPORT_FUNC (grub_parser_split_cmdline) (const char *cmdline,
+					 grub_reader_getline_t getline,
+					 int *argc, char ***argv);
+
+struct grub_parser
+{
+  /* The next parser.  */
+  struct grub_parser *next;
+
+  /* The parser name.  */
+  const char *name;
+
+  /* Initialize the parser.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the parser.  */
+  grub_err_t (*fini) (void);
+
+  grub_err_t (*parse_line) (char *line, grub_reader_getline_t getline);
+};
+typedef struct grub_parser *grub_parser_t;
+
+extern struct grub_handler_class EXPORT_VAR(grub_parser_class);
+grub_err_t EXPORT_FUNC(grub_parser_execute) (char *source);
+
+static inline void
+grub_parser_register (const char *name __attribute__ ((unused)),
+		      grub_parser_t parser)
+{
+  grub_handler_register (&grub_parser_class, GRUB_AS_HANDLER (parser));
+}
+
+static inline void
+grub_parser_unregister (grub_parser_t parser)
+{
+  grub_handler_unregister (&grub_parser_class, GRUB_AS_HANDLER (parser));
+}
+
+static inline grub_parser_t
+grub_parser_get_current (void)
+{
+  return (grub_parser_t) grub_parser_class.cur_handler;
+}
+
+static inline grub_err_t
+grub_parser_set_current (grub_parser_t parser)
+{
+  return grub_handler_set_current (&grub_parser_class,
+				   GRUB_AS_HANDLER (parser));
+}
+
+void grub_register_rescue_parser (void);
+
+#endif /* ! GRUB_PARSER_HEADER */
diff --git a/include/grub/partition.h b/include/grub/partition.h
new file mode 100644
index 0000000..d35658c
--- /dev/null
+++ b/include/grub/partition.h
@@ -0,0 +1,113 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2004,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_PART_HEADER
+#define GRUB_PART_HEADER	1
+
+#include <grub/dl.h>
+
+struct grub_disk;
+
+typedef struct grub_partition *grub_partition_t;
+
+/* Partition map type.  */
+struct grub_partition_map
+{
+  /* The name of the partition map type.  */
+  const char *name;
+
+  /* Call HOOK with each partition, until HOOK returns non-zero.  */
+  grub_err_t (*iterate) (struct grub_disk *disk,
+			 int (*hook) (struct grub_disk *disk,
+				      const grub_partition_t partition));
+
+  /* Return the partition named STR on the disk DISK.  */
+  grub_partition_t (*probe) (struct grub_disk *disk,
+			     const char *str);
+
+  /* Return the name of the partition PARTITION.  */
+  char *(*get_name) (const grub_partition_t partition);
+
+  /* The next partition map type.  */
+  struct grub_partition_map *next;
+};
+typedef struct grub_partition_map *grub_partition_map_t;
+
+/* Partition description.  */
+struct grub_partition
+{
+  /* The start sector.  */
+  grub_disk_addr_t start;
+
+  /* The length in sector units.  */
+  grub_uint64_t len;
+
+  /* The offset of the partition table.  */
+  grub_disk_addr_t offset;
+
+  /* The index of this partition in the partition table.  */
+  int index;
+
+  /* Partition map type specific data.  */
+  void *data;
+
+  /* The type partition map.  */
+  grub_partition_map_t partmap;
+};
+
+grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk,
+						    const char *str);
+int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk,
+					 int (*hook) (struct grub_disk *disk,
+						      const grub_partition_t partition));
+char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition);
+
+int EXPORT_FUNC(grub_partition_map_iterate) (int (*hook) (const grub_partition_map_t partmap));
+
+void EXPORT_FUNC(grub_partition_map_register) (grub_partition_map_t partmap);
+
+void EXPORT_FUNC(grub_partition_map_unregister) (grub_partition_map_t partmap);
+
+#ifdef GRUB_UTIL
+void grub_msdos_partition_map_init (void);
+void grub_msdos_partition_map_fini (void);
+void grub_amiga_partition_map_init (void);
+void grub_amiga_partition_map_fini (void);
+void grub_apple_partition_map_init (void);
+void grub_apple_partition_map_fini (void);
+void grub_sun_partition_map_init (void);
+void grub_sun_partition_map_fini (void);
+void grub_gpt_partition_map_init (void);
+void grub_gpt_partition_map_fini (void);
+void grub_apple_partition_map_init (void);
+void grub_apple_partition_map_fini (void);
+#endif
+
+static inline grub_disk_addr_t
+grub_partition_get_start (const grub_partition_t p)
+{
+  return p->start;
+}
+
+static inline grub_uint64_t
+grub_partition_get_len (const grub_partition_t p)
+{
+  return p->len;
+}
+
+#endif /* ! GRUB_PART_HEADER */
diff --git a/include/grub/parttool.h b/include/grub/parttool.h
new file mode 100644
index 0000000..8291e11
--- /dev/null
+++ b/include/grub/parttool.h
@@ -0,0 +1,58 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_PARTTOOL_HEADER
+#define GRUB_PARTTOOL_HEADER	1
+
+struct grub_parttool_argdesc
+{
+  char *name;
+  char *desc;
+  enum {GRUB_PARTTOOL_ARG_END, GRUB_PARTTOOL_ARG_BOOL, GRUB_PARTTOOL_ARG_VAL}
+    type;
+};
+
+struct grub_parttool_args
+{
+  int set;
+  union
+  {
+    int bool;
+    char *str;
+  };
+};
+
+typedef grub_err_t (*grub_parttool_function_t) (const grub_device_t dev,
+						const struct grub_parttool_args *args);
+
+struct grub_parttool
+{
+  struct grub_parttool *next;
+  char *name;
+  int handle;
+  int nargs;
+  struct grub_parttool_argdesc *args;
+  grub_parttool_function_t func;
+};
+
+int grub_parttool_register(const char *part_name,
+			   const grub_parttool_function_t func,
+			   const struct grub_parttool_argdesc *args);
+void grub_parttool_unregister (int handle);
+
+#endif /* ! GRUB_PARTTOOL_HEADER*/
diff --git a/include/grub/pci.h b/include/grub/pci.h
new file mode 100644
index 0000000..7c8b505
--- /dev/null
+++ b/include/grub/pci.h
@@ -0,0 +1,50 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef	GRUB_PCI_H
+#define	GRUB_PCI_H	1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+#define  GRUB_PCI_ADDR_SPACE_MASK	0x01
+#define  GRUB_PCI_ADDR_SPACE_MEMORY	0x00
+#define  GRUB_PCI_ADDR_SPACE_IO		0x01
+
+#define  GRUB_PCI_ADDR_MEM_TYPE_MASK	0x06
+#define  GRUB_PCI_ADDR_MEM_TYPE_32	0x00	/* 32 bit address */
+#define  GRUB_PCI_ADDR_MEM_TYPE_1M	0x02	/* Below 1M [obsolete] */
+#define  GRUB_PCI_ADDR_MEM_TYPE_64	0x04	/* 64 bit address */
+#define  GRUB_PCI_ADDR_MEM_PREFETCH	0x08	/* prefetchable */
+
+#define  GRUB_PCI_ADDR_MEM_MASK		~0xf
+#define  GRUB_PCI_ADDR_IO_MASK		~0x03
+
+typedef grub_uint32_t grub_pci_id_t;
+typedef int NESTED_FUNC_ATTR (*grub_pci_iteratefunc_t)
+     (int bus, int device, int func, grub_pci_id_t pciid);
+typedef grub_uint32_t grub_pci_address_t;
+
+grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (int bus, int device,
+						       int function, int reg);
+
+void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook);
+
+#include <grub/cpu/pci.h>
+
+#endif /* GRUB_PCI_H */
diff --git a/include/grub/powerpc/ieee1275/biosdisk.h b/include/grub/powerpc/ieee1275/biosdisk.h
new file mode 100644
index 0000000..30584d6
--- /dev/null
+++ b/include/grub/powerpc/ieee1275/biosdisk.h
@@ -0,0 +1,46 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BIOSDISK_MACHINE_HEADER
+#define GRUB_BIOSDISK_MACHINE_HEADER	1
+
+#define GRUB_BIOSDISK_FLAG_LBA	1
+
+struct grub_biosdisk_data
+{
+  int drive;
+  unsigned long cylinders;
+  unsigned long heads;
+  unsigned long sectors;
+  unsigned long flags;
+};
+
+int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap);
+int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff,
+			       int soff, int nsec, int segment);
+int grub_biosdisk_check_int13_extensions (int drive);
+int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp);
+int grub_biosdisk_get_diskinfo_standard (int drive,
+					 unsigned long *cylinders,
+					 unsigned long *heads,
+					 unsigned long *sectors);
+int grub_biosdisk_get_num_floppies (void);
+
+void grub_biosdisk_init (void);
+
+#endif /* ! GRUB_BIOSDISK_MACHINE_HEADER */
diff --git a/include/grub/powerpc/ieee1275/console.h b/include/grub/powerpc/ieee1275/console.h
new file mode 100644
index 0000000..ed2b720
--- /dev/null
+++ b/include/grub/powerpc/ieee1275/console.h
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CONSOLE_MACHINE_HEADER
+#define GRUB_CONSOLE_MACHINE_HEADER	1
+
+/* Initialize the console system.  */
+void grub_console_init (void);
+
+/* Finish the console system.  */
+void grub_console_fini (void);
+
+#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
diff --git a/include/grub/powerpc/ieee1275/ieee1275.h b/include/grub/powerpc/ieee1275/ieee1275.h
new file mode 100644
index 0000000..7e93055
--- /dev/null
+++ b/include/grub/powerpc/ieee1275/ieee1275.h
@@ -0,0 +1,27 @@
+/* ieee1275.h - Access the Open Firmware client interface.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_IEEE1275_MACHINE_HEADER
+#define GRUB_IEEE1275_MACHINE_HEADER	1
+
+#include <grub/types.h>
+
+typedef grub_uint32_t grub_ieee1275_cell_t;
+
+#endif /* ! GRUB_IEEE1275_MACHINE_HEADER */
diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h
new file mode 100644
index 0000000..917e154
--- /dev/null
+++ b/include/grub/powerpc/ieee1275/kernel.h
@@ -0,0 +1,35 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER	1
+
+#include <grub/symbol.h>
+
+#ifndef ASM_FILE
+
+void EXPORT_FUNC (grub_reboot) (void);
+void EXPORT_FUNC (grub_halt) (void);
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+#endif
+
+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/include/grub/powerpc/ieee1275/loader.h b/include/grub/powerpc/ieee1275/loader.h
new file mode 100644
index 0000000..606bfcd
--- /dev/null
+++ b/include/grub/powerpc/ieee1275/loader.h
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER	1
+
+/* The symbol shared between the normal mode and rescue mode
+   loader.  */
+void grub_rescue_cmd_linux (int argc, char *argv[]);
+void grub_rescue_cmd_initrd (int argc, char *argv[]);
+
+void grub_linux_init (void);
+void grub_linux_fini (void);
+void grub_linux_normal_init (void);
+void grub_linux_normal_fini (void);
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/include/grub/powerpc/ieee1275/machine.h b/include/grub/powerpc/ieee1275/machine.h
new file mode 100644
index 0000000..66da1d9
--- /dev/null
+++ b/include/grub/powerpc/ieee1275/machine.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_MACHINE_HEADER
+#define GRUB_MACHINE_MACHINE_HEADER	1
+
+#define GRUB_MACHINE_IEEE1275	1
+
+#endif /* ! GRUB_MACHINE_MACHINE_HEADER */
diff --git a/include/grub/powerpc/ieee1275/memory.h b/include/grub/powerpc/ieee1275/memory.h
new file mode 100644
index 0000000..f8f2ff0
--- /dev/null
+++ b/include/grub/powerpc/ieee1275/memory.h
@@ -0,0 +1,26 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_MACHINE_HEADER
+#define GRUB_MEMORY_MACHINE_HEADER	1
+
+#include <grub/ieee1275/ieee1275.h>
+
+#define GRUB_MACHINE_MEMORY_AVAILABLE		1
+
+#endif
diff --git a/include/grub/powerpc/ieee1275/time.h b/include/grub/powerpc/ieee1275/time.h
new file mode 100644
index 0000000..3f8ad26
--- /dev/null
+++ b/include/grub/powerpc/ieee1275/time.h
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_MACHINE_TIME_HEADER
+#define KERNEL_MACHINE_TIME_HEADER	1
+
+#include <grub/symbol.h>
+
+#define GRUB_TICKS_PER_SECOND	1000
+
+/* Return the real time in ticks.  */
+grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
+
+#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/include/grub/powerpc/ieee1275/util/biosdisk.h b/include/grub/powerpc/ieee1275/util/biosdisk.h
new file mode 100644
index 0000000..f4262a0
--- /dev/null
+++ b/include/grub/powerpc/ieee1275/util/biosdisk.h
@@ -0,0 +1,27 @@
+/* biosdisk.h - emulate biosdisk */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BIOSDISK_MACHINE_UTIL_HEADER
+#define GRUB_BIOSDISK_MACHINE_UTIL_HEADER	1
+
+void grub_util_biosdisk_init (const char *dev_map);
+void grub_util_biosdisk_fini (void);
+char *grub_util_biosdisk_get_grub_dev (const char *os_dev);
+
+#endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
diff --git a/include/grub/powerpc/kernel.h b/include/grub/powerpc/kernel.h
new file mode 100644
index 0000000..b468733
--- /dev/null
+++ b/include/grub/powerpc/kernel.h
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_CPU_HEADER
+#define GRUB_KERNEL_CPU_HEADER	1
+
+#define GRUB_MOD_ALIGN 0x1000
+
+/* Minimal gap between _end and the start of the modules.  It's a hack
+   for PowerMac to prevent "CLAIM failed" error.  The real fix is to
+   rewrite grub-mkimage to generate valid ELF files.  */
+#define GRUB_MOD_GAP 0x8000
+
+#define GRUB_KERNEL_CPU_PREFIX		0x4
+#define GRUB_KERNEL_CPU_DATA_END	0x44
+
+#endif
diff --git a/include/grub/powerpc/libgcc.h b/include/grub/powerpc/libgcc.h
new file mode 100644
index 0000000..452ad43
--- /dev/null
+++ b/include/grub/powerpc/libgcc.h
@@ -0,0 +1,35 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#ifdef HAVE___ASHLDI3
+void EXPORT_FUNC (__ashldi3) (void);
+#endif
+#ifdef HAVE___ASHRDI3
+void EXPORT_FUNC (__ashrdi3) (void);
+#endif
+#ifdef HAVE___LSHRDI3
+void EXPORT_FUNC (__lshrdi3) (void);
+#endif
+#ifdef HAVE___TRAMPOLINE_SETUP
+void EXPORT_FUNC (__trampoline_setup) (void);
+#endif
+#ifdef HAVE___UCMPDI2
+void EXPORT_FUNC (__ucmpdi2) (void);
+#endif
diff --git a/include/grub/powerpc/setjmp.h b/include/grub/powerpc/setjmp.h
new file mode 100644
index 0000000..fa16f73
--- /dev/null
+++ b/include/grub/powerpc/setjmp.h
@@ -0,0 +1,27 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER	1
+
+typedef unsigned long grub_jmp_buf[20];
+
+int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/include/grub/powerpc/time.h b/include/grub/powerpc/time.h
new file mode 100644
index 0000000..5db7ff4
--- /dev/null
+++ b/include/grub/powerpc/time.h
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER	1
+
+static __inline void
+grub_cpu_idle (void)
+{
+  /* FIXME: not implemented */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/include/grub/powerpc/types.h b/include/grub/powerpc/types.h
new file mode 100644
index 0000000..a098ae6
--- /dev/null
+++ b/include/grub/powerpc/types.h
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER	1
+
+/* The size of void *.  */
+#define GRUB_TARGET_SIZEOF_VOID_P	4
+
+/* The size of long.  */
+#define GRUB_TARGET_SIZEOF_LONG		4
+
+/* powerpc is big-endian.  */
+#define GRUB_TARGET_WORDS_BIGENDIAN	1
+
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/include/grub/raid.h b/include/grub/raid.h
new file mode 100644
index 0000000..8fa4c38
--- /dev/null
+++ b/include/grub/raid.h
@@ -0,0 +1,85 @@
+/* raid.h - On disk structures for RAID. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_RAID_H
+#define GRUB_RAID_H	1
+
+#include <grub/types.h>
+
+#define GRUB_RAID_MAX_DEVICES	32
+
+#define GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC	0
+#define GRUB_RAID_LAYOUT_RIGHT_ASYMMETRIC	1
+#define GRUB_RAID_LAYOUT_LEFT_SYMMETRIC		2
+#define GRUB_RAID_LAYOUT_RIGHT_SYMMETRIC	3
+
+#define GRUB_RAID_LAYOUT_RIGHT_MASK		1
+#define GRUB_RAID_LAYOUT_SYMMETRIC_MASK		2
+
+struct grub_raid_array
+{
+  int number;              /* The device number, taken from md_minor so we
+			      are consistent with the device name in
+			      Linux. */
+  int level;               /* RAID levels, only 0, 1 or 5 at the moment. */
+  int layout;              /* Layout for RAID 5/6.  */
+  unsigned int total_devs; /* Total number of devices in the array. */
+  grub_size_t chunk_size;  /* The size of a chunk, in 512 byte sectors. */
+  grub_uint64_t disk_size; /* Size of an individual disk, in 512 byte
+			      sectors. */
+  int index;               /* Index of current device.  */
+  int uuid_len;            /* The length of uuid.  */
+  char *uuid;              /* The UUID of the device. */
+
+  /* The following field is setup by the caller.  */
+  char *name;              /* That will be "md<number>". */
+  unsigned int nr_devs;    /* The number of devices we've found so far. */
+  grub_disk_t device[GRUB_RAID_MAX_DEVICES];  /* Array of total_devs devices. */
+  struct grub_raid_array *next;
+};
+
+struct grub_raid
+{
+  const char *name;
+
+  grub_err_t (*detect) (grub_disk_t disk, struct grub_raid_array *array);
+
+  struct grub_raid *next;
+};
+typedef struct grub_raid *grub_raid_t;
+
+void grub_raid_register (grub_raid_t raid);
+void grub_raid_unregister (grub_raid_t raid);
+
+void grub_raid_block_xor (char *buf1, const char *buf2, int size);
+
+typedef grub_err_t (*grub_raid5_recover_func_t) (struct grub_raid_array *array,
+                                                 int disknr, char *buf,
+                                                 grub_disk_addr_t sector,
+                                                 int size);
+
+typedef grub_err_t (*grub_raid6_recover_func_t) (struct grub_raid_array *array,
+                                                 int disknr, int p, char *buf,
+                                                 grub_disk_addr_t sector,
+                                                 int size);
+
+extern grub_raid5_recover_func_t grub_raid5_recover_func;
+extern grub_raid6_recover_func_t grub_raid6_recover_func;
+
+#endif /* ! GRUB_RAID_H */
diff --git a/include/grub/reader.h b/include/grub/reader.h
new file mode 100644
index 0000000..c7e67bf
--- /dev/null
+++ b/include/grub/reader.h
@@ -0,0 +1,79 @@
+/* reader.h - prototypes for command line reader.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_READER_HEADER
+#define GRUB_READER_HEADER	1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/handler.h>
+
+typedef grub_err_t (*grub_reader_getline_t) (char **, int);
+
+struct grub_reader
+{
+  /* The next reader.  */
+  struct grub_parser *next;
+
+  /* The reader name.  */
+  const char *name;
+
+  /* Initialize the reader.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the reader.  */
+  grub_err_t (*fini) (void);
+
+  grub_reader_getline_t read_line;
+};
+typedef struct grub_reader *grub_reader_t;
+
+extern struct grub_handler_class EXPORT_VAR(grub_reader_class);
+
+grub_err_t EXPORT_FUNC(grub_reader_loop) (grub_reader_getline_t getline);
+
+static inline void
+grub_reader_register (const char *name __attribute__ ((unused)),
+		      grub_reader_t reader)
+{
+  grub_handler_register (&grub_reader_class, GRUB_AS_HANDLER (reader));
+}
+
+static inline void
+grub_reader_unregister (grub_reader_t reader)
+{
+  grub_handler_unregister (&grub_reader_class, GRUB_AS_HANDLER (reader));
+}
+
+static inline grub_reader_t
+grub_reader_get_current (void)
+{
+  return (grub_reader_t) grub_reader_class.cur_handler;
+}
+
+static inline grub_err_t
+grub_reader_set_current (grub_reader_t reader)
+{
+  return grub_handler_set_current (&grub_reader_class,
+				   GRUB_AS_HANDLER (reader));
+}
+
+void grub_register_rescue_reader (void);
+
+#endif /* ! GRUB_READER_HEADER */
diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h
new file mode 100644
index 0000000..f6177b0
--- /dev/null
+++ b/include/grub/script_sh.h
@@ -0,0 +1,290 @@
+/* normal_parser.h  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_NORMAL_PARSER_HEADER
+#define GRUB_NORMAL_PARSER_HEADER	1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/parser.h>
+
+struct grub_script_mem;
+
+/* The generic header for each scripting command or structure.  */
+struct grub_script_cmd
+{
+  /* This function is called to execute the command.  */
+  grub_err_t (*exec) (struct grub_script_cmd *cmd);
+
+  /* The next command.  This can be used by the parent to form a chain
+     of commands.  */
+  struct grub_script_cmd *next;
+};
+
+struct grub_script
+{
+  struct grub_script_mem *mem;
+  struct grub_script_cmd *cmd;
+};
+
+typedef enum
+{
+  GRUB_SCRIPT_ARG_TYPE_STR,
+  GRUB_SCRIPT_ARG_TYPE_VAR
+} grub_script_arg_type_t;
+
+/* A part of an argument.  */
+struct grub_script_arg
+{
+  grub_script_arg_type_t type;
+
+  char *str;
+
+  /* Next argument part.  */
+  struct grub_script_arg *next;
+};
+
+/* A complete argument.  It consists of a list of one or more `struct
+   grub_script_arg's.  */
+struct grub_script_arglist
+{
+  struct grub_script_arglist *next;
+  struct grub_script_arg *arg;
+  /* Only stored in the first link.  */
+  int argcount;
+};
+
+/* A single command line.  */
+struct grub_script_cmdline
+{
+  struct grub_script_cmd cmd;
+
+  /* The arguments for this command.  */
+  struct grub_script_arglist *arglist;
+};
+
+/* A block of commands, this can be used to group commands.  */
+struct grub_script_cmdblock
+{
+  struct grub_script_cmd cmd;
+
+  /* A chain of commands.  */
+  struct grub_script_cmd *cmdlist;
+};
+
+/* An if statement.  */
+struct grub_script_cmdif
+{
+  struct grub_script_cmd cmd;
+
+  /* The command used to check if the 'if' is true or false.  */
+  struct grub_script_cmd *exec_to_evaluate;
+
+  /* The code executed in case the result of 'if' was true.  */
+  struct grub_script_cmd *exec_on_true;
+
+  /* The code executed in case the result of 'if' was false.  */
+  struct grub_script_cmd *exec_on_false;
+};
+
+/* A menu entry generate statement.  */
+struct grub_script_cmd_menuentry
+{
+  struct grub_script_cmd cmd;
+
+  /* The arguments for this menu entry.  */
+  struct grub_script_arglist *arglist;
+
+  /* The sourcecode the entry will be generated from.  */
+  const char *sourcecode;
+
+  /* Options.  XXX: Not used yet.  */
+  int options;
+};
+
+/* State of the lexer as passed to the lexer.  */
+struct grub_lexer_param
+{
+  /* Set to 0 when the lexer is done.  */
+  int done;
+
+  /* State of the state machine.  */
+  grub_parser_state_t state;
+
+  /* Function used by the lexer to get a new line when more input is
+     expected, but not available.  */
+  grub_reader_getline_t getline;
+
+  /* A reference counter.  If this is >0 it means that the parser
+     expects more tokens and `getline' should be called to fetch more.
+     Otherwise the lexer can stop processing if the current buffer is
+     depleted.  */
+  int refs;
+
+  /* The character stream that has to be parsed.  */
+  char *script;
+  char *newscript; /* XXX */
+
+  /* While walking through the databuffer, `record' the characters to
+     this other buffer.  It can be used to edit the menu entry at a
+     later moment.  */
+
+  /* If true, recording is enabled.  */
+  int record;
+
+  /* Points to the recording.  */
+  char *recording;
+
+  /* index in the RECORDING.  */
+  int recordpos;
+
+  /* Size of RECORDING.  */
+  int recordlen;
+
+  /* The token that is already parsed but not yet returned. */
+  int tokenonhold;
+
+  /* Was the last token a newline? */
+  int was_newline;
+};
+
+/* State of the parser as passes to the parser.  */
+struct grub_parser_param
+{
+  /* Keep track of the memory allocated for this specific
+     function.  */
+  struct grub_script_mem *func_mem;
+
+  /* When set to 0, no errors have occurred during parsing.  */
+  int err;
+
+  /* The memory that was used while parsing and scanning.  */
+  struct grub_script_mem *memused;
+
+  /* The result of the parser.  */
+  struct grub_script_cmd *parsed;
+
+  struct grub_lexer_param *lexerstate;
+};
+
+struct grub_script_arglist *
+grub_script_create_arglist (struct grub_parser_param *state);
+
+struct grub_script_arglist *
+grub_script_add_arglist (struct grub_parser_param *state,
+			 struct grub_script_arglist *list,
+			 struct grub_script_arg *arg);
+struct grub_script_cmd *
+grub_script_create_cmdline (struct grub_parser_param *state,
+			    struct grub_script_arglist *arglist);
+struct grub_script_cmd *
+grub_script_create_cmdblock (struct grub_parser_param *state);
+
+struct grub_script_cmd *
+grub_script_create_cmdif (struct grub_parser_param *state,
+			  struct grub_script_cmd *exec_to_evaluate,
+			  struct grub_script_cmd *exec_on_true,
+			  struct grub_script_cmd *exec_on_false);
+
+struct grub_script_cmd *
+grub_script_create_cmdmenu (struct grub_parser_param *state,
+			    struct grub_script_arglist *arglist,
+			    char *sourcecode,
+			    int options);
+
+struct grub_script_cmd *
+grub_script_add_cmd (struct grub_parser_param *state,
+		     struct grub_script_cmdblock *cmdblock,
+		     struct grub_script_cmd *cmd);
+struct grub_script_arg *
+grub_script_arg_add (struct grub_parser_param *state,
+		     struct grub_script_arg *arg,
+		     grub_script_arg_type_t type, char *str);
+
+struct grub_script *grub_script_parse (char *script,
+				       grub_reader_getline_t getline);
+void grub_script_free (struct grub_script *script);
+struct grub_script *grub_script_create (struct grub_script_cmd *cmd,
+					struct grub_script_mem *mem);
+
+struct grub_lexer_param *grub_script_lexer_init (char *s,
+						 grub_reader_getline_t getline);
+void grub_script_lexer_ref (struct grub_lexer_param *);
+void grub_script_lexer_deref (struct grub_lexer_param *);
+void grub_script_lexer_record_start (struct grub_lexer_param *);
+char *grub_script_lexer_record_stop (struct grub_lexer_param *);
+
+/* Functions to track allocated memory.  */
+struct grub_script_mem *grub_script_mem_record (struct grub_parser_param *state);
+struct grub_script_mem *grub_script_mem_record_stop (struct grub_parser_param *state,
+						     struct grub_script_mem *restore);
+void *grub_script_malloc (struct grub_parser_param *state, grub_size_t size);
+
+/* Functions used by bison.  */
+union YYSTYPE;
+int grub_script_yylex (union YYSTYPE *, struct grub_parser_param *);
+int grub_script_yyparse (struct grub_parser_param *);
+void grub_script_yyerror (struct grub_parser_param *, char const *);
+
+/* Commands to execute, don't use these directly.  */
+grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd);
+grub_err_t grub_script_execute_cmdblock (struct grub_script_cmd *cmd);
+grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd);
+grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd);
+
+/* Execute any GRUB pre-parsed command or script.  */
+grub_err_t grub_script_execute (struct grub_script *script);
+
+/* This variable points to the parsed command.  This is used to
+   communicate with the bison code.  */
+extern struct grub_script_cmd *grub_script_parsed;
+
+
+
+/* The function description.  */
+struct grub_script_function
+{
+  /* The name.  */
+  char *name;
+
+  /* The script function.  */
+  struct grub_script *func;
+
+  /* The flags.  */
+  unsigned flags;
+
+  /* The next element.  */
+  struct grub_script_function *next;
+
+  int references;
+};
+typedef struct grub_script_function *grub_script_function_t;
+
+grub_script_function_t grub_script_function_create (struct grub_script_arg *functionname,
+						    struct grub_script *cmd);
+void grub_script_function_remove (const char *name);
+grub_script_function_t grub_script_function_find (char *functionname);
+int grub_script_function_iterate (int (*iterate) (grub_script_function_t));
+int grub_script_function_call (grub_script_function_t func,
+			       int argc, char **args);
+
+char *
+grub_script_execute_argument_to_string (struct grub_script_arg *arg);
+
+#endif /* ! GRUB_NORMAL_PARSER_HEADER */
diff --git a/include/grub/scsi.h b/include/grub/scsi.h
new file mode 100644
index 0000000..fbe4582
--- /dev/null
+++ b/include/grub/scsi.h
@@ -0,0 +1,88 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef	GRUB_SCSI_H
+#define	GRUB_SCSI_H	1
+
+typedef struct grub_scsi_dev *grub_scsi_dev_t;
+
+void grub_scsi_dev_register (grub_scsi_dev_t dev);
+void grub_scsi_dev_unregister (grub_scsi_dev_t dev);
+
+struct grub_scsi;
+
+struct grub_scsi_dev
+{
+  /* The device name.  */
+  const char *name;
+
+  /* Call HOOK with each device name, until HOOK returns non-zero.  */
+  int (*iterate) (int (*hook) (const char *name, int luns));
+
+  /* Open the device named NAME, and set up SCSI.  */
+  grub_err_t (*open) (const char *name, struct grub_scsi *scsi);
+
+  /* Close the scsi device SCSI.  */
+  void (*close) (struct grub_scsi *scsi);
+
+  /* Read SIZE bytes from the device SCSI into BUF after sending the
+     command CMD of size CMDSIZE.  */
+  grub_err_t (*read) (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+		      grub_size_t size, char *buf);
+
+  /* Write SIZE  bytes from BUF to  the device SCSI  after sending the
+     command CMD of size CMDSIZE.  */
+  grub_err_t (*write) (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+		       grub_size_t size, char *buf);
+
+  /* The next scsi device.  */
+  struct grub_scsi_dev *next;
+};
+
+struct grub_scsi
+{
+  /* The scsi device name.  */
+  char *name;
+
+  /* The underlying scsi device.  */
+  grub_scsi_dev_t dev;
+
+  /* Type of SCSI device.  XXX: Make enum.  */
+  grub_uint8_t devtype;
+
+  /* Number of LUNs.  */
+  int luns;
+
+  /* LUN for this `struct grub_scsi'.  */
+  int lun;
+
+  /* Set to 0 when not removable, 1 when removable.  */
+  int removable;
+
+  /* Size of the device in blocks.  */
+  int size;
+
+  /* Size of one block.  */
+  int blocksize;
+
+  /* Device-specific data.  */
+  void *data;
+};
+typedef struct grub_scsi *grub_scsi_t;
+
+#endif /* GRUB_SCSI_H */
diff --git a/include/grub/scsicmd.h b/include/grub/scsicmd.h
new file mode 100644
index 0000000..40f237a
--- /dev/null
+++ b/include/grub/scsicmd.h
@@ -0,0 +1,122 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef	GRUB_SCSICMD_H
+#define	GRUB_SCSICMD_H	1
+
+#include <grub/types.h>
+
+#define GRUB_SCSI_DEVTYPE_MASK	31
+#define GRUB_SCSI_REMOVABLE_BIT	7
+#define GRUB_SCSI_LUN_SHIFT	5
+
+struct grub_scsi_inquiry
+{
+  grub_uint8_t opcode;
+  grub_uint8_t lun;
+  grub_uint16_t reserved;
+  grub_uint16_t alloc_length;
+  grub_uint8_t reserved2;
+  grub_uint8_t pad[5];
+} __attribute__((packed));
+
+struct grub_scsi_inquiry_data
+{
+  grub_uint8_t devtype;
+  grub_uint8_t rmb;
+  grub_uint16_t reserved;
+  grub_uint8_t length;
+  grub_uint8_t reserved2[3];
+  char vendor[8];
+  char prodid[16];
+  char prodrev[4];
+} __attribute__((packed));
+
+struct grub_scsi_read_capacity
+{
+  grub_uint8_t opcode;
+  grub_uint8_t lun;
+  grub_uint8_t reserved[8];
+  grub_uint8_t pad[2];
+} __attribute__((packed));
+
+struct grub_scsi_read_capacity_data
+{
+  grub_uint32_t size;
+  grub_uint32_t blocksize;
+} __attribute__((packed));
+
+struct grub_scsi_read10
+{
+  grub_uint8_t opcode;
+  grub_uint8_t lun;
+  grub_uint32_t lba;
+  grub_uint8_t reserved;
+  grub_uint16_t size;
+  grub_uint8_t reserved2;
+  grub_uint16_t pad;
+} __attribute__((packed));
+
+struct grub_scsi_read12
+{
+  grub_uint8_t opcode;
+  grub_uint8_t lun;
+  grub_uint32_t lba;
+  grub_uint32_t size;
+  grub_uint8_t reserved;
+  grub_uint8_t control;
+} __attribute__((packed));
+
+struct grub_scsi_write10
+{
+  grub_uint8_t opcode;
+  grub_uint8_t lun;
+  grub_uint32_t lba;
+  grub_uint8_t reserved;
+  grub_uint16_t size;
+  grub_uint8_t reserved2;
+  grub_uint16_t pad;
+} __attribute__((packed));
+
+struct grub_scsi_write12
+{
+  grub_uint8_t opcode;
+  grub_uint8_t lun;
+  grub_uint32_t lba;
+  grub_uint32_t size;
+  grub_uint8_t reserved;
+  grub_uint8_t control;
+} __attribute__((packed));
+
+typedef enum
+  {
+    grub_scsi_cmd_inquiry = 0x12,
+    grub_scsi_cmd_read_capacity = 0x25,
+    grub_scsi_cmd_read10 = 0x28,
+    grub_scsi_cmd_write10 = 0x2a,
+    grub_scsi_cmd_read12 = 0xa8,
+    grub_scsi_cmd_write12 = 0xaa
+  } grub_scsi_cmd_t;
+
+typedef enum
+  {
+    grub_scsi_devtype_direct = 0x00,
+    grub_scsi_devtype_cdrom = 0x05
+  } grub_scsi_devtype_t;
+
+#endif /* GRUB_SCSICMD_H */
diff --git a/include/grub/setjmp.h b/include/grub/setjmp.h
new file mode 100644
index 0000000..70147a7
--- /dev/null
+++ b/include/grub/setjmp.h
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_HEADER
+#define GRUB_SETJMP_HEADER	1
+
+#if defined(GRUB_UTIL) && !defined(GRUBOF)
+#include <setjmp.h>
+typedef jmp_buf grub_jmp_buf;
+#define grub_setjmp setjmp
+#define grub_longjmp longjmp
+#else
+/* This must define grub_jmp_buf, and declare grub_setjmp and
+   grub_longjmp.  */
+# include <grub/cpu/setjmp.h>
+#endif
+
+#endif /* ! GRUB_SETJMP_HEADER */
diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h
new file mode 100644
index 0000000..95f311c
--- /dev/null
+++ b/include/grub/sparc64/ieee1275/boot.h
@@ -0,0 +1,58 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009   Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BOOT_MACHINE_HEADER
+#define GRUB_BOOT_MACHINE_HEADER	1
+
+#define CIF_REG				%l0
+#define CHOSEN_NODE_REG			%l4
+#define STDOUT_NODE_REG			%l5
+#define BOOTDEV_REG			%l6
+#define PIC_REG				%l7
+
+#define	SCRATCH_PAD			0x10000
+
+#define GET_ABS(symbol, reg)	\
+	add	PIC_REG, (symbol - pic_base), reg
+#define LDUW_ABS(symbol, offset, reg)	\
+	lduw	[PIC_REG + (symbol - pic_base) + (offset)], reg
+#define LDX_ABS(symbol, offset, reg)	\
+	ldx	[PIC_REG + (symbol - pic_base) + (offset)], reg
+
+#define GRUB_BOOT_AOUT_HEADER_SIZE	32
+
+#define GRUB_BOOT_MACHINE_SIGNATURE	0xbb44aa55
+
+#define GRUB_BOOT_MACHINE_VER_MAJ	0x08
+
+#define GRUB_BOOT_MACHINE_BOOT_DEVPATH	0x0a
+
+#define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END 0x80
+
+#define GRUB_BOOT_MACHINE_KERNEL_SECTOR 0x88
+
+#define GRUB_BOOT_MACHINE_CODE_END \
+	(0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE)
+
+#define GRUB_BOOT_MACHINE_LIST_SIZE	12
+
+#define GRUB_BOOT_MACHINE_IMAGE_ADDRESS	0x200000
+
+#define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200
+
+#endif /* ! BOOT_MACHINE_HEADER */
diff --git a/include/grub/sparc64/ieee1275/console.h b/include/grub/sparc64/ieee1275/console.h
new file mode 100644
index 0000000..ed2b720
--- /dev/null
+++ b/include/grub/sparc64/ieee1275/console.h
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CONSOLE_MACHINE_HEADER
+#define GRUB_CONSOLE_MACHINE_HEADER	1
+
+/* Initialize the console system.  */
+void grub_console_init (void);
+
+/* Finish the console system.  */
+void grub_console_fini (void);
+
+#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
diff --git a/include/grub/sparc64/ieee1275/ieee1275.h b/include/grub/sparc64/ieee1275/ieee1275.h
new file mode 100644
index 0000000..7626e93
--- /dev/null
+++ b/include/grub/sparc64/ieee1275/ieee1275.h
@@ -0,0 +1,49 @@
+/* ieee1275.h - Access the Open Firmware client interface.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_IEEE1275_MACHINE_HEADER
+#define GRUB_IEEE1275_MACHINE_HEADER	1
+
+#include <grub/types.h>
+
+typedef grub_uint64_t grub_ieee1275_cell_t;
+
+/* Encoding of 'mode' argument to grub_ieee1275_map_physical() */
+#define IEEE1275_MAP_WRITE	0x0001 /* Writable */
+#define IEEE1275_MAP_READ	0x0002 /* Readable */
+#define IEEE1275_MAP_EXEC	0x0004 /* Executable */
+#define IEEE1275_MAP_LOCKED	0x0010 /* Locked in TLB */
+#define IEEE1275_MAP_CACHED	0x0020 /* Cacheable */
+#define IEEE1275_MAP_SE		0x0040 /* Side-effects */
+#define IEEE1275_MAP_GLOBAL	0x0080 /* Global */
+#define IEEE1275_MAP_IE		0x0100 /* Invert Endianness */
+#define IEEE1275_MAP_DEFAULT	(IEEE1275_MAP_WRITE | IEEE1275_MAP_READ | \
+				 IEEE1275_MAP_EXEC | IEEE1275_MAP_CACHED)
+
+extern int EXPORT_FUNC(grub_ieee1275_map_physical) (grub_addr_t paddr,
+						    grub_addr_t vaddr,
+						    grub_size_t size,
+						    grub_uint32_t mode);
+extern int EXPORT_FUNC(grub_ieee1275_claim_vaddr) (grub_addr_t vaddr,
+						   grub_size_t size);
+extern int EXPORT_FUNC(grub_ieee1275_alloc_physmem) (grub_addr_t *paddr,
+						     grub_size_t size,
+						     grub_uint32_t align);
+
+#endif /* ! GRUB_IEEE1275_MACHINE_HEADER */
diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h
new file mode 100644
index 0000000..03a6314
--- /dev/null
+++ b/include/grub/sparc64/ieee1275/kernel.h
@@ -0,0 +1,62 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER	1
+
+#define GRUB_MOD_ALIGN 0x2000
+
+/* Non-zero value is only needed for PowerMacs.  */
+#define GRUB_MOD_GAP 0x0
+
+/* The offset of GRUB_TOTAL_MODULE_SIZE.  */
+#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE	0x8
+
+/* The offset of GRUB_KERNEL_IMAGE_SIZE.  */
+#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE	0xc
+
+/* The offset of GRUB_COMPRESSED_SIZE.  */
+#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE	0x10
+
+/* The offset of GRUB_PREFIX.  */
+#define GRUB_KERNEL_MACHINE_PREFIX		0x14
+
+/* End of the data section. */
+#define GRUB_KERNEL_MACHINE_DATA_END		0x114
+
+#ifndef ASM_FILE
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+/* The size of kernel image.  */
+extern grub_int32_t grub_kernel_image_size;
+
+/* The total size of module images following the kernel.  */
+extern grub_int32_t grub_total_module_size;
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+void EXPORT_FUNC (grub_reboot) (void);
+void EXPORT_FUNC (grub_halt) (void);
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/include/grub/sparc64/ieee1275/loader.h b/include/grub/sparc64/ieee1275/loader.h
new file mode 100644
index 0000000..12bb2a6
--- /dev/null
+++ b/include/grub/sparc64/ieee1275/loader.h
@@ -0,0 +1,27 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER	1
+
+/* The symbol shared between the normal mode and rescue mode
+   loader.  */
+void grub_rescue_cmd_linux (int argc, char *argv[]);
+void grub_rescue_cmd_initrd (int argc, char *argv[]);
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/include/grub/sparc64/ieee1275/machine.h b/include/grub/sparc64/ieee1275/machine.h
new file mode 100644
index 0000000..66da1d9
--- /dev/null
+++ b/include/grub/sparc64/ieee1275/machine.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_MACHINE_HEADER
+#define GRUB_MACHINE_MACHINE_HEADER	1
+
+#define GRUB_MACHINE_IEEE1275	1
+
+#endif /* ! GRUB_MACHINE_MACHINE_HEADER */
diff --git a/include/grub/sparc64/ieee1275/memory.h b/include/grub/sparc64/ieee1275/memory.h
new file mode 100644
index 0000000..25e3100
--- /dev/null
+++ b/include/grub/sparc64/ieee1275/memory.h
@@ -0,0 +1,26 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_MACHINE_HEADER
+#define GRUB_MEMORY_MACHINE_HEADER	1
+
+#include <grub/ieee1275/ieee1275.h>
+
+#define GRUB_MACHINE_MEMORY_AVAILABLE		1
+
+#endif
diff --git a/include/grub/sparc64/ieee1275/time.h b/include/grub/sparc64/ieee1275/time.h
new file mode 100644
index 0000000..3f8ad26
--- /dev/null
+++ b/include/grub/sparc64/ieee1275/time.h
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_MACHINE_TIME_HEADER
+#define KERNEL_MACHINE_TIME_HEADER	1
+
+#include <grub/symbol.h>
+
+#define GRUB_TICKS_PER_SECOND	1000
+
+/* Return the real time in ticks.  */
+grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
+
+#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/include/grub/sparc64/kernel.h b/include/grub/sparc64/kernel.h
new file mode 100644
index 0000000..9f404b0
--- /dev/null
+++ b/include/grub/sparc64/kernel.h
@@ -0,0 +1,30 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_CPU_HEADER
+#define GRUB_KERNEL_CPU_HEADER	1
+
+#define GRUB_MOD_ALIGN 0x2000
+
+/* Non-zero value is only needed for PowerMacs.  */
+#define GRUB_MOD_GAP 0x0
+
+#define GRUB_KERNEL_CPU_PREFIX	0x2
+#define GRUB_KERNEL_CPU_DATA_END	0x42
+
+#endif
diff --git a/include/grub/sparc64/libgcc.h b/include/grub/sparc64/libgcc.h
new file mode 100644
index 0000000..008821d
--- /dev/null
+++ b/include/grub/sparc64/libgcc.h
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#ifdef HAVE___BSWAPSI2
+typedef int SItype __attribute__ ((mode (SI)));
+SItype EXPORT_FUNC (__bswapsi2) (SItype);
+#endif
+
+#ifdef HAVE___BSWAPDI2
+typedef int DItype __attribute__ ((mode (DI)));
+DItype EXPORT_FUNC (__bswapdi2) (DItype);
+#endif
diff --git a/include/grub/sparc64/setjmp.h b/include/grub/sparc64/setjmp.h
new file mode 100644
index 0000000..6096bae
--- /dev/null
+++ b/include/grub/sparc64/setjmp.h
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER	1
+
+#include <grub/types.h>
+
+typedef grub_uint64_t grub_jmp_buf[3];
+
+int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/include/grub/sparc64/time.h b/include/grub/sparc64/time.h
new file mode 100644
index 0000000..5db7ff4
--- /dev/null
+++ b/include/grub/sparc64/time.h
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER	1
+
+static __inline void
+grub_cpu_idle (void)
+{
+  /* FIXME: not implemented */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/include/grub/sparc64/types.h b/include/grub/sparc64/types.h
new file mode 100644
index 0000000..b9b0cf9
--- /dev/null
+++ b/include/grub/sparc64/types.h
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER	1
+
+/* The size of void *.  */
+#define GRUB_TARGET_SIZEOF_VOID_P	8
+
+/* The size of long.  */
+#define GRUB_TARGET_SIZEOF_LONG		8
+
+/* sparc64 is big-endian.  */
+#define GRUB_TARGET_WORDS_BIGENDIAN	1
+
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/include/grub/symbol.h b/include/grub/symbol.h
new file mode 100644
index 0000000..6bf512d
--- /dev/null
+++ b/include/grub/symbol.h
@@ -0,0 +1,52 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SYMBOL_HEADER
+#define GRUB_SYMBOL_HEADER	1
+
+#include <config.h>
+
+/* Apple assembler requires local labels to start with a capital L */
+#define LOCAL(sym)	L_ ## sym
+
+/* Add an underscore to a C symbol in assembler code if needed. */
+#ifdef HAVE_ASM_USCORE
+# define EXT_C(sym)	_ ## sym
+#else
+# define EXT_C(sym)	sym
+#endif
+
+#if defined (APPLE_CC)
+#define FUNCTION(x)	.globl EXT_C(x) ; EXT_C(x):
+#define VARIABLE(x)	.globl EXT_C(x) ; EXT_C(x):
+#elif ! defined (__CYGWIN__) && ! defined (__MINGW32__)
+#define FUNCTION(x)	.globl EXT_C(x) ; .type EXT_C(x), "function" ; EXT_C(x):
+#define VARIABLE(x)	.globl EXT_C(x) ; .type EXT_C(x), "object" ; EXT_C(x):
+#else
+/* .type not supported for non-ELF targets.  XXX: Check this in configure? */
+#define FUNCTION(x)	.globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 32; .endef; EXT_C(x):
+#define VARIABLE(x)	.globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 0; .endef; EXT_C(x):
+#endif
+
+/* Mark an exported symbol.  */
+#ifndef GRUB_SYMBOL_GENERATOR
+# define EXPORT_FUNC(x)	x
+# define EXPORT_VAR(x)	x
+#endif /* ! GRUB_SYMBOL_GENERATOR */
+
+#endif /* ! GRUB_SYMBOL_HEADER */
diff --git a/include/grub/term.h b/include/grub/term.h
new file mode 100644
index 0000000..316d753
--- /dev/null
+++ b/include/grub/term.h
@@ -0,0 +1,307 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TERM_HEADER
+#define GRUB_TERM_HEADER	1
+
+/* Internal codes used by GRUB to represent terminal input.  */
+#define GRUB_TERM_LEFT		2
+#define GRUB_TERM_RIGHT		6
+#define GRUB_TERM_UP		16
+#define GRUB_TERM_DOWN		14
+#define GRUB_TERM_HOME		1
+#define GRUB_TERM_END		5
+#define GRUB_TERM_DC		4
+#define GRUB_TERM_PPAGE		7
+#define GRUB_TERM_NPAGE		3
+#define GRUB_TERM_ESC		'\e'
+#define GRUB_TERM_TAB		'\t'
+#define GRUB_TERM_BACKSPACE	8
+
+#ifndef ASM_FILE
+
+#include <grub/err.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/handler.h>
+
+/* These are used to represent the various color states we use.  */
+typedef enum
+  {
+    /* The color used to display all text that does not use the
+       user defined colors below.  */
+    GRUB_TERM_COLOR_STANDARD,
+    /* The user defined colors for normal text.  */
+    GRUB_TERM_COLOR_NORMAL,
+    /* The user defined colors for highlighted text.  */
+    GRUB_TERM_COLOR_HIGHLIGHT
+  }
+grub_term_color_state;
+
+/* Flags for representing the capabilities of a terminal.  */
+/* Some notes about the flags:
+   - These flags are used by higher-level functions but not terminals
+   themselves.
+   - If a terminal is dumb, you may assume that only putchar, getkey and
+   checkkey are called.
+   - Some fancy features (setcolorstate, setcolor and setcursor) can be set
+   to NULL.  */
+
+/* Set when input characters shouldn't be echoed back.  */
+#define GRUB_TERM_NO_ECHO	(1 << 0)
+/* Set when the editing feature should be disabled.  */
+#define GRUB_TERM_NO_EDIT	(1 << 1)
+/* Set when the terminal cannot do fancy things.  */
+#define GRUB_TERM_DUMB		(1 << 2)
+/* Set when the terminal needs to be initialized.  */
+#define GRUB_TERM_NEED_INIT	(1 << 16)
+
+
+/* Bitmasks for modifier keys returned by grub_getkeystatus.  */
+#define GRUB_TERM_STATUS_SHIFT	(1 << 0)
+#define GRUB_TERM_STATUS_CTRL	(1 << 1)
+#define GRUB_TERM_STATUS_ALT	(1 << 2)
+
+
+/* Unicode characters for fancy graphics.  */
+#define GRUB_TERM_DISP_LEFT	0x2190
+#define GRUB_TERM_DISP_UP	0x2191
+#define GRUB_TERM_DISP_RIGHT	0x2192
+#define GRUB_TERM_DISP_DOWN	0x2193
+#define GRUB_TERM_DISP_HLINE	0x2501
+#define GRUB_TERM_DISP_VLINE	0x2503
+#define GRUB_TERM_DISP_UL	0x250F
+#define GRUB_TERM_DISP_UR	0x2513
+#define GRUB_TERM_DISP_LL	0x2517
+#define GRUB_TERM_DISP_LR	0x251B
+
+
+/* Menu-related geometrical constants.  */
+
+/* FIXME: Ugly way to get them form terminal.  */
+#define GRUB_TERM_WIDTH         ((grub_getwh()&0xFF00)>>8)
+#define GRUB_TERM_HEIGHT        (grub_getwh()&0xFF)
+
+/* The number of lines of "GRUB version..." at the top.  */
+#define GRUB_TERM_INFO_HEIGHT	1
+
+/* The number of columns/lines between messages/borders/etc.  */
+#define GRUB_TERM_MARGIN	1
+
+/* The number of columns of scroll information.  */
+#define GRUB_TERM_SCROLL_WIDTH	1
+
+/* The Y position of the top border.  */
+#define GRUB_TERM_TOP_BORDER_Y	(GRUB_TERM_MARGIN + GRUB_TERM_INFO_HEIGHT \
+                                 + GRUB_TERM_MARGIN)
+
+/* The X position of the left border.  */
+#define GRUB_TERM_LEFT_BORDER_X	GRUB_TERM_MARGIN
+
+/* The width of the border.  */
+#define GRUB_TERM_BORDER_WIDTH	(GRUB_TERM_WIDTH \
+                                 - GRUB_TERM_MARGIN * 3 \
+				 - GRUB_TERM_SCROLL_WIDTH)
+
+/* The number of lines of messages at the bottom.  */
+#define GRUB_TERM_MESSAGE_HEIGHT	8
+
+/* The height of the border.  */
+#define GRUB_TERM_BORDER_HEIGHT	(GRUB_TERM_HEIGHT \
+                                 - GRUB_TERM_TOP_BORDER_Y \
+                                 - GRUB_TERM_MESSAGE_HEIGHT)
+
+/* The number of entries shown at a time.  */
+#define GRUB_TERM_NUM_ENTRIES	(GRUB_TERM_BORDER_HEIGHT - 2)
+
+/* The Y position of the first entry.  */
+#define GRUB_TERM_FIRST_ENTRY_Y	(GRUB_TERM_TOP_BORDER_Y + 1)
+
+/* The max column number of an entry. The last "-1" is for a
+   continuation marker.  */
+#define GRUB_TERM_ENTRY_WIDTH	(GRUB_TERM_BORDER_WIDTH - 2 \
+                                 - GRUB_TERM_MARGIN * 2 - 1)
+
+/* The standard X position of the cursor.  */
+#define GRUB_TERM_CURSOR_X	(GRUB_TERM_LEFT_BORDER_X \
+                                 + GRUB_TERM_BORDER_WIDTH \
+                                 - GRUB_TERM_MARGIN \
+                                 - 1)
+
+
+struct grub_term_input
+{
+  /* The next terminal.  */
+  struct grub_term_input *next;
+
+  /* The terminal name.  */
+  const char *name;
+
+  /* Initialize the terminal.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the terminal.  */
+  grub_err_t (*fini) (void);
+
+  /* Check if any input character is available.  */
+  int (*checkkey) (void);
+
+  /* Get a character.  */
+  int (*getkey) (void);
+
+  /* Get keyboard modifier status.  */
+  int (*getkeystatus) (void);
+};
+typedef struct grub_term_input *grub_term_input_t;
+
+struct grub_term_output
+{
+  /* The next terminal.  */
+  struct grub_term_output *next;
+
+  /* The terminal name.  */
+  const char *name;
+
+  /* Initialize the terminal.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the terminal.  */
+  grub_err_t (*fini) (void);
+
+  /* Put a character. C is encoded in Unicode.  */
+  void (*putchar) (grub_uint32_t c);
+
+  /* Get the number of columns occupied by a given character C. C is
+     encoded in Unicode.  */
+  grub_ssize_t (*getcharwidth) (grub_uint32_t c);
+
+  /* Get the screen size. The return value is ((Width << 8) | Height).  */
+  grub_uint16_t (*getwh) (void);
+
+  /* Get the cursor position. The return value is ((X << 8) | Y).  */
+  grub_uint16_t (*getxy) (void);
+
+  /* Go to the position (X, Y).  */
+  void (*gotoxy) (grub_uint8_t x, grub_uint8_t y);
+
+  /* Clear the screen.  */
+  void (*cls) (void);
+
+  /* Set the current color to be used */
+  void (*setcolorstate) (grub_term_color_state state);
+
+  /* Set the normal color and the highlight color. The format of each
+     color is VGA's.  */
+  void (*setcolor) (grub_uint8_t normal_color, grub_uint8_t highlight_color);
+
+  /* Get the normal color and the highlight color. The format of each
+     color is VGA's.  */
+  void (*getcolor) (grub_uint8_t *normal_color, grub_uint8_t *highlight_color);
+
+  /* Turn on/off the cursor.  */
+  void (*setcursor) (int on);
+
+  /* Update the screen.  */
+  void (*refresh) (void);
+
+  /* The feature flags defined above.  */
+  grub_uint32_t flags;
+};
+typedef struct grub_term_output *grub_term_output_t;
+
+extern struct grub_handler_class EXPORT_VAR(grub_term_input_class);
+extern struct grub_handler_class EXPORT_VAR(grub_term_output_class);
+
+static inline void
+grub_term_register_input (const char *name __attribute__ ((unused)),
+			  grub_term_input_t term)
+{
+  grub_handler_register (&grub_term_input_class, GRUB_AS_HANDLER (term));
+}
+
+static inline void
+grub_term_register_output (const char *name __attribute__ ((unused)),
+			   grub_term_output_t term)
+{
+  grub_handler_register (&grub_term_output_class, GRUB_AS_HANDLER (term));
+}
+
+static inline void
+grub_term_unregister_input (grub_term_input_t term)
+{
+  grub_handler_unregister (&grub_term_input_class, GRUB_AS_HANDLER (term));
+}
+
+static inline void
+grub_term_unregister_output (grub_term_output_t term)
+{
+  grub_handler_unregister (&grub_term_output_class, GRUB_AS_HANDLER (term));
+}
+
+static inline grub_err_t
+grub_term_set_current_input (grub_term_input_t term)
+{
+  return grub_handler_set_current (&grub_term_input_class,
+				   GRUB_AS_HANDLER (term));
+}
+
+static inline grub_err_t
+grub_term_set_current_output (grub_term_output_t term)
+{
+  return grub_handler_set_current (&grub_term_output_class,
+				   GRUB_AS_HANDLER (term));
+}
+
+static inline grub_term_input_t
+grub_term_get_current_input (void)
+{
+  return (grub_term_input_t) grub_term_input_class.cur_handler;
+}
+
+static inline grub_term_output_t
+grub_term_get_current_output (void)
+{
+  return (grub_term_output_t) grub_term_output_class.cur_handler;
+}
+
+void EXPORT_FUNC(grub_putchar) (int c);
+void EXPORT_FUNC(grub_putcode) (grub_uint32_t code);
+grub_ssize_t EXPORT_FUNC(grub_getcharwidth) (grub_uint32_t code);
+int EXPORT_FUNC(grub_getkey) (void);
+int EXPORT_FUNC(grub_checkkey) (void);
+int EXPORT_FUNC(grub_getkeystatus) (void);
+grub_uint16_t EXPORT_FUNC(grub_getwh) (void);
+grub_uint16_t EXPORT_FUNC(grub_getxy) (void);
+void EXPORT_FUNC(grub_gotoxy) (grub_uint8_t x, grub_uint8_t y);
+void EXPORT_FUNC(grub_cls) (void);
+void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state);
+void EXPORT_FUNC(grub_setcolor) (grub_uint8_t normal_color,
+				 grub_uint8_t highlight_color);
+void EXPORT_FUNC(grub_getcolor) (grub_uint8_t *normal_color,
+				 grub_uint8_t *highlight_color);
+int EXPORT_FUNC(grub_setcursor) (int on);
+int EXPORT_FUNC(grub_getcursor) (void);
+void EXPORT_FUNC(grub_refresh) (void);
+void EXPORT_FUNC(grub_set_more) (int onoff);
+
+/* For convenience.  */
+#define GRUB_TERM_ASCII_CHAR(c)	((c) & 0xff)
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! GRUB_TERM_HEADER */
diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h
new file mode 100644
index 0000000..1ea741e
--- /dev/null
+++ b/include/grub/terminfo.h
@@ -0,0 +1,35 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TERMINFO_HEADER
+#define GRUB_TERMINFO_HEADER	1
+
+#include <grub/err.h>
+#include <grub/types.h>
+
+char *grub_terminfo_get_current (void);
+grub_err_t grub_terminfo_set_current (const char *);
+
+void grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y);
+void grub_terminfo_cls (void);
+void grub_terminfo_reverse_video_on (void);
+void grub_terminfo_reverse_video_off (void);
+void grub_terminfo_cursor_on (void);
+void grub_terminfo_cursor_off (void);
+
+#endif /* ! GRUB_TERMINFO_HEADER */
diff --git a/include/grub/time.h b/include/grub/time.h
new file mode 100644
index 0000000..4dcd843
--- /dev/null
+++ b/include/grub/time.h
@@ -0,0 +1,40 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007, 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_TIME_HEADER
+#define KERNEL_TIME_HEADER	1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/machine/time.h>
+#include <grub/cpu/time.h>
+
+void EXPORT_FUNC(grub_millisleep) (grub_uint32_t ms);
+grub_uint64_t EXPORT_FUNC(grub_get_time_ms) (void);
+
+grub_uint64_t grub_rtc_get_time_ms (void);
+
+static __inline void
+grub_sleep (grub_uint32_t s)
+{
+  grub_millisleep (1000 * s);
+}
+
+void grub_install_get_time_ms (grub_uint64_t (*get_time_ms_func) (void));
+
+#endif /* ! KERNEL_TIME_HEADER */
diff --git a/include/grub/tparm.h b/include/grub/tparm.h
new file mode 100644
index 0000000..642a22f
--- /dev/null
+++ b/include/grub/tparm.h
@@ -0,0 +1,26 @@
+/* tparm.h - parameter formatting of terminfo */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TPARM_HEADER
+#define GRUB_TPARM_HEADER	1
+
+/* Function prototypes.  */
+char *grub_terminfo_tparm (const char *string, ...);
+
+#endif /* ! GRUB_TPARM_HEADER */
diff --git a/include/grub/types.h b/include/grub/types.h
new file mode 100644
index 0000000..8e2ad15
--- /dev/null
+++ b/include/grub/types.h
@@ -0,0 +1,228 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_HEADER
+#define GRUB_TYPES_HEADER	1
+
+#include <config.h>
+#include <grub/cpu/types.h>
+
+#define UNUSED __attribute__ ((unused))
+
+#ifdef GRUB_UTIL
+# define GRUB_CPU_SIZEOF_VOID_P	SIZEOF_VOID_P
+# define GRUB_CPU_SIZEOF_LONG	SIZEOF_LONG
+# ifdef WORDS_BIGENDIAN
+#  define GRUB_CPU_WORDS_BIGENDIAN	1
+# else
+#  undef GRUB_CPU_WORDS_BIGENDIAN
+# endif
+#else /* ! GRUB_UTIL */
+# define GRUB_CPU_SIZEOF_VOID_P	GRUB_TARGET_SIZEOF_VOID_P
+# define GRUB_CPU_SIZEOF_LONG	GRUB_TARGET_SIZEOF_LONG
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+#  define GRUB_CPU_WORDS_BIGENDIAN	1
+# else
+#  undef GRUB_CPU_WORDS_BIGENDIAN
+# endif
+#endif /* ! GRUB_UTIL */
+
+#if GRUB_CPU_SIZEOF_VOID_P != GRUB_CPU_SIZEOF_LONG
+# error "This architecture is not supported because sizeof(void *) != sizeof(long)"
+#endif
+
+#if GRUB_CPU_SIZEOF_VOID_P != 4 && GRUB_CPU_SIZEOF_VOID_P != 8
+# error "This architecture is not supported because sizeof(void *) != 4 and sizeof(void *) != 8"
+#endif
+
+#ifndef GRUB_TARGET_WORDSIZE
+# if GRUB_TARGET_SIZEOF_VOID_P == 4
+#  define GRUB_TARGET_WORDSIZE 32
+# elif GRUB_TARGET_SIZEOF_VOID_P == 8
+#  define GRUB_TARGET_WORDSIZE 64
+# endif
+#endif
+
+/* Define various wide integers.  */
+typedef signed char		grub_int8_t;
+typedef short			grub_int16_t;
+typedef int			grub_int32_t;
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+typedef long			grub_int64_t;
+#else
+typedef long long		grub_int64_t;
+#endif
+
+typedef unsigned char		grub_uint8_t;
+typedef unsigned short		grub_uint16_t;
+typedef unsigned		grub_uint32_t;
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+typedef unsigned long		grub_uint64_t;
+#else
+typedef unsigned long long	grub_uint64_t;
+#endif
+
+/* Misc types.  */
+#if GRUB_TARGET_SIZEOF_VOID_P == 8
+typedef grub_uint64_t	grub_target_addr_t;
+typedef grub_uint64_t	grub_target_off_t;
+typedef grub_uint64_t	grub_target_size_t;
+typedef grub_int64_t	grub_target_ssize_t;
+#else
+typedef grub_uint32_t	grub_target_addr_t;
+typedef grub_uint32_t	grub_target_off_t;
+typedef grub_uint32_t	grub_target_size_t;
+typedef grub_int32_t	grub_target_ssize_t;
+#endif
+
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+typedef grub_uint64_t	grub_addr_t;
+typedef grub_uint64_t	grub_size_t;
+typedef grub_int64_t	grub_ssize_t;
+#else
+typedef grub_uint32_t	grub_addr_t;
+typedef grub_uint32_t	grub_size_t;
+typedef grub_int32_t	grub_ssize_t;
+#endif
+
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+# define GRUB_ULONG_MAX 18446744073709551615UL
+# define GRUB_LONG_MAX 9223372036854775807L
+# define GRUB_LONG_MIN (-9223372036854775807L - 1)
+#else
+# define GRUB_ULONG_MAX 4294967295UL
+# define GRUB_LONG_MAX 2147483647L
+# define GRUB_LONG_MIN (-2147483647L - 1)
+#endif
+
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+#define UINT_TO_PTR(x) ((void*)(grub_uint32_t)(x))
+#define PTR_TO_UINT64(x) ((grub_uint64_t)(grub_uint32_t)(x))
+#define PTR_TO_UINT32(x) ((grub_uint32_t)(x))
+#else
+#define UINT_TO_PTR(x) ((void*)(grub_uint64_t)(x))
+#define PTR_TO_UINT64(x) ((grub_uint64_t)(x))
+#define PTR_TO_UINT32(x) ((grub_uint32_t)(grub_uint64_t)(x))
+#endif
+
+/* The type for representing a file offset.  */
+typedef grub_uint64_t	grub_off_t;
+
+/* The type for representing a disk block address.  */
+typedef grub_uint64_t	grub_disk_addr_t;
+
+/* Byte-orders.  */
+#define grub_swap_bytes16(x)	\
+({ \
+   grub_uint16_t _x = (x); \
+   (grub_uint16_t) ((_x << 8) | (_x >> 8)); \
+})
+
+#if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
+static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t x)
+{
+	return __builtin_bswap32(x);
+}
+
+static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x)
+{
+	return __builtin_bswap64(x);
+}
+#else					/* not gcc 4.3 or newer */
+#define grub_swap_bytes32(x)	\
+({ \
+   grub_uint32_t _x = (x); \
+   (grub_uint32_t) ((_x << 24) \
+                    | ((_x & (grub_uint32_t) 0xFF00UL) << 8) \
+                    | ((_x & (grub_uint32_t) 0xFF0000UL) >> 8) \
+                    | (_x >> 24)); \
+})
+
+#define grub_swap_bytes64(x)	\
+({ \
+   grub_uint64_t _x = (x); \
+   (grub_uint64_t) ((_x << 56) \
+                    | ((_x & (grub_uint64_t) 0xFF00ULL) << 40) \
+                    | ((_x & (grub_uint64_t) 0xFF0000ULL) << 24) \
+                    | ((_x & (grub_uint64_t) 0xFF000000ULL) << 8) \
+                    | ((_x & (grub_uint64_t) 0xFF00000000ULL) >> 8) \
+                    | ((_x & (grub_uint64_t) 0xFF0000000000ULL) >> 24) \
+                    | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40) \
+                    | (_x >> 56)); \
+})
+#endif					/* not gcc 4.3 or newer */
+
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+# define grub_cpu_to_le16(x)	grub_swap_bytes16(x)
+# define grub_cpu_to_le32(x)	grub_swap_bytes32(x)
+# define grub_cpu_to_le64(x)	grub_swap_bytes64(x)
+# define grub_le_to_cpu16(x)	grub_swap_bytes16(x)
+# define grub_le_to_cpu32(x)	grub_swap_bytes32(x)
+# define grub_le_to_cpu64(x)	grub_swap_bytes64(x)
+# define grub_cpu_to_be16(x)	((grub_uint16_t) (x))
+# define grub_cpu_to_be32(x)	((grub_uint32_t) (x))
+# define grub_cpu_to_be64(x)	((grub_uint64_t) (x))
+# define grub_be_to_cpu16(x)	((grub_uint16_t) (x))
+# define grub_be_to_cpu32(x)	((grub_uint32_t) (x))
+# define grub_be_to_cpu64(x)	((grub_uint64_t) (x))
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+#  define grub_target_to_host16(x)	((grub_uint16_t) (x))
+#  define grub_target_to_host32(x)	((grub_uint32_t) (x))
+#  define grub_target_to_host64(x)	((grub_uint64_t) (x))
+#  define grub_host_to_target16(x)	((grub_uint16_t) (x))
+#  define grub_host_to_target32(x)	((grub_uint32_t) (x))
+#  define grub_host_to_target64(x)	((grub_uint64_t) (x))
+# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */
+#  define grub_target_to_host16(x)	grub_swap_bytes16(x)
+#  define grub_target_to_host32(x)	grub_swap_bytes32(x)
+#  define grub_target_to_host64(x)	grub_swap_bytes64(x)
+#  define grub_host_to_target16(x)	grub_swap_bytes16(x)
+#  define grub_host_to_target32(x)	grub_swap_bytes32(x)
+#  define grub_host_to_target64(x)	grub_swap_bytes64(x)
+# endif
+#else /* ! WORDS_BIGENDIAN */
+# define grub_cpu_to_le16(x)	((grub_uint16_t) (x))
+# define grub_cpu_to_le32(x)	((grub_uint32_t) (x))
+# define grub_cpu_to_le64(x)	((grub_uint64_t) (x))
+# define grub_le_to_cpu16(x)	((grub_uint16_t) (x))
+# define grub_le_to_cpu32(x)	((grub_uint32_t) (x))
+# define grub_le_to_cpu64(x)	((grub_uint64_t) (x))
+# define grub_cpu_to_be16(x)	grub_swap_bytes16(x)
+# define grub_cpu_to_be32(x)	grub_swap_bytes32(x)
+# define grub_cpu_to_be64(x)	grub_swap_bytes64(x)
+# define grub_be_to_cpu16(x)	grub_swap_bytes16(x)
+# define grub_be_to_cpu32(x)	grub_swap_bytes32(x)
+# define grub_be_to_cpu64(x)	grub_swap_bytes64(x)
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+#  define grub_target_to_host16(x)	grub_swap_bytes16(x)
+#  define grub_target_to_host32(x)	grub_swap_bytes32(x)
+#  define grub_target_to_host64(x)	grub_swap_bytes64(x)
+#  define grub_host_to_target16(x)	grub_swap_bytes16(x)
+#  define grub_host_to_target32(x)	grub_swap_bytes32(x)
+#  define grub_host_to_target64(x)	grub_swap_bytes64(x)
+# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */
+#  define grub_target_to_host16(x)	((grub_uint16_t) (x))
+#  define grub_target_to_host32(x)	((grub_uint32_t) (x))
+#  define grub_target_to_host64(x)	((grub_uint64_t) (x))
+#  define grub_host_to_target16(x)	((grub_uint16_t) (x))
+#  define grub_host_to_target32(x)	((grub_uint32_t) (x))
+#  define grub_host_to_target64(x)	((grub_uint64_t) (x))
+# endif
+#endif /* ! WORDS_BIGENDIAN */
+
+#endif /* ! GRUB_TYPES_HEADER */
diff --git a/include/grub/usb.h b/include/grub/usb.h
new file mode 100644
index 0000000..8dd3b6e
--- /dev/null
+++ b/include/grub/usb.h
@@ -0,0 +1,207 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef	GRUB_USB_H
+#define	GRUB_USB_H	1
+
+#include <grub/usbdesc.h>
+#include <grub/usbtrans.h>
+
+typedef struct grub_usb_device *grub_usb_device_t;
+typedef struct grub_usb_controller *grub_usb_controller_t;
+typedef struct grub_usb_controller_dev *grub_usb_controller_dev_t;
+
+typedef enum
+  {
+    GRUB_USB_ERR_NONE,
+    GRUB_USB_ERR_INTERNAL,
+    GRUB_USB_ERR_STALL,
+    GRUB_USB_ERR_DATA,
+    GRUB_USB_ERR_NAK,
+    GRUB_USB_ERR_BABBLE,
+    GRUB_USB_ERR_TIMEOUT,
+    GRUB_USB_ERR_BITSTUFF
+  } grub_usb_err_t;
+
+typedef enum
+  {
+    GRUB_USB_SPEED_NONE,
+    GRUB_USB_SPEED_LOW,
+    GRUB_USB_SPEED_FULL,
+    GRUB_USB_SPEED_HIGH
+  } grub_usb_speed_t;
+
+/* Call HOOK with each device, until HOOK returns non-zero.  */
+int grub_usb_iterate (int (*hook) (grub_usb_device_t dev));
+
+grub_usb_err_t grub_usb_device_initialize (grub_usb_device_t dev);
+
+grub_usb_err_t grub_usb_get_descriptor (grub_usb_device_t dev,
+					grub_uint8_t type, grub_uint8_t index,
+					grub_size_t size, char *data);
+
+struct grub_usb_desc_endp *
+grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr);
+
+grub_usb_err_t grub_usb_clear_halt (grub_usb_device_t dev, int endpoint);
+
+
+grub_usb_err_t grub_usb_set_configuration (grub_usb_device_t dev,
+					   int configuration);
+
+grub_usb_err_t grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index,
+				    int langid, char **string);
+
+void grub_usb_controller_dev_register (grub_usb_controller_dev_t usb);
+
+void grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb);
+
+int grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev));
+
+
+grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype,
+				     grub_uint8_t request, grub_uint16_t value,
+				     grub_uint16_t index, grub_size_t size,
+				     char *data);
+
+grub_usb_err_t
+grub_usb_bulk_read (grub_usb_device_t dev,
+		    int endpoint, grub_size_t size, char *data);
+grub_usb_err_t
+grub_usb_bulk_write (grub_usb_device_t dev,
+		     int endpoint, grub_size_t size, char *data);
+
+grub_usb_err_t
+grub_usb_root_hub (grub_usb_controller_t controller);
+
+
+/* XXX: All handled by libusb for now.  */
+struct grub_usb_controller_dev
+{
+  /* The device name.  */
+  const char *name;
+
+  int (*iterate) (int (*hook) (grub_usb_controller_t dev));
+
+  grub_usb_err_t (*transfer) (grub_usb_controller_t dev,
+			      grub_usb_transfer_t transfer);
+
+  int (*hubports) (grub_usb_controller_t dev);
+
+  grub_err_t (*portstatus) (grub_usb_controller_t dev, unsigned int port,
+			    unsigned int enable);
+
+  grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port);
+
+  /* The next host controller.  */
+  struct grub_usb_controller_dev *next;
+};
+
+struct grub_usb_controller
+{
+  /* The underlying USB Host Controller device.  */
+  grub_usb_controller_dev_t dev;
+
+  /* Data used by the USB Host Controller Driver.  */
+  void *data;
+};
+
+
+struct grub_usb_interface
+{
+  struct grub_usb_desc_if *descif;
+
+  struct grub_usb_desc_endp *descendp;
+};
+
+struct grub_usb_configuration
+{
+  /* Configuration descriptors .  */
+  struct grub_usb_desc_config *descconf;
+
+  /* Interfaces associated to this configuration.  */
+  struct grub_usb_interface interf[32];
+};
+
+struct grub_usb_device
+{
+  /* The device descriptor of this device.  */
+  struct grub_usb_desc_device descdev;
+
+  /* The controller the device is connected to.  */
+  struct grub_usb_controller controller;
+
+  /* Device configurations (after opening the device).  */
+  struct grub_usb_configuration config[8];
+
+  /* Device address.  */
+  int addr;
+
+  /* Device speed.  */
+  grub_usb_speed_t speed;
+
+  /* All descriptors are read if this is set to 1.  */
+  int initialized;
+
+  /* Data toggle values (used for bulk transfers only).  */
+  int toggle[16];
+
+  /* Device-specific data.  */
+  void *data;
+};
+
+
+
+typedef enum
+  {
+    GRUB_USB_CLASS_NOTHERE,
+    GRUB_USB_CLASS_AUDIO,
+    GRUB_USB_CLASS_COMMUNICATION,
+    GRUB_USB_CLASS_HID,
+    GRUB_USB_CLASS_XXX,
+    GRUB_USB_CLASS_PHYSICAL,
+    GRUB_USB_CLASS_IMAGE,
+    GRUB_USB_CLASS_PRINTER,
+    GRUB_USB_CLASS_MASS_STORAGE,
+    GRUB_USB_CLASS_HUB,
+    GRUB_USB_CLASS_DATA_INTERFACE,
+    GRUB_USB_CLASS_SMART_CARD,
+    GRUB_USB_CLASS_CONTENT_SECURITY,
+    GRUB_USB_CLASS_VIDEO
+  } grub_usb_classes_t;
+
+typedef enum
+  {
+    GRUB_USBMS_SUBCLASS_BULK = 0x06
+  } grub_usbms_subclass_t;
+
+typedef enum
+  {
+    GRUB_USBMS_PROTOCOL_BULK = 0x50
+  } grub_usbms_protocol_t;
+
+static inline struct grub_usb_desc_if *
+grub_usb_get_config_interface (struct grub_usb_desc_config *config)
+{
+  struct grub_usb_desc_if *interf;
+
+  interf = (struct grub_usb_desc_if *) (sizeof (*config) + (char *) config);
+  return interf;
+}
+
+#endif /* GRUB_USB_H */
diff --git a/include/grub/usbdesc.h b/include/grub/usbdesc.h
new file mode 100644
index 0000000..2f711d7
--- /dev/null
+++ b/include/grub/usbdesc.h
@@ -0,0 +1,119 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef	GRUB_USBDESC_H
+#define	GRUB_USBDESC_H	1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+typedef enum {
+  GRUB_USB_DESCRIPTOR_DEVICE = 1,
+  GRUB_USB_DESCRIPTOR_CONFIG,
+  GRUB_USB_DESCRIPTOR_STRING,
+  GRUB_USB_DESCRIPTOR_INTERFACE,
+  GRUB_USB_DESCRIPTOR_ENDPOINT,
+  GRUB_USB_DESCRIPTOR_HUB = 0x29
+} grub_usb_descriptor_t;
+
+struct grub_usb_desc_device
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint16_t usbrel;
+  grub_uint8_t class;
+  grub_uint8_t subclass;
+  grub_uint8_t protocol;
+  grub_uint8_t maxsize0;
+  grub_uint16_t vendorid;
+  grub_uint16_t prodid;
+  grub_uint16_t devrel;
+  grub_uint8_t strvendor;
+  grub_uint8_t strprod;
+  grub_uint8_t strserial;
+  grub_uint8_t configcnt;
+} __attribute__ ((packed));
+
+struct grub_usb_desc_config
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint16_t totallen;
+  grub_uint8_t numif;
+  grub_uint8_t config;
+  grub_uint8_t strconfig;
+  grub_uint8_t attrib;
+  grub_uint8_t maxpower;
+} __attribute__ ((packed));
+
+#if 0
+struct grub_usb_desc_if_association
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint8_t firstif;
+  grub_uint8_t ifcnt;
+  grub_uint8_t class;
+  grub_uint8_t subclass;
+  grub_uint8_t protocol;
+  grub_uint8_t function;
+} __attribute__ ((packed));
+#endif
+
+struct grub_usb_desc_if
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint8_t ifnum;
+  grub_uint8_t altsetting;
+  grub_uint8_t endpointcnt;
+  grub_uint8_t class;
+  grub_uint8_t subclass;
+  grub_uint8_t protocol;
+  grub_uint8_t strif;
+} __attribute__ ((packed));
+
+struct grub_usb_desc_endp
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint8_t endp_addr;
+  grub_uint8_t attrib;
+  grub_uint16_t maxpacket;
+  grub_uint8_t interval;
+} __attribute__ ((packed));
+
+struct grub_usb_desc_str
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint16_t str[0];
+} __attribute__ ((packed));
+
+struct grub_usb_usb_hubdesc
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint8_t portcnt;
+  grub_uint16_t characteristics;
+  grub_uint8_t pwdgood;
+  grub_uint8_t current;
+  /* Removable and power control bits follow.  */
+} __attribute__ ((packed));
+
+#endif /* GRUB_USBDESC_H */
diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h
new file mode 100644
index 0000000..7e4a9d7
--- /dev/null
+++ b/include/grub/usbtrans.h
@@ -0,0 +1,107 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef	GRUB_USBTRANS_H
+#define	GRUB_USBTRANS_H	1
+
+typedef enum
+  {
+    GRUB_USB_TRANSFER_TYPE_IN,
+    GRUB_USB_TRANSFER_TYPE_OUT,
+    GRUB_USB_TRANSFER_TYPE_SETUP
+  } grub_transfer_type_t;
+
+typedef enum
+  {
+    GRUB_USB_TRANSACTION_TYPE_CONTROL,
+    GRUB_USB_TRANSACTION_TYPE_BULK
+  } grub_transaction_type_t;
+
+struct grub_usb_transaction
+{
+  int size;
+  int toggle;
+  grub_transfer_type_t pid;
+  char *data;
+};
+typedef struct grub_usb_transaction *grub_usb_transaction_t;
+
+struct grub_usb_transfer
+{
+  int devaddr;
+
+  int endpoint;
+
+  int size;
+
+  int transcnt;
+
+  int max;
+
+  grub_transaction_type_t type;
+
+  struct grub_usb_device *dev;
+
+  struct grub_usb_transaction *transactions;
+};
+typedef struct grub_usb_transfer *grub_usb_transfer_t;
+
+
+#define GRUB_USB_REQTYPE_IN		(1 << 7)
+#define GRUB_USB_REQTYPE_OUT		(0 << 7)
+#define GRUB_USB_REQTYPE_STANDARD	(0 << 5)
+#define GRUB_USB_REQTYPE_CLASS		(1 << 5)
+#define GRUB_USB_REQTYPE_VENDOR		(2 << 5)
+#define GRUB_USB_REQTYPE_TARGET_DEV	(0 << 0)
+#define GRUB_USB_REQTYPE_TARGET_INTERF	(1 << 0)
+#define GRUB_USB_REQTYPE_TARGET_ENDP	(2 << 0)
+#define GRUB_USB_REQTYPE_TARGET_OTHER	(3 << 0)
+
+#define GRUB_USB_REQ_GET_STATUS		0x00
+#define GRUB_USB_REQ_CLEAR_FEATURE	0x01
+#define GRUB_USB_REQ_SET_FEATURE	0x03
+#define GRUB_USB_REQ_SET_ADDRESS	0x05
+#define GRUB_USB_REQ_GET_DESCRIPTOR	0x06
+#define GRUB_USB_REQ_SET_DESCRIPTOR	0x07
+#define GRUB_USB_REQ_GET_CONFIGURATION	0x08
+#define GRUB_USB_REQ_SET_CONFIGURATION	0x09
+#define GRUB_USB_REQ_GET_INTERFACE	0x0A
+#define GRUB_USB_REQ_SET_INTERFACE	0x0B
+#define GRUB_USB_REQ_SYNC_FRAME		0x0C
+
+#define GRUB_USB_REQ_HUB_GET_PORT_STATUS 0x00
+
+#define GRUB_USB_FEATURE_ENDP_HALT	0x01
+#define GRUB_USB_FEATURE_DEV_REMOTE_WU	0x02
+#define GRUB_USB_FEATURE_TEST_MODE	0x04
+
+#define GRUB_USB_HUB_STATUS_CONNECTED	(1 << 0)
+#define GRUB_USB_HUB_STATUS_LOWSPEED	(1 << 9)
+#define GRUB_USB_HUB_STATUS_HIGHSPEED	(1 << 10)
+
+struct grub_usb_packet_setup
+{
+  grub_uint8_t reqtype;
+  grub_uint8_t request;
+  grub_uint16_t value;
+  grub_uint16_t index;
+  grub_uint16_t length;
+} __attribute__((packed));
+
+
+#endif /* GRUB_USBTRANS_H */
diff --git a/include/grub/util/console.h b/include/grub/util/console.h
new file mode 100644
index 0000000..1e55682
--- /dev/null
+++ b/include/grub/util/console.h
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CONSOLE_UTIL_HEADER
+#define GRUB_CONSOLE_UTIL_HEADER	1
+
+/* Initialize the console system.  */
+void grub_console_init (void);
+
+/* Finish the console system.  */
+void grub_console_fini (void);
+
+#endif /* ! GRUB_CONSOLE_UTIL_HEADER */
diff --git a/include/grub/util/deviceiter.h b/include/grub/util/deviceiter.h
new file mode 100644
index 0000000..a8af03c
--- /dev/null
+++ b/include/grub/util/deviceiter.h
@@ -0,0 +1,11 @@
+#ifndef GRUB_DEVICEITER_MACHINE_UTIL_HEADER
+#define GRUB_DEVICEITER_MACHINE_UTIL_HEADER	1
+
+#include <config.h>
+
+void grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
+				int floppy_disks);
+void grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy,
+				     int *num_fd, int *num_hd);
+
+#endif /* ! GRUB_DEVICEITER_MACHINE_UTIL_HEADER */
diff --git a/include/grub/util/getroot.h b/include/grub/util/getroot.h
new file mode 100644
index 0000000..f9f7f9b
--- /dev/null
+++ b/include/grub/util/getroot.h
@@ -0,0 +1,35 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2007, 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_UTIL_GETROOT_HEADER
+#define GRUB_UTIL_GETROOT_HEADER	1
+
+enum grub_dev_abstraction_types {
+  GRUB_DEV_ABSTRACTION_NONE,
+  GRUB_DEV_ABSTRACTION_LVM,
+  GRUB_DEV_ABSTRACTION_RAID,
+};
+
+char *grub_guess_root_device (const char *dir);
+char *grub_get_prefix (const char *dir);
+int grub_util_get_dev_abstraction (const char *os_dev);
+char *grub_util_get_grub_dev (const char *os_dev);
+const char *grub_util_check_block_device (const char *blk_dev);
+const char *grub_util_check_char_device (const char *blk_dev);
+
+#endif /* ! GRUB_UTIL_GETROOT_HEADER */
diff --git a/include/grub/util/hostdisk.h b/include/grub/util/hostdisk.h
new file mode 100644
index 0000000..21efb0d
--- /dev/null
+++ b/include/grub/util/hostdisk.h
@@ -0,0 +1,27 @@
+/* biosdisk.h - emulate biosdisk */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BIOSDISK_MACHINE_UTIL_HEADER
+#define GRUB_BIOSDISK_MACHINE_UTIL_HEADER	1
+
+void grub_util_biosdisk_init (const char *dev_map);
+void grub_util_biosdisk_fini (void);
+char *grub_util_biosdisk_get_grub_dev (const char *os_dev);
+
+#endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
diff --git a/include/grub/util/lvm.h b/include/grub/util/lvm.h
new file mode 100644
index 0000000..7a4c76c
--- /dev/null
+++ b/include/grub/util/lvm.h
@@ -0,0 +1,27 @@
+/* lvm.h - LVM support for GRUB utils.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LVM_UTIL_HEADER
+#define GRUB_LVM_UTIL_HEADER	1
+
+#ifdef __linux__
+int grub_util_lvm_isvolume (char *name);
+#endif
+
+#endif /* ! GRUB_RAID_UTIL_HEADER */
diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h
new file mode 100644
index 0000000..6a93ab0
--- /dev/null
+++ b/include/grub/util/misc.h
@@ -0,0 +1,79 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_UTIL_MISC_HEADER
+#define GRUB_UTIL_MISC_HEADER	1
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include <unistd.h>
+
+#include <config.h>
+#include <grub/types.h>
+
+#ifdef __NetBSD__
+/* NetBSD uses /boot for its boot block.  */
+# define DEFAULT_DIRECTORY	"/grub"
+#else
+# define DEFAULT_DIRECTORY	"/boot/grub"
+#endif
+
+#define DEFAULT_DEVICE_MAP	DEFAULT_DIRECTORY "/device.map"
+
+extern char *progname;
+extern int verbosity;
+
+void grub_util_warn (const char *fmt, ...);
+void grub_util_info (const char *fmt, ...);
+void grub_util_error (const char *fmt, ...) __attribute__ ((noreturn));
+
+void *xmalloc (size_t size);
+void *xrealloc (void *ptr, size_t size);
+char *xstrdup (const char *str);
+
+char *grub_util_get_path (const char *dir, const char *file);
+size_t grub_util_get_fp_size (FILE *fp);
+size_t grub_util_get_image_size (const char *path);
+void grub_util_read_at (void *img, size_t len, off_t offset, FILE *fp);
+char *grub_util_read_image (const char *path);
+void grub_util_load_image (const char *path, char *buf);
+void grub_util_write_image (const char *img, size_t size, FILE *out);
+void grub_util_write_image_at (const void *img, size_t size, off_t offset,
+			       FILE *out);
+
+#ifndef  HAVE_ASPRINTF
+
+int asprintf (char **buf, const char *fmt, ...);
+
+#endif
+
+#ifdef __MINGW32__
+
+#define fseeko fseeko64
+#define ftello ftello64
+
+void sync (void);
+int fsync (int fno);
+void sleep(int s);
+
+grub_int64_t grub_util_get_disk_size (char *name);
+
+#endif
+
+#endif /* ! GRUB_UTIL_MISC_HEADER */
diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h
new file mode 100644
index 0000000..78f24d7
--- /dev/null
+++ b/include/grub/util/ofpath.h
@@ -0,0 +1,6 @@
+#ifndef GRUB_OFPATH_MACHINE_UTIL_HEADER
+#define GRUB_OFPATH_MACHINE_UTIL_HEADER	1
+
+char *grub_util_devname_to_ofpath (char *devname);
+
+#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
diff --git a/include/grub/util/raid.h b/include/grub/util/raid.h
new file mode 100644
index 0000000..67020bb
--- /dev/null
+++ b/include/grub/util/raid.h
@@ -0,0 +1,27 @@
+/* raid.h - RAID support for GRUB utils.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_RAID_UTIL_HEADER
+#define GRUB_RAID_UTIL_HEADER	1
+
+#ifdef __linux__
+char** grub_util_raid_getmembers (char *name);
+#endif
+
+#endif /* ! GRUB_RAID_UTIL_HEADER */
diff --git a/include/grub/util/resolve.h b/include/grub/util/resolve.h
new file mode 100644
index 0000000..f42df32
--- /dev/null
+++ b/include/grub/util/resolve.h
@@ -0,0 +1,35 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_UTIL_RESOLVE_HEADER
+#define GRUB_UTIL_RESOLVE_HEADER	1
+
+struct grub_util_path_list
+{
+  const char *name;
+  struct grub_util_path_list *next;
+};
+
+/* Resolve the dependencies of the modules MODULES using the information
+   in the file DEP_LIST_FILE. The directory PREFIX is used to find files.  */
+struct grub_util_path_list *
+grub_util_resolve_dependencies (const char *prefix,
+				const char *dep_list_file,
+				char *modules[]);
+
+#endif /* ! GRUB_UTIL_RESOLVE_HEADER */
diff --git a/include/grub/video.h b/include/grub/video.h
new file mode 100644
index 0000000..4145db4
--- /dev/null
+++ b/include/grub/video.h
@@ -0,0 +1,313 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VIDEO_HEADER
+#define GRUB_VIDEO_HEADER	1
+
+#include <grub/err.h>
+#include <grub/types.h>
+
+/* Video color in hardware dependent format.  Users should not assume any
+   specific coding format.  */
+typedef grub_uint32_t grub_video_color_t;
+
+/* This structure is driver specific and should not be accessed directly by
+   outside code.  */
+struct grub_video_render_target;
+
+/* Forward declarations for used data structures.  */
+struct grub_video_bitmap;
+
+/* Defines used to describe video mode or rendering target.  */
+#define GRUB_VIDEO_MODE_TYPE_PURE_TEXT		0x00000040
+#define GRUB_VIDEO_MODE_TYPE_ALPHA		0x00000020
+#define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED	0x00000010
+#define GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP	0x00000004
+#define GRUB_VIDEO_MODE_TYPE_INDEX_COLOR	0x00000002
+#define GRUB_VIDEO_MODE_TYPE_RGB		0x00000001
+
+/* Defines used to mask flags.  */
+#define GRUB_VIDEO_MODE_TYPE_COLOR_MASK		0x0000000F
+
+/* Defines used to specify requested bit depth.  */
+#define GRUB_VIDEO_MODE_TYPE_DEPTH_MASK		0x0000ff00
+#define GRUB_VIDEO_MODE_TYPE_DEPTH_POS		8
+
+#define GRUB_VIDEO_RENDER_TARGET_DISPLAY \
+  ((struct grub_video_render_target *) 0)
+
+/* Defined blitting formats.  */
+enum grub_video_blit_format
+  {
+    /* Generic RGBA, use fields & masks.  */
+    GRUB_VIDEO_BLIT_FORMAT_RGBA,
+
+    /* Optimized RGBA's.  */
+    GRUB_VIDEO_BLIT_FORMAT_RGBA_8888,
+    GRUB_VIDEO_BLIT_FORMAT_BGRA_8888,
+
+    /* Generic RGB, use fields & masks.  */
+    GRUB_VIDEO_BLIT_FORMAT_RGB,
+
+    /* Optimized RGB's.  */
+    GRUB_VIDEO_BLIT_FORMAT_RGB_888,
+    GRUB_VIDEO_BLIT_FORMAT_BGR_888,
+    GRUB_VIDEO_BLIT_FORMAT_RGB_565,
+    GRUB_VIDEO_BLIT_FORMAT_BGR_565,
+
+    /* When needed, decode color or just use value as is.  */
+    GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR,
+
+    /* Two color bitmap; bits packed: rows are not padded to byte boundary.  */
+    GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED
+  };
+
+/* Define blitting operators.  */
+enum grub_video_blit_operators
+  {
+    /* Replace target bitmap data with source.  */
+    GRUB_VIDEO_BLIT_REPLACE,
+    /* Blend target and source based on source's alpha value.  */
+    GRUB_VIDEO_BLIT_BLEND
+  };
+
+struct grub_video_mode_info
+{
+  /* Width of the screen.  */
+  unsigned int width;
+
+  /* Height of the screen.  */
+  unsigned int height;
+
+  /* Mode type bitmask.  Contains information like is it Index color or
+     RGB mode.  */
+  unsigned int mode_type;
+
+  /* Bits per pixel.  */
+  unsigned int bpp;
+
+  /* Bytes per pixel.  */
+  unsigned int bytes_per_pixel;
+
+  /* Pitch of one scanline.  How many bytes there are for scanline.  */
+  unsigned int pitch;
+
+  /* In index color mode, number of colors.  In RGB mode this is 256.  */
+  unsigned int number_of_colors;
+
+  /* Optimization hint how binary data is coded.  */
+  enum grub_video_blit_format blit_format;
+
+  /* How many bits are reserved for red color.  */
+  unsigned int red_mask_size;
+
+  /* What is location of red color bits.  In Index Color mode, this is 0.  */
+  unsigned int red_field_pos;
+
+  /* How many bits are reserved for green color.  */
+  unsigned int green_mask_size;
+
+  /* What is location of green color bits.  In Index Color mode, this is 0.  */
+  unsigned int green_field_pos;
+
+  /* How many bits are reserved for blue color.  */
+  unsigned int blue_mask_size;
+
+  /* What is location of blue color bits.  In Index Color mode, this is 0.  */
+  unsigned int blue_field_pos;
+
+  /* How many bits are reserved in color.  */
+  unsigned int reserved_mask_size;
+
+  /* What is location of reserved color bits.  In Index Color mode,
+     this is 0.  */
+  unsigned int reserved_field_pos;
+
+  /* For 1-bit bitmaps, the background color.  Used for bits = 0.  */
+  grub_uint8_t bg_red;
+  grub_uint8_t bg_green;
+  grub_uint8_t bg_blue;
+  grub_uint8_t bg_alpha;
+
+  /* For 1-bit bitmaps, the foreground color.  Used for bits = 1.  */
+  grub_uint8_t fg_red;
+  grub_uint8_t fg_green;
+  grub_uint8_t fg_blue;
+  grub_uint8_t fg_alpha;
+};
+
+struct grub_video_palette_data
+{
+  grub_uint8_t r; /* Red color value (0-255).  */
+  grub_uint8_t g; /* Green color value (0-255).  */
+  grub_uint8_t b; /* Blue color value (0-255).  */
+  grub_uint8_t a; /* Reserved bits value (0-255).  */
+};
+
+struct grub_video_adapter
+{
+  /* The video adapter name.  */
+  const char *name;
+
+  /* Initialize the video adapter.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the video adapter.  */
+  grub_err_t (*fini) (void);
+
+  grub_err_t (*setup) (unsigned int width,  unsigned int height,
+                       unsigned int mode_type);
+
+  grub_err_t (*get_info) (struct grub_video_mode_info *mode_info);
+
+  grub_err_t (*get_info_and_fini) (struct grub_video_mode_info *mode_info,
+				   void **framebuffer);
+
+  grub_err_t (*set_palette) (unsigned int start, unsigned int count,
+                             struct grub_video_palette_data *palette_data);
+
+  grub_err_t (*get_palette) (unsigned int start, unsigned int count,
+                             struct grub_video_palette_data *palette_data);
+
+  grub_err_t (*set_viewport) (unsigned int x, unsigned int y,
+                              unsigned int width, unsigned int height);
+
+  grub_err_t (*get_viewport) (unsigned int *x, unsigned int *y,
+                              unsigned int *width, unsigned int *height);
+
+  grub_video_color_t (*map_color) (grub_uint32_t color_name);
+
+  grub_video_color_t (*map_rgb) (grub_uint8_t red, grub_uint8_t green,
+                                 grub_uint8_t blue);
+
+  grub_video_color_t (*map_rgba) (grub_uint8_t red, grub_uint8_t green,
+                                  grub_uint8_t blue, grub_uint8_t alpha);
+
+  grub_err_t (*unmap_color) (grub_video_color_t color,
+                             grub_uint8_t *red, grub_uint8_t *green,
+                             grub_uint8_t *blue, grub_uint8_t *alpha);
+
+  grub_err_t (*fill_rect) (grub_video_color_t color, int x, int y,
+                           unsigned int width, unsigned int height);
+
+  grub_err_t (*blit_bitmap) (struct grub_video_bitmap *bitmap,
+                             enum grub_video_blit_operators oper,
+                             int x, int y, int offset_x, int offset_y,
+                             unsigned int width, unsigned int height);
+
+  grub_err_t (*blit_render_target) (struct grub_video_render_target *source,
+                                    enum grub_video_blit_operators oper,
+                                    int x, int y, int offset_x, int offset_y,
+                                    unsigned int width, unsigned int height);
+
+  grub_err_t (*scroll) (grub_video_color_t color, int dx, int dy);
+
+  grub_err_t (*swap_buffers) (void);
+
+  grub_err_t (*create_render_target) (struct grub_video_render_target **result,
+                                      unsigned int width, unsigned int height,
+                                      unsigned int mode_type);
+
+  grub_err_t (*delete_render_target) (struct grub_video_render_target *target);
+
+  grub_err_t (*set_active_render_target) (struct grub_video_render_target *target);
+
+  grub_err_t (*get_active_render_target) (struct grub_video_render_target **target);
+
+  /* The next video adapter.  */
+  struct grub_video_adapter *next;
+};
+typedef struct grub_video_adapter *grub_video_adapter_t;
+
+void grub_video_register (grub_video_adapter_t adapter);
+void grub_video_unregister (grub_video_adapter_t adapter);
+void grub_video_iterate (int (*hook) (grub_video_adapter_t adapter));
+
+grub_err_t grub_video_restore (void);
+
+grub_err_t grub_video_get_info (struct grub_video_mode_info *mode_info);
+
+/* Framebuffer address may change as a part of normal operation
+   (e.g. double buffering). That's why you need to stop video subsystem to be
+   sure that framebuffer address doesn't change. To ensure this abstraction
+   grub_video_get_info_and_fini is the only function supplying framebuffer
+   address. */
+grub_err_t grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info,
+					 void **framebuffer);
+
+enum grub_video_blit_format grub_video_get_blit_format (struct grub_video_mode_info *mode_info);
+
+grub_err_t grub_video_set_palette (unsigned int start, unsigned int count,
+                                   struct grub_video_palette_data *palette_data);
+
+grub_err_t grub_video_get_palette (unsigned int start, unsigned int count,
+                                   struct grub_video_palette_data *palette_data);
+
+grub_err_t grub_video_set_viewport (unsigned int x, unsigned int y,
+                                    unsigned int width, unsigned int height);
+
+grub_err_t grub_video_get_viewport (unsigned int *x, unsigned int *y,
+                                    unsigned int *width, unsigned int *height);
+
+grub_video_color_t grub_video_map_color (grub_uint32_t color_name);
+
+grub_video_color_t grub_video_map_rgb (grub_uint8_t red, grub_uint8_t green,
+                                       grub_uint8_t blue);
+
+grub_video_color_t grub_video_map_rgba (grub_uint8_t red, grub_uint8_t green,
+                                        grub_uint8_t blue, grub_uint8_t alpha);
+
+grub_err_t grub_video_unmap_color (grub_video_color_t color,
+                                   grub_uint8_t *red, grub_uint8_t *green,
+                                   grub_uint8_t *blue, grub_uint8_t *alpha);
+
+grub_err_t grub_video_fill_rect (grub_video_color_t color, int x, int y,
+                                 unsigned int width, unsigned int height);
+
+grub_err_t grub_video_blit_bitmap (struct grub_video_bitmap *bitmap,
+                                   enum grub_video_blit_operators oper,
+                                   int x, int y, int offset_x, int offset_y,
+                                   unsigned int width, unsigned int height);
+
+grub_err_t grub_video_blit_render_target (struct grub_video_render_target *source,
+                                          enum grub_video_blit_operators oper,
+                                          int x, int y,
+                                          int offset_x, int offset_y,
+                                          unsigned int width,
+                                          unsigned int height);
+
+grub_err_t grub_video_scroll (grub_video_color_t color, int dx, int dy);
+
+grub_err_t grub_video_swap_buffers (void);
+
+grub_err_t grub_video_create_render_target (struct grub_video_render_target **result,
+                                            unsigned int width,
+                                            unsigned int height,
+                                            unsigned int mode_type);
+
+grub_err_t grub_video_delete_render_target (struct grub_video_render_target *target);
+
+grub_err_t grub_video_set_active_render_target (struct grub_video_render_target *target);
+
+grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target);
+
+grub_err_t grub_video_set_mode (const char *modestring,
+				int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p,
+							      struct grub_video_mode_info *mode_info));
+
+#endif /* ! GRUB_VIDEO_HEADER */
diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h
new file mode 100644
index 0000000..17debd6
--- /dev/null
+++ b/include/grub/video_fb.h
@@ -0,0 +1,118 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VIDEO_FB_HEADER
+#define GRUB_VIDEO_FB_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/video.h>
+
+/* FB module internal prototype (should not be used from elsewhere).  */
+
+struct grub_video_fbblit_info;
+
+struct grub_video_fbrender_target;
+
+#define GRUB_VIDEO_FBSTD_NUMCOLORS 16
+extern struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS];
+
+grub_err_t
+grub_video_fb_init (void);
+
+grub_err_t
+grub_video_fb_fini (void);
+
+grub_err_t
+grub_video_fb_get_info (struct grub_video_mode_info *mode_info);
+
+grub_err_t
+grub_video_fb_get_palette (unsigned int start, unsigned int count,
+			   struct grub_video_palette_data *palette_data);
+grub_err_t
+grub_video_fb_set_palette (unsigned int start, unsigned int count,
+			   struct grub_video_palette_data *palette_data);
+grub_err_t
+grub_video_fb_set_viewport (unsigned int x, unsigned int y,
+			    unsigned int width, unsigned int height);
+grub_err_t
+grub_video_fb_get_viewport (unsigned int *x, unsigned int *y,
+			    unsigned int *width, unsigned int *height);
+
+grub_video_color_t
+grub_video_fb_map_color (grub_uint32_t color_name);
+
+grub_video_color_t
+grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green,
+		       grub_uint8_t blue);
+
+grub_video_color_t
+grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
+			grub_uint8_t blue, grub_uint8_t alpha);
+
+grub_err_t
+grub_video_fb_unmap_color (grub_video_color_t color,
+			   grub_uint8_t *red, grub_uint8_t *green,
+			   grub_uint8_t *blue, grub_uint8_t *alpha);
+
+void
+grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
+			       grub_video_color_t color,
+			       grub_uint8_t *red, grub_uint8_t *green,
+			       grub_uint8_t *blue, grub_uint8_t *alpha);
+
+grub_err_t
+grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
+			 unsigned int width, unsigned int height);
+
+grub_err_t
+grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap,
+			   enum grub_video_blit_operators oper, int x, int y,
+			   int offset_x, int offset_y,
+			   unsigned int width, unsigned int height);
+
+grub_err_t
+grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source,
+                                   enum grub_video_blit_operators oper,
+                                   int x, int y, int offset_x, int offset_y,
+				  unsigned int width, unsigned int height);
+
+grub_err_t
+grub_video_fb_scroll (grub_video_color_t color, int dx, int dy);
+
+grub_err_t
+grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
+				    unsigned int width, unsigned int height,
+				    unsigned int mode_type __attribute__ ((unused)));
+
+grub_err_t
+grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_target **result,
+						 const struct grub_video_mode_info *mode_info,
+						 void *ptr);
+
+grub_err_t
+grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target);
+
+grub_err_t
+grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target);
+
+grub_err_t
+grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target);
+
+#endif /* ! GRUB_VIDEO_FB_HEADER */
diff --git a/include/grub/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h
new file mode 100644
index 0000000..c0549f4
--- /dev/null
+++ b/include/grub/x86_64/efi/kernel.h
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_KERNEL_HEADER
+#define GRUB_MACHINE_KERNEL_HEADER   1
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+/* The offset of GRUB_PREFIX.  */
+#define GRUB_KERNEL_MACHINE_PREFIX		0x8
+
+/* End of the data section. */
+#define GRUB_KERNEL_MACHINE_DATA_END		0x50
+
+#endif /* ! GRUB_MACHINE_KERNEL_HEADER */
+
diff --git a/include/grub/x86_64/efi/loader.h b/include/grub/x86_64/efi/loader.h
new file mode 100644
index 0000000..7c302e8
--- /dev/null
+++ b/include/grub/x86_64/efi/loader.h
@@ -0,0 +1,26 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER	1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/include/grub/x86_64/efi/machine.h b/include/grub/x86_64/efi/machine.h
new file mode 100644
index 0000000..1600768
--- /dev/null
+++ b/include/grub/x86_64/efi/machine.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_MACHINE_HEADER
+#define GRUB_MACHINE_MACHINE_HEADER	1
+
+#define GRUB_MACHINE_EFI	1
+
+#endif /* ! GRUB_MACHINE_MACHINE_HEADER */
diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h
new file mode 100644
index 0000000..c9a61bb
--- /dev/null
+++ b/include/grub/x86_64/efi/memory.h
@@ -0,0 +1 @@
+#include <grub/efi/memory.h>
diff --git a/include/grub/x86_64/efi/time.h b/include/grub/x86_64/efi/time.h
new file mode 100644
index 0000000..7a9241f
--- /dev/null
+++ b/include/grub/x86_64/efi/time.h
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_TIME_HEADER
+#define GRUB_MACHINE_TIME_HEADER	1
+
+#include <grub/efi/time.h>
+
+#endif /* ! GRUB_MACHINE_TIME_HEADER */
diff --git a/include/grub/x86_64/kernel.h b/include/grub/x86_64/kernel.h
new file mode 100644
index 0000000..25ac57e
--- /dev/null
+++ b/include/grub/x86_64/kernel.h
@@ -0,0 +1 @@
+#include <grub/i386/kernel.h>
diff --git a/include/grub/x86_64/linux.h b/include/grub/x86_64/linux.h
new file mode 100644
index 0000000..19ea936
--- /dev/null
+++ b/include/grub/x86_64/linux.h
@@ -0,0 +1,19 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/i386/linux.h>
diff --git a/include/grub/x86_64/macho.h b/include/grub/x86_64/macho.h
new file mode 100644
index 0000000..165b8da
--- /dev/null
+++ b/include/grub/x86_64/macho.h
@@ -0,0 +1 @@
+#include <grub/i386/macho.h>
diff --git a/include/grub/x86_64/pci.h b/include/grub/x86_64/pci.h
new file mode 100644
index 0000000..91a9924
--- /dev/null
+++ b/include/grub/x86_64/pci.h
@@ -0,0 +1,19 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/i386/pci.h>
diff --git a/include/grub/x86_64/setjmp.h b/include/grub/x86_64/setjmp.h
new file mode 100644
index 0000000..4ad968e
--- /dev/null
+++ b/include/grub/x86_64/setjmp.h
@@ -0,0 +1,27 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER	1
+
+typedef unsigned long grub_jmp_buf[8];
+
+int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/include/grub/x86_64/time.h b/include/grub/x86_64/time.h
new file mode 100644
index 0000000..842882c
--- /dev/null
+++ b/include/grub/x86_64/time.h
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER	1
+
+static __inline void
+grub_cpu_idle (void)
+{
+  /* FIXME: this can't work until we handle interrupts.  */
+/*  __asm__ __volatile__ ("hlt"); */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/include/grub/x86_64/types.h b/include/grub/x86_64/types.h
new file mode 100644
index 0000000..bdee5a1
--- /dev/null
+++ b/include/grub/x86_64/types.h
@@ -0,0 +1,31 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER	1
+
+/* The size of void *.  */
+#define GRUB_TARGET_SIZEOF_VOID_P	8
+
+/* The size of long.  */
+#define GRUB_TARGET_SIZEOF_LONG		8
+
+/* x86_64 is little-endian.  */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/include/grub/x86_64/xnu.h b/include/grub/x86_64/xnu.h
new file mode 100644
index 0000000..ae61733
--- /dev/null
+++ b/include/grub/x86_64/xnu.h
@@ -0,0 +1 @@
+#include <grub/i386/xnu.h>
diff --git a/include/grub/xnu.h b/include/grub/xnu.h
new file mode 100644
index 0000000..c3902e6
--- /dev/null
+++ b/include/grub/xnu.h
@@ -0,0 +1,107 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_XNU_H
+#define GRUB_XNU_H 1
+
+#include <grub/bitmap.h>
+
+/* Header of a hibernation image. */
+struct grub_xnu_hibernate_header
+{
+  /* Size of the image. Notice that file containing image is usually bigger. */
+  grub_uint64_t image_size;
+  grub_uint8_t unknown1[8];
+  /* Where to copy launchcode? */
+  grub_uint32_t launchcode_target_page;
+  /* How many pages of launchcode? */
+  grub_uint32_t launchcode_numpages;
+  /* Where to jump? */
+  grub_uint32_t entry_point;
+  /* %esp at start. */
+  grub_uint32_t stack;
+  grub_uint8_t unknown2[44];
+#define GRUB_XNU_HIBERNATE_MAGIC 0x73696d65
+  grub_uint32_t magic;
+  grub_uint8_t unknown3[28];
+  /* This value is non-zero if page is encrypted. Unsupported. */
+  grub_uint64_t encoffset;
+  grub_uint8_t unknown4[360];
+  /* The size of additional header used to locate image without parsing FS.
+     Used only to skip it.
+   */
+  grub_uint32_t extmapsize;
+} __attribute__ ((packed));
+
+/* In-memory structure for temporary keeping device tree. */
+struct grub_xnu_devtree_key
+{
+  char *name;
+  int datasize; /* -1 for not leaves. */
+  union
+  {
+    struct grub_xnu_devtree_key *first_child;
+    void *data;
+  };
+  struct grub_xnu_devtree_key *next;
+};
+
+/* A structure used in memory-map values. */
+struct
+grub_xnu_extdesc
+{
+  grub_uint32_t addr;
+  grub_uint32_t size;
+} __attribute__ ((packed));
+
+/* Header describing extension in the memory. */
+struct grub_xnu_extheader
+{
+  grub_uint32_t infoplistaddr;
+  grub_uint32_t infoplistsize;
+  grub_uint32_t binaryaddr;
+  grub_uint32_t binarysize;
+} __attribute__ ((packed));
+
+struct grub_xnu_devtree_key *grub_xnu_create_key (struct grub_xnu_devtree_key **parent,
+						  char *name);
+
+extern struct grub_xnu_devtree_key *grub_xnu_devtree_root;
+
+void grub_xnu_free_devtree (struct grub_xnu_devtree_key *cur);
+
+grub_err_t grub_xnu_writetree_toheap (void **start, grub_size_t *size);
+struct grub_xnu_devtree_key *grub_xnu_create_value (struct grub_xnu_devtree_key **parent,
+						    char *name);
+
+void grub_xnu_lock (void);
+void grub_xnu_unlock (void);
+grub_err_t grub_xnu_resume (char *imagename);
+struct grub_xnu_devtree_key *grub_xnu_find_key (struct grub_xnu_devtree_key *parent,
+						char *name);
+grub_err_t grub_xnu_align_heap (int align);
+grub_err_t grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired,
+					int maxrecursion);
+grub_err_t grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
+					int maxrecursion);
+void *grub_xnu_heap_malloc (int size);
+extern grub_uint32_t grub_xnu_heap_real_start;
+extern grub_size_t grub_xnu_heap_size;
+extern char *grub_xnu_heap_start;
+extern struct grub_video_bitmap *grub_xnu_bitmap;
+#endif
diff --git a/include/multiboot.h b/include/multiboot.h
new file mode 100644
index 0000000..110ad2f
--- /dev/null
+++ b/include/multiboot.h
@@ -0,0 +1,95 @@
+/* multiboot.h - multiboot header file. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MULTIBOOT_HEADER
+#define MULTIBOOT_HEADER 1
+
+/* How many bytes from the start of the file we search for the header.  */
+#define MULTIBOOT_SEARCH                 8192
+
+/* The magic field should contain this.  */
+#define MULTIBOOT_MAGIC                  0x1BADB002
+
+/* This should be in %eax.  */
+#define MULTIBOOT_MAGIC2                 0x2BADB002
+
+/* The bits in the required part of flags field we don't support.  */
+#define MULTIBOOT_UNSUPPORTED            0x0000fffc
+
+/* Alignment of multiboot modules.  */
+#define MULTIBOOT_MOD_ALIGN              0x00001000
+
+/* Alignment of the multiboot info structure.  */
+#define MULTIBOOT_INFO_ALIGN		 0x00000004
+
+/*
+ * Flags set in the 'flags' member of the multiboot header.
+ */
+
+/* Align all boot modules on i386 page (4KB) boundaries.  */
+#define MULTIBOOT_PAGE_ALIGN		0x00000001
+
+/* Must pass memory information to OS.  */
+#define MULTIBOOT_MEMORY_INFO		0x00000002
+
+/* Must pass video information to OS.  */
+#define MULTIBOOT_VIDEO_MODE		0x00000004
+
+/* This flag indicates the use of the address fields in the header.  */
+#define MULTIBOOT_AOUT_KLUDGE		0x00010000
+
+/*
+ *  Flags to be set in the 'flags' member of the multiboot info structure.
+ */
+
+/* is there basic lower/upper memory information? */
+#define MULTIBOOT_INFO_MEMORY		0x00000001
+/* is there a boot device set? */
+#define MULTIBOOT_INFO_BOOTDEV		0x00000002
+/* is the command-line defined? */
+#define MULTIBOOT_INFO_CMDLINE		0x00000004
+/* are there modules to do something with? */
+#define MULTIBOOT_INFO_MODS		0x00000008
+
+/* These next two are mutually exclusive */
+
+/* is there a symbol table loaded? */
+#define MULTIBOOT_INFO_AOUT_SYMS		0x00000010
+/* is there an ELF section header table? */
+#define MULTIBOOT_INFO_ELF_SHDR		0x00000020
+
+/* is there a full memory map? */
+#define MULTIBOOT_INFO_MEM_MAP		0x00000040
+
+/* Is there drive info?  */
+#define MULTIBOOT_INFO_DRIVE_INFO		0x00000080
+
+/* Is there a config table?  */
+#define MULTIBOOT_INFO_CONFIG_TABLE	0x00000100
+
+/* Is there a boot loader name?  */
+#define MULTIBOOT_INFO_BOOT_LOADER_NAME	0x00000200
+
+/* Is there a APM table?  */
+#define MULTIBOOT_INFO_APM_TABLE		0x00000400
+
+/* Is there video information?  */
+#define MULTIBOOT_INFO_VIDEO_INFO		0x00000800
+
+#endif /* ! MULTIBOOT_HEADER */
diff --git a/include/multiboot2.h b/include/multiboot2.h
new file mode 100644
index 0000000..c87c3d1
--- /dev/null
+++ b/include/multiboot2.h
@@ -0,0 +1,110 @@
+/* multiboot2.h - multiboot 2 header file. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MULTIBOOT2_HEADER
+#define MULTIBOOT2_HEADER 1
+
+/* How many bytes from the start of the file we search for the header.  */
+#define MULTIBOOT2_HEADER_SEARCH           8192
+
+/* The magic field should contain this.  */
+#define MULTIBOOT2_HEADER_MAGIC            0xe85250d6
+
+/* Passed from the bootloader to the kernel.  */
+#define MULTIBOOT2_BOOTLOADER_MAGIC        0x36d76289
+
+/* Alignment of multiboot modules.  */
+#define MULTIBOOT2_MOD_ALIGN               0x00001000
+
+#ifndef ASM_FILE
+
+#ifndef __WORDSIZE
+#include <stdint.h>
+#endif
+
+/* XXX not portable? */
+#if __WORDSIZE == 64
+typedef uint64_t multiboot_word;
+#else
+typedef uint32_t multiboot_word;
+#endif
+
+struct multiboot_header
+{
+  uint32_t magic;
+  uint32_t flags;
+};
+
+struct multiboot_tag_header
+{
+  uint32_t key;
+  uint32_t len;
+};
+
+#define MULTIBOOT2_TAG_RESERVED1 0
+#define MULTIBOOT2_TAG_RESERVED2 (~0)
+
+#define MULTIBOOT2_TAG_START     1
+struct multiboot_tag_start
+{
+  struct multiboot_tag_header header;
+  multiboot_word size; /* Total size of all multiboot tags. */
+};
+
+#define MULTIBOOT2_TAG_NAME      2
+struct multiboot_tag_name
+{
+  struct multiboot_tag_header header;
+  char name[1];
+};
+
+#define MULTIBOOT2_TAG_MODULE    3
+struct multiboot_tag_module
+{
+  struct multiboot_tag_header header;
+  multiboot_word addr;
+  multiboot_word size;
+  char type[36];
+  char cmdline[1];
+};
+
+#define MULTIBOOT2_TAG_MEMORY    4
+struct multiboot_tag_memory
+{
+  struct multiboot_tag_header header;
+  multiboot_word addr;
+  multiboot_word size;
+  multiboot_word type;
+};
+
+#define MULTIBOOT2_TAG_UNUSED    5
+struct multiboot_tag_unused
+{
+  struct multiboot_tag_header header;
+};
+
+#define MULTIBOOT2_TAG_END       0xffff
+struct multiboot_tag_end
+{
+  struct multiboot_tag_header header;
+};
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! MULTIBOOT2_HEADER */
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..a5897de
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,519 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2006-12-25.00
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dst_arg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writeable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	-*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test -z "$d" && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/io/bufio.c b/io/bufio.c
new file mode 100644
index 0000000..92f2927
--- /dev/null
+++ b/io/bufio.c
@@ -0,0 +1,205 @@
+/* bufio.c - buffered io access */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/fs.h>
+#include <grub/bufio.h>
+
+#define GRUB_BUFIO_DEF_SIZE	8192
+#define GRUB_BUFIO_MAX_SIZE	1048576
+
+struct grub_bufio
+{
+  grub_file_t file;
+  grub_size_t block_size;
+  grub_size_t buffer_len;
+  char buffer[0];
+};
+typedef struct grub_bufio *grub_bufio_t;
+
+static struct grub_fs grub_bufio_fs;
+
+grub_file_t
+grub_bufio_open (grub_file_t io, int size)
+{
+  grub_file_t file;
+  grub_bufio_t bufio = 0;
+
+  file = (grub_file_t) grub_malloc (sizeof (*file));
+  if (! file)
+    return 0;
+
+  if (size == 0)
+    size = GRUB_BUFIO_DEF_SIZE;
+  else if (size > GRUB_BUFIO_MAX_SIZE)
+    size = GRUB_BUFIO_MAX_SIZE;
+
+  if ((size < 0) || ((unsigned) size > io->size))
+    size = ((io->size > GRUB_BUFIO_MAX_SIZE) ? GRUB_BUFIO_MAX_SIZE :
+            io->size);
+
+  bufio = grub_malloc (sizeof (struct grub_bufio) + size);
+  if (! bufio)
+    {
+      grub_free (file);
+      return 0;
+    }
+
+  bufio->file = io;
+  bufio->block_size = size;
+  bufio->buffer_len = 0;
+
+  file->device = io->device;
+  file->offset = 0;
+  file->size = io->size;
+  file->data = bufio;
+  file->read_hook = 0;
+  file->fs = &grub_bufio_fs;
+
+  return file;
+}
+
+grub_file_t
+grub_buffile_open (const char *name, int size)
+{
+  grub_file_t io, file;
+
+  io = grub_file_open (name);
+  if (! io)
+    return 0;
+
+  file = grub_bufio_open (io, size);
+  if (! file)
+    {
+      grub_file_close (io);
+      return 0;
+    }
+
+  return file;
+}
+
+static grub_ssize_t
+grub_bufio_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  grub_size_t res = len;
+  grub_bufio_t bufio = file->data;
+  grub_uint32_t pos;
+
+  if ((file->offset >= bufio->file->offset) &&
+      (file->offset < bufio->file->offset + bufio->buffer_len))
+    {
+      grub_size_t n;
+
+      pos = file->offset - bufio->file->offset;
+      n = bufio->buffer_len - pos;
+      if (n > len)
+        n = len;
+
+      grub_memcpy (buf, &bufio->buffer[pos], n);
+      len -= n;
+      if (! len)
+        return res;
+
+      buf += n;
+      bufio->file->offset += bufio->buffer_len;
+      pos = 0;
+    }
+  else
+    {
+      bufio->file->offset = grub_divmod64 (file->offset, bufio->block_size,
+                                           &pos);
+      bufio->file->offset *= bufio->block_size;
+    }
+
+  if (pos + len >= bufio->block_size)
+    {
+      if (pos)
+        {
+          grub_size_t n;
+
+          bufio->file->fs->read (bufio->file, bufio->buffer,
+                                 bufio->block_size);
+          if (grub_errno)
+            return -1;
+
+          n = bufio->block_size - pos;
+          grub_memcpy (buf, &bufio->buffer[pos], n);
+          len -= n;
+          buf += n;
+          bufio->file->offset += bufio->block_size;
+          pos = 0;
+        }
+
+      while (len >= bufio->block_size)
+        {
+          bufio->file->fs->read (bufio->file, buf, bufio->block_size);
+          if (grub_errno)
+            return -1;
+
+          len -= bufio->block_size;
+          buf += bufio->block_size;
+          bufio->file->offset += bufio->block_size;
+        }
+
+      if (! len)
+        {
+          bufio->buffer_len = 0;
+          return res;
+        }
+    }
+
+  bufio->buffer_len = bufio->file->size - bufio->file->offset;
+  if (bufio->buffer_len > bufio->block_size)
+    bufio->buffer_len = bufio->block_size;
+
+  bufio->file->fs->read (bufio->file, bufio->buffer, bufio->buffer_len);
+  if (grub_errno)
+    return -1;
+
+  grub_memcpy (buf, &bufio->buffer[pos], len);
+
+  return res;
+}
+
+static grub_err_t
+grub_bufio_close (grub_file_t file)
+{
+  grub_bufio_t bufio = file->data;
+
+  grub_file_close (bufio->file);
+  grub_free (bufio);
+
+  file->device = 0;
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_bufio_fs =
+  {
+    .name = "bufio",
+    .dir = 0,
+    .open = 0,
+    .read = grub_bufio_read,
+    .close = grub_bufio_close,
+    .label = 0,
+    .next = 0
+  };
diff --git a/io/gzio.c b/io/gzio.c
new file mode 100644
index 0000000..a38bfb3
--- /dev/null
+++ b/io/gzio.c
@@ -0,0 +1,1252 @@
+/* gzio.c - decompression support for gzip */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Most of this file was originally the source file "inflate.c", written
+ * by Mark Adler.  It has been very heavily modified.  In particular, the
+ * original would run through the whole file at once, and this version can
+ * be stopped and restarted on any boundary during the decompression process.
+ *
+ * The license and header comments that file are included here.
+ */
+
+/* inflate.c -- Not copyrighted 1992 by Mark Adler
+   version c10p1, 10 January 1993 */
+
+/* You can do whatever you like with this source file, though I would
+   prefer that if you modify it and redistribute it that you include
+   comments to that effect with your name and the date.  Thank you.
+ */
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/fs.h>
+#include <grub/file.h>
+#include <grub/gzio.h>
+
+/*
+ *  Window Size
+ *
+ *  This must be a power of two, and at least 32K for zip's deflate method
+ */
+
+#define WSIZE	0x8000
+
+
+#define INBUFSIZ  0x2000
+
+/* The state stored in filesystem-specific data.  */
+struct grub_gzio
+{
+  /* The underlying file object.  */
+  grub_file_t file;
+  /* The offset at which the data starts in the underlying file.  */
+  grub_off_t data_offset;
+  /* The type of current block.  */
+  int block_type;
+  /* The length of current block.  */
+  int block_len;
+  /* The flag of the last block.  */
+  int last_block;
+  /* The flag of codes.  */
+  int code_state;
+  /* The length of a copy.  */
+  unsigned inflate_n;
+  /* The index of a copy.  */
+  unsigned inflate_d;
+  /* The input buffer.  */
+  grub_uint8_t inbuf[INBUFSIZ];
+  int inbuf_d;
+  /* The bit buffer.  */
+  unsigned long bb;
+  /* The bits in the bit buffer.  */
+  unsigned bk;
+  /* The sliding window in uncompressed data.  */
+  grub_uint8_t slide[WSIZE];
+  /* Current position in the slide.  */
+  unsigned wp;
+  /* The literal/length code table.  */
+  struct huft *tl;
+  /* The distance code table.  */
+  struct huft *td;
+  /* The lookup bits for the literal/length code table. */
+  int bl;
+  /* The lookup bits for the distance code table.  */
+  int bd;
+  /* The original offset value.  */
+  grub_off_t saved_offset;
+};
+typedef struct grub_gzio *grub_gzio_t;
+
+/* Declare the filesystem structure for grub_gzio_open.  */
+static struct grub_fs grub_gzio_fs;
+
+/* Function prototypes */
+static void initialize_tables (grub_file_t file);
+
+/* Eat variable-length header fields.  */
+static int
+eat_field (grub_file_t file, int len)
+{
+  char ch = 1;
+  int not_retval = 1;
+
+  do
+    {
+      if (len >= 0)
+	{
+	  if (! (len--))
+	    break;
+	}
+      else
+	{
+	  if (! ch)
+	    break;
+	}
+    }
+  while ((not_retval = grub_file_read (file, &ch, 1)) == 1);
+
+  return ! not_retval;
+}
+
+
+/* Little-Endian defines for the 2-byte magic numbers for gzip files.  */
+#define GZIP_MAGIC	grub_le_to_cpu16 (0x8B1F)
+#define OLD_GZIP_MAGIC	grub_le_to_cpu16 (0x9E1F)
+
+/* Compression methods (see algorithm.doc) */
+#define STORED      0
+#define COMPRESSED  1
+#define PACKED      2
+#define LZHED       3
+/* methods 4 to 7 reserved */
+#define DEFLATED    8
+#define MAX_METHODS 9
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01	/* bit 0 set: file probably ascii text */
+#define CONTINUATION 0x02	/* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04	/* bit 2 set: extra field present */
+#define ORIG_NAME    0x08	/* bit 3 set: original file name present */
+#define COMMENT      0x10	/* bit 4 set: file comment present */
+#define ENCRYPTED    0x20	/* bit 5 set: file is encrypted */
+#define RESERVED     0xC0	/* bit 6,7:   reserved */
+
+#define UNSUPPORTED_FLAGS	(CONTINUATION | ENCRYPTED | RESERVED)
+
+/* inflate block codes */
+#define INFLATE_STORED	0
+#define INFLATE_FIXED	1
+#define INFLATE_DYNAMIC	2
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+static int
+test_header (grub_file_t file)
+{
+  struct {
+    grub_uint16_t magic;
+    grub_uint8_t method;
+    grub_uint8_t flags;
+    grub_uint32_t timestamp;
+    grub_uint8_t extra_flags;
+    grub_uint8_t os_type;
+  } hdr;
+  grub_uint16_t extra_len;
+  grub_uint32_t orig_len;
+  grub_gzio_t gzio = file->data;
+
+  if (grub_file_tell (gzio->file) != 0)
+    grub_file_seek (gzio->file, 0);
+
+  /*
+   *  This checks if the file is gzipped.  If a problem occurs here
+   *  (other than a real error with the disk) then we don't think it
+   *  is a compressed file, and simply mark it as such.
+   */
+  if (grub_file_read (gzio->file, &hdr, 10) != 10
+      || ((hdr.magic != GZIP_MAGIC)
+	  && (hdr.magic != OLD_GZIP_MAGIC)))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "no gzip magic found");
+      return 0;
+    }
+
+  /*
+   *  This does consistency checking on the header data.  If a
+   *  problem occurs from here on, then we have corrupt or otherwise
+   *  bad data, and the error should be reported to the user.
+   */
+  if (hdr.method != DEFLATED
+      || (hdr.flags & UNSUPPORTED_FLAGS)
+      || ((hdr.flags & EXTRA_FIELD)
+	  && (grub_file_read (gzio->file, &extra_len, 2) != 2
+	      || eat_field (gzio->file,
+			    grub_le_to_cpu16 (extra_len))))
+      || ((hdr.flags & ORIG_NAME) && eat_field (gzio->file, -1))
+      || ((hdr.flags & COMMENT) && eat_field (gzio->file, -1)))
+    {
+      grub_error (GRUB_ERR_BAD_GZIP_DATA, "unsupported gzip format");
+      return 0;
+    }
+
+  gzio->data_offset = grub_file_tell (gzio->file);
+
+  grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4);
+
+  if (grub_file_read (gzio->file, &orig_len, 4) != 4)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format");
+      return 0;
+    }
+
+  /* FIXME: this does not handle files whose original size is over 4GB.
+     But how can we know the real original size?  */
+  file->size = grub_le_to_cpu32 (orig_len);
+
+  initialize_tables (file);
+
+  return 1;
+}
+
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+   that have 16-bit pointers (e.g. PC's in the small or medium model).
+   Valid extra bits are 0..13.  e == 15 is EOB (end of block), e == 16
+   means that v is a literal, 16 < e < 32 means that v is a pointer to
+   the next table, which codes e - 16 bits, and lastly e == 99 indicates
+   an unused code.  If a code with e == 99 is looked up, this implies an
+   error in the data. */
+struct huft
+{
+  uch e;			/* number of extra bits or operation */
+  uch b;			/* number of bits in this code or subcode */
+  union
+    {
+      ush n;			/* literal, length base, or distance base */
+      struct huft *t;		/* pointer to next level of table */
+    }
+  v;
+};
+
+
+/* The inflate algorithm uses a sliding 32K byte window on the uncompressed
+   stream to find repeated byte strings.  This is implemented here as a
+   circular buffer.  The index is updated simply by incrementing and then
+   and'ing with 0x7fff (32K-1). */
+/* It is left to other modules to supply the 32K area.  It is assumed
+   to be usable as if it were declared "uch slide[32768];" or as just
+   "uch *slide;" and then malloc'ed in the latter case.  The definition
+   must be in unzip.h, included above. */
+
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+static unsigned bitorder[] =
+{				/* Order of the bit length code lengths */
+  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+static ush cplens[] =
+{				/* Copy lengths for literal codes 257..285 */
+  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+	/* note: see note #13 above about the 258 in this list. */
+static ush cplext[] =
+{				/* Extra bits for literal codes 257..285 */
+  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+  3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99};	/* 99==invalid */
+static ush cpdist[] =
+{				/* Copy offsets for distance codes 0..29 */
+  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+  8193, 12289, 16385, 24577};
+static ush cpdext[] =
+{				/* Extra bits for distance codes */
+  0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+  7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+  12, 12, 13, 13};
+
+
+/*
+   Huffman code decoding is performed using a multi-level table lookup.
+   The fastest way to decode is to simply build a lookup table whose
+   size is determined by the longest code.  However, the time it takes
+   to build this table can also be a factor if the data being decoded
+   is not very long.  The most common codes are necessarily the
+   shortest codes, so those codes dominate the decoding time, and hence
+   the speed.  The idea is you can have a shorter table that decodes the
+   shorter, more probable codes, and then point to subsidiary tables for
+   the longer codes.  The time it costs to decode the longer codes is
+   then traded against the time it takes to make longer tables.
+
+   This results of this trade are in the variables lbits and dbits
+   below.  lbits is the number of bits the first level table for literal/
+   length codes can decode in one step, and dbits is the same thing for
+   the distance codes.  Subsequent tables are also less than or equal to
+   those sizes.  These values may be adjusted either when all of the
+   codes are shorter than that, in which case the longest code length in
+   bits is used, or when the shortest code is *longer* than the requested
+   table size, in which case the length of the shortest code in bits is
+   used.
+
+   There are two different values for the two tables, since they code a
+   different number of possibilities each.  The literal/length table
+   codes 286 possible values, or in a flat code, a little over eight
+   bits.  The distance table codes 30 possible values, or a little less
+   than five bits, flat.  The optimum values for speed end up being
+   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+   The optimum values may differ though from machine to machine, and
+   possibly even between compilers.  Your mileage may vary.
+ */
+
+
+static int lbits = 9;		/* bits in base literal/length lookup table */
+static int dbits = 6;		/* bits in base distance lookup table */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
+#define BMAX 16			/* maximum bit length of any code (16 for explode) */
+#define N_MAX 288		/* maximum number of codes in any set */
+
+
+/* Macros for inflate() bit peeking and grabbing.
+   The usage is:
+
+        NEEDBITS(j)
+        x = b & mask_bits[j];
+        DUMPBITS(j)
+
+   where NEEDBITS makes sure that b has at least j bits in it, and
+   DUMPBITS removes the bits from b.  The macros use the variable k
+   for the number of bits in b.  Normally, b and k are register
+   variables for speed, and are initialized at the beginning of a
+   routine that uses these macros from a global bit buffer and count.
+
+   If we assume that EOB will be the longest code, then we will never
+   ask for bits with NEEDBITS that are beyond the end of the stream.
+   So, NEEDBITS should not read any more bytes than are needed to
+   meet the request.  Then no bytes need to be "returned" to the buffer
+   at the end of the last block.
+
+   However, this assumption is not true for fixed blocks--the EOB code
+   is 7 bits, but the other literal/length codes can be 8 or 9 bits.
+   (The EOB code is shorter than other codes because fixed blocks are
+   generally short.  So, while a block always has an EOB, many other
+   literal/length codes have a significantly lower probability of
+   showing up at all.)  However, by making the first table have a
+   lookup of seven bits, the EOB code will be found in that first
+   lookup, and so will not require that too many bits be pulled from
+   the stream.
+ */
+
+static ush mask_bits[] =
+{
+  0x0000,
+  0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+  0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+#define NEEDBITS(n) do {while(k<(n)){b|=((ulg)get_byte(file))<<k;k+=8;}} while (0)
+#define DUMPBITS(n) do {b>>=(n);k-=(n);} while (0)
+
+static int
+get_byte (grub_file_t file)
+{
+  grub_gzio_t gzio = file->data;
+
+  if (grub_file_tell (gzio->file) == (grub_off_t) gzio->data_offset
+      || gzio->inbuf_d == INBUFSIZ)
+    {
+      gzio->inbuf_d = 0;
+      grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ);
+    }
+
+  return gzio->inbuf[gzio->inbuf_d++];
+}
+
+/* more function prototypes */
+static int huft_build (unsigned *, unsigned, unsigned, ush *, ush *,
+		       struct huft **, int *);
+static int huft_free (struct huft *);
+static int inflate_codes_in_window (grub_file_t);
+
+
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.  Return zero on success, one if
+   the given code set is incomplete (the tables are still built in this
+   case), two if the input is invalid (all zero length codes or an
+   oversubscribed set of lengths), and three if not enough memory. */
+
+static int
+huft_build (unsigned *b,	/* code lengths in bits (all assumed <= BMAX) */
+	    unsigned n,		/* number of codes (assumed <= N_MAX) */
+	    unsigned s,		/* number of simple-valued codes (0..s-1) */
+	    ush * d,		/* list of base values for non-simple codes */
+	    ush * e,		/* list of extra bits for non-simple codes */
+	    struct huft **t,	/* result: starting table */
+	    int *m)		/* maximum lookup bits, returns actual */
+{
+  unsigned a;			/* counter for codes of length k */
+  unsigned c[BMAX + 1];		/* bit length count table */
+  unsigned f;			/* i repeats in table every f entries */
+  int g;			/* maximum code length */
+  int h;			/* table level */
+  register unsigned i;		/* counter, current code */
+  register unsigned j;		/* counter */
+  register int k;		/* number of bits in current code */
+  int l;			/* bits per table (returned in m) */
+  register unsigned *p;		/* pointer into c[], b[], or v[] */
+  register struct huft *q;	/* points to current table */
+  struct huft r;		/* table entry for structure assignment */
+  struct huft *u[BMAX];		/* table stack */
+  unsigned v[N_MAX];		/* values in order of bit length */
+  register int w;		/* bits before this table == (l * h) */
+  unsigned x[BMAX + 1];		/* bit offsets, then code stack */
+  unsigned *xp;			/* pointer into x */
+  int y;			/* number of dummy codes added */
+  unsigned z;			/* number of entries in current table */
+
+  /* Generate counts for each bit length */
+  grub_memset ((char *) c, 0, sizeof (c));
+  p = b;
+  i = n;
+  do
+    {
+      c[*p]++;			/* assume all entries <= BMAX */
+      p++;			/* Can't combine with above line (Solaris bug) */
+    }
+  while (--i);
+  if (c[0] == n)		/* null input--all zero length codes */
+    {
+      *t = (struct huft *) NULL;
+      *m = 0;
+      return 0;
+    }
+
+  /* Find minimum and maximum length, bound *m by those */
+  l = *m;
+  for (j = 1; j <= BMAX; j++)
+    if (c[j])
+      break;
+  k = j;			/* minimum code length */
+  if ((unsigned) l < j)
+    l = j;
+  for (i = BMAX; i; i--)
+    if (c[i])
+      break;
+  g = i;			/* maximum code length */
+  if ((unsigned) l > i)
+    l = i;
+  *m = l;
+
+  /* Adjust last length count to fill out codes, if needed */
+  for (y = 1 << j; j < i; j++, y <<= 1)
+    if ((y -= c[j]) < 0)
+      return 2;			/* bad input: more codes than bits */
+  if ((y -= c[i]) < 0)
+    return 2;
+  c[i] += y;
+
+  /* Generate starting offsets into the value table for each length */
+  x[1] = j = 0;
+  p = c + 1;
+  xp = x + 2;
+  while (--i)
+    {				/* note that i == g from above */
+      *xp++ = (j += *p++);
+    }
+
+  /* Make a table of values in order of bit lengths */
+  p = b;
+  i = 0;
+  do
+    {
+      if ((j = *p++) != 0)
+	v[x[j]++] = i;
+    }
+  while (++i < n);
+
+  /* Generate the Huffman codes and for each, make the table entries */
+  x[0] = i = 0;			/* first Huffman code is zero */
+  p = v;			/* grab values in bit order */
+  h = -1;			/* no tables yet--level -1 */
+  w = -l;			/* bits decoded == (l * h) */
+  u[0] = (struct huft *) NULL;	/* just to keep compilers happy */
+  q = (struct huft *) NULL;	/* ditto */
+  z = 0;			/* ditto */
+
+  /* go through the bit lengths (k already is bits in shortest code) */
+  for (; k <= g; k++)
+    {
+      a = c[k];
+      while (a--)
+	{
+	  /* here i is the Huffman code of length k bits for value *p */
+	  /* make tables up to required level */
+	  while (k > w + l)
+	    {
+	      h++;
+	      w += l;		/* previous table always l bits */
+
+	      /* compute minimum size table less than or equal to l bits */
+	      z = (z = (unsigned) (g - w)) > (unsigned) l ? (unsigned) l : z;	/* upper limit on table size */
+	      if ((f = 1 << (j = k - w)) > a + 1)	/* try a k-w bit table */
+		{		/* too few codes for k-w bit table */
+		  f -= a + 1;	/* deduct codes from patterns left */
+		  xp = c + k;
+		  while (++j < z)	/* try smaller tables up to z bits */
+		    {
+		      if ((f <<= 1) <= *++xp)
+			break;	/* enough codes to use up j bits */
+		      f -= *xp;	/* else deduct codes from patterns */
+		    }
+		}
+	      z = 1 << j;	/* table entries for j-bit table */
+
+	      /* allocate and link in new table */
+	      q = (struct huft *) grub_malloc ((z + 1) * sizeof (struct huft));
+	      if (! q)
+		{
+		  if (h)
+		    huft_free (u[0]);
+		  return 3;
+		}
+
+	      *t = q + 1;	/* link to list for huft_free() */
+	      *(t = &(q->v.t)) = (struct huft *) NULL;
+	      u[h] = ++q;	/* table starts after link */
+
+	      /* connect to last table, if there is one */
+	      if (h)
+		{
+		  x[h] = i;	/* save pattern for backing up */
+		  r.b = (uch) l;	/* bits to dump before this table */
+		  r.e = (uch) (16 + j);		/* bits in this table */
+		  r.v.t = q;	/* pointer to this table */
+		  j = i >> (w - l);	/* (get around Turbo C bug) */
+		  u[h - 1][j] = r;	/* connect to last table */
+		}
+	    }
+
+	  /* set up table entry in r */
+	  r.b = (uch) (k - w);
+	  if (p >= v + n)
+	    r.e = 99;		/* out of values--invalid code */
+	  else if (*p < s)
+	    {
+	      r.e = (uch) (*p < 256 ? 16 : 15);		/* 256 is end-of-block code */
+	      r.v.n = (ush) (*p);	/* simple code is just the value */
+	      p++;		/* one compiler does not like *p++ */
+	    }
+	  else
+	    {
+	      r.e = (uch) e[*p - s];	/* non-simple--look up in lists */
+	      r.v.n = d[*p++ - s];
+	    }
+
+	  /* fill code-like entries with r */
+	  f = 1 << (k - w);
+	  for (j = i >> w; j < z; j += f)
+	    q[j] = r;
+
+	  /* backwards increment the k-bit code i */
+	  for (j = 1 << (k - 1); i & j; j >>= 1)
+	    i ^= j;
+	  i ^= j;
+
+	  /* backup over finished tables */
+	  while ((i & ((1 << w) - 1)) != x[h])
+	    {
+	      h--;		/* don't need to update q */
+	      w -= l;
+	    }
+	}
+    }
+
+  /* Return true (1) if we were given an incomplete table */
+  return y != 0 && g != 1;
+}
+
+
+/* Free the malloc'ed tables built by huft_build(), which makes a linked
+   list of the tables it made, with the links in a dummy first entry of
+   each table.  */
+static int
+huft_free (struct huft *t)
+{
+  register struct huft *p, *q;
+
+
+  /* Go through linked list, freeing from the malloced (t[-1]) address. */
+  p = t;
+  while (p != (struct huft *) NULL)
+    {
+      q = (--p)->v.t;
+      grub_free ((char *) p);
+      p = q;
+    }
+  return 0;
+}
+
+
+/*
+ *  inflate (decompress) the codes in a deflated (compressed) block.
+ *  Return an error code or zero if it all goes ok.
+ */
+
+static int
+inflate_codes_in_window (grub_file_t file)
+{
+  register unsigned e;		/* table entry flag/number of extra bits */
+  unsigned n, d;		/* length and index for copy */
+  unsigned w;			/* current window position */
+  struct huft *t;		/* pointer to table entry */
+  unsigned ml, md;		/* masks for bl and bd bits */
+  register ulg b;		/* bit buffer */
+  register unsigned k;		/* number of bits in bit buffer */
+  grub_gzio_t gzio = file->data;
+
+  /* make local copies of globals */
+  d = gzio->inflate_d;
+  n = gzio->inflate_n;
+  b = gzio->bb;			/* initialize bit buffer */
+  k = gzio->bk;
+  w = gzio->wp;			/* initialize window position */
+
+  /* inflate the coded data */
+  ml = mask_bits[gzio->bl];		/* precompute masks for speed */
+  md = mask_bits[gzio->bd];
+  for (;;)			/* do until end of block */
+    {
+      if (! gzio->code_state)
+	{
+	  NEEDBITS ((unsigned) gzio->bl);
+	  if ((e = (t = gzio->tl + ((unsigned) b & ml))->e) > 16)
+	    do
+	      {
+		if (e == 99)
+		  {
+		    grub_error (GRUB_ERR_BAD_GZIP_DATA,
+				"an unused code found");
+		    return 1;
+		  }
+		DUMPBITS (t->b);
+		e -= 16;
+		NEEDBITS (e);
+	      }
+	    while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
+	  DUMPBITS (t->b);
+
+	  if (e == 16)		/* then it's a literal */
+	    {
+	      gzio->slide[w++] = (uch) t->v.n;
+	      if (w == WSIZE)
+		break;
+	    }
+	  else
+	    /* it's an EOB or a length */
+	    {
+	      /* exit if end of block */
+	      if (e == 15)
+		{
+		  gzio->block_len = 0;
+		  break;
+		}
+
+	      /* get length of block to copy */
+	      NEEDBITS (e);
+	      n = t->v.n + ((unsigned) b & mask_bits[e]);
+	      DUMPBITS (e);
+
+	      /* decode distance of block to copy */
+	      NEEDBITS ((unsigned) gzio->bd);
+	      if ((e = (t = gzio->td + ((unsigned) b & md))->e) > 16)
+		do
+		  {
+		    if (e == 99)
+		      {
+			grub_error (GRUB_ERR_BAD_GZIP_DATA,
+				    "an unused code found");
+			return 1;
+		      }
+		    DUMPBITS (t->b);
+		    e -= 16;
+		    NEEDBITS (e);
+		  }
+		while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e)
+		       > 16);
+	      DUMPBITS (t->b);
+	      NEEDBITS (e);
+	      d = w - t->v.n - ((unsigned) b & mask_bits[e]);
+	      DUMPBITS (e);
+	      gzio->code_state++;
+	    }
+	}
+
+      if (gzio->code_state)
+	{
+	  /* do the copy */
+	  do
+	    {
+	      n -= (e = (e = WSIZE - ((d &= WSIZE - 1) > w ? d : w)) > n ? n
+		    : e);
+
+	      if (w - d >= e)
+		{
+		  grub_memmove (gzio->slide + w, gzio->slide + d, e);
+		  w += e;
+		  d += e;
+		}
+	      else
+		/* purposefully use the overlap for extra copies here!! */
+		{
+		  while (e--)
+		    gzio->slide[w++] = gzio->slide[d++];
+		}
+
+	      if (w == WSIZE)
+		break;
+	    }
+	  while (n);
+
+	  if (! n)
+	    gzio->code_state--;
+
+	  /* did we break from the loop too soon? */
+	  if (w == WSIZE)
+	    break;
+	}
+    }
+
+  /* restore the globals from the locals */
+  gzio->inflate_d = d;
+  gzio->inflate_n = n;
+  gzio->wp = w;			/* restore global window pointer */
+  gzio->bb = b;			/* restore global bit buffer */
+  gzio->bk = k;
+
+  return ! gzio->block_len;
+}
+
+
+/* get header for an inflated type 0 (stored) block. */
+
+static void
+init_stored_block (grub_file_t file)
+{
+  register ulg b;		/* bit buffer */
+  register unsigned k;		/* number of bits in bit buffer */
+  grub_gzio_t gzio = file->data;
+
+  /* make local copies of globals */
+  b = gzio->bb;			/* initialize bit buffer */
+  k = gzio->bk;
+
+  /* go to byte boundary */
+  DUMPBITS (k & 7);
+
+  /* get the length and its complement */
+  NEEDBITS (16);
+  gzio->block_len = ((unsigned) b & 0xffff);
+  DUMPBITS (16);
+  NEEDBITS (16);
+  if (gzio->block_len != (int) ((~b) & 0xffff))
+    grub_error (GRUB_ERR_BAD_GZIP_DATA,
+		"the length of a stored block does not match");
+  DUMPBITS (16);
+
+  /* restore global variables */
+  gzio->bb = b;
+  gzio->bk = k;
+}
+
+
+/* get header for an inflated type 1 (fixed Huffman codes) block.  We should
+   either replace this with a custom decoder, or at least precompute the
+   Huffman tables. */
+
+static void
+init_fixed_block (grub_file_t file)
+{
+  int i;			/* temporary variable */
+  unsigned l[288];		/* length list for huft_build */
+  grub_gzio_t gzio = file->data;
+
+  /* set up literal table */
+  for (i = 0; i < 144; i++)
+    l[i] = 8;
+  for (; i < 256; i++)
+    l[i] = 9;
+  for (; i < 280; i++)
+    l[i] = 7;
+  for (; i < 288; i++)		/* make a complete, but wrong code set */
+    l[i] = 8;
+  gzio->bl = 7;
+  if (huft_build (l, 288, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0)
+    {
+      if (grub_errno == GRUB_ERR_NONE)
+	grub_error (GRUB_ERR_BAD_GZIP_DATA,
+		    "failed in building a Huffman code table");
+      return;
+    }
+
+  /* set up distance table */
+  for (i = 0; i < 30; i++)	/* make an incomplete code set */
+    l[i] = 5;
+  gzio->bd = 5;
+  if (huft_build (l, 30, 0, cpdist, cpdext, &gzio->td, &gzio->bd) > 1)
+    {
+      if (grub_errno == GRUB_ERR_NONE)
+	grub_error (GRUB_ERR_BAD_GZIP_DATA,
+		    "failed in building a Huffman code table");
+      huft_free (gzio->tl);
+      gzio->tl = 0;
+      return;
+    }
+
+  /* indicate we're now working on a block */
+  gzio->code_state = 0;
+  gzio->block_len++;
+}
+
+
+/* get header for an inflated type 2 (dynamic Huffman codes) block. */
+
+static void
+init_dynamic_block (grub_file_t file)
+{
+  int i;			/* temporary variables */
+  unsigned j;
+  unsigned l;			/* last length */
+  unsigned m;			/* mask for bit lengths table */
+  unsigned n;			/* number of lengths to get */
+  unsigned nb;			/* number of bit length codes */
+  unsigned nl;			/* number of literal/length codes */
+  unsigned nd;			/* number of distance codes */
+  unsigned ll[286 + 30];	/* literal/length and distance code lengths */
+  register ulg b;		/* bit buffer */
+  register unsigned k;		/* number of bits in bit buffer */
+  grub_gzio_t gzio = file->data;
+
+  /* make local bit buffer */
+  b = gzio->bb;
+  k = gzio->bk;
+
+  /* read in table lengths */
+  NEEDBITS (5);
+  nl = 257 + ((unsigned) b & 0x1f);	/* number of literal/length codes */
+  DUMPBITS (5);
+  NEEDBITS (5);
+  nd = 1 + ((unsigned) b & 0x1f);	/* number of distance codes */
+  DUMPBITS (5);
+  NEEDBITS (4);
+  nb = 4 + ((unsigned) b & 0xf);	/* number of bit length codes */
+  DUMPBITS (4);
+  if (nl > 286 || nd > 30)
+    {
+      grub_error (GRUB_ERR_BAD_GZIP_DATA, "too much data");
+      return;
+    }
+
+  /* read in bit-length-code lengths */
+  for (j = 0; j < nb; j++)
+    {
+      NEEDBITS (3);
+      ll[bitorder[j]] = (unsigned) b & 7;
+      DUMPBITS (3);
+    }
+  for (; j < 19; j++)
+    ll[bitorder[j]] = 0;
+
+  /* build decoding table for trees--single level, 7 bit lookup */
+  gzio->bl = 7;
+  if (huft_build (ll, 19, 19, NULL, NULL, &gzio->tl, &gzio->bl) != 0)
+    {
+      grub_error (GRUB_ERR_BAD_GZIP_DATA,
+		  "failed in building a Huffman code table");
+      return;
+    }
+
+  /* read in literal and distance code lengths */
+  n = nl + nd;
+  m = mask_bits[gzio->bl];
+  i = l = 0;
+  while ((unsigned) i < n)
+    {
+      NEEDBITS ((unsigned) gzio->bl);
+      j = (gzio->td = gzio->tl + ((unsigned) b & m))->b;
+      DUMPBITS (j);
+      j = gzio->td->v.n;
+      if (j < 16)		/* length of code in bits (0..15) */
+	ll[i++] = l = j;	/* save last length in l */
+      else if (j == 16)		/* repeat last length 3 to 6 times */
+	{
+	  NEEDBITS (2);
+	  j = 3 + ((unsigned) b & 3);
+	  DUMPBITS (2);
+	  if ((unsigned) i + j > n)
+	    {
+	      grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
+	      return;
+	    }
+	  while (j--)
+	    ll[i++] = l;
+	}
+      else if (j == 17)		/* 3 to 10 zero length codes */
+	{
+	  NEEDBITS (3);
+	  j = 3 + ((unsigned) b & 7);
+	  DUMPBITS (3);
+	  if ((unsigned) i + j > n)
+	    {
+	      grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
+	      return;
+	    }
+	  while (j--)
+	    ll[i++] = 0;
+	  l = 0;
+	}
+      else
+	/* j == 18: 11 to 138 zero length codes */
+	{
+	  NEEDBITS (7);
+	  j = 11 + ((unsigned) b & 0x7f);
+	  DUMPBITS (7);
+	  if ((unsigned) i + j > n)
+	    {
+	      grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
+	      return;
+	    }
+	  while (j--)
+	    ll[i++] = 0;
+	  l = 0;
+	}
+    }
+
+  /* free decoding table for trees */
+  huft_free (gzio->tl);
+  gzio->td = 0;
+  gzio->tl = 0;
+
+  /* restore the global bit buffer */
+  gzio->bb = b;
+  gzio->bk = k;
+
+  /* build the decoding tables for literal/length and distance codes */
+  gzio->bl = lbits;
+  if (huft_build (ll, nl, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0)
+    {
+      grub_error (GRUB_ERR_BAD_GZIP_DATA,
+		  "failed in building a Huffman code table");
+      return;
+    }
+  gzio->bd = dbits;
+  if (huft_build (ll + nl, nd, 0, cpdist, cpdext, &gzio->td, &gzio->bd) != 0)
+    {
+      huft_free (gzio->tl);
+      gzio->tl = 0;
+      grub_error (GRUB_ERR_BAD_GZIP_DATA,
+		  "failed in building a Huffman code table");
+      return;
+    }
+
+  /* indicate we're now working on a block */
+  gzio->code_state = 0;
+  gzio->block_len++;
+}
+
+
+static void
+get_new_block (grub_file_t file)
+{
+  register ulg b;		/* bit buffer */
+  register unsigned k;		/* number of bits in bit buffer */
+  grub_gzio_t gzio = file->data;
+
+  /* make local bit buffer */
+  b = gzio->bb;
+  k = gzio->bk;
+
+  /* read in last block bit */
+  NEEDBITS (1);
+  gzio->last_block = (int) b & 1;
+  DUMPBITS (1);
+
+  /* read in block type */
+  NEEDBITS (2);
+  gzio->block_type = (unsigned) b & 3;
+  DUMPBITS (2);
+
+  /* restore the global bit buffer */
+  gzio->bb = b;
+  gzio->bk = k;
+
+  switch (gzio->block_type)
+    {
+    case INFLATE_STORED:
+      init_stored_block (file);
+      break;
+    case INFLATE_FIXED:
+      init_fixed_block (file);
+      break;
+    case INFLATE_DYNAMIC:
+      init_dynamic_block (file);
+      break;
+    default:
+      break;
+    }
+}
+
+
+static void
+inflate_window (grub_file_t file)
+{
+  grub_gzio_t gzio = file->data;
+
+  /* initialize window */
+  gzio->wp = 0;
+
+  /*
+   *  Main decompression loop.
+   */
+
+  while (gzio->wp < WSIZE && grub_errno == GRUB_ERR_NONE)
+    {
+      if (! gzio->block_len)
+	{
+	  if (gzio->last_block)
+	    break;
+
+	  get_new_block (file);
+	}
+
+      if (gzio->block_type > INFLATE_DYNAMIC)
+	grub_error (GRUB_ERR_BAD_GZIP_DATA,
+		    "unknown block type %d", gzio->block_type);
+
+      if (grub_errno != GRUB_ERR_NONE)
+	return;
+
+      /*
+       *  Expand stored block here.
+       */
+      if (gzio->block_type == INFLATE_STORED)
+	{
+	  int w = gzio->wp;
+
+	  /*
+	   *  This is basically a glorified pass-through
+	   */
+
+	  while (gzio->block_len && w < WSIZE && grub_errno == GRUB_ERR_NONE)
+	    {
+	      gzio->slide[w++] = get_byte (file);
+	      gzio->block_len--;
+	    }
+
+	  gzio->wp = w;
+
+	  continue;
+	}
+
+      /*
+       *  Expand other kind of block.
+       */
+
+      if (inflate_codes_in_window (file))
+	{
+	  huft_free (gzio->tl);
+	  huft_free (gzio->td);
+	  gzio->tl = 0;
+	  gzio->td = 0;
+	}
+    }
+
+  gzio->saved_offset += WSIZE;
+
+  /* XXX do CRC calculation here! */
+}
+
+
+static void
+initialize_tables (grub_file_t file)
+{
+  grub_gzio_t gzio = file->data;
+
+  gzio->saved_offset = 0;
+  grub_file_seek (gzio->file, gzio->data_offset);
+
+  /* Initialize the bit buffer.  */
+  gzio->bk = 0;
+  gzio->bb = 0;
+
+  /* Reset partial decompression code.  */
+  gzio->last_block = 0;
+  gzio->block_len = 0;
+
+  /* Reset memory allocation stuff.  */
+  huft_free (gzio->tl);
+  huft_free (gzio->td);
+}
+
+
+/* Open a new decompressing object on the top of IO. If TRANSPARENT is true,
+   even if IO does not contain data compressed by gzip, return a valid file
+   object. Note that this function won't close IO, even if an error occurs.  */
+grub_file_t
+grub_gzio_open (grub_file_t io, int transparent)
+{
+  grub_file_t file;
+  grub_gzio_t gzio = 0;
+
+  file = (grub_file_t) grub_malloc (sizeof (*file));
+  if (! file)
+    return 0;
+
+  gzio = grub_malloc (sizeof (*gzio));
+  if (! gzio)
+    {
+      grub_free (file);
+      return 0;
+    }
+
+  grub_memset (gzio, 0, sizeof (*gzio));
+  gzio->file = io;
+
+  file->device = io->device;
+  file->offset = 0;
+  file->data = gzio;
+  file->read_hook = 0;
+  file->fs = &grub_gzio_fs;
+
+  if (! test_header (file))
+    {
+      grub_free (gzio);
+      grub_free (file);
+      grub_file_seek (io, 0);
+
+      if (grub_errno == GRUB_ERR_BAD_FILE_TYPE && transparent)
+	{
+	  grub_errno = GRUB_ERR_NONE;
+	  return io;
+	}
+      else
+	return 0;
+    }
+
+  return file;
+}
+
+/* This is similar to grub_gzio_open, but takes a file name as an argument.  */
+grub_file_t
+grub_gzfile_open (const char *name, int transparent)
+{
+  grub_file_t io, file;
+
+  io = grub_file_open (name);
+  if (! io)
+    return 0;
+
+  file = grub_gzio_open (io, transparent);
+  if (! file)
+    {
+      grub_file_close (io);
+      return 0;
+    }
+
+  return file;
+}
+
+static grub_ssize_t
+grub_gzio_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  grub_ssize_t ret = 0;
+  grub_gzio_t gzio = file->data;
+  grub_off_t offset;
+
+  /* Do we reset decompression to the beginning of the file?  */
+  if (gzio->saved_offset > file->offset + WSIZE)
+    initialize_tables (file);
+
+  /*
+   *  This loop operates upon uncompressed data only.  The only
+   *  special thing it does is to make sure the decompression
+   *  window is within the range of data it needs.
+   */
+
+  offset = file->offset;
+
+  while (len > 0 && grub_errno == GRUB_ERR_NONE)
+    {
+      register grub_size_t size;
+      register char *srcaddr;
+
+      while (offset >= gzio->saved_offset)
+	inflate_window (file);
+
+      srcaddr = (char *) ((offset & (WSIZE - 1)) + gzio->slide);
+      size = gzio->saved_offset - offset;
+      if (size > len)
+	size = len;
+
+      grub_memmove (buf, srcaddr, size);
+
+      buf += size;
+      len -= size;
+      ret += size;
+      offset += size;
+    }
+
+  if (grub_errno != GRUB_ERR_NONE)
+    ret = -1;
+
+  return ret;
+}
+
+/* Release everything, including the underlying file object.  */
+static grub_err_t
+grub_gzio_close (grub_file_t file)
+{
+  grub_gzio_t gzio = file->data;
+
+  grub_file_close (gzio->file);
+  huft_free (gzio->tl);
+  huft_free (gzio->td);
+  grub_free (gzio);
+
+  /* No need to close the same device twice.  */
+  file->device = 0;
+
+  return grub_errno;
+}
+
+
+
+static struct grub_fs grub_gzio_fs =
+  {
+    .name = "gzio",
+    .dir = 0,
+    .open = 0,
+    .read = grub_gzio_read,
+    .close = grub_gzio_close,
+    .label = 0,
+    .next = 0
+  };
diff --git a/kern/command.c b/kern/command.c
new file mode 100644
index 0000000..63b536e
--- /dev/null
+++ b/kern/command.c
@@ -0,0 +1,59 @@
+/* command.c - support basic command */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/command.h>
+
+grub_command_t grub_command_list;
+
+grub_command_t
+grub_register_command_prio (const char *name,
+			    grub_command_func_t func,
+			    const char *summary,
+			    const char *description,
+			    int prio)
+{
+  grub_command_t cmd;
+
+  cmd = (grub_command_t) grub_malloc (sizeof (*cmd));
+  if (! cmd)
+    return 0;
+
+  cmd->name = name;
+  cmd->func = func;
+  cmd->summary = (summary) ? summary : name;
+  cmd->description = description;
+
+  cmd->flags = GRUB_COMMAND_FLAG_BOTH;
+  cmd->prio = prio;
+  cmd->data = 0;
+
+  grub_prio_list_insert (GRUB_AS_PRIO_LIST_P (&grub_command_list),
+			 GRUB_AS_PRIO_LIST (cmd));
+
+  return cmd;
+}
+
+void
+grub_unregister_command (grub_command_t cmd)
+{
+  grub_prio_list_remove (GRUB_AS_PRIO_LIST_P (&grub_command_list),
+			 GRUB_AS_PRIO_LIST (cmd));
+  grub_free (cmd);
+}
diff --git a/kern/corecmd.c b/kern/corecmd.c
new file mode 100644
index 0000000..03944f2
--- /dev/null
+++ b/kern/corecmd.c
@@ -0,0 +1,202 @@
+/* corecmd.c - critical commands which are registered in kernel */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/err.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/file.h>
+#include <grub/device.h>
+#include <grub/command.h>
+
+/* set ENVVAR=VALUE */
+static grub_err_t
+grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)),
+		   int argc, char *argv[])
+{
+  char *var;
+  char *val;
+
+  auto int print_env (struct grub_env_var *env);
+
+  int print_env (struct grub_env_var *env)
+    {
+      grub_printf ("%s=%s\n", env->name, env->value);
+      return 0;
+    }
+
+  if (argc < 1)
+    {
+      grub_env_iterate (print_env);
+      return 0;
+    }
+
+  var = argv[0];
+  val = grub_strchr (var, '=');
+  if (! val)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "not an assignment");
+
+  val[0] = 0;
+  grub_env_set (var, val + 1);
+  val[0] = '=';
+
+  return 0;
+}
+
+static grub_err_t
+grub_core_cmd_unset (struct grub_command *cmd __attribute__ ((unused)),
+		     int argc, char *argv[])
+{
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "no environment variable specified");
+
+  grub_env_unset (argv[0]);
+  return 0;
+}
+
+static grub_err_t
+grub_core_cmd_export (struct grub_command *cmd __attribute__ ((unused)),
+		      int argc, char **args)
+{
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "no environment variable specified");
+
+  grub_env_export (args[0]);
+  return 0;
+}
+
+/* insmod MODULE */
+static grub_err_t
+grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),
+		      int argc, char *argv[])
+{
+  char *p;
+  grub_dl_t mod;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
+
+  p = grub_strchr (argv[0], '/');
+  if (! p)
+    mod = grub_dl_load (argv[0]);
+  else
+    mod = grub_dl_load_file (argv[0]);
+
+  if (mod)
+    grub_dl_ref (mod);
+
+  return 0;
+}
+
+static int
+grub_mini_print_devices (const char *name)
+{
+  grub_printf ("(%s) ", name);
+
+  return 0;
+}
+
+static int
+grub_mini_print_files (const char *filename,
+		       const struct grub_dirhook_info *info)
+{
+  grub_printf ("%s%s ", filename, info->dir ? "/" : "");
+
+  return 0;
+}
+
+/* ls [ARG] */
+static grub_err_t
+grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
+		  int argc, char *argv[])
+{
+  if (argc < 1)
+    {
+      grub_device_iterate (grub_mini_print_devices);
+      grub_putchar ('\n');
+      grub_refresh ();
+    }
+  else
+    {
+      char *device_name;
+      grub_device_t dev;
+      grub_fs_t fs;
+      char *path;
+
+      device_name = grub_file_get_device_name (argv[0]);
+      dev = grub_device_open (device_name);
+      if (! dev)
+	goto fail;
+
+      fs = grub_fs_probe (dev);
+      path = grub_strchr (argv[0], ')');
+      if (! path)
+	path = argv[0];
+      else
+	path++;
+
+      if (! path && ! device_name)
+	{
+	  grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
+	  goto fail;
+	}
+
+      if (! path)
+	{
+	  if (grub_errno == GRUB_ERR_UNKNOWN_FS)
+	    grub_errno = GRUB_ERR_NONE;
+
+	  grub_printf ("(%s): Filesystem is %s.\n",
+		       device_name, fs ? fs->name : "unknown");
+	}
+      else if (fs)
+	{
+	  (fs->dir) (dev, path, grub_mini_print_files);
+	  grub_putchar ('\n');
+	  grub_refresh ();
+	}
+
+    fail:
+      if (dev)
+	grub_device_close (dev);
+
+      grub_free (device_name);
+    }
+
+  return grub_errno;
+}
+
+void
+grub_register_core_commands (void)
+{
+  grub_register_command ("set", grub_core_cmd_set,
+			 "set [ENVVAR=VALUE]", "set an environment variable");
+  grub_register_command ("unset", grub_core_cmd_unset,
+			 "unset ENVVAR", "remove an environment variable");
+  grub_register_command ("export", grub_core_cmd_export,
+			 "export ENVVAR", "Export a variable.");
+  grub_register_command ("ls", grub_core_cmd_ls,
+			 "ls [ARG]", "list devices or files");
+  grub_register_command ("insmod", grub_core_cmd_insmod,
+			 "insmod MODULE", "insert a module");
+}
diff --git a/kern/device.c b/kern/device.c
new file mode 100644
index 0000000..83ae3dc
--- /dev/null
+++ b/kern/device.c
@@ -0,0 +1,158 @@
+/* device.c - device manager */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/net.h>
+#include <grub/fs.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/partition.h>
+
+grub_device_t
+grub_device_open (const char *name)
+{
+  grub_disk_t disk = 0;
+  grub_device_t dev = 0;
+
+  if (! name)
+    {
+      name = grub_env_get ("root");
+      if (*name == '\0')
+	{
+	  grub_error (GRUB_ERR_BAD_DEVICE, "no device is set");
+	  goto fail;
+	}
+    }
+
+  dev = grub_malloc (sizeof (*dev));
+  if (! dev)
+    goto fail;
+
+  /* Try to open a disk.  */
+  disk = grub_disk_open (name);
+  if (! disk)
+    goto fail;
+
+  dev->disk = disk;
+  dev->net = 0;	/* FIXME */
+
+  return dev;
+
+ fail:
+  if (disk)
+    grub_disk_close (disk);
+
+  grub_free (dev);
+
+  return 0;
+}
+
+grub_err_t
+grub_device_close (grub_device_t device)
+{
+  if (device->disk)
+    grub_disk_close (device->disk);
+
+  grub_free (device);
+
+  return grub_errno;
+}
+
+int
+grub_device_iterate (int (*hook) (const char *name))
+{
+  auto int iterate_disk (const char *disk_name);
+  auto int iterate_partition (grub_disk_t disk,
+			      const grub_partition_t partition);
+
+  struct part_ent
+  {
+    struct part_ent *next;
+    char name[0];
+  } *ents;
+
+  int iterate_disk (const char *disk_name)
+    {
+      grub_device_t dev;
+
+      if (hook (disk_name))
+	return 1;
+
+      dev = grub_device_open (disk_name);
+      if (! dev)
+	return 0;
+
+      if (dev->disk && dev->disk->has_partitions)
+	{
+	  struct part_ent *p;
+	  int ret = 0;
+
+	  ents = NULL;
+	  (void) grub_partition_iterate (dev->disk, iterate_partition);
+	  grub_device_close (dev);
+
+	  p = ents;
+	  while (p != NULL)
+	    {
+	      struct part_ent *next = p->next;
+
+	      if (!ret)
+		ret = hook (p->name);
+	      grub_free (p);
+	      p = next;
+	    }
+
+	  return ret;
+	}
+
+      grub_device_close (dev);
+      return 0;
+    }
+
+  int iterate_partition (grub_disk_t disk, const grub_partition_t partition)
+    {
+      char *partition_name;
+      struct part_ent *p;
+
+      partition_name = grub_partition_get_name (partition);
+      if (! partition_name)
+	return 1;
+
+      p = grub_malloc (sizeof (p->next) + grub_strlen (disk->name) + 1 +
+		       grub_strlen (partition_name) + 1);
+      if (!p)
+	{
+	  grub_free (partition_name);
+	  return 1;
+	}
+
+      grub_sprintf (p->name, "%s,%s", disk->name, partition_name);
+      grub_free (partition_name);
+
+      p->next = ents;
+      ents = p;
+
+      return 0;
+    }
+
+  /* Only disk devices are supported at the moment.  */
+  return grub_disk_dev_iterate (iterate_disk);
+}
diff --git a/kern/disk.c b/kern/disk.c
new file mode 100644
index 0000000..e463626
--- /dev/null
+++ b/kern/disk.c
@@ -0,0 +1,600 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/partition.h>
+#include <grub/misc.h>
+#include <grub/time.h>
+#include <grub/file.h>
+
+#define	GRUB_CACHE_TIMEOUT	2
+
+/* The last time the disk was used.  */
+static grub_uint64_t grub_last_time = 0;
+
+
+/* Disk cache.  */
+struct grub_disk_cache
+{
+  enum grub_disk_dev_id dev_id;
+  unsigned long disk_id;
+  grub_disk_addr_t sector;
+  char *data;
+  int lock;
+};
+
+static struct grub_disk_cache grub_disk_cache_table[GRUB_DISK_CACHE_NUM];
+
+void (*grub_disk_firmware_fini) (void);
+int grub_disk_firmware_is_tainted;
+
+grub_err_t (* grub_disk_ata_pass_through) (grub_disk_t,
+	    struct grub_disk_ata_pass_through_parms *);
+
+
+#if 0
+static unsigned long grub_disk_cache_hits;
+static unsigned long grub_disk_cache_misses;
+
+void
+grub_disk_cache_get_performance (unsigned long *hits, unsigned long *misses)
+{
+  *hits = grub_disk_cache_hits;
+  *misses = grub_disk_cache_misses;
+}
+#endif
+
+static unsigned
+grub_disk_cache_get_index (unsigned long dev_id, unsigned long disk_id,
+			   grub_disk_addr_t sector)
+{
+  return ((dev_id * 524287UL + disk_id * 2606459UL
+	   + ((unsigned) (sector >> GRUB_DISK_CACHE_BITS)))
+	  % GRUB_DISK_CACHE_NUM);
+}
+
+static void
+grub_disk_cache_invalidate (unsigned long dev_id, unsigned long disk_id,
+			    grub_disk_addr_t sector)
+{
+  unsigned index;
+  struct grub_disk_cache *cache;
+
+  sector &= ~(GRUB_DISK_CACHE_SIZE - 1);
+  index = grub_disk_cache_get_index (dev_id, disk_id, sector);
+  cache = grub_disk_cache_table + index;
+
+  if (cache->dev_id == dev_id && cache->disk_id == disk_id
+      && cache->sector == sector && cache->data)
+    {
+      cache->lock = 1;
+      grub_free (cache->data);
+      cache->data = 0;
+      cache->lock = 0;
+    }
+}
+
+void
+grub_disk_cache_invalidate_all (void)
+{
+  unsigned i;
+
+  for (i = 0; i < GRUB_DISK_CACHE_NUM; i++)
+    {
+      struct grub_disk_cache *cache = grub_disk_cache_table + i;
+
+      if (cache->data && ! cache->lock)
+	{
+	  grub_free (cache->data);
+	  cache->data = 0;
+	}
+    }
+}
+
+static char *
+grub_disk_cache_fetch (unsigned long dev_id, unsigned long disk_id,
+		       grub_disk_addr_t sector)
+{
+  struct grub_disk_cache *cache;
+  unsigned index;
+
+  index = grub_disk_cache_get_index (dev_id, disk_id, sector);
+  cache = grub_disk_cache_table + index;
+
+  if (cache->dev_id == dev_id && cache->disk_id == disk_id
+      && cache->sector == sector)
+    {
+      cache->lock = 1;
+#if 0
+      grub_disk_cache_hits++;
+#endif
+      return cache->data;
+    }
+
+#if 0
+  grub_disk_cache_misses++;
+#endif
+
+  return 0;
+}
+
+static void
+grub_disk_cache_unlock (unsigned long dev_id, unsigned long disk_id,
+			grub_disk_addr_t sector)
+{
+  struct grub_disk_cache *cache;
+  unsigned index;
+
+  index = grub_disk_cache_get_index (dev_id, disk_id, sector);
+  cache = grub_disk_cache_table + index;
+
+  if (cache->dev_id == dev_id && cache->disk_id == disk_id
+      && cache->sector == sector)
+    cache->lock = 0;
+}
+
+static grub_err_t
+grub_disk_cache_store (unsigned long dev_id, unsigned long disk_id,
+		       grub_disk_addr_t sector, const char *data)
+{
+  unsigned index;
+  struct grub_disk_cache *cache;
+
+  index = grub_disk_cache_get_index (dev_id, disk_id, sector);
+  cache = grub_disk_cache_table + index;
+
+  cache->lock = 1;
+  grub_free (cache->data);
+  cache->data = 0;
+  cache->lock = 0;
+
+  cache->data = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
+  if (! cache->data)
+    return grub_errno;
+
+  grub_memcpy (cache->data, data,
+	       GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
+  cache->dev_id = dev_id;
+  cache->disk_id = disk_id;
+  cache->sector = sector;
+
+  return GRUB_ERR_NONE;
+}
+
+
+
+static grub_disk_dev_t grub_disk_dev_list;
+
+void
+grub_disk_dev_register (grub_disk_dev_t dev)
+{
+  dev->next = grub_disk_dev_list;
+  grub_disk_dev_list = dev;
+}
+
+void
+grub_disk_dev_unregister (grub_disk_dev_t dev)
+{
+  grub_disk_dev_t *p, q;
+
+  for (p = &grub_disk_dev_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == dev)
+      {
+        *p = q->next;
+	break;
+      }
+}
+
+int
+grub_disk_dev_iterate (int (*hook) (const char *name))
+{
+  grub_disk_dev_t p;
+
+  for (p = grub_disk_dev_list; p; p = p->next)
+    if (p->iterate && (p->iterate) (hook))
+      return 1;
+
+  return 0;
+}
+
+/* Return the location of the first ',', if any, which is not
+   escaped by a '\'.  */
+static const char *
+find_part_sep (const char *name)
+{
+  const char *p = name;
+  char c;
+
+  while ((c = *p++) != '\0')
+    {
+      if (c == '\\' && *p == ',')
+	p++;
+      else if (c == ',')
+	return p - 1;
+    }
+  return NULL;
+}
+
+grub_disk_t
+grub_disk_open (const char *name)
+{
+  const char *p;
+  grub_disk_t disk;
+  grub_disk_dev_t dev;
+  char *raw = (char *) name;
+  grub_uint64_t current_time;
+
+  grub_dprintf ("disk", "Opening `%s'...\n", name);
+
+  disk = (grub_disk_t) grub_zalloc (sizeof (*disk));
+  if (! disk)
+    return 0;
+
+  disk->name = grub_strdup (name);
+  if (! disk->name)
+    goto fail;
+
+  p = find_part_sep (name);
+  if (p)
+    {
+      grub_size_t len = p - name;
+
+      raw = grub_malloc (len + 1);
+      if (! raw)
+	goto fail;
+
+      grub_memcpy (raw, name, len);
+      raw[len] = '\0';
+    }
+
+  for (dev = grub_disk_dev_list; dev; dev = dev->next)
+    {
+      if ((dev->open) (raw, disk) == GRUB_ERR_NONE)
+	break;
+      else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE)
+	grub_errno = GRUB_ERR_NONE;
+      else
+	goto fail;
+    }
+
+  if (! dev)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such disk");
+      goto fail;
+    }
+
+  if (p && ! disk->has_partitions)
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "no partition on this disk");
+      goto fail;
+    }
+
+  disk->dev = dev;
+
+  if (p)
+    {
+      disk->partition = grub_partition_probe (disk, p + 1);
+      if (! disk->partition)
+	{
+	  grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such partition");
+	  goto fail;
+	}
+    }
+
+  /* The cache will be invalidated about 2 seconds after a device was
+     closed.  */
+  current_time = grub_get_time_ms ();
+
+  if (current_time > (grub_last_time
+		      + GRUB_CACHE_TIMEOUT * 1000))
+    grub_disk_cache_invalidate_all ();
+
+  grub_last_time = current_time;
+
+ fail:
+
+  if (raw && raw != name)
+    grub_free (raw);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_error_push ();
+      grub_dprintf ("disk", "Opening `%s' failed.\n", name);
+      grub_error_pop ();
+
+      grub_disk_close (disk);
+      return 0;
+    }
+
+  return disk;
+}
+
+void
+grub_disk_close (grub_disk_t disk)
+{
+  grub_dprintf ("disk", "Closing `%s'.\n", disk->name);
+
+  if (disk->dev && disk->dev->close)
+    (disk->dev->close) (disk);
+
+  /* Reset the timer.  */
+  grub_last_time = grub_get_time_ms ();
+
+  grub_free (disk->partition);
+  grub_free ((void *) disk->name);
+  grub_free (disk);
+}
+
+/* This function performs three tasks:
+   - Make sectors disk relative from partition relative.
+   - Normalize offset to be less than the sector size.
+   - Verify that the range is inside the partition.  */
+static grub_err_t
+grub_disk_adjust_range (grub_disk_t disk, grub_disk_addr_t *sector,
+		       grub_off_t *offset, grub_size_t size)
+{
+  *sector += *offset >> GRUB_DISK_SECTOR_BITS;
+  *offset &= GRUB_DISK_SECTOR_SIZE - 1;
+
+  if (disk->partition)
+    {
+      grub_disk_addr_t start;
+      grub_uint64_t len;
+
+      start = grub_partition_get_start (disk->partition);
+      len = grub_partition_get_len (disk->partition);
+
+      if (*sector >= len
+	  || len - *sector < ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1)
+			      >> GRUB_DISK_SECTOR_BITS))
+	return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of partition");
+
+      *sector += start;
+    }
+
+  if (disk->total_sectors <= *sector
+      || ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1)
+	  >> GRUB_DISK_SECTOR_BITS) > disk->total_sectors - *sector)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of disk");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Read data from the disk.  */
+grub_err_t
+grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
+		grub_off_t offset, grub_size_t size, void *buf)
+{
+  char *tmp_buf;
+  unsigned real_offset;
+
+  grub_dprintf ("disk", "Reading `%s'...\n", disk->name);
+
+  /* First of all, check if the region is within the disk.  */
+  if (grub_disk_adjust_range (disk, &sector, &offset, size) != GRUB_ERR_NONE)
+    {
+      grub_error_push ();
+      grub_dprintf ("disk", "Read out of range: sector 0x%llx (%s).\n",
+		    (unsigned long long) sector, grub_errmsg);
+      grub_error_pop ();
+      return grub_errno;
+    }
+
+  real_offset = offset;
+
+  /* Allocate a temporary buffer.  */
+  tmp_buf = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
+  if (! tmp_buf)
+    return grub_errno;
+
+  /* Until SIZE is zero...  */
+  while (size)
+    {
+      char *data;
+      grub_disk_addr_t start_sector;
+      grub_size_t len;
+      grub_size_t pos;
+
+      /* For reading bulk data.  */
+      start_sector = sector & ~(GRUB_DISK_CACHE_SIZE - 1);
+      pos = (sector - start_sector) << GRUB_DISK_SECTOR_BITS;
+      len = ((GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS)
+	     - pos - real_offset);
+      if (len > size)
+	len = size;
+
+      /* Fetch the cache.  */
+      data = grub_disk_cache_fetch (disk->dev->id, disk->id, start_sector);
+      if (data)
+	{
+	  /* Just copy it!  */
+	  grub_memcpy (buf, data + pos + real_offset, len);
+	  grub_disk_cache_unlock (disk->dev->id, disk->id, start_sector);
+	}
+      else
+	{
+	  /* Otherwise read data from the disk actually.  */
+	  if ((disk->dev->read) (disk, start_sector,
+				 GRUB_DISK_CACHE_SIZE, tmp_buf)
+	      != GRUB_ERR_NONE)
+	    {
+	      /* Uggh... Failed. Instead, just read necessary data.  */
+	      unsigned num;
+	      char *p;
+
+	      grub_errno = GRUB_ERR_NONE;
+
+	      num = ((size + GRUB_DISK_SECTOR_SIZE - 1)
+		     >> GRUB_DISK_SECTOR_BITS);
+
+	      p = grub_realloc (tmp_buf, num << GRUB_DISK_SECTOR_BITS);
+	      if (!p)
+		goto finish;
+
+	      tmp_buf = p;
+
+	      if ((disk->dev->read) (disk, sector, num, tmp_buf))
+		{
+		  grub_error_push ();
+		  grub_dprintf ("disk", "%s read failed\n", disk->name);
+		  grub_error_pop ();
+		  goto finish;
+		}
+
+	      grub_memcpy (buf, tmp_buf + real_offset, size);
+
+	      /* Call the read hook, if any.  */
+	      if (disk->read_hook)
+		while (size)
+		  {
+		    (disk->read_hook) (sector, real_offset,
+				       ((size > GRUB_DISK_SECTOR_SIZE)
+					? GRUB_DISK_SECTOR_SIZE
+					: size));
+		    sector++;
+		    size -= GRUB_DISK_SECTOR_SIZE - real_offset;
+		    real_offset = 0;
+		  }
+
+	      /* This must be the end.  */
+	      goto finish;
+	    }
+
+	  /* Copy it and store it in the disk cache.  */
+	  grub_memcpy (buf, tmp_buf + pos + real_offset, len);
+	  grub_disk_cache_store (disk->dev->id, disk->id,
+				 start_sector, tmp_buf);
+	}
+
+      /* Call the read hook, if any.  */
+      if (disk->read_hook)
+	{
+	  grub_disk_addr_t s = sector;
+	  grub_size_t l = len;
+
+	  while (l)
+	    {
+	      (disk->read_hook) (s, real_offset,
+				 ((l > GRUB_DISK_SECTOR_SIZE)
+				  ? GRUB_DISK_SECTOR_SIZE
+				  : l));
+
+	      if (l < GRUB_DISK_SECTOR_SIZE - real_offset)
+		break;
+
+	      s++;
+	      l -= GRUB_DISK_SECTOR_SIZE - real_offset;
+	      real_offset = 0;
+	    }
+	}
+
+      sector = start_sector + GRUB_DISK_CACHE_SIZE;
+      buf = (char *) buf + len;
+      size -= len;
+      real_offset = 0;
+    }
+
+ finish:
+
+  grub_free (tmp_buf);
+
+  return grub_errno;
+}
+
+grub_err_t
+grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector,
+		 grub_off_t offset, grub_size_t size, const void *buf)
+{
+  unsigned real_offset;
+
+  grub_dprintf ("disk", "Writing `%s'...\n", disk->name);
+
+  if (grub_disk_adjust_range (disk, &sector, &offset, size) != GRUB_ERR_NONE)
+    return -1;
+
+  real_offset = offset;
+
+  while (size)
+    {
+      if (real_offset != 0 || (size < GRUB_DISK_SECTOR_SIZE && size != 0))
+	{
+	  char tmp_buf[GRUB_DISK_SECTOR_SIZE];
+	  grub_size_t len;
+	  grub_partition_t part;
+
+	  part = disk->partition;
+	  disk->partition = 0;
+	  if (grub_disk_read (disk, sector, 0, GRUB_DISK_SECTOR_SIZE, tmp_buf)
+	      != GRUB_ERR_NONE)
+	    {
+	      disk->partition = part;
+	      goto finish;
+	    }
+	  disk->partition = part;
+
+	  len = GRUB_DISK_SECTOR_SIZE - real_offset;
+	  if (len > size)
+	    len = size;
+
+	  grub_memcpy (tmp_buf + real_offset, buf, len);
+
+	  grub_disk_cache_invalidate (disk->dev->id, disk->id, sector);
+
+	  if ((disk->dev->write) (disk, sector, 1, tmp_buf) != GRUB_ERR_NONE)
+	    goto finish;
+
+	  sector++;
+	  buf = (char *) buf + len;
+	  size -= len;
+	  real_offset = 0;
+	}
+      else
+	{
+	  grub_size_t len;
+	  grub_size_t n;
+
+	  len = size & ~(GRUB_DISK_SECTOR_SIZE - 1);
+	  n = size >> GRUB_DISK_SECTOR_BITS;
+
+	  if ((disk->dev->write) (disk, sector, n, buf) != GRUB_ERR_NONE)
+	    goto finish;
+
+	  while (n--)
+	    grub_disk_cache_invalidate (disk->dev->id, disk->id, sector++);
+
+	  buf = (char *) buf + len;
+	  size -= len;
+	}
+    }
+
+ finish:
+
+  return grub_errno;
+}
+
+grub_uint64_t
+grub_disk_get_size (grub_disk_t disk)
+{
+  if (disk->partition)
+    return grub_partition_get_len (disk->partition);
+  else
+    return disk->total_sectors;
+}
diff --git a/kern/dl.c b/kern/dl.c
new file mode 100644
index 0000000..78ebc1e
--- /dev/null
+++ b/kern/dl.c
@@ -0,0 +1,726 @@
+/* dl.c - loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Force native word size */
+#define GRUB_TARGET_WORDSIZE (8 * GRUB_CPU_SIZEOF_VOID_P)
+
+#include <config.h>
+#include <grub/elf.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/file.h>
+#include <grub/env.h>
+#include <grub/cache.h>
+#include <grub/machine/machine.h>
+
+/* Platforms where modules are in a readonly area of memory.  */
+#if defined(GRUB_MACHINE_QEMU)
+#define GRUB_MODULES_MACHINE_READONLY
+#endif
+
+
+
+struct grub_dl_list
+{
+  struct grub_dl_list *next;
+  grub_dl_t mod;
+};
+typedef struct grub_dl_list *grub_dl_list_t;
+
+static grub_dl_list_t grub_dl_head;
+
+static grub_err_t
+grub_dl_add (grub_dl_t mod)
+{
+  grub_dl_list_t l;
+
+  if (grub_dl_get (mod->name))
+    return grub_error (GRUB_ERR_BAD_MODULE,
+		       "`%s' is already loaded", mod->name);
+
+  l = (grub_dl_list_t) grub_malloc (sizeof (*l));
+  if (! l)
+    return grub_errno;
+
+  l->mod = mod;
+  l->next = grub_dl_head;
+  grub_dl_head = l;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_dl_remove (grub_dl_t mod)
+{
+  grub_dl_list_t *p, q;
+
+  for (p = &grub_dl_head, q = *p; q; p = &q->next, q = *p)
+    if (q->mod == mod)
+      {
+	*p = q->next;
+	grub_free (q);
+	return;
+      }
+}
+
+grub_dl_t
+grub_dl_get (const char *name)
+{
+  grub_dl_list_t l;
+
+  for (l = grub_dl_head; l; l = l->next)
+    if (grub_strcmp (name, l->mod->name) == 0)
+      return l->mod;
+
+  return 0;
+}
+
+void
+grub_dl_iterate (int (*hook) (grub_dl_t mod))
+{
+  grub_dl_list_t l;
+
+  for (l = grub_dl_head; l; l = l->next)
+    if (hook (l->mod))
+      break;
+}
+
+
+
+struct grub_symbol
+{
+  struct grub_symbol *next;
+  const char *name;
+  void *addr;
+  grub_dl_t mod;	/* The module to which this symbol belongs.  */
+};
+typedef struct grub_symbol *grub_symbol_t;
+
+/* The size of the symbol table.  */
+#define GRUB_SYMTAB_SIZE	509
+
+/* The symbol table (using an open-hash).  */
+static struct grub_symbol *grub_symtab[GRUB_SYMTAB_SIZE];
+
+/* Simple hash function.  */
+static unsigned
+grub_symbol_hash (const char *s)
+{
+  unsigned key = 0;
+
+  while (*s)
+    key = key * 65599 + *s++;
+
+  return (key + (key >> 5)) % GRUB_SYMTAB_SIZE;
+}
+
+/* Resolve the symbol name NAME and return the address.
+   Return NULL, if not found.  */
+static void *
+grub_dl_resolve_symbol (const char *name)
+{
+  grub_symbol_t sym;
+
+  for (sym = grub_symtab[grub_symbol_hash (name)]; sym; sym = sym->next)
+    if (grub_strcmp (sym->name, name) == 0)
+      return sym->addr;
+
+  return 0;
+}
+
+/* Register a symbol with the name NAME and the address ADDR.  */
+grub_err_t
+grub_dl_register_symbol (const char *name, void *addr, grub_dl_t mod)
+{
+  grub_symbol_t sym;
+  unsigned k;
+
+  sym = (grub_symbol_t) grub_malloc (sizeof (*sym));
+  if (! sym)
+    return grub_errno;
+
+  if (mod)
+    {
+      sym->name = grub_strdup (name);
+      if (! sym->name)
+	{
+	  grub_free (sym);
+	  return grub_errno;
+	}
+    }
+  else
+    sym->name = name;
+
+  sym->addr = addr;
+  sym->mod = mod;
+
+  k = grub_symbol_hash (name);
+  sym->next = grub_symtab[k];
+  grub_symtab[k] = sym;
+
+  return GRUB_ERR_NONE;
+}
+
+/* Unregister all the symbols defined in the module MOD.  */
+static void
+grub_dl_unregister_symbols (grub_dl_t mod)
+{
+  unsigned i;
+
+  if (! mod)
+    grub_fatal ("core symbols cannot be unregistered");
+
+  for (i = 0; i < GRUB_SYMTAB_SIZE; i++)
+    {
+      grub_symbol_t sym, *p, q;
+
+      for (p = &grub_symtab[i], sym = *p; sym; sym = q)
+	{
+	  q = sym->next;
+	  if (sym->mod == mod)
+	    {
+	      *p = q;
+	      grub_free ((void *) sym->name);
+	      grub_free (sym);
+	    }
+	  else
+	    p = &sym->next;
+	}
+    }
+}
+
+/* Return the address of a section whose index is N.  */
+static void *
+grub_dl_get_section_addr (grub_dl_t mod, unsigned n)
+{
+  grub_dl_segment_t seg;
+
+  for (seg = mod->segment; seg; seg = seg->next)
+    if (seg->section == n)
+      return seg->addr;
+
+  return 0;
+}
+
+/* Check if EHDR is a valid ELF header.  */
+static grub_err_t
+grub_dl_check_header (void *ehdr, grub_size_t size)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the header size.  */
+  if (size < sizeof (Elf_Ehdr))
+    return grub_error (GRUB_ERR_BAD_OS, "ELF header smaller than expected");
+
+  /* Check the magic numbers.  */
+  if (grub_arch_dl_check_header (ehdr)
+      || 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_VERSION] != EV_CURRENT
+      || e->e_version != EV_CURRENT)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch independent ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Load all segments from memory specified by E.  */
+static grub_err_t
+grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
+{
+  unsigned i;
+  Elf_Shdr *s;
+
+  for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
+    {
+      if (s->sh_flags & SHF_ALLOC)
+	{
+	  grub_dl_segment_t seg;
+
+	  seg = (grub_dl_segment_t) grub_malloc (sizeof (*seg));
+	  if (! seg)
+	    return grub_errno;
+
+	  if (s->sh_size)
+	    {
+	      void *addr;
+
+	      addr = grub_memalign (s->sh_addralign, s->sh_size);
+	      if (! addr)
+		{
+		  grub_free (seg);
+		  return grub_errno;
+		}
+
+	      switch (s->sh_type)
+		{
+		case SHT_PROGBITS:
+		  grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
+		  break;
+		case SHT_NOBITS:
+		  grub_memset (addr, 0, s->sh_size);
+		  break;
+		}
+
+	      seg->addr = addr;
+	    }
+	  else
+	    seg->addr = 0;
+
+	  seg->size = s->sh_size;
+	  seg->section = i;
+	  seg->next = mod->segment;
+	  mod->segment = seg;
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
+{
+  unsigned i;
+  Elf_Shdr *s;
+  Elf_Sym *sym;
+  const char *str;
+  Elf_Word size, entsize;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no symbol table");
+
+#ifdef GRUB_MODULES_MACHINE_READONLY
+  mod->symtab = grub_malloc (s->sh_size);
+  memcpy (mod->symtab, (char *) e + s->sh_offset, s->sh_size);
+#else
+  mod->symtab = (Elf_Sym *) ((char *) e + s->sh_offset);
+#endif
+  sym = mod->symtab;
+  size = s->sh_size;
+  entsize = s->sh_entsize;
+
+  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
+  str = (char *) e + s->sh_offset;
+
+  for (i = 0;
+       i < size / entsize;
+       i++, sym = (Elf_Sym *) ((char *) sym + entsize))
+    {
+      unsigned char type = ELF_ST_TYPE (sym->st_info);
+      unsigned char bind = ELF_ST_BIND (sym->st_info);
+      const char *name = str + sym->st_name;
+
+      switch (type)
+	{
+	case STT_NOTYPE:
+	  /* Resolve a global symbol.  */
+	  if (sym->st_name != 0 && sym->st_shndx == 0)
+	    {
+	      sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name);
+	      if (! sym->st_value)
+		return grub_error (GRUB_ERR_BAD_MODULE,
+				   "the symbol `%s' not found", name);
+	    }
+	  else
+	    sym->st_value = 0;
+	  break;
+
+	case STT_OBJECT:
+	  sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
+								sym->st_shndx);
+	  if (bind != STB_LOCAL)
+	    if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
+	      return grub_errno;
+	  break;
+
+	case STT_FUNC:
+	  sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
+								sym->st_shndx);
+	  if (bind != STB_LOCAL)
+	    if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
+	      return grub_errno;
+
+	  if (grub_strcmp (name, "grub_mod_init") == 0)
+	    mod->init = (void (*) (grub_dl_t)) sym->st_value;
+	  else if (grub_strcmp (name, "grub_mod_fini") == 0)
+	    mod->fini = (void (*) (void)) sym->st_value;
+	  break;
+
+	case STT_SECTION:
+	  sym->st_value = (Elf_Addr) grub_dl_get_section_addr (mod,
+							       sym->st_shndx);
+	  break;
+
+	case STT_FILE:
+	  sym->st_value = 0;
+	  break;
+
+	default:
+	  return grub_error (GRUB_ERR_BAD_MODULE,
+			     "unknown symbol type `%d'", (int) type);
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_dl_call_init (grub_dl_t mod)
+{
+  if (mod->init)
+    (mod->init) (mod);
+}
+
+static grub_err_t
+grub_dl_resolve_name (grub_dl_t mod, Elf_Ehdr *e)
+{
+  Elf_Shdr *s;
+  const char *str;
+  unsigned i;
+
+  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
+  str = (char *) e + s->sh_offset;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (grub_strcmp (str + s->sh_name, ".modname") == 0)
+      {
+	mod->name = grub_strdup ((char *) e + s->sh_offset);
+	if (! mod->name)
+	  return grub_errno;
+	break;
+      }
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no module name found");
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_dl_resolve_dependencies (grub_dl_t mod, Elf_Ehdr *e)
+{
+  Elf_Shdr *s;
+  const char *str;
+  unsigned i;
+
+  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
+  str = (char *) e + s->sh_offset;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (grub_strcmp (str + s->sh_name, ".moddeps") == 0)
+      {
+	const char *name = (char *) e + s->sh_offset;
+	const char *max = name + s->sh_size;
+
+	while ((name < max) && (*name))
+	  {
+	    grub_dl_t m;
+	    grub_dl_dep_t dep;
+
+	    m = grub_dl_load (name);
+	    if (! m)
+	      return grub_errno;
+
+	    grub_dl_ref (m);
+
+	    dep = (grub_dl_dep_t) grub_malloc (sizeof (*dep));
+	    if (! dep)
+	      return grub_errno;
+
+	    dep->mod = m;
+	    dep->next = mod->dep;
+	    mod->dep = dep;
+
+	    name += grub_strlen (name) + 1;
+	  }
+      }
+
+  return GRUB_ERR_NONE;
+}
+
+#ifndef GRUB_UTIL
+int
+grub_dl_ref (grub_dl_t mod)
+{
+  grub_dl_dep_t dep;
+
+  for (dep = mod->dep; dep; dep = dep->next)
+    grub_dl_ref (dep->mod);
+
+  return ++mod->ref_count;
+}
+
+int
+grub_dl_unref (grub_dl_t mod)
+{
+  grub_dl_dep_t dep;
+
+  for (dep = mod->dep; dep; dep = dep->next)
+    grub_dl_unref (dep->mod);
+
+  return --mod->ref_count;
+}
+#endif
+
+static void
+grub_dl_flush_cache (grub_dl_t mod)
+{
+  grub_dl_segment_t seg;
+
+  for (seg = mod->segment; seg; seg = seg->next) {
+    if (seg->size) {
+      grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n",
+		    (unsigned long) seg->size, seg->addr);
+      grub_arch_sync_caches (seg->addr, seg->size);
+    }
+  }
+}
+
+/* Load a module from core memory.  */
+grub_dl_t
+grub_dl_load_core (void *addr, grub_size_t size)
+{
+  Elf_Ehdr *e;
+  grub_dl_t mod;
+
+  grub_dprintf ("modules", "module at %p, size 0x%lx\n", addr,
+		(unsigned long) size);
+  e = addr;
+  if (grub_dl_check_header (e, size))
+    return 0;
+
+  if (e->e_type != ET_REL)
+    {
+      grub_error (GRUB_ERR_BAD_MODULE, "invalid ELF file type");
+      return 0;
+    }
+
+  /* Make sure that every section is within the core.  */
+  if (size < e->e_shoff + e->e_shentsize * e->e_shnum)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "ELF sections outside core");
+      return 0;
+    }
+
+  mod = (grub_dl_t) grub_zalloc (sizeof (*mod));
+  if (! mod)
+    return 0;
+
+  mod->ref_count = 1;
+
+  grub_dprintf ("modules", "relocating to %p\n", mod);
+  if (grub_dl_resolve_name (mod, e)
+      || grub_dl_resolve_dependencies (mod, e)
+      || grub_dl_load_segments (mod, e)
+      || grub_dl_resolve_symbols (mod, e)
+      || grub_arch_dl_relocate_symbols (mod, e))
+    {
+      mod->fini = 0;
+      grub_dl_unload (mod);
+      return 0;
+    }
+
+  grub_dl_flush_cache (mod);
+
+  grub_dprintf ("modules", "module name: %s\n", mod->name);
+  grub_dprintf ("modules", "init function: %p\n", mod->init);
+  grub_dl_call_init (mod);
+
+  if (grub_dl_add (mod))
+    {
+      grub_dl_unload (mod);
+      return 0;
+    }
+
+  return mod;
+}
+
+/* Load a module from the file FILENAME.  */
+grub_dl_t
+grub_dl_load_file (const char *filename)
+{
+  grub_file_t file = NULL;
+  grub_ssize_t size;
+  void *core = 0;
+  grub_dl_t mod = 0;
+
+  file = grub_file_open (filename);
+  if (! file)
+    return 0;
+
+  size = grub_file_size (file);
+  core = grub_malloc (size);
+  if (! core)
+    {
+      grub_file_close (file);
+      return 0;
+    }
+
+  if (grub_file_read (file, core, size) != (int) size)
+    {
+      grub_file_close (file);
+      grub_free (core);
+      return 0;
+    }
+
+  /* We must close this before we try to process dependencies.
+     Some disk backends do not handle gracefully multiple concurrent
+     opens of the same device.  */
+  grub_file_close (file);
+
+  mod = grub_dl_load_core (core, size);
+  if (! mod)
+    {
+      grub_free (core);
+      return 0;
+    }
+
+  mod->ref_count = 0;
+  return mod;
+}
+
+/* Load a module using a symbolic name.  */
+grub_dl_t
+grub_dl_load (const char *name)
+{
+  char *filename;
+  grub_dl_t mod;
+  char *grub_dl_dir = grub_env_get ("prefix");
+
+  mod = grub_dl_get (name);
+  if (mod)
+    return mod;
+
+  if (! grub_dl_dir) {
+    grub_error (GRUB_ERR_FILE_NOT_FOUND, "\"prefix\" is not set");
+    return 0;
+  }
+
+  filename = (char *) grub_malloc (grub_strlen (grub_dl_dir) + 1
+				   + grub_strlen (name) + 4 + 1);
+  if (! filename)
+    return 0;
+
+  grub_sprintf (filename, "%s/%s.mod", grub_dl_dir, name);
+  mod = grub_dl_load_file (filename);
+  grub_free (filename);
+
+  if (! mod)
+    return 0;
+
+  if (grub_strcmp (mod->name, name) != 0)
+    grub_error (GRUB_ERR_BAD_MODULE, "mismatched names");
+
+  return mod;
+}
+
+/* Unload the module MOD.  */
+int
+grub_dl_unload (grub_dl_t mod)
+{
+  grub_dl_dep_t dep, depn;
+  grub_dl_segment_t seg, segn;
+
+  if (mod->ref_count > 0)
+    return 0;
+
+  if (mod->fini)
+    (mod->fini) ();
+
+  grub_dl_remove (mod);
+  grub_dl_unregister_symbols (mod);
+
+  for (dep = mod->dep; dep; dep = depn)
+    {
+      depn = dep->next;
+
+      if (! grub_dl_unref (dep->mod))
+	grub_dl_unload (dep->mod);
+
+      grub_free (dep);
+    }
+
+  for (seg = mod->segment; seg; seg = segn)
+    {
+      segn = seg->next;
+      grub_free (seg->addr);
+      grub_free (seg);
+    }
+
+  grub_free (mod->name);
+#ifdef GRUB_MODULES_MACHINE_READONLY
+  grub_free (mod->symtab);
+#endif
+  grub_free (mod);
+  return 1;
+}
+
+/* Unload unneeded modules.  */
+void
+grub_dl_unload_unneeded (void)
+{
+  /* Because grub_dl_remove modifies the list of modules, this
+     implementation is tricky.  */
+  grub_dl_list_t p = grub_dl_head;
+
+  while (p)
+    {
+      if (grub_dl_unload (p->mod))
+	{
+	  p = grub_dl_head;
+	  continue;
+	}
+
+      p = p->next;
+    }
+}
+
+/* Unload all modules.  */
+void
+grub_dl_unload_all (void)
+{
+  while (grub_dl_head)
+    {
+      grub_dl_list_t p;
+
+      grub_dl_unload_unneeded ();
+
+      /* Force to decrement the ref count. This will purge pre-loaded
+	 modules and manually inserted modules.  */
+      for (p = grub_dl_head; p; p = p->next)
+	p->mod->ref_count--;
+    }
+}
diff --git a/kern/efi/efi.c b/kern/efi/efi.c
new file mode 100644
index 0000000..8e09a90
--- /dev/null
+++ b/kern/efi/efi.c
@@ -0,0 +1,760 @@
+/* efi.c - generic EFI support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/console_control.h>
+#include <grub/efi/pe32.h>
+#include <grub/machine/time.h>
+#include <grub/term.h>
+#include <grub/kernel.h>
+#include <grub/mm.h>
+
+/* The handle of GRUB itself. Filled in by the startup code.  */
+grub_efi_handle_t grub_efi_image_handle;
+
+/* The pointer to a system table. Filled in by the startup code.  */
+grub_efi_system_table_t *grub_efi_system_table;
+
+static grub_efi_guid_t console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID;
+static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID;
+static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
+
+void *
+grub_efi_locate_protocol (grub_efi_guid_t *protocol, void *registration)
+{
+  void *interface;
+  grub_efi_status_t status;
+
+  status = efi_call_3 (grub_efi_system_table->boot_services->locate_protocol,
+                       protocol, registration, &interface);
+  if (status != GRUB_EFI_SUCCESS)
+    return 0;
+
+  return interface;
+}
+
+/* Return the array of handles which meet the requirement. If successful,
+   the number of handles is stored in NUM_HANDLES. The array is allocated
+   from the heap.  */
+grub_efi_handle_t *
+grub_efi_locate_handle (grub_efi_locate_search_type_t search_type,
+			grub_efi_guid_t *protocol,
+			void *search_key,
+			grub_efi_uintn_t *num_handles)
+{
+  grub_efi_boot_services_t *b;
+  grub_efi_status_t status;
+  grub_efi_handle_t *buffer;
+  grub_efi_uintn_t buffer_size = 8 * sizeof (grub_efi_handle_t);
+
+  buffer = grub_malloc (buffer_size);
+  if (! buffer)
+    return 0;
+
+  b = grub_efi_system_table->boot_services;
+  status = efi_call_5 (b->locate_handle, search_type, protocol, search_key,
+			     &buffer_size, buffer);
+  if (status == GRUB_EFI_BUFFER_TOO_SMALL)
+    {
+      grub_free (buffer);
+      buffer = grub_malloc (buffer_size);
+      if (! buffer)
+	return 0;
+
+      status = efi_call_5 (b->locate_handle, search_type, protocol, search_key,
+				 &buffer_size, buffer);
+    }
+
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      grub_free (buffer);
+      return 0;
+    }
+
+  *num_handles = buffer_size / sizeof (grub_efi_handle_t);
+  return buffer;
+}
+
+void *
+grub_efi_open_protocol (grub_efi_handle_t handle,
+			grub_efi_guid_t *protocol,
+			grub_efi_uint32_t attributes)
+{
+  grub_efi_boot_services_t *b;
+  grub_efi_status_t status;
+  void *interface;
+
+  b = grub_efi_system_table->boot_services;
+  status = efi_call_6 (b->open_protocol, handle,
+		       protocol,
+		       &interface,
+		       grub_efi_image_handle,
+		       0,
+		       attributes);
+  if (status != GRUB_EFI_SUCCESS)
+    return 0;
+
+  return interface;
+}
+
+int
+grub_efi_set_text_mode (int on)
+{
+  grub_efi_console_control_protocol_t *c;
+  grub_efi_screen_mode_t mode, new_mode;
+
+  c = grub_efi_locate_protocol (&console_control_guid, 0);
+  if (! c)
+    /* No console control protocol instance available, assume it is
+       already in text mode. */
+    return 1;
+
+  if (efi_call_4 (c->get_mode, c, &mode, 0, 0) != GRUB_EFI_SUCCESS)
+    return 0;
+
+  new_mode = on ? GRUB_EFI_SCREEN_TEXT : GRUB_EFI_SCREEN_GRAPHICS;
+  if (mode != new_mode)
+    if (efi_call_2 (c->set_mode, c, new_mode) != GRUB_EFI_SUCCESS)
+      return 0;
+
+  return 1;
+}
+
+void
+grub_efi_stall (grub_efi_uintn_t microseconds)
+{
+  efi_call_1 (grub_efi_system_table->boot_services->stall, microseconds);
+}
+
+grub_efi_loaded_image_t *
+grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
+{
+  return grub_efi_open_protocol (image_handle,
+				 &loaded_image_guid,
+				 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+}
+
+void
+grub_exit (void)
+{
+  grub_efi_fini ();
+  efi_call_4 (grub_efi_system_table->boot_services->exit,
+              grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0);
+  for (;;) ;
+}
+
+void
+grub_reboot (void)
+{
+  grub_efi_fini ();
+  efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
+              GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
+}
+
+void
+grub_halt (void)
+{
+  grub_efi_fini ();
+  efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
+              GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL);
+}
+
+int
+grub_efi_exit_boot_services (grub_efi_uintn_t map_key)
+{
+  grub_efi_boot_services_t *b;
+  grub_efi_status_t status;
+
+  b = grub_efi_system_table->boot_services;
+  status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, map_key);
+  return status == GRUB_EFI_SUCCESS;
+}
+
+grub_uint32_t
+grub_get_rtc (void)
+{
+  grub_efi_time_t time;
+  grub_efi_runtime_services_t *r;
+
+  r = grub_efi_system_table->runtime_services;
+  if (efi_call_2 (r->get_time, &time, 0) != GRUB_EFI_SUCCESS)
+    /* What is possible in this case?  */
+    return 0;
+
+  return (((time.minute * 60 + time.second) * 1000
+	   + time.nanosecond / 1000000)
+	  * GRUB_TICKS_PER_SECOND / 1000);
+}
+
+/* Search the mods section from the PE32/PE32+ image. This code uses
+   a PE32 header, but should work with PE32+ as well.  */
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  grub_efi_loaded_image_t *image;
+  struct grub_pe32_header *header;
+  struct grub_pe32_coff_header *coff_header;
+  struct grub_pe32_section_table *sections;
+  struct grub_pe32_section_table *section;
+  struct grub_module_info *info;
+  grub_uint16_t i;
+
+  image = grub_efi_get_loaded_image (grub_efi_image_handle);
+  if (! image)
+    return 0;
+
+  header = image->image_base;
+  coff_header = &(header->coff_header);
+  sections
+    = (struct grub_pe32_section_table *) ((char *) coff_header
+					  + sizeof (*coff_header)
+					  + coff_header->optional_header_size);
+
+  for (i = 0, section = sections;
+       i < coff_header->num_sections;
+       i++, section++)
+    {
+      if (grub_strcmp (section->name, "mods") == 0)
+	break;
+    }
+
+  if (i == coff_header->num_sections)
+    return 0;
+
+  info = (struct grub_module_info *) ((char *) image->image_base
+				      + section->virtual_address);
+  if (info->magic != GRUB_MODULE_MAGIC)
+    return 0;
+
+  return (grub_addr_t) info;
+}
+
+char *
+grub_efi_get_filename (grub_efi_device_path_t *dp)
+{
+  char *name = 0;
+
+  while (1)
+    {
+      grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
+      grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
+
+      if (type == GRUB_EFI_END_DEVICE_PATH_TYPE)
+	break;
+      else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
+	       && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
+	{
+	  grub_efi_file_path_device_path_t *fp;
+	  grub_efi_uint16_t len;
+	  char *p;
+	  grub_size_t size;
+
+	  if (name)
+	    {
+	      size = grub_strlen (name);
+	      name[size] = '/';
+	      size++;
+	    }
+	  else
+	    size = 0;
+
+	  len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
+		 / sizeof (grub_efi_char16_t));
+	  p = grub_realloc (name, size + len * 4 + 1);
+	  if (! p)
+	    {
+	      grub_free (name);
+	      return 0;
+	    }
+
+	  name = p;
+	  fp = (grub_efi_file_path_device_path_t *) dp;
+	  *grub_utf16_to_utf8 ((grub_uint8_t *) name + size,
+			       fp->path_name, len) = '\0';
+	}
+
+      dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
+    }
+
+  if (name)
+    {
+      /* EFI breaks paths with backslashes.  */
+      char *p;
+
+      for (p = name; *p; p++)
+	if (*p == '\\')
+	  *p = '/';
+    }
+
+  return name;
+}
+
+grub_efi_device_path_t *
+grub_efi_get_device_path (grub_efi_handle_t handle)
+{
+  return grub_efi_open_protocol (handle, &device_path_guid,
+				 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+}
+
+/* Print the chain of Device Path nodes. This is mainly for debugging. */
+void
+grub_efi_print_device_path (grub_efi_device_path_t *dp)
+{
+  while (1)
+    {
+      grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
+      grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
+      grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
+
+      switch (type)
+	{
+	case GRUB_EFI_END_DEVICE_PATH_TYPE:
+	  switch (subtype)
+	    {
+	    case GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE:
+	      grub_printf ("/EndEntire\n");
+	      //grub_putchar ('\n');
+	      break;
+	    case GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE:
+	      grub_printf ("/EndThis\n");
+	      //grub_putchar ('\n');
+	      break;
+	    default:
+	      grub_printf ("/EndUnknown(%x)\n", (unsigned) subtype);
+	      break;
+	    }
+	  break;
+
+	case GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE:
+	  switch (subtype)
+	    {
+	    case GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_pci_device_path_t pci;
+		grub_memcpy (&pci, dp, len);
+		grub_printf ("/PCI(%x,%x)",
+			     (unsigned) pci.function, (unsigned) pci.device);
+	      }
+	      break;
+	    case GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_pccard_device_path_t pccard;
+		grub_memcpy (&pccard, dp, len);
+		grub_printf ("/PCCARD(%x)",
+			     (unsigned) pccard.function);
+	      }
+	      break;
+	    case GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_memory_mapped_device_path_t mmapped;
+		grub_memcpy (&mmapped, dp, len);
+		grub_printf ("/MMap(%x,%llx,%llx)",
+			     (unsigned) mmapped.memory_type,
+			     (unsigned long long) mmapped.start_address,
+			     (unsigned long long) mmapped.end_address);
+	      }
+	      break;
+	    case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_vendor_device_path_t vendor;
+		grub_memcpy (&vendor, dp, sizeof (vendor));
+		grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
+			     (unsigned) vendor.vendor_guid.data1,
+			     (unsigned) vendor.vendor_guid.data2,
+			     (unsigned) vendor.vendor_guid.data3,
+			     (unsigned) vendor.vendor_guid.data4[0],
+			     (unsigned) vendor.vendor_guid.data4[1],
+			     (unsigned) vendor.vendor_guid.data4[2],
+			     (unsigned) vendor.vendor_guid.data4[3],
+			     (unsigned) vendor.vendor_guid.data4[4],
+			     (unsigned) vendor.vendor_guid.data4[5],
+			     (unsigned) vendor.vendor_guid.data4[6],
+			     (unsigned) vendor.vendor_guid.data4[7]);
+	      }
+	      break;
+	    case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_controller_device_path_t controller;
+		grub_memcpy (&controller, dp, len);
+		grub_printf ("/Ctrl(%x)",
+			     (unsigned) controller.controller_number);
+	      }
+	      break;
+	    default:
+	      grub_printf ("/UnknownHW(%x)", (unsigned) subtype);
+	      break;
+	    }
+	  break;
+
+	case GRUB_EFI_ACPI_DEVICE_PATH_TYPE:
+	  switch (subtype)
+	    {
+	    case GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_acpi_device_path_t acpi;
+		grub_memcpy (&acpi, dp, len);
+		grub_printf ("/ACPI(%x,%x)",
+			     (unsigned) acpi.hid,
+			     (unsigned) acpi.uid);
+	      }
+	      break;
+	    case GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_expanded_acpi_device_path_t eacpi;
+		grub_memcpy (&eacpi, dp, sizeof (eacpi));
+		grub_printf ("/ACPI(");
+
+		if (GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp)[0] == '\0')
+		  grub_printf ("%x,", (unsigned) eacpi.hid);
+		else
+		  grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp));
+
+		if (GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp)[0] == '\0')
+		  grub_printf ("%x,", (unsigned) eacpi.uid);
+		else
+		  grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp));
+
+		if (GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp)[0] == '\0')
+		  grub_printf ("%x)", (unsigned) eacpi.cid);
+		else
+		  grub_printf ("%s)", GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp));
+	      }
+	      break;
+	    default:
+	      grub_printf ("/UnknownACPI(%x)", (unsigned) subtype);
+	      break;
+	    }
+	  break;
+
+	case GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE:
+	  switch (subtype)
+	    {
+	    case GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_atapi_device_path_t atapi;
+		grub_memcpy (&atapi, dp, len);
+		grub_printf ("/ATAPI(%x,%x,%x)",
+			     (unsigned) atapi.primary_secondary,
+			     (unsigned) atapi.slave_master,
+			     (unsigned) atapi.lun);
+	      }
+	      break;
+	    case GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_scsi_device_path_t scsi;
+		grub_memcpy (&scsi, dp, len);
+		grub_printf ("/SCSI(%x,%x)",
+			     (unsigned) scsi.pun,
+			     (unsigned) scsi.lun);
+	      }
+	      break;
+	    case GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_fibre_channel_device_path_t fc;
+		grub_memcpy (&fc, dp, len);
+		grub_printf ("/FibreChannel(%llx,%llx)",
+			     (unsigned long long) fc.wwn,
+			     (unsigned long long) fc.lun);
+	      }
+	      break;
+	    case GRUB_EFI_1394_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_1394_device_path_t firewire;
+		grub_memcpy (&firewire, dp, len);
+		grub_printf ("/1394(%llx)", (unsigned long long) firewire.guid);
+	      }
+	      break;
+	    case GRUB_EFI_USB_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_usb_device_path_t usb;
+		grub_memcpy (&usb, dp, len);
+		grub_printf ("/USB(%x,%x)",
+			     (unsigned) usb.parent_port_number,
+			     (unsigned) usb.interface);
+	      }
+	      break;
+	    case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_usb_class_device_path_t usb_class;
+		grub_memcpy (&usb_class, dp, len);
+		grub_printf ("/USBClass(%x,%x,%x,%x,%x)",
+			     (unsigned) usb_class.vendor_id,
+			     (unsigned) usb_class.product_id,
+			     (unsigned) usb_class.device_class,
+			     (unsigned) usb_class.device_subclass,
+			     (unsigned) usb_class.device_protocol);
+	      }
+	      break;
+	    case GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_i2o_device_path_t i2o;
+		grub_memcpy (&i2o, dp, len);
+		grub_printf ("/I2O(%x)", (unsigned) i2o.tid);
+	      }
+	      break;
+	    case GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_mac_address_device_path_t mac;
+		grub_memcpy (&mac, dp, len);
+		grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)",
+			     (unsigned) mac.mac_address[0],
+			     (unsigned) mac.mac_address[1],
+			     (unsigned) mac.mac_address[2],
+			     (unsigned) mac.mac_address[3],
+			     (unsigned) mac.mac_address[4],
+			     (unsigned) mac.mac_address[5],
+			     (unsigned) mac.if_type);
+	      }
+	      break;
+	    case GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_ipv4_device_path_t ipv4;
+		grub_memcpy (&ipv4, dp, len);
+		grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)",
+			     (unsigned) ipv4.local_ip_address[0],
+			     (unsigned) ipv4.local_ip_address[1],
+			     (unsigned) ipv4.local_ip_address[2],
+			     (unsigned) ipv4.local_ip_address[3],
+			     (unsigned) ipv4.remote_ip_address[0],
+			     (unsigned) ipv4.remote_ip_address[1],
+			     (unsigned) ipv4.remote_ip_address[2],
+			     (unsigned) ipv4.remote_ip_address[3],
+			     (unsigned) ipv4.local_port,
+			     (unsigned) ipv4.remote_port,
+			     (unsigned) ipv4.protocol,
+			     (unsigned) ipv4.static_ip_address);
+	      }
+	      break;
+	    case GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_ipv6_device_path_t ipv6;
+		grub_memcpy (&ipv6, dp, len);
+		grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)",
+			     (unsigned) ipv6.local_ip_address[0],
+			     (unsigned) ipv6.local_ip_address[1],
+			     (unsigned) ipv6.local_ip_address[2],
+			     (unsigned) ipv6.local_ip_address[3],
+			     (unsigned) ipv6.local_ip_address[4],
+			     (unsigned) ipv6.local_ip_address[5],
+			     (unsigned) ipv6.local_ip_address[6],
+			     (unsigned) ipv6.local_ip_address[7],
+			     (unsigned) ipv6.remote_ip_address[0],
+			     (unsigned) ipv6.remote_ip_address[1],
+			     (unsigned) ipv6.remote_ip_address[2],
+			     (unsigned) ipv6.remote_ip_address[3],
+			     (unsigned) ipv6.remote_ip_address[4],
+			     (unsigned) ipv6.remote_ip_address[5],
+			     (unsigned) ipv6.remote_ip_address[6],
+			     (unsigned) ipv6.remote_ip_address[7],
+			     (unsigned) ipv6.local_port,
+			     (unsigned) ipv6.remote_port,
+			     (unsigned) ipv6.protocol,
+			     (unsigned) ipv6.static_ip_address);
+	      }
+	      break;
+	    case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_infiniband_device_path_t ib;
+		grub_memcpy (&ib, dp, len);
+		grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)",
+			     (unsigned) ib.port_gid[0], /* XXX */
+			     (unsigned long long) ib.remote_id,
+			     (unsigned long long) ib.target_port_id,
+			     (unsigned long long) ib.device_id);
+	      }
+	      break;
+	    case GRUB_EFI_UART_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_uart_device_path_t uart;
+		grub_memcpy (&uart, dp, len);
+		grub_printf ("/UART(%llu,%u,%x,%x)",
+			     (unsigned long long) uart.baud_rate,
+			     uart.data_bits,
+			     uart.parity,
+			     uart.stop_bits);
+	      }
+	      break;
+	    case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_vendor_messaging_device_path_t vendor;
+		grub_memcpy (&vendor, dp, sizeof (vendor));
+		grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
+			     (unsigned) vendor.vendor_guid.data1,
+			     (unsigned) vendor.vendor_guid.data2,
+			     (unsigned) vendor.vendor_guid.data3,
+			     (unsigned) vendor.vendor_guid.data4[0],
+			     (unsigned) vendor.vendor_guid.data4[1],
+			     (unsigned) vendor.vendor_guid.data4[2],
+			     (unsigned) vendor.vendor_guid.data4[3],
+			     (unsigned) vendor.vendor_guid.data4[4],
+			     (unsigned) vendor.vendor_guid.data4[5],
+			     (unsigned) vendor.vendor_guid.data4[6],
+			     (unsigned) vendor.vendor_guid.data4[7]);
+	      }
+	      break;
+	    default:
+	      grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype);
+	      break;
+	    }
+	  break;
+
+	case GRUB_EFI_MEDIA_DEVICE_PATH_TYPE:
+	  switch (subtype)
+	    {
+	    case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_hard_drive_device_path_t hd;
+		grub_memcpy (&hd, dp, len);
+		grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)",
+			     hd.partition_number,
+			     (unsigned long long) hd.partition_start,
+			     (unsigned long long) hd.partition_size,
+			     (unsigned) hd.partition_signature[0],
+			     (unsigned) hd.partition_signature[1],
+			     (unsigned) hd.partition_signature[2],
+			     (unsigned) hd.partition_signature[3],
+			     (unsigned) hd.partition_signature[4],
+			     (unsigned) hd.partition_signature[5],
+			     (unsigned) hd.partition_signature[6],
+			     (unsigned) hd.partition_signature[7],
+			     (unsigned) hd.mbr_type,
+			     (unsigned) hd.signature_type);
+	      }
+	      break;
+	    case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_cdrom_device_path_t cd;
+		grub_memcpy (&cd, dp, len);
+		grub_printf ("/CD(%u,%llx,%llx)",
+			     cd.boot_entry,
+			     (unsigned long long) cd.partition_start,
+			     (unsigned long long) cd.partition_size);
+	      }
+	      break;
+	    case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_vendor_media_device_path_t vendor;
+		grub_memcpy (&vendor, dp, sizeof (vendor));
+		grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
+			     (unsigned) vendor.vendor_guid.data1,
+			     (unsigned) vendor.vendor_guid.data2,
+			     (unsigned) vendor.vendor_guid.data3,
+			     (unsigned) vendor.vendor_guid.data4[0],
+			     (unsigned) vendor.vendor_guid.data4[1],
+			     (unsigned) vendor.vendor_guid.data4[2],
+			     (unsigned) vendor.vendor_guid.data4[3],
+			     (unsigned) vendor.vendor_guid.data4[4],
+			     (unsigned) vendor.vendor_guid.data4[5],
+			     (unsigned) vendor.vendor_guid.data4[6],
+			     (unsigned) vendor.vendor_guid.data4[7]);
+	      }
+	      break;
+	    case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_file_path_device_path_t *fp;
+		grub_uint8_t buf[(len - 4) * 2 + 1];
+		fp = (grub_efi_file_path_device_path_t *) dp;
+		*grub_utf16_to_utf8 (buf, fp->path_name,
+				     (len - 4) / sizeof (grub_efi_char16_t))
+		  = '\0';
+		grub_printf ("/File(%s)", buf);
+	      }
+	      break;
+	    case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_protocol_device_path_t proto;
+		grub_memcpy (&proto, dp, sizeof (proto));
+		grub_printf ("/Protocol(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
+			     (unsigned) proto.guid.data1,
+			     (unsigned) proto.guid.data2,
+			     (unsigned) proto.guid.data3,
+			     (unsigned) proto.guid.data4[0],
+			     (unsigned) proto.guid.data4[1],
+			     (unsigned) proto.guid.data4[2],
+			     (unsigned) proto.guid.data4[3],
+			     (unsigned) proto.guid.data4[4],
+			     (unsigned) proto.guid.data4[5],
+			     (unsigned) proto.guid.data4[6],
+			     (unsigned) proto.guid.data4[7]);
+	      }
+	      break;
+	    default:
+	      grub_printf ("/UnknownMedia(%x)", (unsigned) subtype);
+	      break;
+	    }
+	  break;
+
+	case GRUB_EFI_BIOS_DEVICE_PATH_TYPE:
+	  switch (subtype)
+	    {
+	    case GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE:
+	      {
+		grub_efi_bios_device_path_t bios;
+		grub_memcpy (&bios, dp, sizeof (bios));
+		grub_printf ("/BIOS(%x,%x,%s)",
+			     (unsigned) bios.device_type,
+			     (unsigned) bios.status_flags,
+			     (char *) (dp + 1));
+	      }
+	      break;
+	    default:
+	      grub_printf ("/UnknownBIOS(%x)", (unsigned) subtype);
+	      break;
+	    }
+	  break;
+
+	default:
+	  grub_printf ("/UnknownType(%x,%x)\n",
+		       (unsigned) type,
+		       (unsigned) subtype);
+	  return;
+	  break;
+	}
+
+      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
+	break;
+
+      dp = (grub_efi_device_path_t *) ((char *) dp + len);
+    }
+}
+
+int
+grub_efi_finish_boot_services (void)
+{
+  grub_efi_uintn_t mmap_size = 0;
+  grub_efi_uintn_t map_key;
+  grub_efi_uintn_t desc_size;
+  grub_efi_uint32_t desc_version;
+  void *mmap_buf = 0;
+
+  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
+			       &desc_size, &desc_version) < 0)
+    return 0;
+
+  mmap_buf = grub_malloc (mmap_size);
+
+  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
+			       &desc_size, &desc_version) <= 0)
+    return 0;
+
+  return grub_efi_exit_boot_services (map_key);
+}
+
diff --git a/kern/efi/init.c b/kern/efi/init.c
new file mode 100644
index 0000000..f9ba038
--- /dev/null
+++ b/kern/efi/init.c
@@ -0,0 +1,87 @@
+/* init.c - generic EFI initialization and finalization */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/efi/efi.h>
+#include <grub/efi/console.h>
+#include <grub/efi/disk.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/mm.h>
+#include <grub/machine/kernel.h>
+
+void
+grub_efi_init (void)
+{
+  /* First of all, initialize the console so that GRUB can display
+     messages.  */
+  grub_console_init ();
+
+  /* Initialize the memory management system.  */
+  grub_efi_mm_init ();
+
+  grub_efidisk_init ();
+}
+
+void
+grub_efi_set_prefix (void)
+{
+  grub_efi_loaded_image_t *image;
+
+  image = grub_efi_get_loaded_image (grub_efi_image_handle);
+  if (image)
+    {
+      char *device;
+      char *file;
+
+      device = grub_efidisk_get_device_name (image->device_handle);
+      file = grub_efi_get_filename (image->file_path);
+
+      if (device && file)
+	{
+	  char *p;
+	  char *prefix;
+
+	  /* Get the directory.  */
+	  p = grub_strrchr (file, '/');
+	  if (p)
+	    *p = '\0';
+
+	  prefix = grub_malloc (1 + grub_strlen (device) + 1
+				+ grub_strlen (file) + 1);
+	  if (prefix)
+	    {
+	      grub_sprintf (prefix, "(%s)%s", device, file);
+	      grub_env_set ("prefix", prefix);
+	      grub_free (prefix);
+	    }
+	}
+
+      grub_free (device);
+      grub_free (file);
+    }
+}
+
+void
+grub_efi_fini (void)
+{
+  grub_efidisk_fini ();
+  grub_efi_mm_fini ();
+  grub_console_fini ();
+}
diff --git a/kern/efi/mm.c b/kern/efi/mm.c
new file mode 100644
index 0000000..e1fca81
--- /dev/null
+++ b/kern/efi/mm.c
@@ -0,0 +1,431 @@
+/* mm.c - generic EFI memory management */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+
+#define NEXT_MEMORY_DESCRIPTOR(desc, size)	\
+  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+#define BYTES_TO_PAGES(bytes)	((bytes) >> 12)
+#define PAGES_TO_BYTES(pages)	((pages) << 12)
+
+/* The size of a memory map obtained from the firmware. This must be
+   a multiplier of 4KB.  */
+#define MEMORY_MAP_SIZE	0x3000
+
+/* Maintain the list of allocated pages.  */
+struct allocated_page
+{
+  grub_efi_physical_address_t addr;
+  grub_efi_uint64_t num_pages;
+};
+
+#define ALLOCATED_PAGES_SIZE	0x1000
+#define MAX_ALLOCATED_PAGES	\
+  (ALLOCATED_PAGES_SIZE / sizeof (struct allocated_page))
+
+static struct allocated_page *allocated_pages = 0;
+
+/* The minimum and maximum heap size for GRUB itself.  */
+#define MIN_HEAP_SIZE	0x100000
+#define MAX_HEAP_SIZE	(1600 * 0x100000)
+
+
+/* Allocate pages. Return the pointer to the first of allocated pages.  */
+void *
+grub_efi_allocate_pages (grub_efi_physical_address_t address,
+			 grub_efi_uintn_t pages)
+{
+  grub_efi_allocate_type_t type;
+  grub_efi_status_t status;
+  grub_efi_boot_services_t *b;
+
+#if GRUB_TARGET_SIZEOF_VOID_P < 8
+  /* Limit the memory access to less than 4GB for 32-bit platforms.  */
+  if (address > 0xffffffff)
+    return 0;
+#endif
+
+#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
+  if (address == 0)
+    {
+      type = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
+      address = 0xffffffff;
+    }
+  else
+    type = GRUB_EFI_ALLOCATE_ADDRESS;
+#else
+  if (address == 0)
+    type = GRUB_EFI_ALLOCATE_ANY_PAGES;
+  else
+    type = GRUB_EFI_ALLOCATE_ADDRESS;
+#endif
+
+  b = grub_efi_system_table->boot_services;
+  status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address);
+  if (status != GRUB_EFI_SUCCESS)
+    return 0;
+
+  if (address == 0)
+    {
+      /* Uggh, the address 0 was allocated... This is too annoying,
+	 so reallocate another one.  */
+      address = 0xffffffff;
+      status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address);
+      grub_efi_free_pages (0, pages);
+      if (status != GRUB_EFI_SUCCESS)
+	return 0;
+    }
+
+  if (allocated_pages)
+    {
+      unsigned i;
+
+      for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
+	if (allocated_pages[i].addr == 0)
+	  {
+	    allocated_pages[i].addr = address;
+	    allocated_pages[i].num_pages = pages;
+	    break;
+	  }
+
+      if (i == MAX_ALLOCATED_PAGES)
+	grub_fatal ("too many page allocations");
+    }
+
+  return (void *) ((grub_addr_t) address);
+}
+
+/* Free pages starting from ADDRESS.  */
+void
+grub_efi_free_pages (grub_efi_physical_address_t address,
+		     grub_efi_uintn_t pages)
+{
+  grub_efi_boot_services_t *b;
+
+  if (allocated_pages
+      && ((grub_efi_physical_address_t) ((grub_addr_t) allocated_pages)
+	  != address))
+    {
+      unsigned i;
+
+      for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
+	if (allocated_pages[i].addr == address)
+	  {
+	    allocated_pages[i].addr = 0;
+	    break;
+	  }
+    }
+
+  b = grub_efi_system_table->boot_services;
+  efi_call_2 (b->free_pages, address, pages);
+}
+
+/* Get the memory map as defined in the EFI spec. Return 1 if successful,
+   return 0 if partial, or return -1 if an error occurs.  */
+int
+grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size,
+			 grub_efi_memory_descriptor_t *memory_map,
+			 grub_efi_uintn_t *map_key,
+			 grub_efi_uintn_t *descriptor_size,
+			 grub_efi_uint32_t *descriptor_version)
+{
+  grub_efi_status_t status;
+  grub_efi_boot_services_t *b;
+  grub_efi_uintn_t key;
+  grub_efi_uint32_t version;
+
+  /* Allow some parameters to be missing.  */
+  if (! map_key)
+    map_key = &key;
+  if (! descriptor_version)
+    descriptor_version = &version;
+
+  b = grub_efi_system_table->boot_services;
+  status = efi_call_5 (b->get_memory_map, memory_map_size, memory_map, map_key,
+			      descriptor_size, descriptor_version);
+  if (status == GRUB_EFI_SUCCESS)
+    return 1;
+  else if (status == GRUB_EFI_BUFFER_TOO_SMALL)
+    return 0;
+  else
+    return -1;
+}
+
+/* Sort the memory map in place.  */
+static void
+sort_memory_map (grub_efi_memory_descriptor_t *memory_map,
+		 grub_efi_uintn_t desc_size,
+		 grub_efi_memory_descriptor_t *memory_map_end)
+{
+  grub_efi_memory_descriptor_t *d1;
+  grub_efi_memory_descriptor_t *d2;
+
+  for (d1 = memory_map;
+       d1 < memory_map_end;
+       d1 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size))
+    {
+      grub_efi_memory_descriptor_t *max_desc = d1;
+
+      for (d2 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size);
+	   d2 < memory_map_end;
+	   d2 = NEXT_MEMORY_DESCRIPTOR (d2, desc_size))
+	{
+	  if (max_desc->num_pages < d2->num_pages)
+	    max_desc = d2;
+	}
+
+      if (max_desc != d1)
+	{
+	  grub_efi_memory_descriptor_t tmp;
+
+	  tmp = *d1;
+	  *d1 = *max_desc;
+	  *max_desc = tmp;
+	}
+    }
+}
+
+/* Filter the descriptors. GRUB needs only available memory.  */
+static grub_efi_memory_descriptor_t *
+filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
+		   grub_efi_memory_descriptor_t *filtered_memory_map,
+		   grub_efi_uintn_t desc_size,
+		   grub_efi_memory_descriptor_t *memory_map_end)
+{
+  grub_efi_memory_descriptor_t *desc;
+  grub_efi_memory_descriptor_t *filtered_desc;
+
+  for (desc = memory_map, filtered_desc = filtered_memory_map;
+       desc < memory_map_end;
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
+#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
+	  && desc->physical_start <= 0xffffffff
+#endif
+	  && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
+	  && desc->num_pages != 0)
+	{
+	  grub_memcpy (filtered_desc, desc, desc_size);
+
+	  /* Avoid less than 1MB, because some loaders seem to be confused.  */
+	  if (desc->physical_start < 0x100000)
+	    {
+	      desc->num_pages -= BYTES_TO_PAGES (0x100000
+						 - desc->physical_start);
+	      desc->physical_start = 0x100000;
+	    }
+
+#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
+	  if (BYTES_TO_PAGES (filtered_desc->physical_start)
+	      + filtered_desc->num_pages
+	      > BYTES_TO_PAGES (0x100000000LL))
+	    filtered_desc->num_pages
+	      = (BYTES_TO_PAGES (0x100000000LL)
+		 - BYTES_TO_PAGES (filtered_desc->physical_start));
+#endif
+
+	  if (filtered_desc->num_pages == 0)
+	    continue;
+
+	  filtered_desc = NEXT_MEMORY_DESCRIPTOR (filtered_desc, desc_size);
+	}
+    }
+
+  return filtered_desc;
+}
+
+/* Return the total number of pages.  */
+static grub_efi_uint64_t
+get_total_pages (grub_efi_memory_descriptor_t *memory_map,
+		 grub_efi_uintn_t desc_size,
+		 grub_efi_memory_descriptor_t *memory_map_end)
+{
+  grub_efi_memory_descriptor_t *desc;
+  grub_efi_uint64_t total = 0;
+
+  for (desc = memory_map;
+       desc < memory_map_end;
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    total += desc->num_pages;
+
+  return total;
+}
+
+/* Add memory regions.  */
+static void
+add_memory_regions (grub_efi_memory_descriptor_t *memory_map,
+		    grub_efi_uintn_t desc_size,
+		    grub_efi_memory_descriptor_t *memory_map_end,
+		    grub_efi_uint64_t required_pages)
+{
+  grub_efi_memory_descriptor_t *desc;
+
+  for (desc = memory_map;
+       desc < memory_map_end;
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      grub_efi_uint64_t pages;
+      grub_efi_physical_address_t start;
+      void *addr;
+
+      start = desc->physical_start;
+      pages = desc->num_pages;
+      if (pages > required_pages)
+	{
+	  start += PAGES_TO_BYTES (pages - required_pages);
+	  pages = required_pages;
+	}
+
+      addr = grub_efi_allocate_pages (start, pages);
+      if (! addr)
+	grub_fatal ("cannot allocate conventional memory %p with %u pages",
+		    (void *) ((grub_addr_t) start),
+		    (unsigned) pages);
+
+      grub_mm_init_region (addr, PAGES_TO_BYTES (pages));
+
+      required_pages -= pages;
+      if (required_pages == 0)
+	break;
+    }
+
+  if (required_pages > 0)
+    grub_fatal ("too little memory");
+}
+
+#if 0
+/* Print the memory map.  */
+static void
+print_memory_map (grub_efi_memory_descriptor_t *memory_map,
+		  grub_efi_uintn_t desc_size,
+		  grub_efi_memory_descriptor_t *memory_map_end)
+{
+  grub_efi_memory_descriptor_t *desc;
+  int i;
+
+  for (desc = memory_map, i = 0;
+       desc < memory_map_end;
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++)
+    {
+      grub_printf ("MD: t=%x, p=%llx, v=%llx, n=%llx, a=%llx\n",
+		   desc->type, desc->physical_start, desc->virtual_start,
+		   desc->num_pages, desc->attribute);
+    }
+}
+#endif
+
+void
+grub_efi_mm_init (void)
+{
+  grub_efi_memory_descriptor_t *memory_map;
+  grub_efi_memory_descriptor_t *memory_map_end;
+  grub_efi_memory_descriptor_t *filtered_memory_map;
+  grub_efi_memory_descriptor_t *filtered_memory_map_end;
+  grub_efi_uintn_t map_size;
+  grub_efi_uintn_t desc_size;
+  grub_efi_uint64_t total_pages;
+  grub_efi_uint64_t required_pages;
+
+  /* First of all, allocate pages to maintain allocations.  */
+  allocated_pages
+    = grub_efi_allocate_pages (0, BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
+  if (! allocated_pages)
+    grub_fatal ("cannot allocate memory");
+
+  grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE);
+
+  /* Prepare a memory region to store two memory maps.  */
+  memory_map = grub_efi_allocate_pages (0,
+					2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+  if (! memory_map)
+    grub_fatal ("cannot allocate memory");
+
+  filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, MEMORY_MAP_SIZE);
+
+  /* Obtain descriptors for available memory.  */
+  map_size = MEMORY_MAP_SIZE;
+
+  if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
+    grub_fatal ("cannot get memory map");
+
+  memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size);
+
+  filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map,
+					       desc_size, memory_map_end);
+
+  /* By default, request a quarter of the available memory.  */
+  total_pages = get_total_pages (filtered_memory_map, desc_size,
+				 filtered_memory_map_end);
+  required_pages = (total_pages >> 2);
+  if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE))
+    required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE);
+  else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE))
+    required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE);
+
+  /* Sort the filtered descriptors, so that GRUB can allocate pages
+     from smaller regions.  */
+  sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end);
+
+  /* Allocate memory regions for GRUB's memory management.  */
+  add_memory_regions (filtered_memory_map, desc_size,
+		      filtered_memory_map_end, required_pages);
+
+#if 0
+  /* For debug.  */
+  map_size = MEMORY_MAP_SIZE;
+
+  if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
+    grub_fatal ("cannot get memory map");
+
+  grub_printf ("printing memory map\n");
+  print_memory_map (memory_map, desc_size,
+		    NEXT_MEMORY_DESCRIPTOR (memory_map, map_size));
+  grub_abort ();
+#endif
+
+  /* Release the memory maps.  */
+  grub_efi_free_pages ((grub_addr_t) memory_map,
+		       2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+}
+
+void
+grub_efi_mm_fini (void)
+{
+  if (allocated_pages)
+    {
+      unsigned i;
+
+      for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
+	{
+	  struct allocated_page *p;
+
+	  p = allocated_pages + i;
+	  if (p->addr != 0)
+	    grub_efi_free_pages ((grub_addr_t) p->addr, p->num_pages);
+	}
+
+      grub_efi_free_pages ((grub_addr_t) allocated_pages,
+			   BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
+    }
+}
diff --git a/kern/elf.c b/kern/elf.c
new file mode 100644
index 0000000..f141610
--- /dev/null
+++ b/kern/elf.c
@@ -0,0 +1,465 @@
+/* elf.c - load ELF files */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/elf.h>
+#include <grub/elfload.h>
+#include <grub/file.h>
+#include <grub/gzio.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+/* Check if EHDR is a valid ELF header.  */
+static grub_err_t
+grub_elf_check_header (grub_elf_t elf)
+{
+  Elf32_Ehdr *e = &elf->ehdr.ehdr32;
+
+  if (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_VERSION] != EV_CURRENT
+      || e->e_version != EV_CURRENT)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch independent ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_elf_close (grub_elf_t elf)
+{
+  grub_file_t file = elf->file;
+
+  grub_free (elf->phdrs);
+  grub_free (elf);
+
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+grub_elf_t
+grub_elf_file (grub_file_t file)
+{
+  grub_elf_t elf;
+
+  elf = grub_zalloc (sizeof (*elf));
+  if (! elf)
+    return 0;
+
+  elf->file = file;
+
+  if (grub_file_seek (elf->file, 0) == (grub_off_t) -1)
+    goto fail;
+
+  if (grub_file_read (elf->file, &elf->ehdr, sizeof (elf->ehdr))
+      != sizeof (elf->ehdr))
+    {
+      grub_error_push ();
+      grub_error (GRUB_ERR_READ_ERROR, "Cannot read ELF header.");
+      goto fail;
+    }
+
+  if (grub_elf_check_header (elf))
+    goto fail;
+
+  return elf;
+
+fail:
+  grub_free (elf->phdrs);
+  grub_free (elf);
+  return 0;
+}
+
+grub_elf_t
+grub_elf_open (const char *name)
+{
+  grub_file_t file;
+  grub_elf_t elf;
+
+  file = grub_gzfile_open (name, 1);
+  if (! file)
+    return 0;
+
+  elf = grub_elf_file (file);
+  if (! elf)
+    grub_file_close (file);
+
+  return elf;
+}
+
+
+/* 32-bit */
+
+int
+grub_elf_is_elf32 (grub_elf_t elf)
+{
+  return elf->ehdr.ehdr32.e_ident[EI_CLASS] == ELFCLASS32;
+}
+
+static grub_err_t
+grub_elf32_load_phdrs (grub_elf_t elf)
+{
+  grub_ssize_t phdrs_size;
+
+  phdrs_size = elf->ehdr.ehdr32.e_phnum * elf->ehdr.ehdr32.e_phentsize;
+
+  grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n",
+		(unsigned long long) elf->ehdr.ehdr32.e_phoff,
+		(unsigned long) phdrs_size);
+
+  elf->phdrs = grub_malloc (phdrs_size);
+  if (! elf->phdrs)
+    return grub_errno;
+
+  if ((grub_file_seek (elf->file, elf->ehdr.ehdr32.e_phoff) == (grub_off_t) -1)
+      || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size))
+    {
+      grub_error_push ();
+      return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers");
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_elf32_phdr_iterate (grub_elf_t elf,
+			 int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf32_Phdr *, void *),
+			 void *hook_arg)
+{
+  Elf32_Phdr *phdrs;
+  unsigned int i;
+
+  if (! elf->phdrs)
+    if (grub_elf32_load_phdrs (elf))
+      return grub_errno;
+  phdrs = elf->phdrs;
+
+  for (i = 0; i < elf->ehdr.ehdr32.e_phnum; i++)
+    {
+      Elf32_Phdr *phdr = phdrs + i;
+      grub_dprintf ("elf",
+		    "Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx "
+		    "filesz %lx\n",
+		    i, phdr->p_type,
+		    (unsigned long) phdr->p_paddr,
+		    (unsigned long) phdr->p_memsz,
+		    (unsigned long) phdr->p_filesz);
+      if (hook (elf, phdr, hook_arg))
+	break;
+    }
+
+  return grub_errno;
+}
+
+/* Calculate the amount of memory spanned by the segments.  */
+grub_size_t
+grub_elf32_size (grub_elf_t elf)
+{
+  Elf32_Addr segments_start = (Elf32_Addr) -1;
+  Elf32_Addr segments_end = 0;
+  int nr_phdrs = 0;
+
+  /* Run through the program headers to calculate the total memory size we
+   * should claim.  */
+  auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf32_Phdr *phdr, void *_arg);
+  int NESTED_FUNC_ATTR calcsize (grub_elf_t UNUSED _elf, Elf32_Phdr *phdr, void UNUSED *_arg)
+    {
+      /* Only consider loadable segments.  */
+      if (phdr->p_type != PT_LOAD)
+	return 0;
+      nr_phdrs++;
+      if (phdr->p_paddr < segments_start)
+	segments_start = phdr->p_paddr;
+      if (phdr->p_paddr + phdr->p_memsz > segments_end)
+	segments_end = phdr->p_paddr + phdr->p_memsz;
+      return 0;
+    }
+
+  grub_elf32_phdr_iterate (elf, calcsize, 0);
+
+  if (nr_phdrs == 0)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "No program headers present");
+      return 0;
+    }
+
+  if (segments_end < segments_start)
+    {
+      /* Very bad addresses.  */
+      grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses");
+      return 0;
+    }
+
+  return segments_end - segments_start;
+}
+
+
+/* Load every loadable segment into memory specified by `_load_hook'.  */
+grub_err_t
+grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook,
+		 grub_addr_t *base, grub_size_t *size)
+{
+  grub_addr_t load_base = (grub_addr_t) -1ULL;
+  grub_size_t load_size = 0;
+  grub_err_t err;
+
+  auto int NESTED_FUNC_ATTR grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook);
+  int NESTED_FUNC_ATTR grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook)
+  {
+    grub_elf32_load_hook_t load_hook = (grub_elf32_load_hook_t) hook;
+    grub_addr_t load_addr;
+    int do_load = 1;
+
+    load_addr = phdr->p_paddr;
+    if (load_hook && load_hook (phdr, &load_addr, &do_load))
+      return 1;
+
+    if (! do_load)
+      return 0;
+
+    if (load_addr < load_base)
+      load_base = load_addr;
+
+    grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
+		  (unsigned long long) load_addr,
+		  (unsigned long long) phdr->p_memsz);
+
+    if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
+      {
+	grub_error_push ();
+	return grub_error (GRUB_ERR_BAD_OS,
+			   "Invalid offset in program header.");
+      }
+
+    if (phdr->p_filesz)
+      {
+	grub_ssize_t read;
+	read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
+	if (read != (grub_ssize_t) phdr->p_filesz)
+	  {
+	    /* XXX How can we free memory from `load_hook'? */
+	    grub_error_push ();
+	    return grub_error (GRUB_ERR_BAD_OS,
+			       "Couldn't read segment from file: "
+			       "wanted 0x%lx bytes; read 0x%lx bytes.",
+			       phdr->p_filesz, read);
+	  }
+      }
+
+    if (phdr->p_filesz < phdr->p_memsz)
+      grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
+		   0, phdr->p_memsz - phdr->p_filesz);
+
+    load_size += phdr->p_memsz;
+
+    return 0;
+  }
+
+  err = grub_elf32_phdr_iterate (_elf, grub_elf32_load_segment, _load_hook);
+
+  if (base)
+    *base = load_base;
+  if (size)
+    *size = load_size;
+
+  return err;
+}
+
+
+
+/* 64-bit */
+
+int
+grub_elf_is_elf64 (grub_elf_t elf)
+{
+  return elf->ehdr.ehdr64.e_ident[EI_CLASS] == ELFCLASS64;
+}
+
+static grub_err_t
+grub_elf64_load_phdrs (grub_elf_t elf)
+{
+  grub_ssize_t phdrs_size;
+
+  phdrs_size = elf->ehdr.ehdr64.e_phnum * elf->ehdr.ehdr64.e_phentsize;
+
+  grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n",
+		(unsigned long long) elf->ehdr.ehdr64.e_phoff,
+		(unsigned long) phdrs_size);
+
+  elf->phdrs = grub_malloc (phdrs_size);
+  if (! elf->phdrs)
+    return grub_errno;
+
+  if ((grub_file_seek (elf->file, elf->ehdr.ehdr64.e_phoff) == (grub_off_t) -1)
+      || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size))
+    {
+      grub_error_push ();
+      return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers");
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_elf64_phdr_iterate (grub_elf_t elf,
+			 int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf64_Phdr *, void *),
+			 void *hook_arg)
+{
+  Elf64_Phdr *phdrs;
+  unsigned int i;
+
+  if (! elf->phdrs)
+    if (grub_elf64_load_phdrs (elf))
+      return grub_errno;
+  phdrs = elf->phdrs;
+
+  for (i = 0; i < elf->ehdr.ehdr64.e_phnum; i++)
+    {
+      Elf64_Phdr *phdr = phdrs + i;
+      grub_dprintf ("elf",
+		    "Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx "
+		    "filesz %lx\n",
+		    i, phdr->p_type,
+		    (unsigned long) phdr->p_paddr,
+		    (unsigned long) phdr->p_memsz,
+		    (unsigned long) phdr->p_filesz);
+      if (hook (elf, phdr, hook_arg))
+	break;
+    }
+
+  return grub_errno;
+}
+
+/* Calculate the amount of memory spanned by the segments.  */
+grub_size_t
+grub_elf64_size (grub_elf_t elf)
+{
+  Elf64_Addr segments_start = (Elf64_Addr) -1;
+  Elf64_Addr segments_end = 0;
+  int nr_phdrs = 0;
+
+  /* Run through the program headers to calculate the total memory size we
+   * should claim.  */
+  auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg);
+  int NESTED_FUNC_ATTR calcsize (grub_elf_t UNUSED _elf, Elf64_Phdr *phdr, void UNUSED *_arg)
+    {
+      /* Only consider loadable segments.  */
+      if (phdr->p_type != PT_LOAD)
+	return 0;
+      nr_phdrs++;
+      if (phdr->p_paddr < segments_start)
+	segments_start = phdr->p_paddr;
+      if (phdr->p_paddr + phdr->p_memsz > segments_end)
+	segments_end = phdr->p_paddr + phdr->p_memsz;
+      return 0;
+    }
+
+  grub_elf64_phdr_iterate (elf, calcsize, 0);
+
+  if (nr_phdrs == 0)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "No program headers present");
+      return 0;
+    }
+
+  if (segments_end < segments_start)
+    {
+      /* Very bad addresses.  */
+      grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses");
+      return 0;
+    }
+
+  return segments_end - segments_start;
+}
+
+
+/* Load every loadable segment into memory specified by `_load_hook'.  */
+grub_err_t
+grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook,
+		 grub_addr_t *base, grub_size_t *size)
+{
+  grub_addr_t load_base = (grub_addr_t) -1ULL;
+  grub_size_t load_size = 0;
+  grub_err_t err;
+
+  auto int NESTED_FUNC_ATTR grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr,
+						     void *hook);
+  int NESTED_FUNC_ATTR grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr, void *hook)
+  {
+    grub_elf64_load_hook_t load_hook = (grub_elf64_load_hook_t) hook;
+    grub_addr_t load_addr;
+    int do_load = 1;
+
+    load_addr = phdr->p_paddr;
+    if (load_hook && load_hook (phdr, &load_addr, &do_load))
+      return 1;
+
+    if (! do_load)
+      return 0;
+
+    if (load_addr < load_base)
+      load_base = load_addr;
+
+    grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
+		  (unsigned long long) load_addr,
+		  (unsigned long long) phdr->p_memsz);
+
+    if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
+      {
+	grub_error_push ();
+	return grub_error (GRUB_ERR_BAD_OS,
+			   "Invalid offset in program header.");
+      }
+
+    if (phdr->p_filesz)
+      {
+	grub_ssize_t read;
+	read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
+	if (read != (grub_ssize_t) phdr->p_filesz)
+          {
+	    /* XXX How can we free memory from `load_hook'?  */
+	    grub_error_push ();
+	    return grub_error (GRUB_ERR_BAD_OS,
+			      "Couldn't read segment from file: "
+			      "wanted 0x%lx bytes; read 0x%lx bytes.",
+			      phdr->p_filesz, read);
+          }
+      }
+
+    if (phdr->p_filesz < phdr->p_memsz)
+      grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
+		   0, phdr->p_memsz - phdr->p_filesz);
+
+    load_size += phdr->p_memsz;
+
+    return 0;
+  }
+
+  err = grub_elf64_phdr_iterate (_elf, grub_elf64_load_segment, _load_hook);
+
+  if (base)
+    *base = load_base;
+  if (size)
+    *size = load_size;
+
+  return err;
+}
diff --git a/kern/env.c b/kern/env.c
new file mode 100644
index 0000000..750902a
--- /dev/null
+++ b/kern/env.c
@@ -0,0 +1,426 @@
+/* env.c - Environment variables */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+/* The size of the hash table.  */
+#define	HASHSZ	13
+
+/* A hashtable for quick lookup of variables.  */
+struct grub_env_context
+{
+  /* A hash table for variables.  */
+  struct grub_env_var *vars[HASHSZ];
+
+  /* One level deeper on the stack.  */
+  struct grub_env_context *prev;
+};
+
+/* This is used for sorting only.  */
+struct grub_env_sorted_var
+{
+  struct grub_env_var *var;
+  struct grub_env_sorted_var *next;
+};
+
+/* The initial context.  */
+static struct grub_env_context initial_context;
+
+/* The current context.  */
+static struct grub_env_context *current_context = &initial_context;
+
+/* Return the hash representation of the string S.  */
+static unsigned int
+grub_env_hashval (const char *s)
+{
+  unsigned int i = 0;
+
+  /* XXX: This can be done much more efficiently.  */
+  while (*s)
+    i += 5 * *(s++);
+
+  return i % HASHSZ;
+}
+
+static struct grub_env_var *
+grub_env_find (const char *name)
+{
+  struct grub_env_var *var;
+  int idx = grub_env_hashval (name);
+
+  /* Look for the variable in the current context.  */
+  for (var = current_context->vars[idx]; var; var = var->next)
+    if (grub_strcmp (var->name, name) == 0)
+      return var;
+
+  return 0;
+}
+
+grub_err_t
+grub_env_context_open (int export)
+{
+  struct grub_env_context *context;
+  int i;
+
+  context = grub_zalloc (sizeof (*context));
+  if (! context)
+    return grub_errno;
+
+  context->prev = current_context;
+  current_context = context;
+
+  /* Copy exported variables.  */
+  for (i = 0; i < HASHSZ; i++)
+    {
+      struct grub_env_var *var;
+
+      for (var = context->prev->vars[i]; var; var = var->next)
+	{
+	  if (export && var->type == GRUB_ENV_VAR_GLOBAL)
+	    {
+	      if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE)
+		{
+		  grub_env_context_close ();
+		  return grub_errno;
+		}
+	      grub_register_variable_hook (var->name, var->read_hook, var->write_hook);
+	    }
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_env_context_close (void)
+{
+  struct grub_env_context *context;
+  int i;
+
+  if (! current_context->prev)
+    grub_fatal ("cannot close the initial context");
+
+  /* Free the variables associated with this context.  */
+  for (i = 0; i < HASHSZ; i++)
+    {
+      struct grub_env_var *p, *q;
+
+      for (p = current_context->vars[i]; p; p = q)
+	{
+	  q = p->next;
+          grub_free (p->name);
+          if (p->type != GRUB_ENV_VAR_DATA)
+            grub_free (p->value);
+	  grub_free (p);
+	}
+    }
+
+  /* Restore the previous context.  */
+  context = current_context->prev;
+  grub_free (current_context);
+  current_context = context;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_env_insert (struct grub_env_context *context,
+		 struct grub_env_var *var)
+{
+  int idx = grub_env_hashval (var->name);
+
+  /* Insert the variable into the hashtable.  */
+  var->prevp = &context->vars[idx];
+  var->next = context->vars[idx];
+  if (var->next)
+    var->next->prevp = &(var->next);
+  context->vars[idx] = var;
+}
+
+static void
+grub_env_remove (struct grub_env_var *var)
+{
+  /* Remove the entry from the variable table.  */
+  *var->prevp = var->next;
+  if (var->next)
+    var->next->prevp = var->prevp;
+}
+
+grub_err_t
+grub_env_export (const char *name)
+{
+  struct grub_env_var *var;
+
+  var = grub_env_find (name);
+  if (var)
+    var->type = GRUB_ENV_VAR_GLOBAL;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_env_set (const char *name, const char *val)
+{
+  struct grub_env_var *var;
+
+  /* If the variable does already exist, just update the variable.  */
+  var = grub_env_find (name);
+  if (var)
+    {
+      char *old = var->value;
+
+      if (var->write_hook)
+	var->value = var->write_hook (var, val);
+      else
+	var->value = grub_strdup (val);
+
+      if (! var->value)
+	{
+	  var->value = old;
+	  return grub_errno;
+	}
+
+      grub_free (old);
+      return GRUB_ERR_NONE;
+    }
+
+  /* The variable does not exist, so create a new one.  */
+  var = grub_zalloc (sizeof (*var));
+  if (! var)
+    return grub_errno;
+
+  /* This is not necessary, because GRUB_ENV_VAR_LOCAL == 0. But leave
+     this for readability.  */
+  var->type = GRUB_ENV_VAR_LOCAL;
+
+  var->name = grub_strdup (name);
+  if (! var->name)
+    goto fail;
+
+  var->value = grub_strdup (val);
+  if (! var->value)
+    goto fail;
+
+  grub_env_insert (current_context, var);
+
+  return GRUB_ERR_NONE;
+
+ fail:
+  grub_free (var->name);
+  grub_free (var->value);
+  grub_free (var);
+
+  return grub_errno;
+}
+
+char *
+grub_env_get (const char *name)
+{
+  struct grub_env_var *var;
+
+  var = grub_env_find (name);
+  if (! var)
+    return 0;
+
+  if (var->read_hook)
+    return var->read_hook (var, var->value);
+
+  return var->value;
+}
+
+void
+grub_env_unset (const char *name)
+{
+  struct grub_env_var *var;
+
+  var = grub_env_find (name);
+  if (! var)
+    return;
+
+  /* XXX: It is not possible to unset variables with a read or write
+     hook.  */
+  if (var->read_hook || var->write_hook)
+    return;
+
+  grub_env_remove (var);
+
+  grub_free (var->name);
+  if (var->type != GRUB_ENV_VAR_DATA)
+    grub_free (var->value);
+  grub_free (var);
+}
+
+void
+grub_env_iterate (int (*func) (struct grub_env_var *var))
+{
+  struct grub_env_sorted_var *sorted_list = 0;
+  struct grub_env_sorted_var *sorted_var;
+  int i;
+
+  /* Add variables associated with this context into a sorted list.  */
+  for (i = 0; i < HASHSZ; i++)
+    {
+      struct grub_env_var *var;
+
+      for (var = current_context->vars[i]; var; var = var->next)
+	{
+	  struct grub_env_sorted_var *p, **q;
+
+	  /* Ignore data slots.  */
+	  if (var->type == GRUB_ENV_VAR_DATA)
+	    continue;
+
+	  sorted_var = grub_malloc (sizeof (*sorted_var));
+	  if (! sorted_var)
+	    goto fail;
+
+	  sorted_var->var = var;
+
+	  for (q = &sorted_list, p = *q; p; q = &((*q)->next), p = *q)
+	    {
+	      if (grub_strcmp (p->var->name, var->name) > 0)
+		break;
+	    }
+
+	  sorted_var->next = *q;
+	  *q = sorted_var;
+	}
+    }
+
+  /* Iterate FUNC on the sorted list.  */
+  for (sorted_var = sorted_list; sorted_var; sorted_var = sorted_var->next)
+    if (func (sorted_var->var))
+      break;
+
+ fail:
+
+  /* Free the sorted list.  */
+  for (sorted_var = sorted_list; sorted_var; )
+    {
+      struct grub_env_sorted_var *tmp = sorted_var->next;
+
+      grub_free (sorted_var);
+      sorted_var = tmp;
+    }
+}
+
+grub_err_t
+grub_register_variable_hook (const char *name,
+			     grub_env_read_hook_t read_hook,
+			     grub_env_write_hook_t write_hook)
+{
+  struct grub_env_var *var = grub_env_find (name);
+
+  if (! var)
+    {
+      if (grub_env_set (name, "") != GRUB_ERR_NONE)
+	return grub_errno;
+
+      var = grub_env_find (name);
+      /* XXX Insert an assertion?  */
+    }
+
+  var->read_hook = read_hook;
+  var->write_hook = write_hook;
+
+  return GRUB_ERR_NONE;
+}
+
+static char *
+mangle_data_slot_name (const char *name)
+{
+  char *mangled_name;
+
+  mangled_name = grub_malloc (grub_strlen (name) + 2);
+  if (! mangled_name)
+    return 0;
+
+  grub_sprintf (mangled_name, "\e%s", name);
+  return mangled_name;
+}
+
+grub_err_t
+grub_env_set_data_slot (const char *name, const void *ptr)
+{
+  char *mangled_name;
+  struct grub_env_var *var;
+
+  mangled_name = mangle_data_slot_name (name);
+  if (! mangled_name)
+    goto fail;
+
+  /* If the variable does already exist, just update the variable.  */
+  var = grub_env_find (mangled_name);
+  if (var)
+    {
+      var->value = (char *) ptr;
+      return GRUB_ERR_NONE;
+    }
+
+  /* The variable does not exist, so create a new one.  */
+  var = grub_zalloc (sizeof (*var));
+  if (! var)
+    goto fail;
+
+  var->type = GRUB_ENV_VAR_DATA;
+  var->name = mangled_name;
+  var->value = (char *) ptr;
+
+  grub_env_insert (current_context, var);
+
+  return GRUB_ERR_NONE;
+
+ fail:
+
+  grub_free (mangled_name);
+  return grub_errno;
+}
+
+void *
+grub_env_get_data_slot (const char *name)
+{
+  char *mangled_name;
+  void *ptr = 0;
+
+  mangled_name = mangle_data_slot_name (name);
+  if (! mangled_name)
+    goto fail;
+
+  ptr = grub_env_get (mangled_name);
+  grub_free (mangled_name);
+
+ fail:
+
+  return ptr;
+}
+
+void
+grub_env_unset_data_slot (const char *name)
+{
+  char *mangled_name;
+
+  mangled_name = mangle_data_slot_name (name);
+  if (! mangled_name)
+    return;
+
+  grub_env_unset (mangled_name);
+  grub_free (mangled_name);
+}
diff --git a/kern/err.c b/kern/err.c
new file mode 100644
index 0000000..3111301
--- /dev/null
+++ b/kern/err.c
@@ -0,0 +1,134 @@
+/* err.c - error handling routines */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <stdarg.h>
+
+#define GRUB_MAX_ERRMSG		256
+#define GRUB_ERROR_STACK_SIZE	10
+
+grub_err_t grub_errno;
+char grub_errmsg[GRUB_MAX_ERRMSG];
+
+static struct
+{
+  grub_err_t errno;
+  char errmsg[GRUB_MAX_ERRMSG];
+} grub_error_stack_items[GRUB_ERROR_STACK_SIZE];
+
+static int grub_error_stack_pos;
+static int grub_error_stack_assert;
+
+grub_err_t
+grub_error (grub_err_t n, const char *fmt, ...)
+{
+  va_list ap;
+
+  grub_errno = n;
+
+  va_start (ap, fmt);
+  grub_vsprintf (grub_errmsg, fmt, ap);
+  va_end (ap);
+
+  return n;
+}
+
+void
+grub_fatal (const char *fmt, ...)
+{
+  va_list ap;
+
+  va_start (ap, fmt);
+  grub_vprintf (fmt, ap);
+  va_end (ap);
+
+  grub_abort ();
+}
+
+void
+grub_error_push (void)
+{
+  /* Only add items to stack, if there is enough room.  */
+  if (grub_error_stack_pos < GRUB_ERROR_STACK_SIZE)
+    {
+      /* Copy active error message to stack.  */
+      grub_error_stack_items[grub_error_stack_pos].errno = grub_errno;
+      grub_memcpy (grub_error_stack_items[grub_error_stack_pos].errmsg,
+                   grub_errmsg,
+                   sizeof (grub_errmsg));
+
+      /* Advance to next error stack position.  */
+      grub_error_stack_pos++;
+    }
+  else
+    {
+      /* There is no room for new error message. Discard new error message
+         and mark error stack assertion flag.  */
+      grub_error_stack_assert = 1;
+    }
+
+  /* Allow further operation of other components by resetting
+     active errno to GRUB_ERR_NONE.  */
+  grub_errno = GRUB_ERR_NONE;
+}
+
+int
+grub_error_pop (void)
+{
+  if (grub_error_stack_pos > 0)
+    {
+      /* Pop error message from error stack to current active error.  */
+      grub_error_stack_pos--;
+
+      grub_errno = grub_error_stack_items[grub_error_stack_pos].errno;
+      grub_memcpy (grub_errmsg,
+                   grub_error_stack_items[grub_error_stack_pos].errmsg,
+                   sizeof (grub_errmsg));
+
+      return 1;
+    }
+  else
+    {
+      /* There is no more items on error stack, reset to no error state.  */
+      grub_errno = GRUB_ERR_NONE;
+
+      return 0;
+    }
+}
+
+void
+grub_print_error (void)
+{
+  /* Print error messages in reverse order. First print active error message
+     and then empty error stack.  */
+  do
+    {
+      if (grub_errno != GRUB_ERR_NONE)
+        grub_err_printf ("error: %s\n", grub_errmsg);
+    }
+  while (grub_error_pop ());
+
+  /* If there was an assert while using error stack, report about it.  */
+  if (grub_error_stack_assert)
+    {
+      grub_err_printf ("assert: error stack overflow detected!\n");
+      grub_error_stack_assert = 0;
+    }
+}
diff --git a/kern/file.c b/kern/file.c
new file mode 100644
index 0000000..f713acb
--- /dev/null
+++ b/kern/file.c
@@ -0,0 +1,166 @@
+/* file.c - file I/O functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/fs.h>
+#include <grub/device.h>
+
+/* Get the device part of the filename NAME. It is enclosed by parentheses.  */
+char *
+grub_file_get_device_name (const char *name)
+{
+  if (name[0] == '(')
+    {
+      char *p = grub_strchr (name, ')');
+      char *ret;
+
+      if (! p)
+	{
+	  grub_error (GRUB_ERR_BAD_FILENAME, "missing `)'");
+	  return 0;
+	}
+
+      ret = (char *) grub_malloc (p - name);
+      if (! ret)
+	return 0;
+
+      grub_memcpy (ret, name + 1, p - name - 1);
+      ret[p - name - 1] = '\0';
+      return ret;
+    }
+
+  return 0;
+}
+
+grub_file_t
+grub_file_open (const char *name)
+{
+  grub_device_t device;
+  grub_file_t file = 0;
+  char *device_name;
+  char *file_name;
+
+  device_name = grub_file_get_device_name (name);
+  if (grub_errno)
+    return 0;
+
+  /* Get the file part of NAME.  */
+  file_name = grub_strchr (name, ')');
+  if (file_name)
+    file_name++;
+  else
+    file_name = (char *) name;
+
+  device = grub_device_open (device_name);
+  grub_free (device_name);
+  if (! device)
+    goto fail;
+
+  file = (grub_file_t) grub_zalloc (sizeof (*file));
+  if (! file)
+    goto fail;
+
+  file->device = device;
+
+  if (device->disk && file_name[0] != '/')
+    /* This is a block list.  */
+    file->fs = &grub_fs_blocklist;
+  else
+    {
+      file->fs = grub_fs_probe (device);
+      if (! file->fs)
+	goto fail;
+    }
+
+  if ((file->fs->open) (file, file_name) != GRUB_ERR_NONE)
+    goto fail;
+
+  return file;
+
+ fail:
+  if (device)
+    grub_device_close (device);
+
+  /* if (net) grub_net_close (net);  */
+
+  grub_free (file);
+
+  return 0;
+}
+
+grub_ssize_t
+grub_file_read (grub_file_t file, void *buf, grub_size_t len)
+{
+  grub_ssize_t res;
+
+  if (file->offset > file->size)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE,
+		  "Attempt to read past the end of file.");
+      return -1;
+    }
+
+  if (len == 0 || len > file->size - file->offset)
+    len = file->size - file->offset;
+
+  /* Prevent an overflow.  */
+  if ((grub_ssize_t) len < 0)
+    len >>= 1;
+
+  if (len == 0)
+    return 0;
+
+  res = (file->fs->read) (file, buf, len);
+  if (res > 0)
+    file->offset += res;
+
+  return res;
+}
+
+grub_err_t
+grub_file_close (grub_file_t file)
+{
+  if (file->fs->close)
+    (file->fs->close) (file);
+
+  if (file->device)
+    grub_device_close (file->device);
+  grub_free (file);
+  return grub_errno;
+}
+
+grub_off_t
+grub_file_seek (grub_file_t file, grub_off_t offset)
+{
+  grub_off_t old;
+
+  if (offset > file->size)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE,
+		  "attempt to seek outside of the file");
+      return -1;
+    }
+
+  old = file->offset;
+  file->offset = offset;
+  return old;
+}
diff --git a/kern/fs.c b/kern/fs.c
new file mode 100644
index 0000000..0c45637
--- /dev/null
+++ b/kern/fs.c
@@ -0,0 +1,261 @@
+/* fs.c - filesystem manager */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/net.h>
+#include <grub/fs.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/term.h>
+
+static grub_fs_t grub_fs_list;
+
+grub_fs_autoload_hook_t grub_fs_autoload_hook = 0;
+
+void
+grub_fs_register (grub_fs_t fs)
+{
+  fs->next = grub_fs_list;
+  grub_fs_list = fs;
+}
+
+void
+grub_fs_unregister (grub_fs_t fs)
+{
+  grub_fs_t *p, q;
+
+  for (p = &grub_fs_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == fs)
+      {
+	*p = q->next;
+	break;
+      }
+}
+
+void
+grub_fs_iterate (int (*hook) (const grub_fs_t fs))
+{
+  grub_fs_t p;
+
+  for (p = grub_fs_list; p; p = p->next)
+    if (hook (p))
+      break;
+}
+
+grub_fs_t
+grub_fs_probe (grub_device_t device)
+{
+  grub_fs_t p;
+  auto int dummy_func (const char *filename,
+		       const struct grub_dirhook_info *info);
+
+  int dummy_func (const char *filename __attribute__ ((unused)),
+		  const struct grub_dirhook_info *info  __attribute__ ((unused)))
+    {
+      return 1;
+    }
+
+  if (device->disk)
+    {
+      /* Make it sure not to have an infinite recursive calls.  */
+      static int count = 0;
+
+      for (p = grub_fs_list; p; p = p->next)
+	{
+	  grub_dprintf ("fs", "Detecting %s...\n", p->name);
+	  (p->dir) (device, "/", dummy_func);
+	  if (grub_errno == GRUB_ERR_NONE)
+	    return p;
+
+	  grub_error_push ();
+	  grub_dprintf ("fs", "%s detection failed.\n", p->name);
+	  grub_error_pop ();
+
+	  if (grub_errno != GRUB_ERR_BAD_FS)
+	    return 0;
+
+	  grub_errno = GRUB_ERR_NONE;
+	}
+
+      /* Let's load modules automatically.  */
+      if (grub_fs_autoload_hook && count == 0)
+	{
+	  count++;
+
+	  while (grub_fs_autoload_hook ())
+	    {
+	      p = grub_fs_list;
+
+	      (p->dir) (device, "/", dummy_func);
+	      if (grub_errno == GRUB_ERR_NONE)
+		{
+		  count--;
+		  return p;
+		}
+
+	      if (grub_errno != GRUB_ERR_BAD_FS)
+		{
+		  count--;
+		  return 0;
+		}
+
+	      grub_errno = GRUB_ERR_NONE;
+	    }
+
+	  count--;
+	}
+    }
+  else if (device->net->fs)
+    return device->net->fs;
+
+  grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem");
+  return 0;
+}
+
+
+
+/* Block list support routines.  */
+
+struct grub_fs_block
+{
+  grub_disk_addr_t offset;
+  unsigned long length;
+};
+
+static grub_err_t
+grub_fs_blocklist_open (grub_file_t file, const char *name)
+{
+  char *p = (char *) name;
+  unsigned num = 0;
+  unsigned i;
+  grub_disk_t disk = file->device->disk;
+  struct grub_fs_block *blocks;
+
+  /* First, count the number of blocks.  */
+  do
+    {
+      num++;
+      p = grub_strchr (p, ',');
+      if (p)
+	p++;
+    }
+  while (p);
+
+  /* Allocate a block list.  */
+  blocks = grub_zalloc (sizeof (struct grub_fs_block) * (num + 1));
+  if (! blocks)
+    return 0;
+
+  file->size = 0;
+  p = (char *) name;
+  for (i = 0; i < num; i++)
+    {
+      if (*p != '+')
+	{
+	  blocks[i].offset = grub_strtoull (p, &p, 0);
+	  if (grub_errno != GRUB_ERR_NONE || *p != '+')
+	    {
+	      grub_error (GRUB_ERR_BAD_FILENAME,
+			  "invalid file name `%s'", name);
+	      goto fail;
+	    }
+	}
+
+      p++;
+      blocks[i].length = grub_strtoul (p, &p, 0);
+      if (grub_errno != GRUB_ERR_NONE
+	  || blocks[i].length == 0
+	  || (*p && *p != ',' && ! grub_isspace (*p)))
+	{
+	  grub_error (GRUB_ERR_BAD_FILENAME,
+		      "invalid file name `%s'", name);
+	  goto fail;
+	}
+
+      if (disk->total_sectors < blocks[i].offset + blocks[i].length)
+	{
+	  grub_error (GRUB_ERR_BAD_FILENAME, "beyond the total sectors");
+	  goto fail;
+	}
+
+      file->size += (blocks[i].length << GRUB_DISK_SECTOR_BITS);
+      p++;
+    }
+
+  file->data = blocks;
+
+  return GRUB_ERR_NONE;
+
+ fail:
+  grub_free (blocks);
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_fs_block *p;
+  grub_disk_addr_t sector;
+  grub_off_t offset;
+  grub_ssize_t ret = 0;
+
+  if (len > file->size - file->offset)
+    len = file->size - file->offset;
+
+  sector = (file->offset >> GRUB_DISK_SECTOR_BITS);
+  offset = (file->offset & (GRUB_DISK_SECTOR_SIZE - 1));
+  for (p = file->data; p->length && len > 0; p++)
+    {
+      if (sector < p->length)
+	{
+	  grub_size_t size;
+
+	  size = len;
+	  if (((size + offset + GRUB_DISK_SECTOR_SIZE - 1)
+	       >> GRUB_DISK_SECTOR_BITS) > p->length - sector)
+	    size = ((p->length - sector) << GRUB_DISK_SECTOR_BITS) - offset;
+
+	  if (grub_disk_read (file->device->disk, p->offset + sector, offset,
+			      size, buf) != GRUB_ERR_NONE)
+	    return -1;
+
+	  ret += size;
+	  len -= size;
+	  sector -= ((size + offset) >> GRUB_DISK_SECTOR_BITS);
+	  offset = ((size + offset) & (GRUB_DISK_SECTOR_SIZE - 1));
+	}
+      else
+	sector -= p->length;
+    }
+
+  return ret;
+}
+
+struct grub_fs grub_fs_blocklist =
+  {
+    .name = "blocklist",
+    .dir = 0,
+    .open = grub_fs_blocklist_open,
+    .read = grub_fs_blocklist_read,
+    .close = 0,
+    .next = 0
+  };
diff --git a/kern/generic/millisleep.c b/kern/generic/millisleep.c
new file mode 100644
index 0000000..9d5971f
--- /dev/null
+++ b/kern/generic/millisleep.c
@@ -0,0 +1,39 @@
+/* millisleep.c - generic millisleep function.
+ * The generic implementation of these functions can be used for architectures
+ * or platforms that do not have a more specialized implementation. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/time.h>
+
+void
+grub_millisleep (grub_uint32_t ms)
+{
+  grub_uint64_t start;
+
+  start = grub_get_time_ms ();
+
+  /* Instead of setting an end time and looping while the current time is
+     less than that, comparing the elapsed sleep time with the desired sleep
+     time handles the (unlikely!) case that the timer would wrap around
+     during the sleep. */
+
+  while (grub_get_time_ms () - start < ms)
+    grub_cpu_idle ();
+}
diff --git a/kern/generic/rtc_get_time_ms.c b/kern/generic/rtc_get_time_ms.c
new file mode 100644
index 0000000..3592336
--- /dev/null
+++ b/kern/generic/rtc_get_time_ms.c
@@ -0,0 +1,37 @@
+/* rtc_get_time_ms.c - get_time_ms implementation using platform RTC.
+ * The generic implementation of these functions can be used for architectures
+ * or platforms that do not have a more specialized implementation. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/time.h>
+#include <grub/misc.h>
+
+/* Calculate the time in milliseconds since the epoch based on the RTC. */
+grub_uint64_t
+grub_rtc_get_time_ms (void)
+{
+  /* By dimensional analysis:
+
+      1000 ms   N rtc ticks       1 s
+      ------- * ----------- * ----------- = 1000*N/T ms
+        1 s          1        T rtc ticks
+   */
+  grub_uint64_t ticks_ms_per_sec = ((grub_uint64_t) 1000) * grub_get_rtc ();
+  return grub_divmod64 (ticks_ms_per_sec, GRUB_TICKS_PER_SECOND, 0);
+}
diff --git a/kern/handler.c b/kern/handler.c
new file mode 100644
index 0000000..2bf8531
--- /dev/null
+++ b/kern/handler.c
@@ -0,0 +1,64 @@
+/* handler.c - grub handler function */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/handler.h>
+
+grub_handler_class_t grub_handler_class_list;
+
+void
+grub_handler_register (grub_handler_class_t class, grub_handler_t handler)
+{
+  int first_handler = (class->handler_list == 0);
+
+  grub_list_push (GRUB_AS_LIST_P (&class->handler_list),
+		  GRUB_AS_LIST (handler));
+
+  if (first_handler)
+    {
+      grub_list_push (GRUB_AS_LIST_P (&grub_handler_class_list),
+		      GRUB_AS_LIST (class));
+      grub_handler_set_current (class, handler);
+    }
+}
+
+void
+grub_handler_unregister (grub_handler_class_t class, grub_handler_t handler)
+{
+  grub_list_remove (GRUB_AS_LIST_P (&class->handler_list),
+		    GRUB_AS_LIST (handler));
+
+  if (class->handler_list == 0)
+    grub_list_remove (GRUB_AS_LIST_P (&grub_handler_class_list),
+		      GRUB_AS_LIST (class));
+}
+
+grub_err_t
+grub_handler_set_current (grub_handler_class_t class, grub_handler_t handler)
+{
+  if (class->cur_handler && class->cur_handler->fini)
+    if ((class->cur_handler->fini) () != GRUB_ERR_NONE)
+      return grub_errno;
+
+  if (handler->init)
+    if ((handler->init) () != GRUB_ERR_NONE)
+      return grub_errno;
+
+  class->cur_handler = handler;
+  return GRUB_ERR_NONE;
+}
diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c
new file mode 100644
index 0000000..1b9ca38
--- /dev/null
+++ b/kern/i386/coreboot/init.c
@@ -0,0 +1,153 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/mm.h>
+#include <grub/machine/time.h>
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/console.h>
+#include <grub/machine/kernel.h>
+#include <grub/machine/machine.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/loader.h>
+#include <grub/env.h>
+#include <grub/cache.h>
+#include <grub/time.h>
+#include <grub/symbol.h>
+#include <grub/cpu/io.h>
+#include <grub/cpu/kernel.h>
+#include <grub/cpu/tsc.h>
+
+#define GRUB_FLOPPY_REG_DIGITAL_OUTPUT		0x3f2
+
+extern char _start[];
+extern char _end[];
+
+grub_addr_t grub_os_area_addr;
+grub_size_t grub_os_area_size;
+
+grub_uint32_t
+grub_get_rtc (void)
+{
+  grub_fatal ("grub_get_rtc() is not implemented.\n");
+}
+
+/* Stop the floppy drive from spinning, so that other software is
+   jumped to with a known state.  */
+void
+grub_stop_floppy (void)
+{
+  grub_outb (0, GRUB_FLOPPY_REG_DIGITAL_OUTPUT);
+}
+
+void
+grub_exit (void)
+{
+  grub_fatal ("grub_exit() is not implemented.\n");
+}
+
+void
+grub_arch_sync_caches (void *address __attribute__ ((unused)),
+		       grub_size_t len __attribute__ ((unused)))
+{
+}
+
+void
+grub_machine_init (void)
+{
+  /* Initialize the console as early as possible.  */
+  grub_vga_text_init ();
+
+  auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+  {
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+    /* Restrict ourselves to 32-bit memory space.  */
+    if (addr > GRUB_ULONG_MAX)
+      return 0;
+    if (addr + size > GRUB_ULONG_MAX)
+      size = GRUB_ULONG_MAX - addr;
+#endif
+
+    if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+      return 0;
+
+    /* Avoid the lower memory.  */
+    if (addr < GRUB_MEMORY_MACHINE_LOWER_SIZE)
+      {
+	if (addr + size <= GRUB_MEMORY_MACHINE_LOWER_SIZE)
+	  return 0;
+	else
+	  {
+	    size -= GRUB_MEMORY_MACHINE_LOWER_SIZE - addr;
+	    addr = GRUB_MEMORY_MACHINE_LOWER_SIZE;
+	  }
+      }
+
+    if (addr == GRUB_MEMORY_MACHINE_UPPER_START
+	|| (addr >= GRUB_MEMORY_MACHINE_LOWER_SIZE
+	    && addr <= GRUB_MEMORY_MACHINE_UPPER_START
+	    && (addr + size > GRUB_MEMORY_MACHINE_UPPER_START)))
+      {
+	grub_size_t quarter = size >> 2;
+
+	grub_os_area_addr = addr;
+	grub_os_area_size = size - quarter;
+	grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size),
+			     quarter);
+      }
+    else
+      grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size);
+
+    return 0;
+  }
+
+  grub_machine_mmap_init ();
+  grub_machine_mmap_iterate (heap_init);
+
+  grub_tsc_init ();
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  /* Initialize the prefix.  */
+  grub_env_set ("prefix", grub_prefix);
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_vga_text_fini ();
+  grub_stop_floppy ();
+}
+
+/* Return the end of the core image.  */
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+#ifdef GRUB_MACHINE_QEMU
+  return grub_core_entry_addr + grub_kernel_image_size;
+#else
+  return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN);
+#endif
+}
diff --git a/kern/i386/coreboot/mmap.c b/kern/i386/coreboot/mmap.c
new file mode 100644
index 0000000..b15369e
--- /dev/null
+++ b/kern/i386/coreboot/mmap.c
@@ -0,0 +1,97 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+
+static grub_err_t
+grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t))
+{
+  grub_linuxbios_table_header_t table_header;
+  grub_linuxbios_table_item_t table_item;
+
+  auto int check_signature (grub_linuxbios_table_header_t);
+  int check_signature (grub_linuxbios_table_header_t tbl_header)
+  {
+    if (! grub_memcmp (tbl_header->signature, "LBIO", 4))
+      return 1;
+
+    return 0;
+  }
+
+  /* Assuming table_header is aligned to its size (8 bytes).  */
+
+  for (table_header = (grub_linuxbios_table_header_t) 0x500;
+       table_header < (grub_linuxbios_table_header_t) 0x1000; table_header++)
+    if (check_signature (table_header))
+      goto signature_found;
+
+  for (table_header = (grub_linuxbios_table_header_t) 0xf0000;
+       table_header < (grub_linuxbios_table_header_t) 0x100000; table_header++)
+    if (check_signature (table_header))
+      goto signature_found;
+
+  grub_fatal ("Could not find coreboot table\n");
+
+signature_found:
+
+  table_item =
+    (grub_linuxbios_table_item_t) ((long) table_header +
+			       (long) table_header->size);
+  for (; table_item->size;
+       table_item = (grub_linuxbios_table_item_t) ((long) table_item + (long) table_item->size))
+    if (hook (table_item))
+      return 1;
+
+  return 0;
+}
+
+void
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
+{
+  mem_region_t mem_region;
+
+  auto int iterate_linuxbios_table (grub_linuxbios_table_item_t);
+  int iterate_linuxbios_table (grub_linuxbios_table_item_t table_item)
+  {
+    if (table_item->tag != GRUB_LINUXBIOS_MEMBER_MEMORY)
+      return 0;
+
+    mem_region =
+      (mem_region_t) ((long) table_item +
+				 sizeof (struct grub_linuxbios_table_item));
+    while ((long) mem_region < (long) table_item + (long) table_item->size)
+      {
+	if (hook (mem_region->addr, mem_region->size,
+		  /* Multiboot mmaps match with the coreboot mmap definition.
+		     Therefore, we can just pass type through.  */
+		  mem_region->type))
+	  return 1;
+
+	mem_region++;
+      }
+
+    return 0;
+  }
+
+  grub_linuxbios_table_iterate (iterate_linuxbios_table);
+
+  return 0;
+}
diff --git a/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S
new file mode 100644
index 0000000..3f2dd5f
--- /dev/null
+++ b/kern/i386/coreboot/startup.S
@@ -0,0 +1,89 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+#include <grub/cpu/linux.h>
+#include <grub/cpu/kernel.h>
+#include <multiboot.h>
+#include <multiboot2.h>
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ *       So the first three arguments are passed in %eax, %edx, and %ecx,
+ *       respectively, and if a function has a fixed number of arguments
+ *       and the number if greater than three, the function must return
+ *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+	.file	"startup.S"
+	.text
+	.globl	start, _start
+start:
+_start:
+	jmp codestart
+
+	/*
+	 *  This is a special data area at a fixed offset from the beginning.
+	 */
+
+	. = _start + GRUB_KERNEL_CPU_PREFIX
+
+VARIABLE(grub_prefix)
+	/* to be filled by grub-mkimage */
+
+	/*
+	 *  Leave some breathing room for the prefix.
+	 */
+
+	. = _start + GRUB_KERNEL_CPU_DATA_END
+
+/*
+ *  Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
+ */
+	.p2align	2	/* force 4-byte alignment */
+multiboot_header:
+	/* magic */
+	.long	0x1BADB002
+	/* flags */
+	.long	MULTIBOOT_MEMORY_INFO
+	/* checksum */
+	.long	-0x1BADB002 - MULTIBOOT_MEMORY_INFO
+
+codestart:
+	cmpl	$MULTIBOOT_MAGIC2, %eax
+	jne 0f
+	movl	%ebx, EXT_C(startup_multiboot_info)
+0:
+
+	/* initialize the stack */
+	movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp
+
+	/* jump to the main body of C code */
+	jmp EXT_C(grub_main)
+
+/*
+ *  prot_to_real and associated structures (but NOT real_to_prot, that is
+ *  only needed for BIOS gates).
+ */
+#include "../realmode.S"
+
+/*
+ *  Routines needed by Linux and Multiboot loaders.
+ */
+#include "../loader.S"
diff --git a/kern/i386/dl.c b/kern/i386/dl.c
new file mode 100644
index 0000000..91121f6
--- /dev/null
+++ b/kern/i386/dl.c
@@ -0,0 +1,109 @@
+/* dl-386.c - arch-dependent part of loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+
+/* Check if EHDR is a valid ELF header.  */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+  if (e->e_ident[EI_CLASS] != ELFCLASS32
+      || e->e_ident[EI_DATA] != ELFDATA2LSB
+      || e->e_machine != EM_386)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+  Elf_Shdr *s;
+  Elf_Word entsize;
+  unsigned i;
+
+  /* Find a symbol table.  */
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
+
+  entsize = s->sh_entsize;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_REL)
+      {
+	grub_dl_segment_t seg;
+
+	/* Find the target segment.  */
+	for (seg = mod->segment; seg; seg = seg->next)
+	  if (seg->section == s->sh_info)
+	    break;
+
+	if (seg)
+	  {
+	    Elf_Rel *rel, *max;
+
+	    for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
+		   max = rel + s->sh_size / s->sh_entsize;
+		 rel < max;
+		 rel++)
+	      {
+		Elf_Word *addr;
+		Elf_Sym *sym;
+
+		if (seg->size < rel->r_offset)
+		  return grub_error (GRUB_ERR_BAD_MODULE,
+				     "reloc offset is out of the segment");
+
+		addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
+		sym = (Elf_Sym *) ((char *) mod->symtab
+				     + entsize * ELF_R_SYM (rel->r_info));
+
+		switch (ELF_R_TYPE (rel->r_info))
+		  {
+		  case R_386_32:
+		    *addr += sym->st_value;
+		    break;
+
+		  case R_386_PC32:
+		    *addr += (sym->st_value - (Elf_Word) seg->addr
+			      - rel->r_offset);
+		    break;
+		  }
+	      }
+	  }
+      }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/kern/i386/efi/init.c b/kern/i386/efi/init.c
new file mode 100644
index 0000000..e1950d7
--- /dev/null
+++ b/kern/i386/efi/init.c
@@ -0,0 +1,53 @@
+/* init.c - initialize an x86-based EFI system */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/cache.h>
+#include <grub/kernel.h>
+#include <grub/efi/efi.h>
+#include <grub/i386/tsc.h>
+
+void
+grub_machine_init (void)
+{
+  grub_efi_init ();
+  grub_tsc_init ();
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_efi_fini ();
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  grub_efi_set_prefix ();
+}
+
+void
+grub_arch_sync_caches (void *address __attribute__ ((unused)),
+                       grub_size_t len __attribute__ ((unused)))
+{
+}
diff --git a/kern/i386/efi/startup.S b/kern/i386/efi/startup.S
new file mode 100644
index 0000000..b886280
--- /dev/null
+++ b/kern/i386/efi/startup.S
@@ -0,0 +1,64 @@
+/* startup.S - bootstrap GRUB itself */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/boot.h>
+
+        .file   "startup.S"
+        .text
+        .globl  start, _start
+start:
+_start:
+	jmp codestart
+
+        /*
+         *  Compatibility version number
+         *
+         *  These MUST be at byte offset 6 and 7 of the executable
+         *  DO NOT MOVE !!!
+         */
+        . = _start + 0x6
+        .byte   GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
+
+        /*
+         *  This is a special data area 8 bytes from the beginning.
+         */
+
+        . = _start + 0x8
+
+VARIABLE(grub_prefix)
+	/* to be filled by grub-mkimage */
+
+        /*
+         *  Leave some breathing room for the prefix.
+         */
+
+        . = _start + 0x50
+
+codestart:
+	/*
+	 *  EFI_SYSTEM_TABLE * and EFI_HANDLE are passed on the stack.
+	 */
+	movl	4(%esp), %eax
+	movl	%eax, EXT_C(grub_efi_image_handle)
+	movl	8(%esp), %eax
+	movl	%eax, EXT_C(grub_efi_system_table)
+	call	EXT_C(grub_main)
+	ret
diff --git a/kern/i386/halt.c b/kern/i386/halt.c
new file mode 100644
index 0000000..2f00435
--- /dev/null
+++ b/kern/i386/halt.c
@@ -0,0 +1,43 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/cpu/io.h>
+#include <grub/cpu/halt.h>
+#include <grub/machine/init.h>
+#include <grub/misc.h>
+
+const char bochs_shutdown[] = "Shutdown";
+
+void
+grub_halt (void)
+{
+  unsigned int i;
+
+  /* Disable interrupts.  */
+  __asm__ __volatile__ ("cli");
+
+  /* Bochs, QEMU, etc.  */
+  for (i = 0; i < sizeof (bochs_shutdown) - 1; i++)
+    grub_outb (bochs_shutdown[i], 0x8900);
+
+  grub_printf ("GRUB doesn't know how to halt this machine yet!\n");
+
+  /* In order to return we'd have to check what the previous status of IF
+     flag was.  But user most likely doesn't want to return anyway ...  */
+  grub_stop ();
+}
diff --git a/kern/i386/ieee1275/init.c b/kern/i386/ieee1275/init.c
new file mode 100644
index 0000000..7658ee1
--- /dev/null
+++ b/kern/i386/ieee1275/init.c
@@ -0,0 +1,34 @@
+/*  init.c -- Initialize GRUB on Open Firmware.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/cache.h>
+
+void grub_stop_floppy (void);
+
+void
+grub_stop_floppy (void)
+{
+}
+
+void
+grub_arch_sync_caches (void *address __attribute__ ((unused)),
+		       grub_size_t len __attribute__ ((unused)))
+{
+}
diff --git a/kern/i386/ieee1275/startup.S b/kern/i386/ieee1275/startup.S
new file mode 100644
index 0000000..35258ad
--- /dev/null
+++ b/kern/i386/ieee1275/startup.S
@@ -0,0 +1,70 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+#include <grub/cpu/linux.h>
+#include <grub/cpu/kernel.h>
+#include <multiboot.h>
+#include <multiboot2.h>
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ *       So the first three arguments are passed in %eax, %edx, and %ecx,
+ *       respectively, and if a function has a fixed number of arguments
+ *       and the number if greater than three, the function must return
+ *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+	.file	"startup.S"
+	.text
+	.globl	start, _start
+
+start:
+_start:
+	jmp codestart
+
+	/*
+	 *  This is a special data area at a fixed offset from the beginning.
+	 */
+
+	. = _start + GRUB_KERNEL_CPU_PREFIX
+
+VARIABLE(grub_prefix)
+	/* to be filled by grub-mkimage */
+
+	/*
+	 *  Leave some breathing room for the prefix.
+	 */
+
+	. = _start + GRUB_KERNEL_CPU_DATA_END
+
+codestart:
+	movl %eax, EXT_C(grub_ieee1275_entry_fn)
+	jmp EXT_C(grub_main)
+
+/*
+ *  prot_to_real and associated structures (but NOT real_to_prot, that is
+ *  only needed for BIOS gates).
+ */
+#include "../realmode.S"
+
+/*
+ *  Routines needed by Linux and Multiboot loaders.
+ */
+#include "../loader.S"
diff --git a/kern/i386/loader.S b/kern/i386/loader.S
new file mode 100644
index 0000000..3e9c713
--- /dev/null
+++ b/kern/i386/loader.S
@@ -0,0 +1,120 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*
+ * Note: These functions defined in this file may be called from C.
+ *       Be careful of that you must not modify some registers. Quote
+ *       from gcc-2.95.2/gcc/config/i386/i386.h:
+
+   1 for registers not available across function calls.
+   These must include the FIXED_REGISTERS and also any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like.
+
+  ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
+{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
+ */
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ *       So the first three arguments are passed in %eax, %edx, and %ecx,
+ *       respectively, and if a function has a fixed number of arguments
+ *       and the number if greater than three, the function must return
+ *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+/*
+ *  This is the area for all of the special variables.
+ */
+
+	.p2align	2	/* force 4-byte alignment */
+
+/*
+ * void grub_linux_boot_zimage (void)
+ */
+VARIABLE(grub_linux_prot_size)
+	.long	0
+VARIABLE(grub_linux_tmp_addr)
+	.long	0
+VARIABLE(grub_linux_real_addr)
+	.long	0
+VARIABLE(grub_linux_is_bzimage)
+	.long	0
+
+FUNCTION(grub_linux16_boot)
+	/* Must be done before zImage copy.  */
+	call	EXT_C(grub_dl_unload_all)
+
+	movl	EXT_C(grub_linux_is_bzimage), %ebx
+	test	%ebx, %ebx
+	jne bzimage
+
+	/* copy the kernel */
+	movl	EXT_C(grub_linux_prot_size), %ecx
+	addl	$3, %ecx
+	shrl	$2, %ecx
+	movl	$GRUB_LINUX_BZIMAGE_ADDR, %esi
+	movl	$GRUB_LINUX_ZIMAGE_ADDR, %edi
+	cld
+	rep
+	movsl
+
+bzimage:
+	movl	EXT_C(grub_linux_real_addr), %ebx
+
+	/* copy the real mode code */
+	movl	EXT_C(grub_linux_tmp_addr), %esi
+	movl	%ebx, %edi
+	movl	$GRUB_LINUX_SETUP_MOVE_SIZE, %ecx
+	cld
+	rep
+	movsb
+
+	/* change %ebx to the segment address */
+	shrl	$4, %ebx
+	movl	%ebx, %eax
+	addl	$0x20, %eax
+	movw	%ax, linux_setup_seg
+
+	/* XXX new stack pointer in safe area for calling functions */
+	movl	$0x4000, %esp
+	call	EXT_C(grub_stop_floppy)
+
+	/* final setup for linux boot */
+	call	prot_to_real
+	.code16
+
+	cli
+	movw	%bx, %ss
+	movw	$GRUB_LINUX_SETUP_STACK, %sp
+
+	movw	%bx, %ds
+	movw	%bx, %es
+	movw	%bx, %fs
+	movw	%bx, %gs
+
+	/* ljmp */
+	.byte	0xea
+	.word	0
+linux_setup_seg:
+	.word	0
+	.code32
+
diff --git a/kern/i386/misc.S b/kern/i386/misc.S
new file mode 100644
index 0000000..7d57df9
--- /dev/null
+++ b/kern/i386/misc.S
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+	.text
+/*
+ *  This call is special...  it never returns...  in fact it should simply
+ *  hang at this point!
+ */
+FUNCTION(grub_stop)
+	cli
+1:	hlt
+	jmp	1b
diff --git a/kern/i386/multiboot_mmap.c b/kern/i386/multiboot_mmap.c
new file mode 100644
index 0000000..8331bd5
--- /dev/null
+++ b/kern/i386/multiboot_mmap.c
@@ -0,0 +1,86 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/types.h>
+#include <grub/multiboot.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+
+grub_size_t grub_lower_mem, grub_upper_mem;
+
+/* A pointer to the MBI in its initial location.  */
+struct grub_multiboot_info *startup_multiboot_info;
+
+/* The MBI has to be copied to our BSS so that it won't be
+   overwritten.  This is its final location.  */
+static struct grub_multiboot_info kern_multiboot_info;
+
+/* Unfortunately we can't use heap at this point.  But 32 looks like a sane
+   limit (used by memtest86).  */
+static grub_uint8_t mmap_entries[sizeof (struct grub_multiboot_mmap_entry) * 32];
+
+void
+grub_machine_mmap_init ()
+{
+  if (! startup_multiboot_info)
+    grub_fatal ("Must be loaded using Multiboot specification (is this an old version of coreboot?)");
+
+  /* Move MBI to a safe place.  */
+  grub_memmove (&kern_multiboot_info, startup_multiboot_info, sizeof (struct grub_multiboot_info));
+
+  if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEM_MAP) == 0)
+    grub_fatal ("Missing Multiboot memory information");
+
+  /* Move the memory map to a safe place.  */
+  if (kern_multiboot_info.mmap_length > sizeof (mmap_entries))
+    {
+      grub_printf ("WARNING: Memory map size exceeds limit; it will be truncated\n");
+      kern_multiboot_info.mmap_length = sizeof (mmap_entries);
+    }
+  grub_memmove (mmap_entries, (void *) kern_multiboot_info.mmap_addr, kern_multiboot_info.mmap_length);
+  kern_multiboot_info.mmap_addr = (grub_uint32_t) mmap_entries;
+
+  if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEMORY) == 0)
+    {
+      grub_lower_mem = GRUB_MEMORY_MACHINE_LOWER_USABLE;
+      grub_upper_mem = 0;
+    }
+  else
+    {
+      grub_lower_mem = kern_multiboot_info.mem_lower * 1024;
+      grub_upper_mem = kern_multiboot_info.mem_upper * 1024;
+    }
+}
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
+{
+  struct grub_multiboot_mmap_entry *entry = (void *) kern_multiboot_info.mmap_addr;
+
+  while ((unsigned long) entry < kern_multiboot_info.mmap_addr + kern_multiboot_info.mmap_length)
+    {
+      if (hook (entry->addr, entry->len, entry->type))
+	break;
+
+      entry = (void *) ((grub_addr_t) entry + entry->size + sizeof (entry->size));
+    }
+
+  return 0;
+}
diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c
new file mode 100644
index 0000000..ebe4bb6
--- /dev/null
+++ b/kern/i386/pc/init.c
@@ -0,0 +1,231 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/mm.h>
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/console.h>
+#include <grub/machine/kernel.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/loader.h>
+#include <grub/env.h>
+#include <grub/cache.h>
+#include <grub/time.h>
+#include <grub/cpu/tsc.h>
+
+struct mem_region
+{
+  grub_addr_t addr;
+  grub_size_t size;
+};
+
+#define MAX_REGIONS	32
+
+static struct mem_region mem_regions[MAX_REGIONS];
+static int num_regions;
+
+grub_addr_t grub_os_area_addr;
+grub_size_t grub_os_area_size;
+
+void
+grub_arch_sync_caches (void *address __attribute__ ((unused)),
+		       grub_size_t len __attribute__ ((unused)))
+{
+}
+
+static char *
+make_install_device (void)
+{
+  /* XXX: This should be enough.  */
+  char dev[100];
+
+  if (grub_prefix[0] != '(')
+    {
+      /* No hardcoded root partition - make it from the boot drive and the
+	 partition number encoded at the install time.  */
+      grub_sprintf (dev, "(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f',
+		    grub_boot_drive & 0x7f);
+
+      if (grub_install_dos_part >= 0)
+	grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
+
+      if (grub_install_bsd_part >= 0)
+	grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
+
+      grub_sprintf (dev + grub_strlen (dev), ")%s", grub_prefix);
+      grub_strcpy (grub_prefix, dev);
+    }
+
+  return grub_prefix;
+}
+
+/* Add a memory region.  */
+static void
+add_mem_region (grub_addr_t addr, grub_size_t size)
+{
+  if (num_regions == MAX_REGIONS)
+    /* Ignore.  */
+    return;
+
+  mem_regions[num_regions].addr = addr;
+  mem_regions[num_regions].size = size;
+  num_regions++;
+}
+
+/* Compact memory regions.  */
+static void
+compact_mem_regions (void)
+{
+  int i, j;
+
+  /* Sort them.  */
+  for (i = 0; i < num_regions - 1; i++)
+    for (j = i + 1; j < num_regions; j++)
+      if (mem_regions[i].addr > mem_regions[j].addr)
+	{
+	  struct mem_region tmp = mem_regions[i];
+	  mem_regions[i] = mem_regions[j];
+	  mem_regions[j] = tmp;
+	}
+
+  /* Merge overlaps.  */
+  for (i = 0; i < num_regions - 1; i++)
+    if (mem_regions[i].addr + mem_regions[i].size >= mem_regions[i + 1].addr)
+      {
+	j = i + 1;
+
+	if (mem_regions[i].addr + mem_regions[i].size
+	    < mem_regions[j].addr + mem_regions[j].size)
+	  mem_regions[i].size = (mem_regions[j].addr + mem_regions[j].size
+				 - mem_regions[i].addr);
+
+	grub_memmove (mem_regions + j, mem_regions + j + 1,
+		      (num_regions - j - 1) * sizeof (struct mem_region));
+	i--;
+        num_regions--;
+      }
+}
+
+void
+grub_machine_init (void)
+{
+  int i;
+  int grub_lower_mem;
+
+  /* Initialize the console as early as possible.  */
+  grub_console_init ();
+
+  grub_lower_mem = grub_get_memsize (0) << 10;
+
+  /* Sanity check.  */
+  if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END)
+    grub_fatal ("too small memory");
+
+#if 0
+  /* Turn on Gate A20 to access >1MB.  */
+  grub_gate_a20 (1);
+#endif
+
+/* FIXME: This prevents loader/i386/linux.c from using low memory.  When our
+   heap implements support for requesting a chunk in low memory, this should
+   no longer be a problem.  */
+#if 0
+  /* Add the lower memory into free memory.  */
+  if (grub_lower_mem >= GRUB_MEMORY_MACHINE_RESERVED_END)
+    add_mem_region (GRUB_MEMORY_MACHINE_RESERVED_END,
+		    grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END);
+#endif
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      /* Avoid the lower memory.  */
+      if (addr < 0x100000)
+	{
+	  if (size <= 0x100000 - addr)
+	    return 0;
+
+	  size -= 0x100000 - addr;
+	  addr = 0x100000;
+	}
+
+      /* Ignore >4GB.  */
+      if (addr <= 0xFFFFFFFF && type == GRUB_MACHINE_MEMORY_AVAILABLE)
+	{
+	  grub_size_t len;
+
+	  len = (grub_size_t) ((addr + size > 0xFFFFFFFF)
+		 ? 0xFFFFFFFF - addr
+		 : size);
+	  add_mem_region (addr, len);
+	}
+
+      return 0;
+    }
+
+  grub_machine_mmap_iterate (hook);
+
+  compact_mem_regions ();
+
+  /* Add the memory regions to free memory, except for the region starting
+     from 1MB. This region is partially used for loading OS images.
+     For now, 1/4 of this is added to free memory.  */
+  for (i = 0; i < num_regions; i++)
+    if (mem_regions[i].addr == 0x100000)
+      {
+	grub_size_t quarter = mem_regions[i].size >> 2;
+
+	grub_os_area_addr = mem_regions[i].addr;
+	grub_os_area_size = mem_regions[i].size - quarter;
+	grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size),
+			     quarter);
+      }
+    else
+      grub_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size);
+
+  if (! grub_os_area_addr)
+    grub_fatal ("no upper memory");
+
+  grub_tsc_init ();
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  /* Initialize the prefix.  */
+  grub_env_set ("prefix", make_install_device ());
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_console_fini ();
+  grub_stop_floppy ();
+}
+
+/* Return the end of the core image.  */
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  return GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR
+    + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE);
+}
diff --git a/kern/i386/pc/lzma_decode.S b/kern/i386/pc/lzma_decode.S
new file mode 100644
index 0000000..a5a8684
--- /dev/null
+++ b/kern/i386/pc/lzma_decode.S
@@ -0,0 +1,677 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define FIXED_PROPS
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+#define kNumTopBits 24
+#define kTopValue (1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+
+#if 0
+
+DbgOut:
+	pushf
+	pushl	%ebp
+	pushl	%edi
+	pushl	%esi
+	pushl	%edx
+	pushl	%ecx
+	pushl	%ebx
+	pushl	%eax
+
+	call	_DebugPrint
+
+	popl	%eax
+	popl	%ebx
+	popl	%ecx
+	popl	%edx
+	popl	%esi
+	popl	%edi
+	popl	%ebp
+	popf
+
+	ret
+
+
+/*
+ * int LzmaDecodeProperties(CLzmaProperties *propsRes,
+ *                          const unsigned char *propsData,
+ *                          int size);
+ */
+
+_LzmaDecodePropertiesA:
+	movb	(%edx), %dl
+
+	xorl	%ecx, %ecx
+1:
+	cmpb	$45, %dl
+	jb	2f
+	incl	%ecx
+	subb	$45, %dl
+	jmp	1b
+2:
+	movl	%ecx, 8(%eax)		/* pb */
+	xorl	%ecx, %ecx
+1:
+	cmpb	$9, %dl
+	jb	2f
+	incl	%ecx
+	subb	$9, %dl
+2:
+	movl	%ecx, 4(%eax)		/* lp */
+	movb	%dl, %cl
+	movl	%ecx, (%eax)		/* lc */
+
+#endif
+
+#ifndef ASM_FILE
+	xorl	%eax, %eax
+#endif
+	ret
+
+#define out_size	8(%ebp)
+
+#define now_pos		-4(%ebp)
+#define prev_byte	-8(%ebp)
+#define range		-12(%ebp)
+#define code		-16(%ebp)
+#define state		-20(%ebp)
+#define rep0		-24(%ebp)
+#define rep1		-28(%ebp)
+#define rep2		-32(%ebp)
+#define rep3		-36(%ebp)
+
+#ifdef FIXED_PROPS
+
+#define FIXED_LC	3
+#define FIXED_LP	0
+#define FIXED_PB	2
+
+#define POS_STATE_MASK	((1 << (FIXED_PB)) - 1)
+#define LIT_POS_MASK	((1 << (FIXED_LP)) - 1)
+
+#define LOCAL_SIZE	36
+
+#else
+
+#define lc		(%ebx)
+#define lp		4(%ebx)
+#define pb		8(%ebx)
+#define probs		12(%ebx)
+
+#define pos_state_mask	-40(%ebp)
+#define lit_pos_mask	-44(%ebp)
+
+#define LOCAL_SIZE	44
+
+#endif
+
+RangeDecoderBitDecode:
+#ifdef FIXED_PROPS
+	leal	(%ebx, %eax, 4), %eax
+#else
+	shll	$2, %eax
+	addl	probs, %eax
+#endif
+
+	movl	%eax, %ecx
+	movl	(%ecx), %eax
+
+	movl	range, %edx
+	shrl	$kNumBitModelTotalBits, %edx
+	mull	%edx
+
+	cmpl	code, %eax
+	jbe	1f
+
+	movl	%eax, range
+	movl	$kBitModelTotal, %edx
+	subl	(%ecx), %edx
+	shrl	$kNumMoveBits, %edx
+	addl	%edx, (%ecx)
+	clc
+3:
+	pushf
+	cmpl	$kTopValue, range
+	jnc	2f
+	shll	$8, code
+	lodsb
+	movb	%al, code
+	shll	$8, range
+2:
+	popf
+	ret
+1:
+	subl	%eax, range
+	subl	%eax, code
+	movl	(%ecx), %edx
+	shrl	$kNumMoveBits, %edx
+	subl	%edx, (%ecx)
+	stc
+	jmp	3b
+
+RangeDecoderBitTreeDecode:
+RangeDecoderReverseBitTreeDecode:
+	movzbl	%cl, %ecx
+	xorl	%edx, %edx
+	pushl	%edx
+	incl	%edx
+	pushl	%edx
+
+1:
+	pushl	%eax
+	pushl	%ecx
+	pushl	%edx
+
+	addl	%edx, %eax
+	call	RangeDecoderBitDecode
+
+	popl	%edx
+	popl	%ecx
+
+	jnc	2f
+	movl	4(%esp), %eax
+	orl	%eax, 8(%esp)
+	stc
+
+2:
+	adcl	%edx, %edx
+	popl	%eax
+
+	shll	$1, (%esp)
+	loop	1b
+
+	popl	%ecx
+	subl	%ecx, %edx		/* RangeDecoderBitTreeDecode */
+	popl	%ecx			/* RangeDecoderReverseBitTreeDecode */
+	ret
+
+LzmaLenDecode:
+	pushl	%eax
+	addl	$LenChoice, %eax
+	call	RangeDecoderBitDecode
+	popl	%eax
+	jc	1f
+	pushl	$0
+	movb	$kLenNumLowBits, %cl
+	addl	$LenLow, %eax
+2:
+	movl	12(%esp), %edx
+	shll	%cl, %edx
+	addl	%edx, %eax
+3:
+
+	call	RangeDecoderBitTreeDecode
+	popl	%eax
+	addl	%eax, %edx
+	ret
+
+1:
+	pushl	%eax
+	addl	$LenChoice2, %eax
+	call	RangeDecoderBitDecode
+	popl	%eax
+	jc	1f
+	pushl	$kLenNumLowSymbols
+	movb	$kLenNumMidBits, %cl
+	addl	$LenMid, %eax
+	jmp	2b
+
+1:
+	pushl	$(kLenNumLowSymbols + kLenNumMidSymbols)
+	addl	$LenHigh, %eax
+	movb	$kLenNumHighBits, %cl
+	jmp	3b
+
+WriteByte:
+	movb	%al, prev_byte
+	stosb
+	incl	now_pos
+	ret
+
+/*
+ * int LzmaDecode(CLzmaDecoderState *vs,
+ *                const unsigned char *inStream,
+ *                unsigned char *outStream,
+ *                SizeT outSize);
+ */
+
+_LzmaDecodeA:
+
+	pushl	%ebp
+	movl	%esp, %ebp
+	subl	$LOCAL_SIZE, %esp
+
+#ifndef ASM_FILE
+	pushl	%esi
+	pushl	%edi
+	pushl	%ebx
+
+	movl	%eax, %ebx
+	movl	%edx, %esi
+	pushl	%ecx
+#else
+	pushl	%edi
+#endif
+
+	cld
+
+#ifdef FIXED_PROPS
+	movl	%ebx, %edi
+	movl	$(Literal + (LZMA_LIT_SIZE << (FIXED_LC + FIXED_LP))), %ecx
+#else
+	movl	$LZMA_LIT_SIZE, %eax
+	movb	lc, %cl
+	addb	lp, %cl
+	shll	%cl, %eax
+	addl	$Literal, %eax
+	movl	%eax, %ecx
+	movl	probs, %edi
+#endif
+
+	movl	$(kBitModelTotal >> 1), %eax
+
+	rep
+	stosl
+
+	popl	%edi
+
+	xorl	%eax, %eax
+	movl	%eax, now_pos
+	movl	%eax, prev_byte
+	movl	%eax, state
+
+	incl	%eax
+	movl	%eax, rep0
+	movl	%eax, rep1
+	movl	%eax, rep2
+	movl	%eax, rep3
+
+#ifndef FIXED_PROPS
+	movl	%eax, %edx
+	movb	pb, %cl
+	shll	%cl, %edx
+	decl	%edx
+	movl	%edx, pos_state_mask
+
+	movl	%eax, %edx
+	movb	lp, %cl
+	shll	%cl, %edx
+	decl	%edx
+	movl	%edx, lit_pos_mask;
+#endif
+
+	/* RangeDecoderInit */
+	negl	%eax
+	movl	%eax, range
+
+	incl	%eax
+	movb	$5, %cl
+
+1:
+	shll	$8, %eax
+	lodsb
+	loop	1b
+
+	movl	%eax, code
+
+lzma_decode_loop:
+	movl	now_pos, %eax
+	cmpl	out_size, %eax
+
+	jb	1f
+
+#ifndef ASM_FILE
+	xorl	%eax, %eax
+
+	popl	%ebx
+	popl	%edi
+	popl	%esi
+#endif
+
+	movl	%ebp, %esp
+	popl	%ebp
+	ret
+
+1:
+#ifdef FIXED_PROPS
+	andl	$POS_STATE_MASK, %eax
+#else
+	andl	pos_state_mask, %eax
+#endif
+	pushl	%eax				/* posState */
+	movl	state, %edx
+	shll	$kNumPosBitsMax, %edx
+	addl	%edx, %eax
+	pushl	%eax				/* (state << kNumPosBitsMax) + posState */
+
+	call	RangeDecoderBitDecode
+	jc	1f
+
+	movl	now_pos, %eax
+
+#ifdef FIXED_PROPS
+	andl	$LIT_POS_MASK, %eax
+	shll	$FIXED_LC, %eax
+	movl	prev_byte, %edx
+	shrl	$(8 - FIXED_LC), %edx
+#else
+	andl	lit_pos_mask, %eax
+	movb	lc, %cl
+	shll	%cl, %eax
+	negb	%cl
+	addb	$8, %cl
+	movl	prev_byte, %edx
+	shrl	%cl, %edx
+#endif
+
+	addl	%edx, %eax
+	movl	$LZMA_LIT_SIZE, %edx
+	mull	%edx
+	addl	$Literal, %eax
+	pushl	%eax
+
+	incl	%edx			/* edx = 1 */
+
+	movl	rep0, %eax
+	negl	%eax
+	pushl	(%edi, %eax)		/* matchByte */
+
+	cmpb	$kNumLitStates, state
+	jb	5f
+
+	/* LzmaLiteralDecodeMatch */
+
+3:
+	cmpl	$0x100, %edx
+	jae	4f
+
+	xorl	%eax, %eax
+	shlb	$1, (%esp)
+	adcl	%eax, %eax
+
+	pushl	%eax
+	pushl	%edx
+
+	shll	$8, %eax
+	leal	0x100(%edx, %eax), %eax
+	addl	12(%esp), %eax
+	call	RangeDecoderBitDecode
+
+	setc	%al
+	popl	%edx
+	adcl	%edx, %edx
+
+	popl	%ecx
+	cmpb	%cl, %al
+	jz	3b
+
+5:
+
+	/* LzmaLiteralDecode */
+
+	cmpl	$0x100, %edx
+	jae	4f
+
+	pushl	%edx
+	movl	%edx, %eax
+	addl	8(%esp), %eax
+	call	RangeDecoderBitDecode
+	popl	%edx
+	adcl	%edx, %edx
+	jmp	5b
+
+4:
+	addl	$16, %esp
+
+	movb	%dl, %al
+	call	WriteByte
+
+	movb	state, %al
+	cmpb	$4, %al
+	jae	2f
+	xorb	%al, %al
+	jmp	3f
+2:
+	subb	$3, %al
+	cmpb	$7, %al
+	jb	3f
+	subb	$3, %al
+3:
+	movb	%al, state
+	jmp	lzma_decode_loop
+
+1:
+	movl	state, %eax
+	addl	$IsRep, %eax
+	call	RangeDecoderBitDecode
+	jnc	1f
+
+	movl	state, %eax
+	addl	$IsRepG0, %eax
+	call	RangeDecoderBitDecode
+	jc	10f
+
+	movl	(%esp), %eax
+	addl	$IsRep0Long, %eax
+	call	RangeDecoderBitDecode
+	jc	20f
+
+	cmpb	$7, state
+	movb	$9, state
+	jb	100f
+	addb	$2, state
+100:
+
+	movl	$1, %ecx
+
+3:
+	movl	rep0, %edx
+	negl	%edx
+
+4:
+	movb	(%edi, %edx), %al
+	call	WriteByte
+	loop	4b
+
+	popl	%eax
+	popl	%eax
+	jmp	lzma_decode_loop
+
+10:
+	movl	state, %eax
+	addl	$IsRepG1, %eax
+	call	RangeDecoderBitDecode
+	movl	rep1, %edx
+	jnc	100f
+
+	movl	state, %eax
+	addl	$IsRepG2, %eax
+	call	RangeDecoderBitDecode
+	movl	rep2, %edx
+	jnc	1000f
+	movl	rep2, %edx
+	xchgl	rep3, %edx
+1000:
+	pushl	rep1
+	popl	rep2
+100:
+	xchg	rep0, %edx
+	movl	%edx, rep1
+20:
+
+	movl	$RepLenCoder, %eax
+	call	LzmaLenDecode
+
+	cmpb	$7, state
+	movb	$8, state
+	jb	100f
+	addb	$3, state
+100:
+	jmp	2f
+
+1:
+	movl	rep0, %eax
+	xchgl	rep1, %eax
+	xchgl	rep2, %eax
+	movl	%eax, rep3
+
+	cmpb	$7, state
+	movb	$7, state
+	jb	10f
+	addb	$3, state
+10:
+
+	movl	$LenCoder, %eax
+	call	LzmaLenDecode
+	pushl	%edx
+
+	movl	$(kNumLenToPosStates - 1), %eax
+	cmpl	%eax, %edx
+	jbe	100f
+	movl	%eax, %edx
+100:
+	movb	$kNumPosSlotBits, %cl
+	shll	%cl, %edx
+	leal	PosSlot(%edx), %eax
+	call	RangeDecoderBitTreeDecode
+
+	movl	%edx, rep0
+	cmpl	$kStartPosModelIndex, %edx
+	jb	100f
+
+	movl	%edx, %ecx
+	shrl	$1, %ecx
+	decl	%ecx
+
+	movzbl	%dl, %eax
+	andb	$1, %al
+	orb	$2, %al
+	shll	%cl, %eax
+	movl	%eax, rep0
+
+	cmpl	$kEndPosModelIndex, %edx
+	jae	200f
+	movl	rep0, %eax
+	addl	$(SpecPos - 1), %eax
+	subl	%edx, %eax
+	jmp	300f
+200:
+
+	subb	$kNumAlignBits, %cl
+
+	/* RangeDecoderDecodeDirectBits */
+	xorl	%edx, %edx
+
+1000:
+	shrl	$1, range
+	shll	$1, %edx
+
+	movl	range, %eax
+	cmpl	%eax, code
+	jb	2000f
+	subl	%eax, code
+	orb	$1, %dl
+2000:
+
+	cmpl	$kTopValue, %eax
+	jae	3000f
+	shll	$8, range
+	shll	$8, code
+	lodsb
+	movb	%al, code
+
+3000:
+	loop	1000b
+
+	movb	$kNumAlignBits, %cl
+	shll	%cl, %edx
+	addl	%edx, rep0
+
+	movl	$Align, %eax
+
+300:
+	call	RangeDecoderReverseBitTreeDecode
+	addl	%ecx, rep0
+
+100:
+	incl	rep0
+	popl	%edx
+
+2:
+
+	addl	$kMatchMinLen, %edx
+	movl	%edx, %ecx
+
+	jmp	3b
diff --git a/kern/i386/pc/mmap.c b/kern/i386/pc/mmap.c
new file mode 100644
index 0000000..52d8fd5
--- /dev/null
+++ b/kern/i386/pc/mmap.c
@@ -0,0 +1,63 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/err.h>
+#include <grub/types.h>
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
+{
+  grub_uint32_t cont;
+  struct grub_machine_mmap_entry *entry
+    = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+
+  /* Check if grub_get_mmap_entry works.  */
+  cont = grub_get_mmap_entry (entry, 0);
+
+  if (entry->size)
+    do
+      {
+	if (hook (entry->addr, entry->len,
+		  /* Multiboot mmaps have been defined to match with the E820 definition.
+		     Therefore, we can just pass type through.  */
+		  entry->type))
+	  break;
+
+	if (! cont)
+	  break;
+
+	cont = grub_get_mmap_entry (entry, cont);
+      }
+    while (entry->size);
+  else
+    {
+      grub_uint32_t eisa_mmap = grub_get_eisa_mmap ();
+
+      if (eisa_mmap)
+	{
+	  if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, GRUB_MACHINE_MEMORY_AVAILABLE) == 0)
+	    hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MACHINE_MEMORY_AVAILABLE);
+	}
+      else
+	hook (0x100000, grub_get_memsize (1) << 10, GRUB_MACHINE_MEMORY_AVAILABLE);
+    }
+
+  return 0;
+}
diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S
new file mode 100644
index 0000000..da3624c
--- /dev/null
+++ b/kern/i386/pc/startup.S
@@ -0,0 +1,2146 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*
+ * Note: These functions defined in this file may be called from C.
+ *       Be careful of that you must not modify some registers. Quote
+ *       from gcc-2.95.2/gcc/config/i386/i386.h:
+
+   1 for registers not available across function calls.
+   These must include the FIXED_REGISTERS and also any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like.
+
+  ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
+{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
+ */
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ *       So the first three arguments are passed in %eax, %edx, and %ecx,
+ *       respectively, and if a function has a fixed number of arguments
+ *       and the number is greater than three, the function must return
+ *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/console.h>
+#include <grub/cpu/linux.h>
+#include <grub/machine/kernel.h>
+#include <grub/term.h>
+#include <multiboot.h>
+#include <multiboot2.h>
+
+#define ABS(x)	((x) - _start + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)
+
+	.file	"startup.S"
+
+	.text
+
+	/* Tell GAS to generate 16-bit instructions so that this code works
+	   in real mode. */
+	.code16
+
+	.globl	start, _start
+start:
+_start:
+	/*
+	 *  Guarantee that "main" is loaded at 0x0:0x8200.
+	 */
+#ifdef APPLE_CC
+	codestart_abs = ABS(codestart) - 0x10000
+	ljmp $0, $(codestart_abs)
+#else
+	ljmp $0, $ABS(codestart)
+#endif
+
+	/*
+	 *  Compatibility version number
+	 *
+	 *  These MUST be at byte offset 6 and 7 of the executable
+	 *  DO NOT MOVE !!!
+	 */
+	. = _start + 0x6
+	.byte	GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
+
+	/*
+	 *  This is a special data area 8 bytes from the beginning.
+	 */
+
+	. = _start + 0x8
+
+VARIABLE(grub_total_module_size)
+	.long	0
+VARIABLE(grub_kernel_image_size)
+	.long	0
+VARIABLE(grub_compressed_size)
+	.long	0
+VARIABLE(grub_install_dos_part)
+	.long	0xFFFFFFFF
+VARIABLE(grub_install_bsd_part)
+	.long	0xFFFFFFFF
+VARIABLE(grub_prefix)
+	/* to be filled by grub-mkimage */
+
+	/*
+	 *  Leave some breathing room for the prefix.
+	 */
+
+	. = _start + GRUB_KERNEL_MACHINE_DATA_END
+
+#ifdef APPLE_CC
+bss_start:
+	.long 0
+bss_end:
+	.long 0
+#endif
+
+/*
+ * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
+ * This uses the a.out kludge to load raw binary to the area starting at 1MB,
+ * and relocates itself after loaded.
+ */
+	.p2align	2	/* force 4-byte alignment */
+multiboot_header:
+	/* magic */
+	.long	0x1BADB002
+	/* flags */
+	.long	(1 << 16)
+	/* checksum */
+	.long	-0x1BADB002 - (1 << 16)
+	/* header addr */
+	.long	multiboot_header - _start + 0x100000 + 0x200
+	/* load addr */
+	.long	0x100000
+	/* load end addr */
+	.long	0
+	/* bss end addr */
+	.long	0
+	/* entry addr */
+	.long	multiboot_entry - _start + 0x100000 + 0x200
+
+multiboot_entry:
+	.code32
+	/* obtain the boot device */
+	movl	12(%ebx), %edx
+
+	/* relocate the code */
+	movl	$(GRUB_KERNEL_MACHINE_RAW_SIZE + 0x200), %ecx
+	addl	EXT_C(grub_compressed_size) - _start + 0x100000 + 0x200, %ecx
+	movl	$0x100000, %esi
+	movl	$GRUB_BOOT_MACHINE_KERNEL_ADDR, %edi
+	cld
+	rep
+	movsb
+	/* jump to the real address */
+	movl	$multiboot_trampoline, %eax
+	jmp	*%eax
+
+multiboot_trampoline:
+	/* fill the boot information */
+	movl	%edx, %eax
+	shrl	$8, %eax
+	xorl	%ebx, %ebx
+	cmpb	$0xFF, %ah
+	je	1f
+	movb	%ah, %bl
+	movl	%ebx, EXT_C(grub_install_dos_part)
+1:
+	cmpb	$0xFF, %al
+	je	2f
+	movb	%al, %bl
+	movl	%ebx, EXT_C(grub_install_bsd_part)
+2:
+	shrl	$24, %edx
+        movb    $0xFF, %dh
+	/* enter the usual booting */
+	call	prot_to_real
+	.code16
+
+/* the real mode code continues... */
+codestart:
+	cli		/* we're not safe here! */
+
+	/* set up %ds, %ss, and %es */
+	xorw	%ax, %ax
+	movw	%ax, %ds
+	movw	%ax, %ss
+	movw	%ax, %es
+
+	/* set up the real mode/BIOS stack */
+	movl	$GRUB_MEMORY_MACHINE_REAL_STACK, %ebp
+	movl	%ebp, %esp
+
+	sti		/* we're safe again */
+
+	/* save the boot drive */
+	ADDR32	movb	%dl, EXT_C(grub_boot_drive)
+
+	/* reset disk system (%ah = 0) */
+	int	$0x13
+
+	/* transition to protected mode */
+	DATA32	call real_to_prot
+
+	/* The ".code32" directive takes GAS out of 16-bit mode. */
+	.code32
+
+	incl	%eax
+	call	EXT_C(grub_gate_a20)
+
+#ifdef ENABLE_LZMA
+	movl	$GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi
+	movl	$(_start + GRUB_KERNEL_MACHINE_RAW_SIZE), %esi
+	pushl	%edi
+	pushl	%esi
+	movl	EXT_C(grub_kernel_image_size), %ecx
+	addl	EXT_C(grub_total_module_size), %ecx
+	subl	$GRUB_KERNEL_MACHINE_RAW_SIZE, %ecx
+	pushl	%ecx
+	leal	(%edi, %ecx), %ebx
+	call	_LzmaDecodeA
+	/* _LzmaDecodeA clears DF, so no need to run cld */
+	popl	%ecx
+	popl	%edi
+	popl	%esi
+#endif
+
+	/* copy back the decompressed part (except the modules) */
+	subl	EXT_C(grub_total_module_size), %ecx
+	rep
+	movsb
+
+#if 0
+	/* copy modules before cleaning out the bss */
+	movl	EXT_C(grub_total_module_size), %ecx
+	movl	EXT_C(grub_kernel_image_size), %esi
+	addl	%ecx, %esi
+	addl	$_start, %esi
+	decl	%esi
+	movl	$END_SYMBOL, %edi
+	addl	%ecx, %edi
+	decl	%edi
+	std
+	rep
+	movsb
+#endif
+
+#ifdef APPLE_CC
+	/* clean out the bss */
+	bss_start_abs = ABS (bss_start)
+	bss_end_abs = ABS (bss_end)
+
+	movl    bss_start_abs, %edi
+
+	/* compute the bss length */
+	movl	bss_end_abs, %ecx
+	subl	%edi, %ecx
+#else
+	/* clean out the bss */
+	movl	$BSS_START_SYMBOL, %edi
+
+	/* compute the bss length */
+	movl	$END_SYMBOL, %ecx
+	subl	%edi, %ecx
+#endif
+
+	/* clean out */
+	xorl	%eax, %eax
+	cld
+	rep
+	stosb
+
+	/*
+	 *  Call the start of main body of C code.
+	 */
+	call EXT_C(grub_main)
+
+/*
+ *  This is the area for all of the special variables.
+ */
+
+VARIABLE(grub_boot_drive)
+	.byte	0
+
+	.p2align	2	/* force 4-byte alignment */
+
+#include "../realmode.S"
+
+/*
+ * grub_gate_a20(int on)
+ *
+ * Gate address-line 20 for high memory.
+ *
+ * This routine is probably overconservative in what it does, but so what?
+ *
+ * It also eats any keystrokes in the keyboard buffer.  :-(
+ */
+
+FUNCTION(grub_gate_a20)
+	movl	%eax, %edx
+
+gate_a20_test_current_state:
+	/* first of all, test if already in a good state */
+	call	gate_a20_check_state
+	cmpb	%al, %dl
+	jnz	gate_a20_try_bios
+	ret
+
+gate_a20_try_bios:
+	/* second, try a BIOS call */
+	pushl	%ebp
+	call	prot_to_real
+
+	.code16
+	movw	$0x2400, %ax
+	testb	%dl, %dl
+	jz	1f
+	incw	%ax
+1:	int	$0x15
+
+	DATA32	call	real_to_prot
+	.code32
+
+	popl	%ebp
+	call	gate_a20_check_state
+	cmpb	%al, %dl
+	jnz	gate_a20_try_system_control_port_a
+	ret
+
+gate_a20_try_system_control_port_a:
+	/*
+	 * In macbook, the keyboard test would hang the machine, so we move
+	 * this forward.
+	 */
+	/* fourth, try the system control port A */
+	inb	$0x92
+	andb	$(~0x03), %al
+	testb	%dl, %dl
+	jz	6f
+	orb	$0x02, %al
+6:	outb	$0x92
+
+	/* When turning off Gate A20, do not check the state strictly,
+	   because a failure is not fatal usually, and Gate A20 is always
+	   on some modern machines.  */
+	testb	%dl, %dl
+	jz	7f
+	call	gate_a20_check_state
+	cmpb	%al, %dl
+	jnz	gate_a20_try_keyboard_controller
+7:	ret
+
+gate_a20_flush_keyboard_buffer:
+	inb	$0x64
+	andb	$0x02, %al
+	jnz	gate_a20_flush_keyboard_buffer
+2:
+	inb	$0x64
+	andb	$0x01, %al
+	jz	3f
+	inb	$0x60
+	jmp	2b
+3:
+	ret
+
+gate_a20_try_keyboard_controller:
+	/* third, try the keyboard controller */
+	call    gate_a20_flush_keyboard_buffer
+
+	movb	$0xd1, %al
+	outb	$0x64
+4:
+	inb	$0x64
+	andb	$0x02, %al
+	jnz	4b
+
+	movb	$0xdd, %al
+	testb	%dl, %dl
+	jz	5f
+	orb	$0x02, %al
+5:	outb	$0x60
+	call    gate_a20_flush_keyboard_buffer
+
+	/* output a dummy command (USB keyboard hack) */
+	movb	$0xff, %al
+	outb	$0x64
+	call    gate_a20_flush_keyboard_buffer
+
+	call	gate_a20_check_state
+	cmpb	%al, %dl
+	/* everything failed, so restart from the beginning */
+	jnz	gate_a20_try_bios
+	ret
+
+gate_a20_check_state:
+	/* iterate the checking for a while */
+	movl	$100, %ecx
+1:
+	call	3f
+	cmpb	%al, %dl
+	jz	2f
+	loop	1b
+2:
+	ret
+3:
+	pushl	%ebx
+	pushl	%ecx
+	xorl	%eax, %eax
+	/* compare the byte at 0x8000 with that at 0x108000 */
+	movl	$GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx
+	pushl	%ebx
+	/* save the original byte in CL */
+	movb	(%ebx), %cl
+	/* store the value at 0x108000 in AL */
+	addl	$0x100000, %ebx
+	movb	(%ebx), %al
+	/* try to set one less value at 0x8000 */
+	popl	%ebx
+	movb	%al, %ch
+	decb	%ch
+	movb	%ch, (%ebx)
+	/* serialize */
+	outb	%al, $0x80
+	outb	%al, $0x80
+	/* obtain the value at 0x108000 in CH */
+	pushl	%ebx
+	addl	$0x100000, %ebx
+	movb	(%ebx), %ch
+	/* this result is 1 if A20 is on or 0 if it is off */
+	subb	%ch, %al
+	xorb	$1, %al
+	/* restore the original */
+	popl	%ebx
+	movb	%cl, (%ebx)
+	popl	%ecx
+	popl	%ebx
+	ret
+
+#ifdef ENABLE_LZMA
+#include "lzma_decode.S"
+#endif
+
+/*
+ * The code beyond this point is compressed.  Assert that the uncompressed
+ * code fits GRUB_KERNEL_MACHINE_RAW_SIZE.
+ */
+	. = _start + GRUB_KERNEL_MACHINE_RAW_SIZE
+
+	/*
+	 * This next part is sort of evil.  It takes advantage of the
+	 * byte ordering on the x86 to work in either 16-bit or 32-bit
+	 * mode, so think about it before changing it.
+	 */
+
+FUNCTION(grub_hard_stop)
+	hlt
+	jmp EXT_C(grub_hard_stop)
+
+
+/*
+ * grub_stop_floppy()
+ *
+ * Stop the floppy drive from spinning, so that other software is
+ * jumped to with a known state.
+ */
+FUNCTION(grub_stop_floppy)
+	movw	$0x3F2, %dx
+	xorb	%al, %al
+	outb	%al, %dx
+	ret
+
+/*
+ * grub_exit()
+ *
+ * Exit the system.
+ */
+FUNCTION(grub_exit)
+	call	prot_to_real
+	.code16
+	/* Tell the BIOS a boot failure. If this does not work, reboot.  */
+	int	$0x18
+	jmp	cold_reboot
+	.code32
+
+/*
+ * grub_reboot()
+ *
+ * Reboot the system. At the moment, rely on BIOS.
+ */
+FUNCTION(grub_reboot)
+	call	prot_to_real
+	.code16
+cold_reboot:
+	/* cold boot */
+	movw	$0x0472, %di
+	movw	%ax, (%di)
+	ljmp	$0xFFFF, $0x0000
+	.code32
+
+/*
+ * grub_halt(int no_apm)
+ *
+ * Halt the system, using APM if possible. If NO_APM is true, don't use
+ * APM even if it is available.
+ */
+FUNCTION(grub_halt)
+	/* see if zero */
+	testl	%eax, %eax
+	jnz	EXT_C(grub_stop)
+
+	call	prot_to_real
+	.code16
+
+	/* detect APM */
+	movw	$0x5300, %ax
+	xorw	%bx, %bx
+	int	$0x15
+	jc	EXT_C(grub_hard_stop)
+	/* don't check %bx for buggy BIOSes... */
+
+	/* disconnect APM first */
+	movw	$0x5304, %ax
+	xorw	%bx, %bx
+	int	$0x15
+
+	/* connect APM */
+	movw	$0x5301, %ax
+	xorw	%bx, %bx
+	int	$0x15
+	jc	EXT_C(grub_hard_stop)
+
+	/* set APM protocol level - 1.1 or bust. (this covers APM 1.2 also) */
+	movw	$0x530E, %ax
+	xorw	%bx, %bx
+	movw	$0x0101, %cx
+	int	$0x15
+	jc	EXT_C(grub_hard_stop)
+
+	/* set the power state to off */
+	movw	$0x5307, %ax
+	movw	$1, %bx
+	movw	$3, %cx
+	int	$0x15
+
+	/* shouldn't reach here */
+	jmp	EXT_C(grub_hard_stop)
+	.code32
+
+
+/*
+ *  void grub_chainloader_real_boot (int drive, void *part_addr)
+ *
+ *  This starts another boot loader.
+ */
+
+FUNCTION(grub_chainloader_real_boot)
+	pushl	%edx
+	pushl	%eax
+
+	call	EXT_C(grub_dl_unload_all)
+
+	/* Turn off Gate A20 */
+	xorl	%eax, %eax
+	call	EXT_C(grub_gate_a20)
+
+	/* set up to pass boot drive */
+	popl	%edx
+
+	/* ESI must point to a partition table entry */
+	popl	%esi
+
+	call	prot_to_real
+	.code16
+	ljmp	$0, $GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR
+	.code32
+
+#include "../loader.S"
+
+/*
+ *   int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap)
+ *
+ *   Call IBM/MS INT13 Extensions (int 13 %ah=AH) for DRIVE. DAP
+ *   is passed for disk address packet. If an error occurs, return
+ *   non-zero, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_rw_int13_extensions)
+	pushl	%ebp
+	pushl	%esi
+
+	/* compute the address of disk_address_packet */
+	movw	%cx, %si
+	xorw	%cx, %cx
+	shrl	$4, %ecx	/* save the segment to cx */
+
+	/* ah */
+	movb	%al, %dh
+	/* enter real mode */
+	call	prot_to_real
+
+	.code16
+	movb	%dh, %ah
+	movw	%cx, %ds
+	int	$0x13		/* do the operation */
+	movb	%ah, %dl	/* save return value */
+	/* back to protected mode */
+	DATA32	call	real_to_prot
+	.code32
+
+	movb	%dl, %al	/* return value in %eax */
+
+	popl	%esi
+	popl	%ebp
+
+	ret
+
+/*
+ *   int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff,
+ *                                  int soff, int nsec, int segment)
+ *
+ *   Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write
+ *   NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs,
+ *   return non-zero, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_rw_standard)
+	pushl	%ebp
+	movl	%esp, %ebp
+
+	pushl	%ebx
+	pushl	%edi
+	pushl	%esi
+
+	/* set up CHS information */
+
+	/* set %ch to low eight bits of cylinder */
+	xchgb	%cl, %ch
+	/* set bits 6-7 of %cl to high two bits of cylinder */
+	shlb	$6, %cl
+	/* set bits 0-5 of %cl to sector */
+	addb	0xc(%ebp), %cl
+	/* set %dh to head */
+	movb	0x8(%ebp), %dh
+	/* set %ah to AH */
+	movb	%al, %ah
+	/* set %al to NSEC */
+	movb	0x10(%ebp), %al
+	/* save %ax in %di */
+	movw	%ax, %di
+	/* save SEGMENT in %bx */
+	movw	0x14(%ebp), %bx
+
+	/* enter real mode */
+	call	prot_to_real
+
+	.code16
+	movw	%bx, %es
+	xorw	%bx, %bx
+	movw	$3, %si		/* attempt at least three times */
+
+1:
+	movw	%di, %ax
+	int	$0x13		/* do the operation */
+	jnc	2f		/* check if successful */
+
+	movb	%ah, %bl	/* save return value */
+	/* if fail, reset the disk system */
+	xorw	%ax, %ax
+	int	$0x13
+
+	decw	%si
+	cmpw	$0, %si
+	je	2f
+	xorb	%bl, %bl
+	jmp	1b		/* retry */
+2:
+	/* back to protected mode */
+	DATA32	call	real_to_prot
+	.code32
+
+	movb	%bl, %al	/* return value in %eax */
+
+	popl	%esi
+	popl	%edi
+	popl	%ebx
+	popl	%ebp
+
+	ret	$(4 * 4)
+
+
+/*
+ *   int grub_biosdisk_check_int13_extensions (int drive)
+ *
+ *   Check if LBA is supported for DRIVE. If it is supported, then return
+ *   the major version of extensions, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_check_int13_extensions)
+	pushl	%ebp
+	pushl	%ebx
+
+	/* drive */
+	movb	%al, %dl
+	/* enter real mode */
+	call	prot_to_real
+
+	.code16
+	movb	$0x41, %ah
+	movw	$0x55aa, %bx
+	int	$0x13		/* do the operation */
+
+	/* check the result */
+	jc	1f
+	cmpw	$0xaa55, %bx
+	jne	1f
+
+	movb	%ah, %bl	/* save the major version into %bl */
+
+	/* check if AH=0x42 is supported */
+	andw	$1, %cx
+	jnz	2f
+
+1:
+	xorb	%bl, %bl
+2:
+	/* back to protected mode */
+	DATA32	call	real_to_prot
+	.code32
+
+	movb	%bl, %al	/* return value in %eax */
+
+	popl	%ebx
+	popl	%ebp
+
+	ret
+
+
+/*
+ *   int grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp)
+ *
+ *   Return the cdrom information of DRIVE in CDRP. If an error occurs,
+ *   then return non-zero, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_get_cdinfo_int13_extensions)
+	movw	$0x4B01, %cx
+	jmp	1f
+
+/*
+ *   int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp)
+ *
+ *   Return the geometry of DRIVE in a drive parameters, DRP. If an error
+ *   occurs, then return non-zero, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions)
+	movb	$0x48, %ch
+1:
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%esi
+
+	/* compute the address of drive parameters */
+	movw	%dx, %si
+	andl	$0xf, %esi
+	shrl	$4, %edx
+	movw	%dx, %bx	/* save the segment into %bx */
+	/* drive */
+	movb	%al, %dl
+	/* enter real mode */
+	call	prot_to_real
+
+	.code16
+	movw	%cx, %ax
+	movw	%bx, %ds
+	int	$0x13		/* do the operation */
+	movb	%ah, %bl	/* save return value in %bl */
+	/* back to protected mode */
+	DATA32	call	real_to_prot
+	.code32
+
+	movb	%bl, %al	/* return value in %eax */
+
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+
+	ret
+
+
+/*
+ *   int grub_biosdisk_get_diskinfo_standard (int drive,
+ *                                            unsigned long *cylinders,
+ *                                            unsigned long *heads,
+ *                                            unsigned long *sectors)
+ *
+ *   Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an
+ *   error occurs, then return non-zero, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_get_diskinfo_standard)
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%edi
+
+	/* push CYLINDERS */
+	pushl	%edx
+	/* push HEADS */
+	pushl	%ecx
+	/* SECTORS is on the stack */
+
+	/* drive */
+	movb	%al, %dl
+	/* enter real mode */
+	call	prot_to_real
+
+	.code16
+	movb	$0x8, %ah
+	int	$0x13		/* do the operation */
+	/* check if successful */
+	testb	%ah, %ah
+	jnz	1f
+	/* bogus BIOSes may not return an error number */
+	testb	$0x3f, %cl	/* 0 sectors means no disk */
+	jnz	1f		/* if non-zero, then succeed */
+	/* XXX 0x60 is one of the unused error numbers */
+	movb	$0x60, %ah
+1:
+	movb	%ah, %bl	/* save return value in %bl */
+	/* back to protected mode */
+	DATA32	call	real_to_prot
+	.code32
+
+	/* pop HEADS */
+	popl	%edi
+	movb	%dh, %al
+	incl	%eax	/* the number of heads is counted from zero */
+	movl	%eax, (%edi)
+
+	/* pop CYLINDERS */
+	popl	%edi
+	movb	%ch, %al
+	movb	%cl, %ah
+	shrb	$6, %ah	/* the number of cylinders is counted from zero */
+	incl	%eax
+	movl	%eax, (%edi)
+
+	/* SECTORS */
+	movl	0x10(%esp), %edi
+	andb	$0x3f, %cl
+	movzbl	%cl, %eax
+	movl	%eax, (%edi)
+
+	xorl	%eax, %eax
+	movb	%bl, %al	/* return value in %eax */
+
+	popl	%edi
+	popl	%ebx
+	popl	%ebp
+
+	ret	$4
+
+
+/*
+ * int grub_biosdisk_get_num_floppies (void)
+ */
+FUNCTION(grub_biosdisk_get_num_floppies)
+	pushl	%ebp
+
+	xorl	%edx, %edx
+	call	prot_to_real
+
+	.code16
+	/* reset the disk system first */
+	int	$0x13
+1:
+	stc
+
+	/* call GET DISK TYPE */
+	movb	$0x15, %ah
+	int	$0x13
+
+	jc	2f
+
+	/* check if this drive exists */
+	testb	$0x3, %ah
+	jz	2f
+
+	incb	%dl
+	cmpb	$2, %dl
+	jne	1b
+2:
+	DATA32	call	real_to_prot
+	.code32
+
+	movl	%edx, %eax
+	popl	%ebp
+	ret
+
+
+/*
+ *
+ * grub_get_memsize(i) :  return the memory size in KB. i == 0 for conventional
+ *		memory, i == 1 for extended memory
+ *	BIOS call "INT 12H" to get conventional memory size
+ *	BIOS call "INT 15H, AH=88H" to get extended memory size
+ *		Both have the return value in AX.
+ *
+ */
+
+FUNCTION(grub_get_memsize)
+	pushl	%ebp
+
+	movl	%eax, %edx
+
+	call	prot_to_real	/* enter real mode */
+	.code16
+
+	testl	%edx, %edx
+	jnz	xext
+
+	int	$0x12
+	jmp	xdone
+
+xext:
+	movb	$0x88, %ah
+	int	$0x15
+
+xdone:
+	movw	%ax, %dx
+
+	DATA32	call	real_to_prot
+	.code32
+
+	movw	%dx, %ax
+
+	popl	%ebp
+	ret
+
+
+/*
+ *
+ * grub_get_eisa_mmap() :  return packed EISA memory map, lower 16 bits is
+ *		memory between 1M and 16M in 1K parts, upper 16 bits is
+ *		memory above 16M in 64K parts.  If error, return zero.
+ *	BIOS call "INT 15H, AH=E801H" to get EISA memory map,
+ *		AX = memory between 1M and 16M in 1K parts.
+ *		BX = memory above 16M in 64K parts.
+ *
+ */
+
+FUNCTION(grub_get_eisa_mmap)
+	pushl	%ebp
+	pushl	%ebx
+
+	call	prot_to_real	/* enter real mode */
+	.code16
+
+	movw	$0xe801, %ax
+	int	$0x15
+
+	shll	$16, %ebx
+	movw	%ax, %bx
+
+	DATA32	call	real_to_prot
+	.code32
+
+	cmpb	$0x86, %bh
+	je	xnoteisa
+
+	movl	%ebx, %eax
+
+xnoteisa:
+	popl	%ebx
+	popl	%ebp
+	ret
+
+/*
+ *
+ * grub_get_mmap_entry(addr, cont) : address and old continuation value (zero to
+ *		start), for the Query System Address Map BIOS call.
+ *
+ *  Sets the first 4-byte int value of "addr" to the size returned by
+ *  the call.  If the call fails, sets it to zero.
+ *
+ *	Returns:  new (non-zero) continuation value, 0 if done.
+ */
+
+FUNCTION(grub_get_mmap_entry)
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%edi
+	pushl	%esi
+
+	/* push ADDR */
+	pushl	%eax
+
+	/* place address (+4) in ES:DI */
+	addl	$4, %eax
+	movl	%eax, %edi
+	andl	$0xf, %edi
+	shrl	$4, %eax
+	movl	%eax, %esi
+
+	/* set continuation value */
+	movl	%edx, %ebx
+
+	/* set default maximum buffer size */
+	movl	$0x14, %ecx
+
+	/* set EDX to 'SMAP' */
+	movl	$0x534d4150, %edx
+
+	call	prot_to_real	/* enter real mode */
+	.code16
+
+	movw	%si, %es
+	movl	$0xe820, %eax
+	int	$0x15
+
+	DATA32	jc	xnosmap
+
+	cmpl	$0x534d4150, %eax
+	jne	xnosmap
+
+	cmpl	$0x14, %ecx
+	jl	xnosmap
+
+	cmpl	$0x400, %ecx
+	jg	xnosmap
+
+	jmp	xsmap
+
+xnosmap:
+	xorl	%ecx, %ecx
+
+/* 	Apple's cc jumps few bytes before the correct
+	label in this context. Hence nops. */
+#ifdef APPLE_CC
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+#endif
+
+xsmap:
+	DATA32	call	real_to_prot
+	.code32
+
+	/* write length of buffer (zero if error) into ADDR */
+	popl	%eax
+	movl	%ecx, (%eax)
+
+	/* set return value to continuation */
+	movl	%ebx, %eax
+
+	popl	%esi
+	popl	%edi
+	popl	%ebx
+	popl	%ebp
+	ret
+
+
+/*
+ * void grub_console_real_putchar (int c)
+ *
+ * Put the character C on the console. Because GRUB wants to write a
+ * character with an attribute, this implementation is a bit tricky.
+ * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh
+ * (TELETYPE OUTPUT). Otherwise, save the original position, put a space,
+ * save the current position, restore the original position, write the
+ * character and the attribute, and restore the current position.
+ *
+ * The reason why this is so complicated is that there is no easy way to
+ * get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't
+ * support setting a background attribute.
+ */
+FUNCTION(grub_console_real_putchar)
+	movl	%eax, %edx
+	pusha
+	movb	EXT_C(grub_console_cur_color), %bl
+
+	call	prot_to_real
+	.code16
+	movb	%dl, %al
+	xorb	%bh, %bh
+
+	/* use teletype output if control character */
+	cmpb	$0x7, %al
+	je	1f
+	cmpb	$0x8, %al
+	je	1f
+	cmpb	$0xa, %al
+	je	1f
+	cmpb	$0xd, %al
+	je	1f
+
+	/* save the character and the attribute on the stack */
+	pushw	%ax
+	pushw	%bx
+
+	/* get the current position */
+	movb	$0x3, %ah
+	int	$0x10
+
+	/* check the column with the width */
+	cmpb	$79, %dl
+	jl	2f
+
+	/* print CR and LF, if next write will exceed the width */
+	movw	$0x0e0d, %ax
+	int	$0x10
+	movb	$0x0a, %al
+	int	$0x10
+
+	/* get the current position */
+	movb	$0x3, %ah
+	int	$0x10
+
+2:
+	/* restore the character and the attribute */
+	popw	%bx
+	popw	%ax
+
+	/* write the character with the attribute */
+	movb	$0x9, %ah
+	movw	$1, %cx
+	int	$0x10
+
+	/* move the cursor forward */
+	incb	%dl
+	movb	$0x2, %ah
+	int	$0x10
+
+	jmp	3f
+
+1:	movw	$1, %bx
+	movb	$0xe, %ah
+	int	$0x10
+
+3:	DATA32	call	real_to_prot
+	.code32
+
+	popa
+	ret
+
+
+/*
+ * int grub_console_getkey (void)
+ * BIOS call "INT 16H Function 00H" to read character from keyboard
+ *	Call with	%ah = 0x0
+ *	Return:		%ah = keyboard scan code
+ *			%al = ASCII character
+ */
+
+/* this table is used in translate_keycode below */
+translation_table:
+	.word	GRUB_CONSOLE_KEY_LEFT, GRUB_TERM_LEFT
+	.word	GRUB_CONSOLE_KEY_RIGHT, GRUB_TERM_RIGHT
+	.word	GRUB_CONSOLE_KEY_UP, GRUB_TERM_UP
+	.word	GRUB_CONSOLE_KEY_DOWN, GRUB_TERM_DOWN
+	.word	GRUB_CONSOLE_KEY_HOME, GRUB_TERM_HOME
+	.word	GRUB_CONSOLE_KEY_END, GRUB_TERM_END
+	.word	GRUB_CONSOLE_KEY_DC, GRUB_TERM_DC
+	.word	GRUB_CONSOLE_KEY_BACKSPACE, GRUB_TERM_BACKSPACE
+	.word	GRUB_CONSOLE_KEY_PPAGE, GRUB_TERM_PPAGE
+	.word	GRUB_CONSOLE_KEY_NPAGE, GRUB_TERM_NPAGE
+	.word	0
+
+/*
+ * translate_keycode translates the key code %dx to an ascii code.
+ */
+	.code16
+
+translate_keycode:
+	pushw	%bx
+	pushw	%si
+
+#ifdef APPLE_CC
+	translation_table_abs = ABS (translation_table) - 0x10000
+	movw	$(translation_table_abs), %si
+#else
+	movw	$ABS(translation_table), %si
+#endif
+
+1:	lodsw
+	/* check if this is the end */
+	testw	%ax, %ax
+	jz	2f
+	/* load the ascii code into %ax */
+	movw	%ax, %bx
+	lodsw
+	/* check if this matches the key code */
+	cmpw	%bx, %dx
+	jne	1b
+	/* translate %dx, if successful */
+	movw	%ax, %dx
+
+2:	popw	%si
+	popw	%bx
+	ret
+
+	.code32
+
+FUNCTION(grub_console_getkey)
+	pushl	%ebp
+
+	call	prot_to_real
+	.code16
+
+	/*
+	 * Due to a bug in apple's bootcamp implementation, INT 16/AH = 0 would
+	 * cause the machine to hang at the second keystroke. However, we can
+	 * work around this problem by ensuring the presence of keystroke with
+	 * INT 16/AH = 1 before calling INT 16/AH = 0.
+	 */
+
+1:
+	movb	$1, %ah
+	int	$0x16
+	jnz	2f
+	hlt
+	jmp	1b
+
+2:
+
+	movb	$0, %ah
+	int	$0x16
+
+	movw	%ax, %dx		/* real_to_prot uses %eax */
+	call	translate_keycode
+
+	DATA32	call	real_to_prot
+	.code32
+
+	movw	%dx, %ax
+
+	popl	%ebp
+	ret
+
+
+/*
+ * int grub_console_checkkey (void)
+ *	if there is a character pending, return it; otherwise return -1
+ * BIOS call "INT 16H Function 01H" to check whether a character is pending
+ *	Call with	%ah = 0x1
+ *	Return:
+ *		If key waiting to be input:
+ *			%ah = keyboard scan code
+ *			%al = ASCII character
+ *			Zero flag = clear
+ *		else
+ *			Zero flag = set
+ */
+FUNCTION(grub_console_checkkey)
+	pushl	%ebp
+	xorl	%edx, %edx
+
+	call	prot_to_real	/* enter real mode */
+	.code16
+
+	movb	$0x1, %ah
+	int	$0x16
+
+	jz	notpending
+
+	movw	%ax, %dx
+	DATA32	jmp	pending
+
+notpending:
+	decl	%edx
+
+pending:
+	DATA32	call	real_to_prot
+	.code32
+
+	movl	%edx, %eax
+
+	popl	%ebp
+	ret
+
+
+/*
+ * grub_uint16_t grub_console_getxy (void)
+ * BIOS call "INT 10H Function 03h" to get cursor position
+ *	Call with	%ah = 0x03
+ *			%bh = page
+ *      Returns         %ch = starting scan line
+ *                      %cl = ending scan line
+ *                      %dh = row (0 is top)
+ *                      %dl = column (0 is left)
+ */
+
+
+FUNCTION(grub_console_getxy)
+	pushl	%ebp
+	pushl	%ebx                    /* save EBX */
+
+	call	prot_to_real
+	.code16
+
+        xorb	%bh, %bh                /* set page to 0 */
+	movb	$0x3, %ah
+	int	$0x10			/* get cursor position */
+
+	DATA32	call	real_to_prot
+	.code32
+
+	movb	%dl, %ah
+	movb	%dh, %al
+
+	popl	%ebx
+	popl	%ebp
+	ret
+
+
+/*
+ * void grub_console_gotoxy(grub_uint8_t x, grub_uint8_t y)
+ * BIOS call "INT 10H Function 02h" to set cursor position
+ *	Call with	%ah = 0x02
+ *			%bh = page
+ *                      %dh = row (0 is top)
+ *                      %dl = column (0 is left)
+ */
+
+
+FUNCTION(grub_console_gotoxy)
+	pushl	%ebp
+	pushl	%ebx                    /* save EBX */
+
+	movb	%dl, %dh	/* %dh = y */
+	movb	%al, %dl	/* %dl = x */
+
+	call	prot_to_real
+	.code16
+
+        xorb	%bh, %bh                /* set page to 0 */
+	movb	$0x2, %ah
+	int	$0x10			/* set cursor position */
+
+	DATA32	call	real_to_prot
+	.code32
+
+	popl	%ebx
+	popl	%ebp
+	ret
+
+
+/*
+ * void grub_console_cls (void)
+ * BIOS call "INT 10H Function 09h" to write character and attribute
+ *	Call with	%ah = 0x09
+ *                      %al = (character)
+ *                      %bh = (page number)
+ *                      %bl = (attribute)
+ *                      %cx = (number of times)
+ */
+
+FUNCTION(grub_console_cls)
+	pushl	%ebp
+	pushl	%ebx                    /* save EBX */
+
+	call	prot_to_real
+	.code16
+
+	/* move the cursor to the beginning */
+	movb	$0x02, %ah
+	xorb	%bh, %bh
+	xorw	%dx, %dx
+	int	$0x10
+
+	/* write spaces to the entire screen */
+	movw	$0x0920, %ax
+	movw	$0x07, %bx
+	movw	$(80 * 25), %cx
+        int	$0x10
+
+	/* move back the cursor */
+	movb	$0x02, %ah
+	int	$0x10
+
+	DATA32	call	real_to_prot
+	.code32
+
+	popl	%ebx
+	popl	%ebp
+	ret
+
+
+/*
+ * void grub_console_setcursor (int on)
+ * BIOS call "INT 10H Function 01h" to set cursor type
+ *      Call with       %ah = 0x01
+ *                      %ch = cursor starting scanline
+ *                      %cl = cursor ending scanline
+ */
+
+console_cursor_state:
+	.byte	1
+console_cursor_shape:
+	.word	0
+
+FUNCTION(grub_console_setcursor)
+	pushl	%ebp
+	pushl	%ebx
+
+	/* push ON */
+	pushl	%eax
+
+	/* check if the standard cursor shape has already been saved */
+	movw	console_cursor_shape, %ax
+	testw	%ax, %ax
+	jne	1f
+
+	call	prot_to_real
+	.code16
+
+	movb	$0x03, %ah
+	xorb	%bh, %bh
+	int	$0x10
+
+	DATA32	call	real_to_prot
+	.code32
+
+	movw	%cx, console_cursor_shape
+1:
+	/* set %cx to the designated cursor shape */
+	movw	$0x2000, %cx
+	popl	%eax
+	testl	%eax, %eax
+	jz	2f
+	movw	console_cursor_shape, %cx
+2:
+	call	prot_to_real
+	.code16
+
+	movb    $0x1, %ah
+	int     $0x10
+
+	DATA32	call	real_to_prot
+	.code32
+
+	popl	%ebx
+	popl	%ebp
+	ret
+
+/*
+ * grub_getrtsecs()
+ *	if a seconds value can be read, read it and return it (BCD),
+ *      otherwise return 0xFF
+ * BIOS call "INT 1AH Function 02H" to check whether a character is pending
+ *	Call with	%ah = 0x2
+ *	Return:
+ *		If RT Clock can give correct values
+ *			%ch = hour (BCD)
+ *			%cl = minutes (BCD)
+ *                      %dh = seconds (BCD)
+ *                      %dl = daylight savings time (00h std, 01h daylight)
+ *			Carry flag = clear
+ *		else
+ *			Carry flag = set
+ *                         (this indicates that the clock is updating, or
+ *                          that it isn't running)
+ */
+FUNCTION(grub_getrtsecs)
+	pushl	%ebp
+
+	call	prot_to_real	/* enter real mode */
+	.code16
+
+	clc
+	movb	$0x2, %ah
+	int	$0x1a
+
+	DATA32	jnc	gottime
+	movb	$0xff, %dh
+
+gottime:
+	DATA32	call	real_to_prot
+	.code32
+
+	movb	%dh, %al
+
+	popl	%ebp
+	ret
+
+
+/*
+ * grub_get_rtc()
+ *	return the real time in ticks, of which there are about
+ *	18-20 per second
+ */
+FUNCTION(grub_get_rtc)
+	pushl	%ebp
+
+	call	prot_to_real	/* enter real mode */
+	.code16
+
+	/* %ax is already zero */
+        int	$0x1a
+
+	DATA32	call	real_to_prot
+	.code32
+
+	movl	%ecx, %eax
+	shll	$16, %eax
+	movw	%dx, %ax
+
+	popl	%ebp
+	ret
+
+
+/*
+ * unsigned char grub_vga_set_mode (unsigned char mode)
+ */
+FUNCTION(grub_vga_set_mode)
+	pushl	%ebp
+	pushl	%ebx
+	movl	%eax, %ecx
+
+	call	prot_to_real
+	.code16
+	/* get current mode */
+	xorw	%bx, %bx
+	movb	$0x0f, %ah
+	int	$0x10
+	movb	%al, %dl
+
+	/* set the new mode */
+	movb	%cl, %al
+	xorb	%ah, %ah
+	int	$0x10
+
+	DATA32	call	real_to_prot
+	.code32
+
+	movb	%dl, %al
+	popl	%ebx
+	popl	%ebp
+	ret
+
+
+/*
+ * unsigned char *grub_vga_get_font (void)
+ */
+FUNCTION(grub_vga_get_font)
+	pushl	%ebp
+	pushl	%ebx
+
+	call	prot_to_real
+	.code16
+	movw	$0x1130, %ax
+	movb	$0x06, %bh
+	int	$0x10
+	movw	%es, %bx
+	movw	%bp, %dx
+	DATA32	call	real_to_prot
+	.code32
+
+	movzwl	%bx, %ecx
+	shll	$4, %ecx
+	movw	%dx, %ax
+	addl	%ecx, %eax
+
+	popl	%ebx
+	popl	%ebp
+	ret
+
+/*
+ * grub_vbe_bios_status_t grub_vbe_get_controller_info (struct grub_vbe_info_block *controller_info)
+ *
+ * Register allocations for parameters:
+ * %eax		*controller_info
+ */
+FUNCTION(grub_vbe_bios_get_controller_info)
+	pushl	%ebp
+	pushl	%edi
+	pushl	%edx
+
+	movw	%ax, %di	/* Store *controller_info to %edx:%di.  */
+	xorw	%ax, %ax
+	shrl	$4, %eax
+	mov	%eax, %edx	/* prot_to_real destroys %eax.  */
+
+	call	prot_to_real
+	.code16
+
+	pushw	%es
+
+	movw	%dx, %es	/* *controller_info is now on %es:%di.  */
+	movw	$0x4f00, %ax
+	int	$0x10
+
+	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
+
+	popw	%es
+
+	DATA32 call	real_to_prot
+	.code32
+
+	movl	%edx, %eax
+	andl	$0x0FFFF, %eax	/* Return value in %eax.  */
+
+	pop	%edx
+	popl	%edi
+	popl	%ebp
+	ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_get_mode_info (grub_uint32_t mode,
+ *						  struct grub_vbe_mode_info_block *mode_info)
+ *
+ * Register allocations for parameters:
+ * %eax		mode
+ * %edx		*mode_info
+ */
+FUNCTION(grub_vbe_bios_get_mode_info)
+	pushl   %ebp
+	pushl   %edi
+
+	movl	%eax, %ecx	/* Store mode number to %ecx.  */
+
+	movw    %dx, %di	/* Store *mode_info to %edx:%di.  */
+	xorw    %dx, %dx
+	shrl    $4, %edx
+
+	call    prot_to_real
+	.code16
+
+	pushw   %es
+
+	movw    %dx, %es	/* *mode_info is now on %es:%di.  */
+	movw    $0x4f01, %ax
+	int     $0x10
+
+	movw    %ax, %dx        /* real_to_prot destroys %eax.  */
+
+	popw    %es
+
+	DATA32 call     real_to_prot
+	.code32
+
+	movl    %edx, %eax
+	andl    $0x0FFFF, %eax  /* Return value in %eax.  */
+
+	popl    %edi
+	popl    %ebp
+	ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_set_mode (grub_uint32_t mode,
+ *					     struct grub_vbe_crtc_info_block *crtc_info)
+ *
+ * Register allocations for parameters:
+ * %eax		mode
+ * %edx		*crtc_info
+ */
+FUNCTION(grub_vbe_bios_set_mode)
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%edi
+
+	movl	%eax, %ebx	/* Store mode in %ebx.  */
+
+	movw    %dx, %di	/* Store *crtc_info to %edx:%di.  */
+	xorw    %dx, %dx
+	shrl    $4, %edx
+
+	call    prot_to_real
+	.code16
+
+	pushw   %es
+
+	movw    %dx, %es	/* *crtc_info is now on %es:%di.  */
+
+	movw	$0x4f02, %ax
+	int	$0x10
+
+	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
+
+	popw	%es
+
+	DATA32 call	real_to_prot
+	.code32
+
+	movw	%dx, %ax
+	andl	$0xFFFF, %eax	/* Return value in %eax.  */
+
+	popl	%edi
+	popl	%ebx
+	popl	%ebp
+	ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_get_mode (grub_uint32_t *mode)
+ *
+ * Register allocations for parameters:
+ * %eax		*mode
+ */
+FUNCTION(grub_vbe_bios_get_mode)
+	pushl   %ebp
+	pushl   %ebx
+	pushl	%edi
+	pushl	%edx
+	pushl	%eax		/* Push *mode to stack.  */
+
+	call    prot_to_real
+	.code16
+
+	movw    $0x4f03, %ax
+	int     $0x10
+
+	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
+
+	DATA32 call     real_to_prot
+	.code32
+
+	popl	%edi		/* Pops *mode from stack to %edi.  */
+	andl	$0xFFFF, %ebx
+	movl	%ebx, (%edi)
+
+	movw	%dx, %ax
+	andl	$0xFFFF, %eax	/* Return value in %eax.  */
+
+	popl	%edx
+	popl	%edi
+	popl    %ebx
+	popl    %ebp
+	ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *dac_mask_size)
+ *
+ * Register allocations for parameters:
+ * %eax		set
+ * %edx		*dac_mask_size
+ */
+FUNCTION(grub_vbe_bios_getset_dac_palette_width)
+	pushl	%ebp
+	pushl	%ebx
+
+	xorl	%ebx, %ebx
+
+	/* If we only want to fetch the value, set %bl to 1.  */
+	testl	%eax, %eax
+	jne	1f
+	incb	%bl
+1:
+
+	/* Put desired width in %bh.  */
+	movl	(%edx), %eax
+	movb	%al, %bh
+
+	call    prot_to_real
+	.code16
+
+	movw	$0x4f08, %ax
+	int	$0x10
+
+	movw	%ax, %cx	/* real_to_prot destroys %eax.  */
+
+	DATA32 call	real_to_prot
+	.code32
+
+	/* Move result back to *dac_mask_size.  */
+	xorl	%eax, %eax
+	movb	%bh, %al
+	movl	%eax, (%edx)
+
+	/* Return value in %eax.  */
+	movw	%cx, %ax
+
+	popl	%ebx
+	popl	%ebp
+	ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_set_memory_window (grub_uint32_t window,
+ *						      grub_uint32_t position);
+ *
+ * Register allocations for parameters:
+ * %eax		window
+ * %edx		position
+ */
+FUNCTION(grub_vbe_bios_set_memory_window)
+	pushl	%ebp
+	pushl	%ebx
+
+	movl	%eax, %ebx
+
+	call	prot_to_real
+	.code16
+
+	movw	$0x4f05, %ax
+	andw	$0x00ff, %bx	/* BL = window, BH = 0, Set memory window.  */
+	int	$0x10
+
+	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
+
+	DATA32 call	real_to_prot
+	.code32
+
+	movw	%dx, %ax
+	andl	$0xFFFF, %eax	/* Return value in %eax.  */
+
+	popl	%ebx
+	popl	%ebp
+	ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_get_memory_window (grub_uint32_t window,
+ * 						      grub_uint32_t *position);
+ *
+ * Register allocations for parameters:
+ * %eax		window
+ * %edx		*position
+ */
+FUNCTION(grub_vbe_bios_get_memory_window)
+	pushl   %ebp
+	pushl   %ebx
+	pushl	%edi
+	pushl	%edx		/* Push *position to stack.  */
+
+	movl	%eax, %ebx	/* Store window in %ebx.  */
+
+	call    prot_to_real
+	.code16
+
+	movw    $0x4f05, %ax
+	andw	$0x00ff, %bx	/* BL = window.  */
+	orw	$0x0100, %bx	/* BH = 1, Get memory window.  */
+	int     $0x10
+
+	movw	%ax, %bx	/* real_to_prot destroys %eax.  */
+
+	DATA32 call     real_to_prot
+	.code32
+
+	popl	%edi		/* pops *position from stack to %edi.  */
+	andl	$0xFFFF, %edx
+	movl	%edx, (%edi)	/* Return position to caller.  */
+
+	movw	%bx, %ax
+	andl	$0xFFFF, %eax	/* Return value in %eax.  */
+
+	popl	%edi
+	popl    %ebx
+	popl    %ebp
+	ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_set_scanline_length (grub_uint32_t length)
+ *
+ * Register allocations for parameters:
+ * %eax		length
+ */
+FUNCTION(grub_vbe_bios_set_scanline_length)
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%edx
+
+	movl	%eax, %ecx	/* Store length in %ecx.  */
+
+	call	prot_to_real
+	.code16
+
+	movw	$0x4f06, %ax
+	movw	$0x0002, %bx	/* BL = 2, Set Scan Line in Bytes.  */
+	int	$0x10
+
+	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
+
+	DATA32 call	real_to_prot
+	.code32
+
+	movw	%dx, %ax
+	andl	$0xFFFF, %eax	/* Return value in %eax.  */
+
+	popl	%edx
+	popl	%ebx
+	popl	%ebp
+	ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_get_scanline_length (grub_uint32_t *length)
+ *
+ * Register allocations for parameters:
+ * %eax		*length
+ */
+FUNCTION(grub_vbe_bios_get_scanline_length)
+	pushl   %ebp
+	pushl   %ebx
+	pushl	%edi
+	pushl	%edx		/* Push *length to stack.  */
+
+	call    prot_to_real
+	.code16
+
+	movw    $0x4f06, %ax
+	movw	$0x0001, %bx	/* BL = 1, Get Scan Line Length (in bytes).  */
+	int     $0x10
+
+	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
+
+	DATA32 call     real_to_prot
+	.code32
+
+	popl	%edi		/* Pops *length from stack to %edi.  */
+	andl	$0xFFFF, %ebx
+	movl	%ebx, (%edi)	/* Return length to caller.  */
+
+	movw	%dx, %ax
+	andl	$0xFFFF, %eax	/* Return value in %eax.  */
+
+	popl	%edi
+	popl    %ebx
+	popl    %ebp
+	ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_set_display_start (grub_uint32_t x,
+ *						      grub_uint32_t y)
+ *
+ * Register allocations for parameters:
+ * %eax		x
+ * %edx		y
+ */
+FUNCTION(grub_vbe_bios_set_display_start)
+	pushl	%ebp
+	pushl	%ebx
+
+	movl	%eax, %ecx	/* Store x in %ecx.  */
+
+	call	prot_to_real
+	.code16
+
+	movw	$0x4f07, %ax
+	movw	$0x0080, %bx	/* BL = 80h, Set Display Start
+				   during Vertical Retrace.  */
+	int	$0x10
+
+	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
+
+	DATA32 call	real_to_prot
+	.code32
+
+	movw	%dx, %ax
+	andl	$0xFFFF, %eax	/* Return value in %eax.  */
+
+	popl	%ebx
+	popl	%ebp
+	ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_get_display_start (grub_uint32_t *x,
+ *						      grub_uint32_t *y)
+ *
+ * Register allocations for parameters:
+ * %eax		*x
+ * %edx		*y
+ */
+FUNCTION(grub_vbe_bios_get_display_start)
+	pushl   %ebp
+	pushl   %ebx
+	pushl	%edi
+	pushl	%eax		/* Push *x to stack.  */
+	pushl	%edx		/* Push *y to stack.  */
+
+	call    prot_to_real
+	.code16
+
+	movw    $0x4f07, %ax
+	movw	$0x0001, %bx	/* BL = 1, Get Display Start.  */
+	int     $0x10
+
+	movw	%ax, %bx	/* real_to_prot destroys %eax.  */
+
+	DATA32 call     real_to_prot
+	.code32
+
+	popl	%edi		/* Pops *y from stack to %edi.  */
+	andl	$0xFFFF, %edx
+	movl	%edx, (%edi)	/* Return y-position to caller.  */
+
+	popl	%edi		/* Pops *x from stack to %edi.  */
+	andl	$0xFFFF, %ecx
+	movl	%ecx, (%edi)	/* Return x-position to caller.  */
+
+	movw	%bx, %ax
+	andl	$0xFFFF, %eax	/* Return value in %eax.  */
+
+	popl	%edi
+	popl    %ebx
+	popl    %ebp
+	ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_set_palette_data (grub_uint32_t color_count,
+ *						     grub_uint32_t start_index,
+ *						     struct grub_vbe_palette_data *palette_data)
+ *
+ * Register allocations for parameters:
+ * %eax		color_count
+ * %edx		start_index
+ * %ecx		*palette_data
+ */
+FUNCTION(grub_vbe_bios_set_palette_data)
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%edi
+
+	movl	%eax, %ebx	/* Store color_count in %ebx.  */
+
+	movw    %cx, %di	/* Store *palette_data to %ecx:%di.  */
+	xorw    %cx, %cx
+	shrl    $4, %ecx
+
+	call    prot_to_real
+	.code16
+
+	pushw   %es
+
+	movw    %cx, %es	/* *palette_data is now on %es:%di.  */
+	movw	%bx, %cx	/* color_count is now on %cx.  */
+
+	movw	$0x4f09, %ax
+	xorw	%bx, %bx	/* BL = 0, Set Palette Data.  */
+	int	$0x10
+
+	movw	%ax, %dx	/* real_to_prot destroys %eax.  */
+
+	popw	%es
+
+	DATA32 call	real_to_prot
+	.code32
+
+	movw	%dx, %ax
+	andl	$0xFFFF, %eax	/* Return value in %eax.  */
+
+	popl	%edi
+	popl	%ebx
+	popl	%ebp
+	ret
+
+
+pxe_rm_entry:
+	.long	0
+
+/*
+ * struct grub_pxenv *grub_pxe_scan (void);
+ */
+FUNCTION(grub_pxe_scan)
+	pushl	%ebp
+	pushl	%ebx
+
+	xorl	%ebx, %ebx
+	xorl	%ecx, %ecx
+
+	call    prot_to_real
+	.code16
+
+	pushw	%es
+
+	movw	$0x5650, %ax
+	int	$0x1A
+	cmpw	$0x564E, %ax
+	jnz	1f
+	cmpl	$0x4E455850, %es:(%bx)		/* PXEN(V+)  */
+	jnz	1f
+	cmpw	$0x201, %es:6(%bx)		/* API version  */
+	jb	1f
+	lesw	%es:0x28(%bx), %bx		/* !PXE structure  */
+	cmpl	$0x45585021, %es:(%bx)		/* !PXE  */
+	jnz	1f
+	movw	%es, %cx
+	jmp	2f
+1:
+	xorw	%bx, %bx
+	xorw	%cx, %cx
+2:
+
+	popw	%es
+
+	DATA32 call	real_to_prot
+	.code32
+
+	xorl	%eax, %eax
+	leal	(%eax, %ecx, 4), %ecx
+	leal	(%ebx, %ecx, 4), %eax		/* eax = ecx * 16 + ebx  */
+
+	orl	%eax, %eax
+	jz	1f
+
+	movl	0x10(%eax), %ecx
+	movl	%ecx, pxe_rm_entry
+
+1:
+
+	popl	%ebx
+	popl	%ebp
+	ret
+
+/*
+ * int grub_pxe_call (int func, void* data);
+ */
+FUNCTION(grub_pxe_call)
+	pushl	%ebp
+	movl	%esp, %ebp
+	pushl	%esi
+	pushl	%edi
+	pushl	%ebx
+
+	movl	%eax, %ecx
+	movl	%edx, %eax
+	andl	$0xF, %eax
+	shrl	$4, %edx
+	shll	$16, %edx
+	addl	%eax, %edx
+	movl	pxe_rm_entry, %ebx
+
+	call    prot_to_real
+	.code16
+
+	pushl	%ebx
+	pushl	%edx
+	pushw	%cx
+	movw	%sp, %bx
+	lcall	*%ss:6(%bx)
+	cld
+	addw	$10, %sp
+	movw	%ax, %cx
+
+	DATA32  call	real_to_prot
+	.code32
+
+	movzwl	%cx, %eax
+
+	popl	%ebx
+	popl	%edi
+	popl	%esi
+	popl	%ebp
+	ret
diff --git a/kern/i386/pit.c b/kern/i386/pit.c
new file mode 100644
index 0000000..82a17d3
--- /dev/null
+++ b/kern/i386/pit.c
@@ -0,0 +1,56 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/i386/io.h>
+#include <grub/i386/pit.h>
+
+#define TIMER2_REG_CONTROL	0x42
+#define TIMER_REG_COMMAND	0x43
+#define TIMER2_REG_LATCH	0x61
+
+#define TIMER2_SELECT		0x80
+#define TIMER_ENABLE_LSB	0x20
+#define TIMER_ENABLE_MSB	0x10
+#define TIMER2_LATCH		0x20
+#define TIMER2_SPEAKER		0x02
+#define TIMER2_GATE		0x01
+
+void
+grub_pit_wait (grub_uint16_t tics)
+{
+  /* Disable timer2 gate and speaker.  */
+  grub_outb (grub_inb (TIMER2_REG_LATCH) & ~ (TIMER2_SPEAKER | TIMER2_GATE),
+             TIMER2_REG_LATCH);
+
+  /* Set tics.  */
+  grub_outb (TIMER2_SELECT | TIMER_ENABLE_LSB | TIMER_ENABLE_MSB, TIMER_REG_COMMAND);
+  grub_outb (tics & 0xff, TIMER2_REG_CONTROL);
+  grub_outb (tics >> 8, TIMER2_REG_CONTROL);
+
+  /* Enable timer2 gate, keep speaker disabled.  */
+  grub_outb ((grub_inb (TIMER2_REG_LATCH) & ~ TIMER2_SPEAKER) | TIMER2_GATE,
+             TIMER2_REG_LATCH);
+
+  /* Wait.  */
+  while ((grub_inb (TIMER2_REG_LATCH) & TIMER2_LATCH) == 0x00);
+
+  /* Disable timer2 gate and speaker.  */
+  grub_outb (grub_inb (TIMER2_REG_LATCH) & ~ (TIMER2_SPEAKER | TIMER2_GATE),
+             TIMER2_REG_LATCH);
+}
diff --git a/kern/i386/qemu/mmap.c b/kern/i386/qemu/mmap.c
new file mode 100644
index 0000000..4ccae02
--- /dev/null
+++ b/kern/i386/qemu/mmap.c
@@ -0,0 +1,74 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/boot.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/i386/cmos.h>
+
+#define QEMU_CMOS_MEMSIZE_HIGH		0x35
+#define QEMU_CMOS_MEMSIZE_LOW		0x34
+
+#define min(a,b)	((a) > (b) ? (b) : (a))
+
+extern char _start[];
+extern char _end[];
+
+grub_size_t grub_lower_mem, grub_upper_mem;
+grub_uint64_t mem_size;
+
+void
+grub_machine_mmap_init ()
+{
+  mem_size = grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH) << 24 | grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW) << 16;
+
+  /* Don't ask... */
+  mem_size += (16 * 1024 * 1024);
+}
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
+{
+  if (hook (0x0,
+	    (grub_addr_t) _start,
+	    GRUB_MACHINE_MEMORY_AVAILABLE))
+    return 1;
+
+  if (hook (GRUB_MEMORY_MACHINE_UPPER,
+	    0x100000 - GRUB_MEMORY_MACHINE_UPPER,
+	    GRUB_MACHINE_MEMORY_RESERVED))
+    return 1;
+
+  /* Protect boot.img, which contains the gdt.  It is mapped at the top of memory
+     (it is also mapped below 0x100000, but we already reserved that area).  */
+  if (hook ((grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE,
+	    GRUB_BOOT_MACHINE_SIZE,
+	    GRUB_MACHINE_MEMORY_RESERVED))
+    return 1;
+
+  /* Everything else is free.  */
+  if (hook (0x100000,
+	    min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000,
+	    GRUB_MACHINE_MEMORY_AVAILABLE))
+    return 1;
+
+  return 0;
+}
diff --git a/kern/i386/qemu/startup.S b/kern/i386/qemu/startup.S
new file mode 100644
index 0000000..0be5ae8
--- /dev/null
+++ b/kern/i386/qemu/startup.S
@@ -0,0 +1,97 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/kernel.h>
+
+	.text
+	.code32
+	.globl _start
+_start:
+	jmp	codestart
+
+	. = _start + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR
+VARIABLE(grub_core_entry_addr)
+	.long	0
+VARIABLE(grub_kernel_image_size)
+	.long	0
+VARIABLE(grub_prefix)
+	/* to be filled by grub-mkimage */
+
+	/*
+	 *  Leave some breathing room for the prefix.
+	 */
+
+	. = _start + GRUB_KERNEL_MACHINE_DATA_END
+
+codestart:
+	/* Relocate to low memory.  First we figure out our location.
+	   We will derive the rom start address from it.  */
+	call	1f
+1:	popl	%esi
+
+	/* Rom size is a multiple of 64 kiB.  With this we get the
+	   value of `grub_core_entry_addr' in %esi.  */
+	xorw	%si, %si
+
+	/* ... which allows us to access `grub_kernel_image_size'
+	   before relocation.  */
+	movl	(grub_kernel_image_size - _start)(%esi), %ecx
+
+
+	movl	$_start, %edi
+	cld
+	rep
+	movsb
+	ljmp	$GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $1f
+1:
+
+#ifdef APPLE_CC
+	/* clean out the bss */
+	bss_start_abs = ABS (bss_start)
+	bss_end_abs = ABS (bss_end)
+
+	movl    bss_start_abs, %edi
+
+	/* compute the bss length */
+	movl	bss_end_abs, %ecx
+	subl	%edi, %ecx
+#else
+	/* clean out the bss */
+	movl	$BSS_START_SYMBOL, %edi
+
+	/* compute the bss length */
+	movl	$END_SYMBOL, %ecx
+	subl	%edi, %ecx
+#endif
+			
+	/* clean out */
+	xorl	%eax, %eax
+	cld
+	rep
+	stosb
+
+	/*
+	 *  Call the start of main body of C code.
+	 */
+	call	EXT_C(grub_main)
+
+	/* This should never happen.  */
+	jmp	EXT_C(grub_stop)
diff --git a/kern/i386/realmode.S b/kern/i386/realmode.S
new file mode 100644
index 0000000..11f4d53
--- /dev/null
+++ b/kern/i386/realmode.S
@@ -0,0 +1,224 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2009 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*
+ * Note: These functions defined in this file may be called from C.
+ *       Be careful of that you must not modify some registers. Quote
+ *       from gcc-2.95.2/gcc/config/i386/i386.h:
+
+   1 for registers not available across function calls.
+   These must include the FIXED_REGISTERS and also any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like.
+
+  ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
+{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
+ */
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ *       So the first three arguments are passed in %eax, %edx, and %ecx,
+ *       respectively, and if a function has a fixed number of arguments
+ *       and the number if greater than three, the function must return
+ *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+/*
+ *  This is the area for all of the special variables.
+ */
+
+	.p2align	2	/* force 4-byte alignment */
+
+protstack:
+	.long	GRUB_MEMORY_MACHINE_PROT_STACK
+
+/*
+ * This is the Global Descriptor Table
+ *
+ *  An entry, a "Segment Descriptor", looks like this:
+ *
+ * 31          24         19   16                 7           0
+ * ------------------------------------------------------------
+ * |             | |B| |A|       | |   |1|0|E|W|A|            |
+ * | BASE 31..24 |G|/|L|V| LIMIT |P|DPL|  TYPE   | BASE 23:16 |  4
+ * |             | |D| |L| 19..16| |   |1|1|C|R|A|            |
+ * ------------------------------------------------------------
+ * |                             |                            |
+ * |        BASE 15..0           |       LIMIT 15..0          |  0
+ * |                             |                            |
+ * ------------------------------------------------------------
+ *
+ *  Note the ordering of the data items is reversed from the above
+ *  description.
+ */
+
+	.p2align	2	/* force 4-byte alignment */
+gdt:
+	.word	0, 0
+	.byte	0, 0, 0, 0
+
+	/* -- code segment --
+	 * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present
+	 * type = 32bit code execute/read, DPL = 0
+	 */
+	.word	0xFFFF, 0
+	.byte	0, 0x9A, 0xCF, 0
+
+	/* -- data segment --
+	 * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present
+	 * type = 32 bit data read/write, DPL = 0
+	 */
+	.word	0xFFFF, 0
+	.byte	0, 0x92, 0xCF, 0
+
+	/* -- 16 bit real mode CS --
+	 * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present
+	 * type = 16 bit code execute/read only/conforming, DPL = 0
+	 */
+	.word	0xFFFF, 0
+	.byte	0, 0x9E, 0, 0
+
+	/* -- 16 bit real mode DS --
+	 * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present
+	 * type = 16 bit data read/write, DPL = 0
+	 */
+	.word	0xFFFF, 0
+	.byte	0, 0x92, 0, 0
+
+
+/* this is the GDT descriptor */
+gdtdesc:
+	.word	0x27			/* limit */
+	.long	gdt			/* addr */
+
+/*
+ *  These next two routines, "real_to_prot" and "prot_to_real" are structured
+ *  in a very specific way.  Be very careful when changing them.
+ *
+ *  NOTE:  Use of either one messes up %eax and %ebp.
+ */
+
+real_to_prot:
+	.code16
+	cli
+
+	/* load the GDT register */
+	xorw	%ax, %ax
+	movw	%ax, %ds
+	DATA32	ADDR32	lgdt	gdtdesc
+
+	/* turn on protected mode */
+	movl	%cr0, %eax
+	orl	$GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax
+	movl	%eax, %cr0
+
+	/* jump to relocation, flush prefetch queue, and reload %cs */
+	DATA32	ljmp	$GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
+
+	.code32
+protcseg:
+	/* reload other segment registers */
+	movw	$GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+
+	/* put the return address in a known safe location */
+	movl	(%esp), %eax
+	movl	%eax, GRUB_MEMORY_MACHINE_REAL_STACK
+
+	/* get protected mode stack */
+	movl	protstack, %eax
+	movl	%eax, %esp
+	movl	%eax, %ebp
+
+	/* get return address onto the right stack */
+	movl	GRUB_MEMORY_MACHINE_REAL_STACK, %eax
+	movl	%eax, (%esp)
+
+	/* zero %eax */
+	xorl	%eax, %eax
+
+	/* return on the old (or initialized) stack! */
+	ret
+
+prot_to_real:
+	/* just in case, set GDT */
+	lgdt	gdtdesc
+
+	/* save the protected mode stack */
+	movl	%esp, %eax
+	movl	%eax, protstack
+
+	/* get the return address */
+	movl	(%esp), %eax
+	movl	%eax, GRUB_MEMORY_MACHINE_REAL_STACK
+
+	/* set up new stack */
+	movl	$GRUB_MEMORY_MACHINE_REAL_STACK, %eax
+	movl	%eax, %esp
+	movl	%eax, %ebp
+
+	/* set up segment limits */
+	movw	$GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+
+	/* this might be an extra step */
+	/* jump to a 16 bit segment */
+	ljmp	$GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg
+
+tmpcseg:
+	.code16
+
+	/* clear the PE bit of CR0 */
+	movl	%cr0, %eax
+	andl 	$(~GRUB_MEMORY_MACHINE_CR0_PE_ON), %eax
+	movl	%eax, %cr0
+
+	/* flush prefetch queue, reload %cs */
+	DATA32	ljmp	$0, $realcseg
+
+realcseg:
+	/* we are in real mode now
+	 * set up the real mode segment registers : DS, SS, ES
+	 */
+	/* zero %eax */
+	xorl	%eax, %eax
+
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+
+	/* restore interrupts */
+	sti
+
+	/* return on new stack! */
+	DATA32	ret
+
+	.code32
diff --git a/kern/i386/reboot.c b/kern/i386/reboot.c
new file mode 100644
index 0000000..6d562f8
--- /dev/null
+++ b/kern/i386/reboot.c
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/cpu/io.h>
+#include <grub/cpu/at_keyboard.h>
+#include <grub/cpu/reboot.h>
+#include <grub/misc.h>
+
+void
+grub_reboot (void)
+{
+  /* Use the keyboard controller to reboot.  That's what keyboards were
+     designed for, isn't it?  */
+  grub_outb (KEYBOARD_COMMAND_REBOOT, KEYBOARD_REG_STATUS);
+
+  grub_printf ("GRUB doesn't know how to reboot this machine yet!\n");
+}
diff --git a/kern/i386/tsc.c b/kern/i386/tsc.c
new file mode 100644
index 0000000..36b35e2
--- /dev/null
+++ b/kern/i386/tsc.c
@@ -0,0 +1,74 @@
+/* kern/i386/tsc.c - x86 TSC time source implementation
+ * Requires Pentium or better x86 CPU that supports the RDTSC instruction.
+ * This module uses the RTC (via grub_get_rtc()) to calibrate the TSC to
+ * real time.
+ *
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/time.h>
+#include <grub/misc.h>
+#include <grub/i386/tsc.h>
+#include <grub/i386/pit.h>
+
+/* This defines the value TSC had at the epoch (that is, when we calibrated it). */
+static grub_uint64_t tsc_boot_time;
+
+/* Calibrated TSC rate.  (In TSC ticks per millisecond.) */
+static grub_uint64_t tsc_ticks_per_ms;
+
+
+grub_uint64_t
+grub_tsc_get_time_ms (void)
+{
+  return tsc_boot_time + grub_divmod64 (grub_get_tsc (), tsc_ticks_per_ms, 0);
+}
+
+
+/* How many RTC ticks to use for calibration loop. (>= 1) */
+#define CALIBRATION_TICKS 2
+
+/* Calibrate the TSC based on the RTC.  */
+static void
+calibrate_tsc (void)
+{
+  /* First calibrate the TSC rate (relative, not absolute time). */
+  grub_uint64_t start_tsc;
+  grub_uint64_t end_tsc;
+
+  start_tsc = grub_get_tsc ();
+  grub_pit_wait (0xffff);
+  end_tsc = grub_get_tsc ();
+
+  tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0);
+}
+
+void
+grub_tsc_init (void)
+{
+  if (grub_cpu_is_tsc_supported ())
+    {
+      tsc_boot_time = grub_get_tsc ();
+      calibrate_tsc ();
+      grub_install_get_time_ms (grub_tsc_get_time_ms);
+    }
+  else
+    {
+      grub_install_get_time_ms (grub_rtc_get_time_ms);
+    }
+}
diff --git a/kern/ieee1275/cmain.c b/kern/ieee1275/cmain.c
new file mode 100644
index 0000000..c1185f8
--- /dev/null
+++ b/kern/ieee1275/cmain.c
@@ -0,0 +1,165 @@
+/* cmain.c - Startup code for the PowerPC.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/machine/kernel.h>
+#include <grub/ieee1275/ieee1275.h>
+
+int (*grub_ieee1275_entry_fn) (void *);
+
+grub_ieee1275_phandle_t grub_ieee1275_chosen;
+grub_ieee1275_ihandle_t grub_ieee1275_mmu;
+
+static grub_uint32_t grub_ieee1275_flags;
+
+
+
+int
+grub_ieee1275_test_flag (enum grub_ieee1275_flag flag)
+{
+  return (grub_ieee1275_flags & (1 << flag));
+}
+
+void
+grub_ieee1275_set_flag (enum grub_ieee1275_flag flag)
+{
+  grub_ieee1275_flags |= (1 << flag);
+}
+
+#define SF "SmartFirmware(tm)"
+#define OHW "PPC Open Hack'Ware"
+
+static void
+grub_ieee1275_find_options (void)
+{
+  grub_ieee1275_phandle_t root;
+  grub_ieee1275_phandle_t options;
+  grub_ieee1275_phandle_t openprom;
+  grub_ieee1275_phandle_t bootrom;
+  int rc;
+  grub_uint32_t realmode = 0;
+  char tmp[32];
+  int is_smartfirmware = 0;
+  int is_olpc = 0;
+
+  grub_ieee1275_finddevice ("/", &root);
+  grub_ieee1275_finddevice ("/options", &options);
+  grub_ieee1275_finddevice ("/openprom", &openprom);
+
+  rc = grub_ieee1275_get_integer_property (options, "real-mode?", &realmode,
+					   sizeof realmode, 0);
+  if (((rc >= 0) && realmode) || (grub_ieee1275_mmu == 0))
+    grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE);
+
+  rc = grub_ieee1275_get_property (openprom, "CodeGen-copyright",
+				   tmp,	sizeof (tmp), 0);
+  if (rc >= 0 && !grub_strncmp (tmp, SF, sizeof (SF) - 1))
+    is_smartfirmware = 1;
+
+  rc = grub_ieee1275_get_property (root, "architecture",
+				   tmp,	sizeof (tmp), 0);
+  if (rc >= 0 && !grub_strcmp (tmp, "OLPC"))
+    is_olpc = 1;
+
+  if (is_smartfirmware)
+    {
+      /* Broken in all versions */
+      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);
+
+      /* There are two incompatible ways of checking the version number.  Try
+         both. */
+      rc = grub_ieee1275_get_property (openprom, "SmartFirmware-version",
+				       tmp, sizeof (tmp), 0);
+      if (rc < 0)
+	rc = grub_ieee1275_get_property (openprom, "firmware-version",
+					 tmp, sizeof (tmp), 0);
+      if (rc >= 0)
+	{
+	  /* It is tempting to implement a version parser to set the flags for
+	     e.g. 1.3 and below.  However, there's a special situation here.
+	     3rd party updates which fix the partition bugs are common, and for
+	     some reason their fixes aren't being merged into trunk.  So for
+	     example we know that 1.2 and 1.3 are broken, but there's 1.2.99
+	     and 1.3.99 which are known good (and applying this workaround
+	     would cause breakage). */
+	  if (!grub_strcmp (tmp, "1.0")
+	      || !grub_strcmp (tmp, "1.1")
+	      || !grub_strcmp (tmp, "1.2")
+	      || !grub_strcmp (tmp, "1.3"))
+	    {
+	      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
+	      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS);
+	    }
+	}
+    }
+
+  if (is_olpc)
+    {
+      /* OLPC / XO laptops have three kinds of storage devices:
+
+	 - NAND flash.  These are accessible via OFW callbacks, but:
+	   - Follow strange semantics, imposed by hardware constraints.
+	   - Its ABI is undocumented, and not stable.
+	   They lack "device_type" property, which conveniently makes GRUB
+	   skip them.
+
+	 - USB drives.  Not accessible, because OFW shuts down the controller
+	   in order to prevent collisions with applications accessing it
+	   directly.  Even worse, attempts to access it will NOT return
+	   control to the caller, so we have to avoid probing them.
+
+	 - SD cards.  These work fine.
+
+	 To avoid breakage, we only need to skip USB probing.  However,
+	 since detecting SD cards is more reliable, we do that instead.
+      */
+
+      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY);
+    }
+
+  if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom))
+    {
+      rc = grub_ieee1275_get_property (bootrom, "model", tmp, sizeof (tmp), 0);
+      if (rc >= 0 && !grub_strncmp (tmp, OHW, sizeof (OHW) - 1))
+	{
+	  grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);
+	  grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS);
+	  grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET);
+	  grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM);
+	  grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_ANSI);
+	}
+    }
+}
+
+#undef SF
+#undef OHW
+
+void
+grub_ieee1275_init (void)
+{
+  grub_ieee1275_finddevice ("/chosen", &grub_ieee1275_chosen);
+
+  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "mmu", &grub_ieee1275_mmu,
+					  sizeof grub_ieee1275_mmu, 0) < 0)
+    grub_ieee1275_mmu = 0;
+
+  grub_ieee1275_find_options ();
+}
diff --git a/kern/ieee1275/ieee1275.c b/kern/ieee1275/ieee1275.c
new file mode 100644
index 0000000..37a9807
--- /dev/null
+++ b/kern/ieee1275/ieee1275.c
@@ -0,0 +1,602 @@
+/* of.c - Access the Open Firmware client interface.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/types.h>
+
+#define IEEE1275_PHANDLE_INVALID  ((grub_ieee1275_cell_t) -1)
+#define IEEE1275_IHANDLE_INVALID  ((grub_ieee1275_cell_t) 0)
+#define IEEE1275_CELL_INVALID     ((grub_ieee1275_cell_t) -1)
+
+
+
+int
+grub_ieee1275_finddevice (char *name, grub_ieee1275_phandle_t *phandlep)
+{
+  struct find_device_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t device;
+    grub_ieee1275_cell_t phandle;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "finddevice", 1, 1);
+  args.device = (grub_ieee1275_cell_t) name;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *phandlep = args.phandle;
+  if (args.phandle == IEEE1275_PHANDLE_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_get_property (grub_ieee1275_phandle_t phandle,
+			    const char *property, void *buf,
+			    grub_size_t size, grub_ssize_t *actual)
+{
+  struct get_property_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t phandle;
+    grub_ieee1275_cell_t prop;
+    grub_ieee1275_cell_t buf;
+    grub_ieee1275_cell_t buflen;
+    grub_ieee1275_cell_t size;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "getprop", 4, 1);
+  args.phandle = phandle;
+  args.prop = (grub_ieee1275_cell_t) property;
+  args.buf = (grub_ieee1275_cell_t) buf;
+  args.buflen = (grub_ieee1275_cell_t) size;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (actual)
+    *actual = (grub_ssize_t) args.size;
+  if (args.size == IEEE1275_CELL_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_get_integer_property (grub_ieee1275_phandle_t phandle,
+				    const char *property, grub_uint32_t *buf,
+				    grub_size_t size, grub_ssize_t *actual)
+{
+  int ret;
+  ret = grub_ieee1275_get_property (phandle, property, (void *) buf, size, actual);
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
+  /* Integer properties are always in big endian.  */
+  if (ret == 0)
+    {
+      unsigned int i;
+      size /= sizeof (grub_uint32_t);
+      for (i = 0; i < size; i++)
+	buf[i] = grub_be_to_cpu32 (buf[i]);
+    }
+#endif
+  return ret;
+}
+
+int
+grub_ieee1275_next_property (grub_ieee1275_phandle_t phandle, char *prev_prop,
+			     char *prop)
+{
+  struct get_property_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t phandle;
+    grub_ieee1275_cell_t prev_prop;
+    grub_ieee1275_cell_t next_prop;
+    grub_ieee1275_cell_t flags;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "nextprop", 3, 1);
+  args.phandle = phandle;
+  args.prev_prop = (grub_ieee1275_cell_t) prev_prop;
+  args.next_prop = (grub_ieee1275_cell_t) prop;
+  args.flags = (grub_ieee1275_cell_t) -1;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  return (int) args.flags;
+}
+
+int
+grub_ieee1275_get_property_length (grub_ieee1275_phandle_t phandle,
+				   const char *prop, grub_ssize_t *length)
+{
+  struct get_property_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t phandle;
+    grub_ieee1275_cell_t prop;
+    grub_ieee1275_cell_t length;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "getproplen", 2, 1);
+  args.phandle = phandle;
+  args.prop = (grub_ieee1275_cell_t) prop;
+  args.length = (grub_ieee1275_cell_t) -1;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *length = args.length;
+  if (args.length == IEEE1275_CELL_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_instance_to_package (grub_ieee1275_ihandle_t ihandle,
+				   grub_ieee1275_phandle_t *phandlep)
+{
+  struct instance_to_package_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t phandle;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "instance-to-package", 1, 1);
+  args.ihandle = ihandle;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *phandlep = args.phandle;
+  if (args.phandle == IEEE1275_PHANDLE_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_package_to_path (grub_ieee1275_phandle_t phandle,
+			       char *path, grub_size_t len,
+			       grub_ssize_t *actual)
+{
+  struct instance_to_package_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t phandle;
+    grub_ieee1275_cell_t buf;
+    grub_ieee1275_cell_t buflen;
+    grub_ieee1275_cell_t actual;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "package-to-path", 3, 1);
+  args.phandle = phandle;
+  args.buf = (grub_ieee1275_cell_t) path;
+  args.buflen = (grub_ieee1275_cell_t) len;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (actual)
+    *actual = args.actual;
+  if (args.actual == IEEE1275_CELL_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_instance_to_path (grub_ieee1275_ihandle_t ihandle,
+				char *path, grub_size_t len,
+				grub_ssize_t *actual)
+{
+  struct instance_to_path_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t buf;
+    grub_ieee1275_cell_t buflen;
+    grub_ieee1275_cell_t actual;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "instance-to-path", 3, 1);
+  args.ihandle = ihandle;
+  args.buf = (grub_ieee1275_cell_t) path;
+  args.buflen = (grub_ieee1275_cell_t) len;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (actual)
+    *actual = args.actual;
+  if (args.actual == IEEE1275_CELL_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_write (grub_ieee1275_ihandle_t ihandle, void *buffer,
+		     grub_size_t len, grub_ssize_t *actualp)
+{
+  struct write_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t buf;
+    grub_ieee1275_cell_t len;
+    grub_ieee1275_cell_t actual;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "write", 3, 1);
+  args.ihandle = ihandle;
+  args.buf = (grub_ieee1275_cell_t) buffer;
+  args.len = (grub_ieee1275_cell_t) len;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (actualp)
+    *actualp = args.actual;
+  return 0;
+}
+
+int
+grub_ieee1275_read (grub_ieee1275_ihandle_t ihandle, void *buffer,
+		    grub_size_t len, grub_ssize_t *actualp)
+{
+  struct write_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t buf;
+    grub_ieee1275_cell_t len;
+    grub_ieee1275_cell_t actual;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "read", 3, 1);
+  args.ihandle = ihandle;
+  args.buf = (grub_ieee1275_cell_t) buffer;
+  args.len = (grub_ieee1275_cell_t) len;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (actualp)
+    *actualp = args.actual;
+  return 0;
+}
+
+int
+grub_ieee1275_seek (grub_ieee1275_ihandle_t ihandle, int pos_hi,
+		    int pos_lo, grub_ssize_t *result)
+{
+  struct write_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t pos_hi;
+    grub_ieee1275_cell_t pos_lo;
+    grub_ieee1275_cell_t result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "seek", 3, 1);
+  args.ihandle = ihandle;
+  args.pos_hi = (grub_ieee1275_cell_t) pos_hi;
+  args.pos_lo = (grub_ieee1275_cell_t) pos_lo;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+
+  if (result)
+    *result = args.result;
+  return 0;
+}
+
+int
+grub_ieee1275_peer (grub_ieee1275_phandle_t node,
+		    grub_ieee1275_phandle_t *result)
+{
+  struct peer_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t node;
+    grub_ieee1275_cell_t result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "peer", 1, 1);
+  args.node = node;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *result = args.result;
+  if (args.result == 0)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_child (grub_ieee1275_phandle_t node,
+		     grub_ieee1275_phandle_t *result)
+{
+  struct child_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t node;
+    grub_ieee1275_cell_t result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "child", 1, 1);
+  args.node = node;
+  args.result = IEEE1275_PHANDLE_INVALID;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *result = args.result;
+  if (args.result == 0)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_parent (grub_ieee1275_phandle_t node,
+		      grub_ieee1275_phandle_t *result)
+{
+  struct parent_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t node;
+    grub_ieee1275_cell_t result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "parent", 1, 1);
+  args.node = node;
+  args.result = IEEE1275_PHANDLE_INVALID;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *result = args.result;
+  return 0;
+}
+
+int
+grub_ieee1275_interpret (const char *command, grub_ieee1275_cell_t *catch)
+{
+  struct enter_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t command;
+    grub_ieee1275_cell_t catch;
+  }
+  args;
+
+  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
+    return -1;
+
+  INIT_IEEE1275_COMMON (&args.common, "interpret", 1, 1);
+  args.command = (grub_ieee1275_cell_t) command;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (catch)
+    *catch = args.catch;
+  return 0;
+}
+
+int
+grub_ieee1275_enter (void)
+{
+  struct enter_args
+  {
+    struct grub_ieee1275_common_hdr common;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "enter", 0, 0);
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  return 0;
+}
+
+void
+grub_ieee1275_exit (void)
+{
+  struct exit_args
+  {
+    struct grub_ieee1275_common_hdr common;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "exit", 0, 0);
+
+  IEEE1275_CALL_ENTRY_FN (&args);
+  for (;;) ;
+}
+
+int
+grub_ieee1275_open (const char *path, grub_ieee1275_ihandle_t *result)
+{
+  struct open_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t path;
+    grub_ieee1275_cell_t result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "open", 1, 1);
+  args.path = (grub_ieee1275_cell_t) path;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *result = args.result;
+  if (args.result == IEEE1275_IHANDLE_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_close (grub_ieee1275_ihandle_t ihandle)
+{
+  struct close_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t ihandle;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "close", 1, 0);
+  args.ihandle = ihandle;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+
+  return 0;
+}
+
+int
+grub_ieee1275_claim (grub_addr_t addr, grub_size_t size, unsigned int align,
+		     grub_addr_t *result)
+{
+  struct claim_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t addr;
+    grub_ieee1275_cell_t size;
+    grub_ieee1275_cell_t align;
+    grub_ieee1275_cell_t base;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "claim", 3, 1);
+  args.addr = (grub_ieee1275_cell_t) addr;
+  args.size = (grub_ieee1275_cell_t) size;
+  args.align = (grub_ieee1275_cell_t) align;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (result)
+    *result = args.base;
+  if (args.base == IEEE1275_CELL_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_release (grub_addr_t addr, grub_size_t size)
+{
+ struct release_args
+ {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t addr;
+    grub_ieee1275_cell_t size;
+ }
+ args;
+
+  INIT_IEEE1275_COMMON (&args.common, "release", 2, 0);
+  args.addr = addr;
+  args.size = size;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_set_property (grub_ieee1275_phandle_t phandle,
+			    const char *propname, void *buf,
+			    grub_size_t size, grub_ssize_t *actual)
+{
+  struct set_property_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t phandle;
+    grub_ieee1275_cell_t propname;
+    grub_ieee1275_cell_t buf;
+    grub_ieee1275_cell_t size;
+    grub_ieee1275_cell_t actual;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "setprop", 4, 1);
+  args.size = (grub_ieee1275_cell_t) size;
+  args.buf = (grub_ieee1275_cell_t) buf;
+  args.propname = (grub_ieee1275_cell_t) propname;
+  args.phandle = (grub_ieee1275_cell_t) phandle;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *actual = args.actual;
+  if ((args.actual == IEEE1275_CELL_INVALID) || (args.actual != args.size))
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_set_color (grub_ieee1275_ihandle_t ihandle,
+			 int index, int r, int g, int b)
+{
+  struct set_color_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t method;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t index;
+    grub_ieee1275_cell_t b;
+    grub_ieee1275_cell_t g;
+    grub_ieee1275_cell_t r;
+    grub_ieee1275_cell_t catch_result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
+  args.method = (grub_ieee1275_cell_t) "color!";
+  args.ihandle = ihandle;
+  args.index = index;
+  args.r = r;
+  args.g = g;
+  args.b = b;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  return args.catch_result;
+}
+
+int
+grub_ieee1275_milliseconds (grub_uint32_t *msecs)
+{
+  struct milliseconds_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t msecs;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "milliseconds", 0, 1);
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *msecs = args.msecs;
+  return 0;
+}
diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c
new file mode 100644
index 0000000..5d5d733
--- /dev/null
+++ b/kern/ieee1275/init.c
@@ -0,0 +1,291 @@
+/*  init.c -- Initialize GRUB on the newworld mac (PPC).  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/normal.h>
+#include <grub/fs.h>
+#include <grub/setjmp.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/time.h>
+#include <grub/machine/console.h>
+#include <grub/machine/kernel.h>
+#include <grub/cpu/kernel.h>
+#include <grub/ieee1275/ofdisk.h>
+#include <grub/ieee1275/ieee1275.h>
+
+/* The minimal heap size we can live with. */
+#define HEAP_MIN_SIZE		(unsigned long) (2 * 1024 * 1024)
+
+/* The maximum heap size we're going to claim */
+#define HEAP_MAX_SIZE		(unsigned long) (4 * 1024 * 1024)
+
+/* If possible, we will avoid claiming heap above this address, because it
+   seems to cause relocation problems with OSes that link at 4 MiB */
+#define HEAP_MAX_ADDR		(unsigned long) (4 * 1024 * 1024)
+
+extern char _start[];
+extern char _end[];
+
+void
+grub_exit (void)
+{
+  grub_ieee1275_exit ();
+}
+
+/* Translate an OF filesystem path (separated by backslashes), into a GRUB
+   path (separated by forward slashes).  */
+static void
+grub_translate_ieee1275_path (char *filepath)
+{
+  char *backslash;
+
+  backslash = grub_strchr (filepath, '\\');
+  while (backslash != 0)
+    {
+      *backslash = '/';
+      backslash = grub_strchr (filepath, '\\');
+    }
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  char bootpath[64]; /* XXX check length */
+  char *filename;
+  char *prefix;
+
+  if (grub_env_get ("prefix"))
+    /* We already set prefix in grub_machine_init().  */
+    return;
+
+  if (grub_prefix[0])
+    {
+      grub_env_set ("prefix", grub_prefix);
+      /* Prefix is hardcoded in the core image.  */
+      return;
+    }
+
+  if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath,
+				  sizeof (bootpath), 0))
+    {
+      /* Should never happen.  */
+      grub_printf ("/chosen/bootpath property missing!\n");
+      grub_env_set ("prefix", "");
+      return;
+    }
+
+  /* Transform an OF device path to a GRUB path.  */
+
+  prefix = grub_ieee1275_encode_devname (bootpath);
+
+  filename = grub_ieee1275_get_filename (bootpath);
+  if (filename)
+    {
+      char *newprefix;
+      char *lastslash = grub_strrchr (filename, '\\');
+
+      /* Truncate at last directory.  */
+      if (lastslash)
+        {
+	  *lastslash = '\0';
+	  grub_translate_ieee1275_path (filename);
+
+	  newprefix = grub_malloc (grub_strlen (prefix)
+				   + grub_strlen (filename));
+	  grub_sprintf (newprefix, "%s%s", prefix, filename);
+	  grub_free (prefix);
+	  prefix = newprefix;
+	}
+    }
+
+  grub_env_set ("prefix", prefix);
+
+  grub_free (filename);
+  grub_free (prefix);
+}
+
+/* Claim some available memory in the first /memory node. */
+static void grub_claim_heap (void)
+{
+  unsigned long total = 0;
+
+  auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type);
+  int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type)
+  {
+    if (type != 1)
+      return 0;
+
+    len -= 1; /* Required for some firmware.  */
+
+    /* Never exceed HEAP_MAX_SIZE  */
+    if (total + len > HEAP_MAX_SIZE)
+      len = HEAP_MAX_SIZE - total;
+
+    /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */
+    if ((addr < HEAP_MAX_ADDR) &&				/* if it's too late, don't bother */
+        (addr + len > HEAP_MAX_ADDR) &&				/* if it wasn't available anyway, don't bother */
+        (total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE))	/* only limit ourselves when we can afford to */
+       len = HEAP_MAX_ADDR - addr;
+
+    /* In theory, firmware should already prevent this from happening by not
+       listing our own image in /memory/available.  The check below is intended
+       as a safeguard in case that doesn't happen.  However, it doesn't protect
+       us from corrupting our module area, which extends up to a
+       yet-undetermined region above _end.  */
+    if ((addr < (grub_addr_t) _end) && ((addr + len) > (grub_addr_t) _start))
+      {
+        grub_printf ("Warning: attempt to claim over our own code!\n");
+        len = 0;
+      }
+
+    if (len)
+      {
+	/* Claim and use it.  */
+	if (grub_claimmap (addr, len) < 0)
+	  return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			     "Failed to claim heap at 0x%llx, len 0x%llx\n",
+			     addr, len);
+	grub_mm_init_region ((void *) (grub_addr_t) addr, len);
+      }
+
+    total += len;
+    if (total >= HEAP_MAX_SIZE)
+      return 1;
+
+    return 0;
+  }
+
+  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
+    heap_init (HEAP_MAX_ADDR - HEAP_MIN_SIZE, HEAP_MIN_SIZE, 1);
+  else
+    grub_machine_mmap_iterate (heap_init);
+}
+
+#ifdef __i386__
+
+grub_uint32_t grub_upper_mem;
+
+/* We need to call this before grub_claim_memory.  */
+static void
+grub_get_extended_memory (void)
+{
+  auto int NESTED_FUNC_ATTR find_ext_mem (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type);
+  int NESTED_FUNC_ATTR find_ext_mem (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type)
+    {
+      if (type == 1 && addr == 0x100000)
+        {
+          grub_upper_mem = len;
+          return 1;
+        }
+
+      return 0;
+    }
+
+  grub_machine_mmap_iterate (find_ext_mem);
+}
+
+#endif
+
+static grub_uint64_t ieee1275_get_time_ms (void);
+
+void
+grub_machine_init (void)
+{
+  char args[256];
+  grub_ssize_t actual;
+
+  grub_ieee1275_init ();
+
+  grub_console_init ();
+#ifdef __i386__
+  grub_get_extended_memory ();
+#endif
+  grub_claim_heap ();
+  grub_ofdisk_init ();
+
+  /* Process commandline.  */
+  if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
+				  sizeof args, &actual) == 0
+      && actual > 1)
+    {
+      int i = 0;
+
+      while (i < actual)
+	{
+	  char *command = &args[i];
+	  char *end;
+	  char *val;
+
+	  end = grub_strchr (command, ';');
+	  if (end == 0)
+	    i = actual; /* No more commands after this one.  */
+	  else
+	    {
+	      *end = '\0';
+	      i += end - command + 1;
+	      while (grub_isspace(args[i]))
+		i++;
+	    }
+
+	  /* Process command.  */
+	  val = grub_strchr (command, '=');
+	  if (val)
+	    {
+	      *val = '\0';
+	      grub_env_set (command, val + 1);
+	    }
+	}
+    }
+
+  grub_install_get_time_ms (ieee1275_get_time_ms);
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_ofdisk_fini ();
+  grub_console_fini ();
+}
+
+static grub_uint64_t
+ieee1275_get_time_ms (void)
+{
+  grub_uint32_t msecs = 0;
+
+  grub_ieee1275_milliseconds (&msecs);
+
+  return msecs;
+}
+
+grub_uint32_t
+grub_get_rtc (void)
+{
+  return ieee1275_get_time_ms ();
+}
+
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN);
+}
diff --git a/kern/ieee1275/mmap.c b/kern/ieee1275/mmap.c
new file mode 100644
index 0000000..317a121
--- /dev/null
+++ b/kern/ieee1275/mmap.c
@@ -0,0 +1,74 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/types.h>
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
+{
+  grub_ieee1275_phandle_t root;
+  grub_ieee1275_phandle_t memory;
+  grub_uint32_t available[32];
+  grub_ssize_t available_size;
+  grub_uint32_t address_cells = 1;
+  grub_uint32_t size_cells = 1;
+  int i;
+
+  /* Determine the format of each entry in `available'.  */
+  grub_ieee1275_finddevice ("/", &root);
+  grub_ieee1275_get_integer_property (root, "#address-cells", &address_cells,
+				      sizeof address_cells, 0);
+  grub_ieee1275_get_integer_property (root, "#size-cells", &size_cells,
+				      sizeof size_cells, 0);
+
+  if (size_cells > address_cells)
+    address_cells = size_cells;
+
+  /* Load `/memory/available'.  */
+  if (grub_ieee1275_finddevice ("/memory", &memory))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+		       "Couldn't find /memory node");
+  if (grub_ieee1275_get_integer_property (memory, "available", available,
+					  sizeof available, &available_size))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+		       "Couldn't examine /memory/available property");
+
+  /* Decode each entry and call `hook'.  */
+  i = 0;
+  available_size /= sizeof (grub_uint32_t);
+  while (i < available_size)
+    {
+      grub_uint64_t address;
+      grub_uint64_t size;
+
+      address = available[i++];
+      if (address_cells == 2)
+	address = (address << 32) | available[i++];
+
+      size = available[i++];
+      if (size_cells == 2)
+	size = (size << 32) | available[i++];
+
+      if (hook (address, size, GRUB_MACHINE_MEMORY_AVAILABLE))
+	break;
+    }
+
+  return grub_errno;
+}
diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c
new file mode 100644
index 0000000..20ef730
--- /dev/null
+++ b/kern/ieee1275/openfw.c
@@ -0,0 +1,415 @@
+/*  openfw.c -- Open firmware support functions.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/machine/kernel.h>
+#include <grub/ieee1275/ieee1275.h>
+
+enum grub_ieee1275_parse_type
+{
+  GRUB_PARSE_FILENAME,
+  GRUB_PARSE_PARTITION,
+};
+
+/* Walk children of 'devpath', calling hook for each.  */
+int
+grub_children_iterate (char *devpath,
+		       int (*hook) (struct grub_ieee1275_devalias *alias))
+{
+  grub_ieee1275_phandle_t dev;
+  grub_ieee1275_phandle_t child;
+  char *childtype, *childpath;
+  char *childname, *fullname;
+  int ret = 0;
+
+  if (grub_ieee1275_finddevice (devpath, &dev))
+    return 0;
+
+  if (grub_ieee1275_child (dev, &child))
+    return 0;
+
+  childtype = grub_malloc (IEEE1275_MAX_PROP_LEN);
+  if (!childtype)
+    return 0;
+  childpath = grub_malloc (IEEE1275_MAX_PATH_LEN);
+  if (!childpath)
+    {
+      grub_free (childtype);
+      return 0;
+    }
+  childname = grub_malloc (IEEE1275_MAX_PROP_LEN);
+  if (!childname)
+    {
+      grub_free (childpath);
+      grub_free (childtype);
+      return 0;
+    }
+  fullname = grub_malloc (IEEE1275_MAX_PATH_LEN);
+  if (!fullname)
+    {
+      grub_free (childname);
+      grub_free (childpath);
+      grub_free (childtype);
+      return 0;
+    }
+
+  do
+    {
+      struct grub_ieee1275_devalias alias;
+      grub_ssize_t actual;
+
+      if (grub_ieee1275_get_property (child, "device_type", childtype,
+				      IEEE1275_MAX_PROP_LEN, &actual))
+	continue;
+
+      if (grub_ieee1275_package_to_path (child, childpath,
+					 IEEE1275_MAX_PATH_LEN, &actual))
+	continue;
+
+      if (grub_ieee1275_get_property (child, "name", childname,
+				      IEEE1275_MAX_PROP_LEN, &actual))
+	continue;
+
+      grub_sprintf (fullname, "%s/%s", devpath, childname);
+
+      alias.type = childtype;
+      alias.path = childpath;
+      alias.name = fullname;
+      ret = hook (&alias);
+      if (ret)
+	break;
+    }
+  while (grub_ieee1275_peer (child, &child));
+
+  grub_free (fullname);
+  grub_free (childname);
+  grub_free (childpath);
+  grub_free (childtype);
+
+  return ret;
+}
+
+/* Iterate through all device aliases.  This function can be used to
+   find a device of a specific type.  */
+int
+grub_devalias_iterate (int (*hook) (struct grub_ieee1275_devalias *alias))
+{
+  grub_ieee1275_phandle_t aliases;
+  char *aliasname, *devtype;
+  grub_ssize_t actual;
+  struct grub_ieee1275_devalias alias;
+  int ret = 0;
+
+  if (grub_ieee1275_finddevice ("/aliases", &aliases))
+    return 0;
+
+  aliasname = grub_malloc (IEEE1275_MAX_PROP_LEN);
+  if (!aliasname)
+    return 0;
+  devtype = grub_malloc (IEEE1275_MAX_PROP_LEN);
+  if (!devtype)
+    {
+      grub_free (aliasname);
+      return 0;
+    }
+
+  /* Find the first property.  */
+  aliasname[0] = '\0';
+
+  while (grub_ieee1275_next_property (aliases, aliasname, aliasname))
+    {
+      grub_ieee1275_phandle_t dev;
+      grub_ssize_t pathlen;
+      char *devpath;
+
+      grub_dprintf ("devalias", "devalias name = %s\n", aliasname);
+
+      grub_ieee1275_get_property_length (aliases, aliasname, &pathlen);
+
+      /* The property `name' is a special case we should skip.  */
+      if (!grub_strcmp (aliasname, "name"))
+	continue;
+
+      /* Sun's OpenBoot often doesn't zero terminate the device alias
+	 strings, so we will add a NULL byte at the end explicitly.  */
+      pathlen += 1;
+
+      devpath = grub_malloc (pathlen);
+      if (! devpath)
+	{
+	  grub_free (devtype);
+	  grub_free (aliasname);
+	  return 0;
+	}
+
+      if (grub_ieee1275_get_property (aliases, aliasname, devpath, pathlen,
+				      &actual))
+	{
+	  grub_dprintf ("devalias", "get_property (%s) failed\n", aliasname);
+	  goto nextprop;
+	}
+      devpath [actual] = '\0';
+
+      if (grub_ieee1275_finddevice (devpath, &dev))
+	{
+	  grub_dprintf ("devalias", "finddevice (%s) failed\n", devpath);
+	  goto nextprop;
+	}
+
+      if (grub_ieee1275_get_property (dev, "device_type", devtype,
+				      IEEE1275_MAX_PROP_LEN, &actual))
+	{
+	  /* NAND device don't have device_type property.  */
+          devtype[0] = 0;
+	}
+
+      alias.name = aliasname;
+      alias.path = devpath;
+      alias.type = devtype;
+      ret = hook (&alias);
+
+nextprop:
+      grub_free (devpath);
+      if (ret)
+	break;
+    }
+
+  grub_free (devtype);
+  grub_free (aliasname);
+  return ret;
+}
+
+/* Call the "map" method of /chosen/mmu.  */
+static int
+grub_map (grub_addr_t phys, grub_addr_t virt, grub_uint32_t size,
+		   grub_uint8_t mode)
+{
+  struct map_args {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t method;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t mode;
+    grub_ieee1275_cell_t size;
+    grub_ieee1275_cell_t virt;
+    grub_ieee1275_cell_t phys;
+    grub_ieee1275_cell_t catch_result;
+  } args;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
+  args.method = (grub_ieee1275_cell_t) "map";
+  args.ihandle = grub_ieee1275_mmu;
+  args.phys = phys;
+  args.virt = virt;
+  args.size = size;
+  args.mode = mode; /* Format is WIMG0PP.  */
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+
+  return args.catch_result;
+}
+
+int
+grub_claimmap (grub_addr_t addr, grub_size_t size)
+{
+  if (grub_ieee1275_claim (addr, size, 0, 0))
+    return -1;
+
+  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_REAL_MODE)
+      && grub_map (addr, addr, size, 0x00))
+    {
+      grub_printf ("map failed: address 0x%llx, size 0x%llx\n",
+		   (long long) addr, (long long) size);
+      grub_ieee1275_release (addr, size);
+      return -1;
+    }
+
+  return 0;
+}
+
+/* Get the device arguments of the Open Firmware node name `path'.  */
+static char *
+grub_ieee1275_get_devargs (const char *path)
+{
+  char *colon = grub_strchr (path, ':');
+
+  if (! colon)
+    return 0;
+
+  return grub_strdup (colon + 1);
+}
+
+/* Get the device path of the Open Firmware node name `path'.  */
+static char *
+grub_ieee1275_get_devname (const char *path)
+{
+  char *colon = grub_strchr (path, ':');
+  char *newpath = 0;
+  int pathlen = grub_strlen (path);
+  auto int match_alias (struct grub_ieee1275_devalias *alias);
+
+  int match_alias (struct grub_ieee1275_devalias *curalias)
+    {
+      /* briQ firmware can change capitalization in /chosen/bootpath.  */
+      if (! grub_strncasecmp (curalias->path, path, pathlen))
+        {
+	  newpath = grub_strdup (curalias->name);
+	  return 1;
+	}
+
+      return 0;
+    }
+
+  if (colon)
+    pathlen = (int)(colon - path);
+
+  /* Try to find an alias for this device.  */
+  grub_devalias_iterate (match_alias);
+
+  if (! newpath)
+    newpath = grub_strndup (path, pathlen);
+
+  return newpath;
+}
+
+static char *
+grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
+{
+  char type[64]; /* XXX check size.  */
+  char *device = grub_ieee1275_get_devname (path);
+  char *args = grub_ieee1275_get_devargs (path);
+  char *ret = 0;
+  grub_ieee1275_phandle_t dev;
+
+  if (!args)
+    /* Shouldn't happen.  */
+    return 0;
+
+  /* We need to know what type of device it is in order to parse the full
+     file path properly.  */
+  if (grub_ieee1275_finddevice (device, &dev))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Device %s not found\n", device);
+      goto fail;
+    }
+  if (grub_ieee1275_get_property (dev, "device_type", &type, sizeof type, 0))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+		  "Device %s lacks a device_type property\n", device);
+      goto fail;
+    }
+
+  if (!grub_strcmp ("block", type))
+    {
+      /* The syntax of the device arguments is defined in the CHRP and PReP
+         IEEE1275 bindings: "[partition][,[filename]]".  */
+      char *comma = grub_strchr (args, ',');
+
+      if (ptype == GRUB_PARSE_FILENAME)
+	{
+	  if (comma)
+	    {
+	      char *filepath = comma + 1;
+
+	      ret = grub_malloc (grub_strlen (filepath) + 1);
+	      /* Make sure filepath has leading backslash.  */
+	      if (filepath[0] != '\\')
+		grub_sprintf (ret, "\\%s", filepath);
+	      else
+		grub_strcpy (ret, filepath);
+	    }
+	}
+      else if (ptype == GRUB_PARSE_PARTITION)
+        {
+	  if (!comma)
+	    ret = grub_strdup (args);
+	  else
+	    ret = grub_strndup (args, (grub_size_t)(comma - args));
+	}
+    }
+  else
+    {
+      /* XXX Handle net devices by configuring & registering a grub_net_dev
+	 here, then return its name?
+	 Example path: "net:<server ip>,<file name>,<client ip>,<gateway
+	 ip>,<bootp retries>,<tftp retries>".  */
+      grub_printf ("Unsupported type %s for device %s\n", type, device);
+    }
+
+fail:
+  grub_free (device);
+  grub_free (args);
+  return ret;
+}
+
+char *
+grub_ieee1275_get_filename (const char *path)
+{
+  return grub_ieee1275_parse_args (path, GRUB_PARSE_FILENAME);
+}
+
+/* Convert a device name from IEEE1275 syntax to GRUB syntax.  */
+char *
+grub_ieee1275_encode_devname (const char *path)
+{
+  char *device = grub_ieee1275_get_devname (path);
+  char *partition = grub_ieee1275_parse_args (path, GRUB_PARSE_PARTITION);
+  char *encoding;
+
+  if (partition)
+    {
+      unsigned int partno = grub_strtoul (partition, 0, 0);
+
+      if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS))
+	/* GRUB partition 1 is OF partition 0.  */
+	partno++;
+
+      /* Assume partno will require less than five bytes to encode.  */
+      encoding = grub_malloc (grub_strlen (device) + 3 + 5);
+      grub_sprintf (encoding, "(%s,%d)", device, partno);
+    }
+  else
+    {
+      encoding = grub_malloc (grub_strlen (device) + 2);
+      grub_sprintf (encoding, "(%s)", device);
+    }
+
+  grub_free (partition);
+  grub_free (device);
+
+  return encoding;
+}
+
+void
+grub_reboot (void)
+{
+  grub_ieee1275_interpret ("reset-all", 0);
+}
+
+void
+grub_halt (void)
+{
+  /* Not standardized.  We try both known commands.  */
+
+  grub_ieee1275_interpret ("shut-down", 0);
+  grub_ieee1275_interpret ("power-off", 0);
+}
diff --git a/kern/list.c b/kern/list.c
new file mode 100644
index 0000000..b879f13
--- /dev/null
+++ b/kern/list.c
@@ -0,0 +1,130 @@
+/* list.c - grub list function */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/list.h>
+#include <grub/misc.h>
+
+void
+grub_list_push (grub_list_t *head, grub_list_t item)
+{
+  item->next = *head;
+  *head = item;
+}
+
+void *
+grub_list_pop (grub_list_t *head)
+{
+  grub_list_t item;
+
+  item = *head;
+  if (item)
+    *head = item->next;
+
+  return item;
+}
+
+void
+grub_list_remove (grub_list_t *head, grub_list_t item)
+{
+  grub_list_t *p, q;
+
+  for (p = head, q = *p; q; p = &(q->next), q = q->next)
+    if (q == item)
+      {
+	*p = q->next;
+	break;
+      }
+}
+
+int
+grub_list_iterate (grub_list_t head, grub_list_hook_t hook)
+{
+  grub_list_t p;
+
+  for (p = head; p; p = p->next)
+    if (hook (p))
+      return 1;
+
+  return 0;
+}
+
+void
+grub_list_insert (grub_list_t *head, grub_list_t item,
+		  grub_list_test_t test)
+{
+  grub_list_t *p, q;
+
+  for (p = head, q = *p; q; p = &(q->next), q = q->next)
+    if (test (item, q))
+      break;
+
+  *p = item;
+  item->next = q;
+}
+
+void *
+grub_named_list_find (grub_named_list_t head, const char *name)
+{
+  grub_named_list_t result = 0;
+
+  auto int list_find (grub_named_list_t item);
+  int list_find (grub_named_list_t item)
+    {
+      if (! grub_strcmp (item->name, name))
+	{
+	  result = item;
+	  return 1;
+	}
+
+      return 0;
+    }
+
+  grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_find);
+  return result;
+}
+
+void
+grub_prio_list_insert (grub_prio_list_t *head, grub_prio_list_t nitem)
+{
+  int inactive = 0;
+
+  auto int test (grub_prio_list_t new_item, grub_prio_list_t item);
+  int test (grub_prio_list_t new_item, grub_prio_list_t item)
+    {
+      int r;
+
+      r = grub_strcmp (new_item->name, item->name);
+      if (r)
+	return (r < 0);
+
+      if (new_item->prio >= (item->prio & GRUB_PRIO_LIST_PRIO_MASK))
+	{
+	  item->prio &= ~GRUB_PRIO_LIST_FLAG_ACTIVE;
+	  return 1;
+	}
+
+      inactive = 1;
+      return 0;
+    }
+
+  grub_list_insert (GRUB_AS_LIST_P (head), GRUB_AS_LIST (nitem),
+		    (grub_list_test_t) test);
+  if (! inactive)
+    nitem->prio |= GRUB_PRIO_LIST_FLAG_ACTIVE;
+}
diff --git a/kern/main.c b/kern/main.c
new file mode 100644
index 0000000..9215d55
--- /dev/null
+++ b/kern/main.c
@@ -0,0 +1,177 @@
+/* main.c - the kernel main routine */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2006,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/symbol.h>
+#include <grub/dl.h>
+#include <grub/term.h>
+#include <grub/file.h>
+#include <grub/device.h>
+#include <grub/env.h>
+#include <grub/mm.h>
+#include <grub/command.h>
+#include <grub/reader.h>
+#include <grub/parser.h>
+
+void
+grub_module_iterate (int (*hook) (struct grub_module_header *header))
+{
+  struct grub_module_info *modinfo;
+  struct grub_module_header *header;
+  grub_addr_t modbase;
+
+  modbase = grub_arch_modules_addr ();
+  modinfo = (struct grub_module_info *) modbase;
+
+  /* Check if there are any modules.  */
+  if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC)
+    return;
+
+  for (header = (struct grub_module_header *) (modbase + modinfo->offset);
+       header < (struct grub_module_header *) (modbase + modinfo->size);
+       header = (struct grub_module_header *) ((char *) header + header->size))
+    {
+      if (hook (header))
+	break;
+    }
+}
+
+/* Load all modules in core.  */
+static void
+grub_load_modules (void)
+{
+  auto int hook (struct grub_module_header *);
+  int hook (struct grub_module_header *header)
+    {
+      /* Not an ELF module, skip.  */
+      if (header->type != OBJ_TYPE_ELF)
+        return 0;
+
+      if (! grub_dl_load_core ((char *) header + sizeof (struct grub_module_header),
+			       (header->size - sizeof (struct grub_module_header))))
+	grub_fatal ("%s", grub_errmsg);
+
+      return 0;
+    }
+
+  grub_module_iterate (hook);
+}
+
+static void
+grub_load_config (void)
+{
+  auto int hook (struct grub_module_header *);
+  int hook (struct grub_module_header *header)
+    {
+      /* Not an ELF module, skip.  */
+      if (header->type != OBJ_TYPE_CONFIG)
+	return 0;
+
+      grub_parser_execute ((char *) header +
+			   sizeof (struct grub_module_header));
+      return 1;
+    }
+
+  grub_module_iterate (hook);
+}
+
+/* Write hook for the environment variables of root. Remove surrounding
+   parentheses, if any.  */
+static char *
+grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)),
+		     const char *val)
+{
+  /* XXX Is it better to check the existence of the device?  */
+  grub_size_t len = grub_strlen (val);
+
+  if (val[0] == '(' && val[len - 1] == ')')
+    return grub_strndup (val + 1, len - 2);
+
+  return grub_strdup (val);
+}
+
+/* Set the root device according to the dl prefix.  */
+static void
+grub_set_root_dev (void)
+{
+  const char *prefix;
+
+  grub_register_variable_hook ("root", 0, grub_env_write_root);
+  grub_env_export ("root");
+
+  prefix = grub_env_get ("prefix");
+
+  if (prefix)
+    {
+      char *dev;
+
+      dev = grub_file_get_device_name (prefix);
+      if (dev)
+	{
+	  grub_env_set ("root", dev);
+	  grub_free (dev);
+	}
+    }
+}
+
+/* Load the normal mode module and execute the normal mode if possible.  */
+static void
+grub_load_normal_mode (void)
+{
+  /* Load the module.  */
+  grub_dl_load ("normal");
+
+  /* Something went wrong.  Print errors here to let user know why we're entering rescue mode.  */
+  grub_print_error ();
+  grub_errno = 0;
+
+  grub_command_execute ("normal", 0, 0);
+}
+
+/* The main routine.  */
+void
+grub_main (void)
+{
+  /* First of all, initialize the machine.  */
+  grub_machine_init ();
+
+  /* Hello.  */
+  grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
+  grub_printf ("Welcome to GRUB!\n\n");
+  grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
+
+  /* Load pre-loaded modules and free the space.  */
+  grub_register_exported_symbols ();
+  grub_load_modules ();
+
+  /* It is better to set the root device as soon as possible,
+     for convenience.  */
+  grub_machine_set_prefix ();
+  grub_env_export ("prefix");
+  grub_set_root_dev ();
+
+  grub_register_core_commands ();
+  grub_register_rescue_parser ();
+  grub_register_rescue_reader ();
+
+  grub_load_config ();
+  grub_load_normal_mode ();
+  grub_reader_loop (0);
+}
diff --git a/kern/misc.c b/kern/misc.c
new file mode 100644
index 0000000..1c38fe6
--- /dev/null
+++ b/kern/misc.c
@@ -0,0 +1,1017 @@
+/* misc.c - definitions of misc functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <stdarg.h>
+#include <grub/term.h>
+#include <grub/env.h>
+
+static int
+grub_iswordseparator (int c)
+{
+  return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
+}
+
+void *
+grub_memmove (void *dest, const void *src, grub_size_t n)
+{
+  char *d = (char *) dest;
+  const char *s = (const char *) src;
+
+  if (d < s)
+    while (n--)
+      *d++ = *s++;
+  else
+    {
+      d += n;
+      s += n;
+
+      while (n--)
+	*--d = *--s;
+    }
+
+  return dest;
+}
+
+#ifndef APPLE_CC
+void *memmove (void *dest, const void *src, grub_size_t n)
+  __attribute__ ((alias ("grub_memmove")));
+/* GCC emits references to memcpy() for struct copies etc.  */
+void *memcpy (void *dest, const void *src, grub_size_t n)
+  __attribute__ ((alias ("grub_memmove")));
+#else
+void *memcpy (void *dest, const void *src, grub_size_t n)
+{
+	return grub_memmove (dest, src, n);
+}
+void *memmove (void *dest, const void *src, grub_size_t n)
+{
+	return grub_memmove (dest, src, n);
+}
+#endif
+
+char *
+grub_strcpy (char *dest, const char *src)
+{
+  char *p = dest;
+
+  while ((*p++ = *src++) != '\0')
+    ;
+
+  return dest;
+}
+
+char *
+grub_strncpy (char *dest, const char *src, int c)
+{
+  char *p = dest;
+
+  while ((*p++ = *src++) != '\0' && --c)
+    ;
+
+  return dest;
+}
+
+char *
+grub_stpcpy (char *dest, const char *src)
+{
+  char *d = dest;
+  const char *s = src;
+
+  do
+    *d++ = *s;
+  while (*s++ != '\0');
+
+  return d - 1;
+}
+
+int
+grub_printf (const char *fmt, ...)
+{
+  va_list ap;
+  int ret;
+
+  va_start (ap, fmt);
+  ret = grub_vprintf (fmt, ap);
+  va_end (ap);
+
+  return ret;
+}
+
+#if defined (APPLE_CC) && ! defined (GRUB_UTIL)
+int
+grub_err_printf (const char *fmt, ...)
+{
+	va_list ap;
+	int ret;
+
+	va_start (ap, fmt);
+	ret = grub_vprintf (fmt, ap);
+	va_end (ap);
+
+	return ret;
+}
+#endif
+
+#if ! defined (APPLE_CC) && ! defined (GRUB_UTIL)
+int grub_err_printf (const char *fmt, ...)
+__attribute__ ((alias("grub_printf")));
+#endif
+
+void
+grub_real_dprintf (const char *file, const int line, const char *condition,
+		   const char *fmt, ...)
+{
+  va_list args;
+  const char *debug = grub_env_get ("debug");
+
+  if (! debug)
+    return;
+
+  if (grub_strword (debug, "all") || grub_strword (debug, condition))
+    {
+      grub_printf ("%s:%d: ", file, line);
+      va_start (args, fmt);
+      grub_vprintf (fmt, args);
+      va_end (args);
+    }
+}
+
+int
+grub_vprintf (const char *fmt, va_list args)
+{
+  int ret;
+
+  ret = grub_vsprintf (0, fmt, args);
+  grub_refresh ();
+  return ret;
+}
+
+int
+grub_memcmp (const void *s1, const void *s2, grub_size_t n)
+{
+  const char *t1 = s1;
+  const char *t2 = s2;
+
+  while (n--)
+    {
+      if (*t1 != *t2)
+	return (int) *t1 - (int) *t2;
+
+      t1++;
+      t2++;
+    }
+
+  return 0;
+}
+#ifndef APPLE_CC
+int memcmp (const void *s1, const void *s2, grub_size_t n)
+  __attribute__ ((alias ("grub_memcmp")));
+#endif
+
+int
+grub_strcmp (const char *s1, const char *s2)
+{
+  while (*s1 && *s2)
+    {
+      if (*s1 != *s2)
+	break;
+
+      s1++;
+      s2++;
+    }
+
+  return (int) *s1 - (int) *s2;
+}
+
+int
+grub_strncmp (const char *s1, const char *s2, grub_size_t n)
+{
+  if (n == 0)
+    return 0;
+
+  while (*s1 && *s2 && --n)
+    {
+      if (*s1 != *s2)
+	break;
+
+      s1++;
+      s2++;
+    }
+
+  return (int) *s1 - (int) *s2;
+}
+
+char *
+grub_strchr (const char *s, int c)
+{
+  while (*s)
+    {
+      if (*s == c)
+	return (char *) s;
+      s++;
+    }
+
+  return 0;
+}
+
+char *
+grub_strrchr (const char *s, int c)
+{
+  char *p = 0;
+
+  while (*s)
+    {
+      if (*s == c)
+	p = (char *) s;
+      s++;
+    }
+
+  return p;
+}
+
+/* Copied from gnulib.
+   Written by Bruno Haible <bruno@clisp.org>, 2005. */
+char *
+grub_strstr (const char *haystack, const char *needle)
+{
+  /* Be careful not to look at the entire extent of haystack or needle
+     until needed.  This is useful because of these two cases:
+       - haystack may be very long, and a match of needle found early,
+       - needle may be very long, and not even a short initial segment of
+       needle may be found in haystack.  */
+  if (*needle != '\0')
+    {
+      /* Speed up the following searches of needle by caching its first
+	 character.  */
+      char b = *needle++;
+
+      for (;; haystack++)
+	{
+	  if (*haystack == '\0')
+	    /* No match.  */
+	    return NULL;
+	  if (*haystack == b)
+	    /* The first character matches.  */
+	    {
+	      const char *rhaystack = haystack + 1;
+	      const char *rneedle = needle;
+
+	      for (;; rhaystack++, rneedle++)
+		{
+		  if (*rneedle == '\0')
+		    /* Found a match.  */
+		    return (char *) haystack;
+		  if (*rhaystack == '\0')
+		    /* No match.  */
+		    return NULL;
+		  if (*rhaystack != *rneedle)
+		    /* Nothing in this round.  */
+		    break;
+		}
+	    }
+	}
+    }
+  else
+    return (char *) haystack;
+}
+
+int
+grub_strword (const char *haystack, const char *needle)
+{
+  const char *n_pos = needle;
+
+  while (grub_iswordseparator (*haystack))
+    haystack++;
+
+  while (*haystack)
+    {
+      /* Crawl both the needle and the haystack word we're on.  */
+      while(*haystack && !grub_iswordseparator (*haystack)
+            && *haystack == *n_pos)
+        {
+          haystack++;
+          n_pos++;
+        }
+
+      /* If we reached the end of both words at the same time, the word
+      is found. If not, eat everything in the haystack that isn't the
+      next word (or the end of string) and "reset" the needle.  */
+      if ( (!*haystack || grub_iswordseparator (*haystack))
+         && (!*n_pos || grub_iswordseparator (*n_pos)))
+        return 1;
+      else
+        {
+          n_pos = needle;
+          while (*haystack && !grub_iswordseparator (*haystack))
+            haystack++;
+          while (grub_iswordseparator (*haystack))
+            haystack++;
+        }
+    }
+
+  return 0;
+}
+
+int
+grub_isspace (int c)
+{
+  return (c == '\n' || c == '\r' || c == ' ' || c == '\t');
+}
+
+int
+grub_isprint (int c)
+{
+  return (c >= ' ' && c <= '~');
+}
+
+
+unsigned long
+grub_strtoul (const char *str, char **end, int base)
+{
+  unsigned long long num;
+
+  num = grub_strtoull (str, end, base);
+  if (num > ~0UL)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
+      return ~0UL;
+    }
+
+  return (unsigned long) num;
+}
+
+unsigned long long
+grub_strtoull (const char *str, char **end, int base)
+{
+  unsigned long long num = 0;
+  int found = 0;
+
+  /* Skip white spaces.  */
+  while (*str && grub_isspace (*str))
+    str++;
+
+  /* Guess the base, if not specified. The prefix `0x' means 16, and
+     the prefix `0' means 8.  */
+  if (str[0] == '0')
+    {
+      if (str[1] == 'x')
+	{
+	  if (base == 0 || base == 16)
+	    {
+	      base = 16;
+	      str += 2;
+	    }
+	}
+      else if (base == 0 && str[1] >= '0' && str[1] <= '7')
+	base = 8;
+    }
+
+  if (base == 0)
+    base = 10;
+
+  while (*str)
+    {
+      unsigned long digit;
+
+      digit = grub_tolower (*str) - '0';
+      if (digit > 9)
+	{
+	  digit += '0' - 'a' + 10;
+	  if (digit >= (unsigned long) base)
+	    break;
+	}
+
+      found = 1;
+
+      /* NUM * BASE + DIGIT > ~0ULL */
+      if (num > grub_divmod64 (~0ULL - digit, base, 0))
+	{
+	  grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
+	  return ~0ULL;
+	}
+
+      num = num * base + digit;
+      str++;
+    }
+
+  if (! found)
+    {
+      grub_error (GRUB_ERR_BAD_NUMBER, "unrecognized number");
+      return 0;
+    }
+
+  if (end)
+    *end = (char *) str;
+
+  return num;
+}
+
+char *
+grub_strdup (const char *s)
+{
+  grub_size_t len;
+  char *p;
+
+  len = grub_strlen (s) + 1;
+  p = (char *) grub_malloc (len);
+  if (! p)
+    return 0;
+
+  return grub_memcpy (p, s, len);
+}
+
+char *
+grub_strndup (const char *s, grub_size_t n)
+{
+  grub_size_t len;
+  char *p;
+
+  len = grub_strlen (s);
+  if (len > n)
+    len = n;
+  p = (char *) grub_malloc (len + 1);
+  if (! p)
+    return 0;
+
+  grub_memcpy (p, s, len);
+  p[len] = '\0';
+  return p;
+}
+
+void *
+grub_memset (void *s, int c, grub_size_t n)
+{
+  unsigned char *p = (unsigned char *) s;
+
+  while (n--)
+    *p++ = (unsigned char) c;
+
+  return s;
+}
+#ifndef APPLE_CC
+void *memset (void *s, int c, grub_size_t n)
+  __attribute__ ((alias ("grub_memset")));
+#endif
+
+grub_size_t
+grub_strlen (const char *s)
+{
+  const char *p = s;
+
+  while (*p)
+    p++;
+
+  return p - s;
+}
+
+static inline void
+grub_reverse (char *str)
+{
+  char *p = str + grub_strlen (str) - 1;
+
+  while (str < p)
+    {
+      char tmp;
+
+      tmp = *str;
+      *str = *p;
+      *p = tmp;
+      str++;
+      p--;
+    }
+}
+
+/* Divide N by D, return the quotient, and store the remainder in *R.  */
+grub_uint64_t
+grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r)
+{
+  /* This algorithm is typically implemented by hardware. The idea
+     is to get the highest bit in N, 64 times, by keeping
+     upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
+     represents the high 64 bits in 128-bits space.  */
+  unsigned bits = 64;
+  unsigned long long q = 0;
+  unsigned m = 0;
+
+  /* Skip the slow computation if 32-bit arithmetic is possible.  */
+  if (n < 0xffffffff)
+    {
+      if (r)
+	*r = ((grub_uint32_t) n) % d;
+
+      return ((grub_uint32_t) n) / d;
+    }
+
+  while (bits--)
+    {
+      m <<= 1;
+
+      if (n & (1ULL << 63))
+	m |= 1;
+
+      q <<= 1;
+      n <<= 1;
+
+      if (m >= d)
+	{
+	  q |= 1;
+	  m -= d;
+	}
+    }
+
+  if (r)
+    *r = m;
+
+  return q;
+}
+
+/* Convert a long long value to a string. This function avoids 64-bit
+   modular arithmetic or divisions.  */
+static char *
+grub_lltoa (char *str, int c, unsigned long long n)
+{
+  unsigned base = (c == 'x') ? 16 : 10;
+  char *p;
+
+  if ((long long) n < 0 && c == 'd')
+    {
+      n = (unsigned long long) (-((long long) n));
+      *str++ = '-';
+    }
+
+  p = str;
+
+  if (base == 16)
+    do
+      {
+	unsigned d = (unsigned) (n & 0xf);
+	*p++ = (d > 9) ? d + 'a' - 10 : d + '0';
+      }
+    while (n >>= 4);
+  else
+    /* BASE == 10 */
+    do
+      {
+	unsigned m;
+
+	n = grub_divmod64 (n, 10, &m);
+	*p++ = m + '0';
+      }
+    while (n);
+
+  *p = 0;
+
+  grub_reverse (str);
+  return p;
+}
+
+int
+grub_vsprintf (char *str, const char *fmt, va_list args)
+{
+  char c;
+  int count = 0;
+  auto void write_char (unsigned char ch);
+  auto void write_str (const char *s);
+  auto void write_fill (const char ch, int n);
+
+  void write_char (unsigned char ch)
+    {
+      if (str)
+	*str++ = ch;
+      else
+	grub_putchar (ch);
+
+      count++;
+    }
+
+  void write_str (const char *s)
+    {
+      while (*s)
+	write_char (*s++);
+    }
+
+  void write_fill (const char ch, int n)
+    {
+      int i;
+      for (i = 0; i < n; i++)
+	write_char (ch);
+    }
+
+  while ((c = *fmt++) != 0)
+    {
+      if (c != '%')
+	write_char (c);
+      else
+	{
+	  char tmp[32];
+	  char *p;
+	  unsigned int format1 = 0;
+	  unsigned int format2 = ~ 0U;
+	  char zerofill = ' ';
+	  int rightfill = 0;
+	  int n;
+	  int longfmt = 0;
+	  int longlongfmt = 0;
+	  int unsig = 0;
+
+	  if (*fmt && *fmt =='-')
+	    {
+	      rightfill = 1;
+	      fmt++;
+	    }
+
+	  p = (char *) fmt;
+	  /* Read formatting parameters.  */
+	  while (*p && grub_isdigit (*p))
+	    p++;
+
+	  if (p > fmt)
+	    {
+	      char s[p - fmt + 1];
+	      grub_strncpy (s, fmt, p - fmt);
+	      s[p - fmt] = 0;
+	      if (s[0] == '0')
+		zerofill = '0';
+	      format1 = grub_strtoul (s, 0, 10);
+	      fmt = p;
+	    }
+
+	  if (*p && *p == '.')
+	    {
+	      p++;
+	      fmt++;
+	      while (*p && grub_isdigit (*p))
+		p++;
+
+	      if (p > fmt)
+		{
+		  char fstr[p - fmt + 1];
+		  grub_strncpy (fstr, fmt, p - fmt);
+		  fstr[p - fmt] = 0;
+		  format2 = grub_strtoul (fstr, 0, 10);
+		  fmt = p;
+		}
+	    }
+
+	  c = *fmt++;
+	  if (c == 'l')
+	    {
+	      longfmt = 1;
+	      c = *fmt++;
+	      if (c == 'l')
+		{
+		  longlongfmt = 1;
+		  c = *fmt++;
+		}
+	    }
+
+	  switch (c)
+	    {
+	    case 'p':
+	      write_str ("0x");
+	      c = 'x';
+	      longlongfmt |= (sizeof (void *) == sizeof (long long));
+	      /* Fall through. */
+	    case 'x':
+	    case 'u':
+	      unsig = 1;
+	      /* Fall through. */
+	    case 'd':
+	      if (longlongfmt)
+		{
+		  long long ll;
+
+		  ll = va_arg (args, long long);
+		  grub_lltoa (tmp, c, ll);
+		}
+	      else if (longfmt && unsig)
+		{
+		  unsigned long l = va_arg (args, unsigned long);
+		  grub_lltoa (tmp, c, l);
+		}
+	      else if (longfmt)
+		{
+		  long l = va_arg (args, long);
+		  grub_lltoa (tmp, c, l);
+		}
+	      else if (unsig)
+		{
+		  unsigned u = va_arg (args, unsigned);
+		  grub_lltoa (tmp, c, u);
+		}
+	      else
+		{
+		  n = va_arg (args, int);
+		  grub_lltoa (tmp, c, n);
+		}
+	      if (! rightfill && grub_strlen (tmp) < format1)
+		write_fill (zerofill, format1 - grub_strlen (tmp));
+	      write_str (tmp);
+	      if (rightfill && grub_strlen (tmp) < format1)
+		write_fill (zerofill, format1 - grub_strlen (tmp));
+	      break;
+
+	    case 'c':
+	      n = va_arg (args, int);
+	      write_char (n & 0xff);
+	      break;
+
+	    case 'C':
+	      {
+		grub_uint32_t code = va_arg (args, grub_uint32_t);
+		int shift;
+		unsigned mask;
+
+		if (code <= 0x7f)
+		  {
+		    shift = 0;
+		    mask = 0;
+		  }
+		else if (code <= 0x7ff)
+		  {
+		    shift = 6;
+		    mask = 0xc0;
+		  }
+		else if (code <= 0xffff)
+		  {
+		    shift = 12;
+		    mask = 0xe0;
+		  }
+		else if (code <= 0x1fffff)
+		  {
+		    shift = 18;
+		    mask = 0xf0;
+		  }
+		else if (code <= 0x3ffffff)
+		  {
+		    shift = 24;
+		    mask = 0xf8;
+		  }
+		else if (code <= 0x7fffffff)
+		  {
+		    shift = 30;
+		    mask = 0xfc;
+		  }
+		else
+		  {
+		    code = '?';
+		    shift = 0;
+		    mask = 0;
+		  }
+
+		write_char (mask | (code >> shift));
+
+		for (shift -= 6; shift >= 0; shift -= 6)
+		  write_char (0x80 | (0x3f & (code >> shift)));
+	      }
+	      break;
+
+	    case 's':
+	      p = va_arg (args, char *);
+	      if (p)
+		{
+		  grub_size_t len = 0;
+		  while (len < format2 && p[len])
+		    len++;
+
+		  if (!rightfill && len < format1)
+		    write_fill (zerofill, format1 - len);
+
+		  grub_size_t i;
+		  for (i = 0; i < len; i++)
+		    write_char (*p++);
+
+		  if (rightfill && len < format1)
+		    write_fill (zerofill, format1 - len);
+		}
+	      else
+		write_str ("(null)");
+
+	      break;
+
+	    default:
+	      write_char (c);
+	      break;
+	    }
+	}
+    }
+
+  if (str)
+    *str = '\0';
+
+  if (count && !str)
+    grub_refresh ();
+
+  return count;
+}
+
+int
+grub_sprintf (char *str, const char *fmt, ...)
+{
+  va_list ap;
+  int ret;
+
+  va_start (ap, fmt);
+  ret = grub_vsprintf (str, fmt, ap);
+  va_end (ap);
+
+  return ret;
+}
+
+/* Convert UTF-16 to UTF-8.  */
+grub_uint8_t *
+grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
+		    grub_size_t size)
+{
+  grub_uint32_t code_high = 0;
+
+  while (size--)
+    {
+      grub_uint32_t code = *src++;
+
+      if (code_high)
+	{
+	  if (code >= 0xDC00 && code <= 0xDFFF)
+	    {
+	      /* Surrogate pair.  */
+	      code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000;
+
+	      *dest++ = (code >> 18) | 0xF0;
+	      *dest++ = ((code >> 12) & 0x3F) | 0x80;
+	      *dest++ = ((code >> 6) & 0x3F) | 0x80;
+	      *dest++ = (code & 0x3F) | 0x80;
+	    }
+	  else
+	    {
+	      /* Error...  */
+	      *dest++ = '?';
+	    }
+
+	  code_high = 0;
+	}
+      else
+	{
+	  if (code <= 0x007F)
+	    *dest++ = code;
+	  else if (code <= 0x07FF)
+	    {
+	      *dest++ = (code >> 6) | 0xC0;
+	      *dest++ = (code & 0x3F) | 0x80;
+	    }
+	  else if (code >= 0xD800 && code <= 0xDBFF)
+	    {
+	      code_high = code;
+	      continue;
+	    }
+	  else if (code >= 0xDC00 && code <= 0xDFFF)
+	    {
+	      /* Error... */
+	      *dest++ = '?';
+	    }
+	  else
+	    {
+	      *dest++ = (code >> 12) | 0xE0;
+	      *dest++ = ((code >> 6) & 0x3F) | 0x80;
+	      *dest++ = (code & 0x3F) | 0x80;
+	    }
+	}
+    }
+
+  return dest;
+}
+
+/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
+   bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
+   Return the number of characters converted. DEST must be able to hold
+   at least DESTSIZE characters. If an invalid sequence is found, return -1.
+   If SRCEND is not NULL, then *SRCEND is set to the next byte after the
+   last byte used in SRC.  */
+grub_ssize_t
+grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
+		   const grub_uint8_t *src, grub_size_t srcsize,
+		   const grub_uint8_t **srcend)
+{
+  grub_uint32_t *p = dest;
+  int count = 0;
+  grub_uint32_t code = 0;
+
+  if (srcend)
+    *srcend = src;
+
+  while (srcsize && destsize)
+    {
+      grub_uint32_t c = *src++;
+      if (srcsize != (grub_size_t)-1)
+	srcsize--;
+      if (count)
+	{
+	  if ((c & 0xc0) != 0x80)
+	    {
+	      /* invalid */
+	      return -1;
+	    }
+	  else
+	    {
+	      code <<= 6;
+	      code |= (c & 0x3f);
+	      count--;
+	    }
+	}
+      else
+	{
+	  if (c == 0)
+	    break;
+
+	  if ((c & 0x80) == 0x00)
+	    code = c;
+	  else if ((c & 0xe0) == 0xc0)
+	    {
+	      count = 1;
+	      code = c & 0x1f;
+	    }
+	  else if ((c & 0xf0) == 0xe0)
+	    {
+	      count = 2;
+	      code = c & 0x0f;
+	    }
+	  else if ((c & 0xf8) == 0xf0)
+	    {
+	      count = 3;
+	      code = c & 0x07;
+	    }
+	  else if ((c & 0xfc) == 0xf8)
+	    {
+	      count = 4;
+	      code = c & 0x03;
+	    }
+	  else if ((c & 0xfe) == 0xfc)
+	    {
+	      count = 5;
+	      code = c & 0x01;
+	    }
+	  else
+	    return -1;
+	}
+
+      if (count == 0)
+	{
+	  *p++ = code;
+	  destsize--;
+	}
+    }
+
+  if (srcend)
+    *srcend = src;
+  return p - dest;
+}
+
+/* Abort GRUB. This function does not return.  */
+void
+grub_abort (void)
+{
+  if (grub_term_get_current_output ())
+    {
+      grub_printf ("\nAborted.");
+
+      if (grub_term_get_current_input ())
+	{
+	  grub_printf (" Press any key to exit.");
+	  grub_getkey ();
+	}
+    }
+
+  grub_exit ();
+}
+
+#ifndef APPLE_CC
+/* GCC emits references to abort().  */
+void abort (void) __attribute__ ((alias ("grub_abort")));
+#endif
+
+#ifdef NEED_ENABLE_EXECUTE_STACK
+/* Some gcc versions generate a call to this function
+   in trampolines for nested functions.  */
+void __enable_execute_stack (void *addr __attribute__ ((unused)))
+{
+}
+#endif
+
diff --git a/kern/mm.c b/kern/mm.c
new file mode 100644
index 0000000..cbcb995
--- /dev/null
+++ b/kern/mm.c
@@ -0,0 +1,586 @@
+/* mm.c - functions for memory manager */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+  The design of this memory manager.
+
+  This is a simple implementation of malloc with a few extensions. These are
+  the extensions:
+
+  - memalign is implemented efficiently.
+
+  - multiple regions may be used as free space. They may not be
+  contiguous.
+
+  Regions are managed by a singly linked list, and the meta information is
+  stored in the beginning of each region. Space after the meta information
+  is used to allocate memory.
+
+  The memory space is used as cells instead of bytes for simplicity. This
+  is important for some CPUs which may not access multiple bytes at a time
+  when the first byte is not aligned at a certain boundary (typically,
+  4-byte or 8-byte). The size of each cell is equal to the size of struct
+  grub_mm_header, so the header of each allocated/free block fits into one
+  cell precisely. One cell is 16 bytes on 32-bit platforms and 32 bytes
+  on 64-bit platforms.
+
+  There are two types of blocks: allocated blocks and free blocks.
+
+  In allocated blocks, the header of each block has only its size. Note that
+  this size is based on cells but not on bytes. The header is located right
+  before the returned pointer, that is, the header resides at the previous
+  cell.
+
+  Free blocks constitutes a ring, using a singly linked list. The first free
+  block is pointed to by the meta information of a region. The allocator
+  attempts to pick up the second block instead of the first one. This is
+  a typical optimization against defragmentation, and makes the
+  implementation a bit easier.
+
+  For safety, both allocated blocks and free ones are marked by magic
+  numbers. Whenever anything unexpected is detected, GRUB aborts the
+  operation.
+ */
+
+#include <config.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+
+#ifdef MM_DEBUG
+# undef grub_malloc
+# undef grub_zalloc
+# undef grub_realloc
+# undef grub_free
+# undef grub_memalign
+#endif
+
+/* Magic words.  */
+#define GRUB_MM_FREE_MAGIC	0x2d3c2808
+#define GRUB_MM_ALLOC_MAGIC	0x6db08fa4
+
+typedef struct grub_mm_header
+{
+  struct grub_mm_header *next;
+  grub_size_t size;
+  grub_size_t magic;
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+  char padding[4];
+#elif GRUB_CPU_SIZEOF_VOID_P == 8
+  char padding[8];
+#else
+# error "unknown word size"
+#endif
+}
+*grub_mm_header_t;
+
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+# define GRUB_MM_ALIGN_LOG2	4
+#elif GRUB_CPU_SIZEOF_VOID_P == 8
+# define GRUB_MM_ALIGN_LOG2	5
+#endif
+
+#define GRUB_MM_ALIGN	(1 << GRUB_MM_ALIGN_LOG2)
+
+typedef struct grub_mm_region
+{
+  struct grub_mm_header *first;
+  struct grub_mm_region *next;
+  grub_addr_t addr;
+  grub_size_t size;
+}
+*grub_mm_region_t;
+
+
+
+static grub_mm_region_t base;
+
+/* Get a header from the pointer PTR, and set *P and *R to a pointer
+   to the header and a pointer to its region, respectively. PTR must
+   be allocated.  */
+static void
+get_header_from_pointer (void *ptr, grub_mm_header_t *p, grub_mm_region_t *r)
+{
+  if ((grub_addr_t) ptr & (GRUB_MM_ALIGN - 1))
+    grub_fatal ("unaligned pointer %p", ptr);
+
+  for (*r = base; *r; *r = (*r)->next)
+    if ((grub_addr_t) ptr > (*r)->addr
+	&& (grub_addr_t) ptr <= (*r)->addr + (*r)->size)
+      break;
+
+  if (! *r)
+    grub_fatal ("out of range pointer %p", ptr);
+
+  *p = (grub_mm_header_t) ptr - 1;
+  if ((*p)->magic != GRUB_MM_ALLOC_MAGIC)
+    grub_fatal ("alloc magic is broken at %p", *p);
+}
+
+/* Initialize a region starting from ADDR and whose size is SIZE,
+   to use it as free space.  */
+void
+grub_mm_init_region (void *addr, grub_size_t size)
+{
+  grub_mm_header_t h;
+  grub_mm_region_t r, *p, q;
+
+#if 0
+  grub_printf ("Using memory for heap: start=%p, end=%p\n", addr, addr + (unsigned int) size);
+#endif
+
+  /* If this region is too small, ignore it.  */
+  if (size < GRUB_MM_ALIGN * 2)
+    return;
+
+  /* Allocate a region from the head.  */
+  r = (grub_mm_region_t) (((grub_addr_t) addr + GRUB_MM_ALIGN - 1)
+			  & (~(GRUB_MM_ALIGN - 1)));
+  size -= (char *) r - (char *) addr + sizeof (*r);
+
+  h = (grub_mm_header_t) ((char *) r + GRUB_MM_ALIGN);
+  h->next = h;
+  h->magic = GRUB_MM_FREE_MAGIC;
+  h->size = (size >> GRUB_MM_ALIGN_LOG2);
+
+  r->first = h;
+  r->addr = (grub_addr_t) h;
+  r->size = (h->size << GRUB_MM_ALIGN_LOG2);
+
+  /* Find where to insert this region. Put a smaller one before bigger ones,
+     to prevent fragmentation.  */
+  for (p = &base, q = *p; q; p = &(q->next), q = *p)
+    if (q->size > r->size)
+      break;
+
+  *p = r;
+  r->next = q;
+}
+
+/* Allocate the number of units N with the alignment ALIGN from the ring
+   buffer starting from *FIRST.  ALIGN must be a power of two. Both N and
+   ALIGN are in units of GRUB_MM_ALIGN.  Return a non-NULL if successful,
+   otherwise return NULL.  */
+static void *
+grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align)
+{
+  grub_mm_header_t p, q;
+
+  /* When everything is allocated side effect is that *first will have alloc
+     magic marked, meaning that there is no room in this region.  */
+  if ((*first)->magic == GRUB_MM_ALLOC_MAGIC)
+    return 0;
+
+  /* Try to search free slot for allocation in this memory region.  */
+  for (q = *first, p = q->next; ; q = p, p = p->next)
+    {
+      grub_off_t extra;
+
+      extra = ((grub_addr_t) (p + 1) >> GRUB_MM_ALIGN_LOG2) % align;
+      if (extra)
+	extra = align - extra;
+
+      if (! p)
+	grub_fatal ("null in the ring");
+
+      if (p->magic != GRUB_MM_FREE_MAGIC)
+	grub_fatal ("free magic is broken at %p: 0x%x", p, p->magic);
+
+      if (p->size >= n + extra)
+	{
+	  if (extra == 0 && p->size == n)
+	    {
+	      /* There is no special alignment requirement and memory block
+	         is complete match.
+
+	         1. Just mark memory block as allocated and remove it from
+	            free list.
+
+	         Result:
+	         +---------------+ previous block's next
+	         | alloc, size=n |          |
+	         +---------------+          v
+	       */
+	      q->next = p->next;
+	      p->magic = GRUB_MM_ALLOC_MAGIC;
+	    }
+	  else if (extra == 0 || p->size == n + extra)
+	    {
+	      /* There might be alignment requirement, when taking it into
+	         account memory block fits in.
+
+	         1. Allocate new area at end of memory block.
+	         2. Reduce size of available blocks from original node.
+	         3. Mark new area as allocated and "remove" it from free
+	            list.
+
+	         Result:
+	         +---------------+
+	         | free, size-=n | next --+
+	         +---------------+        |
+	         | alloc, size=n |        |
+	         +---------------+        v
+	       */
+	      p->size -= n;
+	      p += p->size;
+	      p->size = n;
+	      p->magic = GRUB_MM_ALLOC_MAGIC;
+	    }
+	  else
+	    {
+	      /* There is alignment requirement and there is room in memory
+	         block.  Split memory block to three pieces.
+
+	         1. Create new memory block right after section being
+	            allocated.  Mark it as free.
+	         2. Add new memory block to free chain.
+	         3. Mark current memory block having only extra blocks.
+	         4. Advance to aligned block and mark that as allocated and
+	            "remove" it from free list.
+
+	         Result:
+	         +------------------------------+
+	         | free, size=extra             | next --+
+	         +------------------------------+        |
+	         | alloc, size=n                |        |
+	         +------------------------------+        |
+	         | free, size=orig.size-extra-n | <------+, next --+
+	         +------------------------------+                  v
+	       */
+	      grub_mm_header_t r;
+
+	      r = p + extra + n;
+	      r->magic = GRUB_MM_FREE_MAGIC;
+	      r->size = p->size - extra - n;
+	      r->next = p->next;
+
+	      p->size = extra;
+	      p->next = r;
+	      p += extra;
+	      p->size = n;
+	      p->magic = GRUB_MM_ALLOC_MAGIC;
+	    }
+
+	  /* Mark find as a start marker for next allocation to fasten it.
+	     This will have side effect of fragmenting memory as small
+	     pieces before this will be un-used.  */
+	  *first = q;
+
+	  return p + 1;
+	}
+
+      /* Search was completed without result.  */
+      if (p == *first)
+	break;
+    }
+
+  return 0;
+}
+
+/* Allocate SIZE bytes with the alignment ALIGN and return the pointer.  */
+void *
+grub_memalign (grub_size_t align, grub_size_t size)
+{
+  grub_mm_region_t r;
+  grub_size_t n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1;
+  int count = 0;
+
+  align = (align >> GRUB_MM_ALIGN_LOG2);
+  if (align == 0)
+    align = 1;
+
+ again:
+
+  for (r = base; r; r = r->next)
+    {
+      void *p;
+
+      p = grub_real_malloc (&(r->first), n, align);
+      if (p)
+	return p;
+    }
+
+  /* If failed, increase free memory somehow.  */
+  switch (count)
+    {
+    case 0:
+      /* Invalidate disk caches.  */
+      grub_disk_cache_invalidate_all ();
+      count++;
+      goto again;
+
+    case 1:
+      /* Unload unneeded modules.  */
+      grub_dl_unload_unneeded ();
+      count++;
+      goto again;
+
+    default:
+      break;
+    }
+
+  grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+  return 0;
+}
+
+/* Allocate SIZE bytes and return the pointer.  */
+void *
+grub_malloc (grub_size_t size)
+{
+  return grub_memalign (0, size);
+}
+
+/* Allocate SIZE bytes, clear them and return the pointer.  */
+void *
+grub_zalloc (grub_size_t size)
+{
+  void *ret;
+
+  ret = grub_memalign (0, size);
+  if (ret)
+    grub_memset (ret, 0, size);
+
+  return ret;
+}
+
+/* Deallocate the pointer PTR.  */
+void
+grub_free (void *ptr)
+{
+  grub_mm_header_t p;
+  grub_mm_region_t r;
+
+  if (! ptr)
+    return;
+
+  get_header_from_pointer (ptr, &p, &r);
+
+  if (r->first->magic == GRUB_MM_ALLOC_MAGIC)
+    {
+      p->magic = GRUB_MM_FREE_MAGIC;
+      r->first = p->next = p;
+    }
+  else
+    {
+      grub_mm_header_t q;
+
+#if 0
+      q = r->first;
+      do
+	{
+	  grub_printf ("%s:%d: q=%p, q->size=0x%x, q->magic=0x%x\n",
+		       __FILE__, __LINE__, q, q->size, q->magic);
+	  q = q->next;
+	}
+      while (q != r->first);
+#endif
+
+      for (q = r->first; q >= p || q->next <= p; q = q->next)
+	{
+	  if (q->magic != GRUB_MM_FREE_MAGIC)
+	    grub_fatal ("free magic is broken at %p: 0x%x", q, q->magic);
+
+	  if (q >= q->next && (q < p || q->next > p))
+	    break;
+	}
+
+      p->magic = GRUB_MM_FREE_MAGIC;
+      p->next = q->next;
+      q->next = p;
+
+      if (p + p->size == p->next)
+	{
+	  if (p->next == q)
+	    q = p;
+
+	  p->next->magic = 0;
+	  p->size += p->next->size;
+	  p->next = p->next->next;
+	}
+
+      if (q + q->size == p)
+	{
+	  p->magic = 0;
+	  q->size += p->size;
+	  q->next = p->next;
+	}
+
+      r->first = q;
+    }
+}
+
+/* Reallocate SIZE bytes and return the pointer. The contents will be
+   the same as that of PTR.  */
+void *
+grub_realloc (void *ptr, grub_size_t size)
+{
+  grub_mm_header_t p;
+  grub_mm_region_t r;
+  void *q;
+  grub_size_t n;
+
+  if (! ptr)
+    return grub_malloc (size);
+
+  if (! size)
+    {
+      grub_free (ptr);
+      return 0;
+    }
+
+  /* FIXME: Not optimal.  */
+  n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1;
+  get_header_from_pointer (ptr, &p, &r);
+
+  if (p->size >= n)
+    return ptr;
+
+  q = grub_malloc (size);
+  if (! q)
+    return q;
+
+  grub_memcpy (q, ptr, size);
+  grub_free (ptr);
+  return q;
+}
+
+#ifdef MM_DEBUG
+int grub_mm_debug = 0;
+
+void
+grub_mm_dump_free (void)
+{
+  grub_mm_region_t r;
+
+  for (r = base; r; r = r->next)
+    {
+      grub_mm_header_t p;
+
+      /* Follow the free list.  */
+      p = r->first;
+      do
+	{
+	  if (p->magic != GRUB_MM_FREE_MAGIC)
+	    grub_fatal ("free magic is broken at %p: 0x%x", p, p->magic);
+
+	  grub_printf ("F:%p:%u:%p\n",
+		       p, (unsigned int) p->size << GRUB_MM_ALIGN_LOG2, p->next);
+	  p = p->next;
+	}
+      while (p != r->first);
+    }
+
+  grub_printf ("\n");
+}
+
+void
+grub_mm_dump (unsigned lineno)
+{
+  grub_mm_region_t r;
+
+  grub_printf ("called at line %u\n", lineno);
+  for (r = base; r; r = r->next)
+    {
+      grub_mm_header_t p;
+
+      for (p = (grub_mm_header_t) ((r->addr + GRUB_MM_ALIGN - 1)
+				   & (~(GRUB_MM_ALIGN - 1)));
+	   (grub_addr_t) p < r->addr + r->size;
+	   p++)
+	{
+	  switch (p->magic)
+	    {
+	    case GRUB_MM_FREE_MAGIC:
+	      grub_printf ("F:%p:%u:%p\n",
+			   p, (unsigned int) p->size << GRUB_MM_ALIGN_LOG2, p->next);
+	      break;
+	    case GRUB_MM_ALLOC_MAGIC:
+	      grub_printf ("A:%p:%u\n", p, (unsigned int) p->size << GRUB_MM_ALIGN_LOG2);
+	      break;
+	    }
+	}
+    }
+
+  grub_printf ("\n");
+}
+
+void *
+grub_debug_malloc (const char *file, int line, grub_size_t size)
+{
+  void *ptr;
+
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: malloc (0x%zx) = ", file, line, size);
+  ptr = grub_malloc (size);
+  if (grub_mm_debug)
+    grub_printf ("%p\n", ptr);
+  return ptr;
+}
+
+void *
+grub_debug_zalloc (const char *file, int line, grub_size_t size)
+{
+  void *ptr;
+
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: zalloc (0x%zx) = ", file, line, size);
+  ptr = grub_zalloc (size);
+  if (grub_mm_debug)
+    grub_printf ("%p\n", ptr);
+  return ptr;
+}
+
+void
+grub_debug_free (const char *file, int line, void *ptr)
+{
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: free (%p)\n", file, line, ptr);
+  grub_free (ptr);
+}
+
+void *
+grub_debug_realloc (const char *file, int line, void *ptr, grub_size_t size)
+{
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: realloc (%p, 0x%zx) = ", file, line, ptr, size);
+  ptr = grub_realloc (ptr, size);
+  if (grub_mm_debug)
+    grub_printf ("%p\n", ptr);
+  return ptr;
+}
+
+void *
+grub_debug_memalign (const char *file, int line, grub_size_t align,
+		    grub_size_t size)
+{
+  void *ptr;
+
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: memalign (0x%zx, 0x%zx) = ",
+		 file, line, align, size);
+  ptr = grub_memalign (align, size);
+  if (grub_mm_debug)
+    grub_printf ("%p\n", ptr);
+  return ptr;
+}
+
+#endif /* MM_DEBUG */
diff --git a/kern/parser.c b/kern/parser.c
new file mode 100644
index 0000000..db59af0
--- /dev/null
+++ b/kern/parser.c
@@ -0,0 +1,269 @@
+/* parser.c - the part of the parser that can return partial tokens */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/parser.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+
+/* All the possible state transitions on the command line.  If a
+   transition can not be found, it is assumed that there is no
+   transition and keep_value is assumed to be 1.  */
+static struct grub_parser_state_transition state_transitions[] =
+{
+  { GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_QUOTE, '\'', 0},
+  { GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_DQUOTE, '\"', 0},
+  { GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_VAR, '$', 0},
+  { GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_ESC, '\\', 0},
+
+  { GRUB_PARSER_STATE_ESC, GRUB_PARSER_STATE_TEXT, 0, 1},
+
+  { GRUB_PARSER_STATE_QUOTE, GRUB_PARSER_STATE_TEXT, '\'', 0},
+
+  { GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_TEXT, '\"', 0},
+  { GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_QVAR, '$', 0},
+
+  { GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME2, '{', 0},
+  { GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME, 0, 1},
+  { GRUB_PARSER_STATE_VARNAME, GRUB_PARSER_STATE_TEXT, ' ', 1},
+  { GRUB_PARSER_STATE_VARNAME2, GRUB_PARSER_STATE_TEXT, '}', 0},
+
+  { GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME2, '{', 0},
+  { GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME, 0, 1},
+  { GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_TEXT, '\"', 0},
+  { GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_DQUOTE, ' ', 1},
+  { GRUB_PARSER_STATE_QVARNAME2, GRUB_PARSER_STATE_DQUOTE, '}', 0},
+
+  { 0, 0, 0, 0}
+};
+
+
+/* Determines the state following STATE, determined by C.  */
+grub_parser_state_t
+grub_parser_cmdline_state (grub_parser_state_t state, char c, char *result)
+{
+  struct grub_parser_state_transition *transition;
+  struct grub_parser_state_transition default_transition;
+
+  default_transition.to_state = state;
+  default_transition.keep_value = 1;
+
+  /* Look for a good translation.  */
+  for (transition = state_transitions; transition->from_state; transition++)
+    {
+      if (transition->from_state != state)
+	continue;
+      /* An exact match was found, use it.  */
+      if (transition->input == c)
+	break;
+
+      if (transition->input == ' ' && ! grub_isalpha (c)
+	  && ! grub_isdigit (c) && c != '_')
+	break;
+
+      /* A less perfect match was found, use this one if no exact
+	 match can be found.  */
+      if (transition->input == 0)
+	break;
+    }
+
+  if (! transition->from_state)
+    transition = &default_transition;
+
+  if (transition->keep_value)
+    *result = c;
+  else
+    *result = 0;
+  return transition->to_state;
+}
+
+
+grub_err_t
+grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
+			   int *argc, char ***argv)
+{
+  grub_parser_state_t state = GRUB_PARSER_STATE_TEXT;
+  /* XXX: Fixed size buffer, perhaps this buffer should be dynamically
+     allocated.  */
+  char buffer[1024];
+  char *bp = buffer;
+  char *rd = (char *) cmdline;
+  char varname[200];
+  char *vp = varname;
+  char *args;
+  int i;
+
+  auto int check_varstate (grub_parser_state_t s);
+
+  int check_varstate (grub_parser_state_t s)
+    {
+      return (s == GRUB_PARSER_STATE_VARNAME
+	      || s == GRUB_PARSER_STATE_VARNAME2
+	      || s == GRUB_PARSER_STATE_QVARNAME
+	      || s == GRUB_PARSER_STATE_QVARNAME2);
+    }
+
+  auto void add_var (grub_parser_state_t newstate);
+
+  void add_var (grub_parser_state_t newstate)
+    {
+      char *val;
+
+      /* Check if a variable was being read in and the end of the name
+	 was reached.  */
+      if (! (check_varstate (state) && !check_varstate (newstate)))
+	return;
+
+      *(vp++) = '\0';
+      val = grub_env_get (varname);
+      vp = varname;
+      if (! val)
+	return;
+
+      /* Insert the contents of the variable in the buffer.  */
+      for (; *val; val++)
+	*(bp++) = *val;
+    }
+
+  *argc = 1;
+  do
+    {
+      if (! *rd)
+	{
+	  if (getline)
+	    getline (&rd, 1);
+	  else break;
+	}
+
+      for (; *rd; rd++)
+	{
+	  grub_parser_state_t newstate;
+	  char use;
+
+	  newstate = grub_parser_cmdline_state (state, *rd, &use);
+
+	  /* If a variable was being processed and this character does
+	     not describe the variable anymore, write the variable to
+	     the buffer.  */
+	  add_var (newstate);
+
+	  if (check_varstate (newstate))
+	    {
+	      if (use)
+		*(vp++) = use;
+	    }
+	  else
+	    {
+	      if (newstate == GRUB_PARSER_STATE_TEXT
+		  && state != GRUB_PARSER_STATE_ESC && use == ' ')
+		{
+		  /* Don't add more than one argument if multiple
+		     spaces are used.  */
+		  if (bp != buffer && *(bp - 1))
+		    {
+		      *(bp++) = '\0';
+		      (*argc)++;
+		    }
+		}
+	      else if (use)
+		*(bp++) = use;
+	    }
+	  state = newstate;
+	}
+    } while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state));
+  *(bp++) = '\0';
+
+  /* A special case for when the last character was part of a
+     variable.  */
+  add_var (GRUB_PARSER_STATE_TEXT);
+
+
+  /* Reserve memory for the return values.  */
+  args = grub_malloc (bp - buffer);
+  if (! args)
+    return grub_errno;
+  grub_memcpy (args, buffer, bp - buffer);
+
+  *argv = grub_malloc (sizeof (char *) * (*argc + 1));
+  if (! *argv)
+    {
+      grub_free (args);
+      return grub_errno;
+    }
+
+  /* The arguments are separated with 0's, setup argv so it points to
+     the right values.  */
+  bp = args;
+  for (i = 0; i < *argc; i++)
+    {
+      (*argv)[i] = bp;
+      while (*bp)
+	bp++;
+      bp++;
+    }
+
+  (*argc)--;
+
+  return 0;
+}
+
+struct grub_handler_class grub_parser_class =
+  {
+    .name = "parser"
+  };
+
+grub_err_t
+grub_parser_execute (char *source)
+{
+  auto grub_err_t getline (char **line, int cont);
+  grub_err_t getline (char **line, int cont __attribute__ ((unused)))
+    {
+      char *p;
+
+      if (! source)
+	{
+	  *line = 0;
+	  return 0;
+	}
+
+      p = grub_strchr (source, '\n');
+      if (p)
+	*p = 0;
+
+      *line = grub_strdup (source);
+      if (p)
+	*p = '\n';
+      source = p ? p + 1 : 0;
+      return 0;
+    }
+
+  while (source)
+    {
+      char *line;
+      grub_parser_t parser;
+
+      getline (&line, 0);
+      parser = grub_parser_get_current ();
+      parser->parse_line (line, getline);
+      grub_free (line);
+    }
+
+  return grub_errno;
+}
diff --git a/kern/partition.c b/kern/partition.c
new file mode 100644
index 0000000..4d5c63a
--- /dev/null
+++ b/kern/partition.c
@@ -0,0 +1,133 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/partition.h>
+#include <grub/disk.h>
+
+static grub_partition_map_t grub_partition_map_list;
+
+void
+grub_partition_map_register (grub_partition_map_t partmap)
+{
+  partmap->next = grub_partition_map_list;
+  grub_partition_map_list = partmap;
+}
+
+void
+grub_partition_map_unregister (grub_partition_map_t partmap)
+{
+  grub_partition_map_t *p, q;
+
+  for (p = &grub_partition_map_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == partmap)
+      {
+        *p = q->next;
+	break;
+      }
+}
+
+int
+grub_partition_map_iterate (int (*hook) (const grub_partition_map_t partmap))
+{
+  grub_partition_map_t p;
+
+  for (p = grub_partition_map_list; p; p = p->next)
+    if (hook (p))
+      return 1;
+
+  return 0;
+}
+
+grub_partition_t
+grub_partition_probe (struct grub_disk *disk, const char *str)
+{
+  grub_partition_t part = 0;
+
+  auto int part_map_probe (const grub_partition_map_t partmap);
+
+  int part_map_probe (const grub_partition_map_t partmap)
+    {
+      part = partmap->probe (disk, str);
+      if (part)
+	return 1;
+
+      if (grub_errno == GRUB_ERR_BAD_PART_TABLE)
+	{
+	  /* Continue to next partition map type.  */
+	  grub_errno = GRUB_ERR_NONE;
+	  return 0;
+	}
+
+      return 1;
+    }
+
+  /* Use the first partition map type found.  */
+  grub_partition_map_iterate (part_map_probe);
+
+  return part;
+}
+
+int
+grub_partition_iterate (struct grub_disk *disk,
+			int (*hook) (grub_disk_t disk,
+				     const grub_partition_t partition))
+{
+  grub_partition_map_t partmap = 0;
+  int ret = 0;
+
+  auto int part_map_iterate (const grub_partition_map_t p);
+  auto int part_map_iterate_hook (grub_disk_t d,
+				  const grub_partition_t partition);
+
+  int part_map_iterate_hook (grub_disk_t d __attribute__ ((unused)),
+			     const grub_partition_t partition __attribute__ ((unused)))
+    {
+      return 1;
+    }
+
+  int part_map_iterate (const grub_partition_map_t p)
+    {
+      grub_dprintf ("partition", "Detecting %s...\n", p->name);
+      p->iterate (disk, part_map_iterate_hook);
+
+      if (grub_errno != GRUB_ERR_NONE)
+	{
+	  /* Continue to next partition map type.  */
+	  grub_dprintf ("partition", "%s detection failed.\n", p->name);
+	  grub_errno = GRUB_ERR_NONE;
+	  return 0;
+	}
+
+      grub_dprintf ("partition", "%s detection succeeded.\n", p->name);
+      partmap = p;
+      return 1;
+    }
+
+  grub_partition_map_iterate (part_map_iterate);
+  if (partmap)
+    ret = partmap->iterate (disk, hook);
+
+  return ret;
+}
+
+char *
+grub_partition_get_name (const grub_partition_t partition)
+{
+  return partition->partmap->get_name (partition);
+}
diff --git a/kern/powerpc/cache.S b/kern/powerpc/cache.S
new file mode 100644
index 0000000..da982af
--- /dev/null
+++ b/kern/powerpc/cache.S
@@ -0,0 +1,48 @@
+/* cache.S - Flush the processor cache for a specific region.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define CACHE_LINE_BYTES 32
+
+	.text
+
+	.align 2
+	.globl grub_arch_sync_caches
+grub_arch_sync_caches:
+	/* `address' may not be CACHE_LINE_BYTES-aligned.  */
+	andi. 6, 3, CACHE_LINE_BYTES - 1 /* Find the misalignment.  */
+	add 4, 4, 6 /* Adjust `size' to compensate.  */
+
+	/* Force the dcache lines to memory.  */
+	li 5, 0
+1:	dcbst 5, 3
+	addi 5, 5, CACHE_LINE_BYTES
+	cmpw 5, 4
+	blt 1b
+	sync            /* Force all dcbsts to complete.  */
+
+	/* Invalidate the icache lines.  */
+	li 5, 0
+1:	icbi 5, 3
+	addi 5, 5, CACHE_LINE_BYTES
+	cmpw 5, 4
+	blt 1b
+	sync            /* Force all icbis to complete.  */
+	isync           /* Discard partially executed instructions that were
+		           loaded from the invalid icache.  */
+	blr
diff --git a/kern/powerpc/dl.c b/kern/powerpc/dl.c
new file mode 100644
index 0000000..2891b0d
--- /dev/null
+++ b/kern/powerpc/dl.c
@@ -0,0 +1,136 @@
+/* dl.c - arch-dependent part of loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+
+/* Check if EHDR is a valid ELF header.  */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+  if (e->e_ident[EI_CLASS] != ELFCLASS32
+      || e->e_ident[EI_DATA] != ELFDATA2MSB
+      || e->e_machine != EM_PPC)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+  Elf_Shdr *s;
+  Elf_Word entsize;
+  unsigned i;
+
+  /* Find a symbol table.  */
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
+
+  entsize = s->sh_entsize;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_RELA)
+      {
+	grub_dl_segment_t seg;
+
+	/* Find the target segment.  */
+	for (seg = mod->segment; seg; seg = seg->next)
+	  if (seg->section == s->sh_info)
+	    break;
+
+	if (seg)
+	  {
+	    Elf_Rela *rel, *max;
+
+	    for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
+		   max = rel + s->sh_size / s->sh_entsize;
+		 rel < max;
+		 rel++)
+	      {
+		Elf_Word *addr;
+		Elf_Sym *sym;
+		grub_uint32_t value;
+
+		if (seg->size < rel->r_offset)
+		  return grub_error (GRUB_ERR_BAD_MODULE,
+				     "reloc offset is out of the segment");
+
+		addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
+		sym = (Elf_Sym *) ((char *) mod->symtab
+				     + entsize * ELF_R_SYM (rel->r_info));
+
+		/* On the PPC the value does not have an explicit
+		   addend, add it.  */
+		value = sym->st_value + rel->r_addend;
+		switch (ELF_R_TYPE (rel->r_info))
+		  {
+		  case R_PPC_ADDR16_LO:
+		    *(Elf_Half *) addr = value;
+		    break;
+
+		  case R_PPC_REL24:
+		    {
+		      Elf_Sword delta = value - (Elf_Word) addr;
+
+		      if (delta << 6 >> 6 != delta)
+			return grub_error (GRUB_ERR_BAD_MODULE, "Relocation overflow");
+		      *addr = (*addr & 0xfc000003) | (delta & 0x3fffffc);
+		      break;
+		    }
+
+		  case R_PPC_ADDR16_HA:
+		    *(Elf_Half *) addr = (value + 0x8000) >> 16;
+		    break;
+
+		  case R_PPC_ADDR32:
+		    *addr = value;
+		    break;
+
+		  case R_PPC_REL32:
+		    *addr = value - (Elf_Word) addr;
+		    break;
+
+		  default:
+		    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+				       "This relocation (%d) is not implemented yet",
+				       ELF_R_TYPE (rel->r_info));
+		  }
+	      }
+	  }
+      }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/kern/powerpc/ieee1275/startup.S b/kern/powerpc/ieee1275/startup.S
new file mode 100644
index 0000000..75e1ed8
--- /dev/null
+++ b/kern/powerpc/ieee1275/startup.S
@@ -0,0 +1,64 @@
+/* startup.S - Startup code for the PowerPC.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/cpu/kernel.h>
+
+.extern __bss_start
+.extern _end
+
+	.text
+	.align	2
+	.globl	start, _start
+start:
+_start:
+	b	codestart
+
+	. = _start + GRUB_KERNEL_CPU_PREFIX
+
+VARIABLE(grub_prefix)
+	/* to be filled by grub-mkelfimage */
+
+	/*
+	 *  Leave some breathing room for the prefix.
+	 */
+
+	. = _start + GRUB_KERNEL_CPU_DATA_END
+
+codestart:
+	li      2, 0
+	li      13, 0
+
+	/* Stage1 won't zero BSS for us. In other cases, why not do it again?  */
+	lis	6, (__bss_start - 4)@h
+	ori	6, 6, (__bss_start - 4)@l
+	lis	7, (_end - 4)@h
+	ori	7, 7, (_end - 4)@l
+	subf	7, 6, 7
+	srwi	7, 7, 2 /* We store 4 bytes at a time.  */
+	mtctr	7
+2:	stwu	2, 4(6) /* We know r2 is already 0 from above.  */
+	bdnz	2b
+
+	/* Store r5 in grub_ieee1275_entry_fn.  */
+	lis	9, grub_ieee1275_entry_fn@ha
+	stw	5, grub_ieee1275_entry_fn@l(9)
+
+	bl	grub_main
+1:	b	1b
diff --git a/kern/reader.c b/kern/reader.c
new file mode 100644
index 0000000..271a90f
--- /dev/null
+++ b/kern/reader.c
@@ -0,0 +1,49 @@
+/* reader.c - reader support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/reader.h>
+#include <grub/parser.h>
+
+struct grub_handler_class grub_reader_class =
+  {
+    .name = "reader"
+  };
+
+grub_err_t
+grub_reader_loop (grub_reader_getline_t getline)
+{
+  while (1)
+    {
+      char *line;
+      grub_reader_getline_t func;
+
+      /* Print an error, if any.  */
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+
+      func = (getline) ? : grub_reader_get_current ()->read_line;
+      if ((func (&line, 0)) || (! line))
+	return grub_errno;
+
+      grub_parser_get_current ()->parse_line (line, func);
+      grub_free (line);
+    }
+}
diff --git a/kern/rescue_parser.c b/kern/rescue_parser.c
new file mode 100644
index 0000000..1e0841e
--- /dev/null
+++ b/kern/rescue_parser.c
@@ -0,0 +1,85 @@
+/* rescue_parser.c - rescue mode parser  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/parser.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+
+static grub_err_t
+grub_rescue_parse_line (char *line, grub_reader_getline_t getline)
+{
+  char *name;
+  int n;
+  grub_command_t cmd;
+  char **args;
+
+  if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0)
+    return grub_errno;
+
+  /* In case of an assignment set the environment accordingly
+     instead of calling a function.  */
+  if (n == 0 && grub_strchr (line, '='))
+    {
+      char *val = grub_strchr (args[0], '=');
+      val[0] = 0;
+      grub_env_set (args[0], val + 1);
+      val[0] = '=';
+      goto quit;
+    }
+
+  /* Get the command name.  */
+  name = args[0];
+
+  /* If nothing is specified, restart.  */
+  if (*name == '\0')
+    goto quit;
+
+  cmd = grub_command_find (name);
+  if (cmd)
+    {
+      (cmd->func) (cmd, n, &args[1]);
+    }
+  else
+    {
+      grub_printf ("Unknown command `%s'\n", name);
+      if (grub_command_find ("help"))
+	grub_printf ("Try `help' for usage\n");
+    }
+
+ quit:
+  grub_free (args[0]);
+  grub_free (args);
+
+  return grub_errno;
+}
+
+static struct grub_parser grub_rescue_parser =
+  {
+    .name = "rescue",
+    .parse_line = grub_rescue_parse_line
+  };
+
+void
+grub_register_rescue_parser (void)
+{
+  grub_parser_register ("rescue", &grub_rescue_parser);
+}
diff --git a/kern/rescue_reader.c b/kern/rescue_reader.c
new file mode 100644
index 0000000..2a06f3f
--- /dev/null
+++ b/kern/rescue_reader.c
@@ -0,0 +1,88 @@
+/* rescue_reader.c - rescue mode reader  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/reader.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+
+#define GRUB_RESCUE_BUF_SIZE	256
+
+static char linebuf[GRUB_RESCUE_BUF_SIZE];
+
+static grub_err_t
+grub_rescue_init (void)
+{
+  grub_printf ("Entering rescue mode...\n");
+  return 0;
+}
+
+/* Prompt to input a command and read the line.  */
+static grub_err_t
+grub_rescue_read_line (char **line, int cont)
+{
+  int c;
+  int pos = 0;
+
+  grub_printf ((cont) ? "> " : "grub rescue> ");
+  grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE);
+
+  while ((c = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && c != '\r')
+    {
+      if (grub_isprint (c))
+	{
+	  if (pos < GRUB_RESCUE_BUF_SIZE - 1)
+	    {
+	      linebuf[pos++] = c;
+	      grub_putchar (c);
+	    }
+	}
+      else if (c == '\b')
+	{
+	  if (pos > 0)
+	    {
+	      linebuf[--pos] = 0;
+	      grub_putchar (c);
+	      grub_putchar (' ');
+	      grub_putchar (c);
+	    }
+	}
+      grub_refresh ();
+    }
+
+  grub_putchar ('\n');
+  grub_refresh ();
+
+  *line = grub_strdup (linebuf);
+
+  return 0;
+}
+
+static struct grub_reader grub_rescue_reader =
+  {
+    .name = "rescue",
+    .init = grub_rescue_init,
+    .read_line = grub_rescue_read_line
+  };
+
+void
+grub_register_rescue_reader (void)
+{
+  grub_reader_register ("rescue", &grub_rescue_reader);
+}
diff --git a/kern/sparc64/cache.S b/kern/sparc64/cache.S
new file mode 100644
index 0000000..1a16add
--- /dev/null
+++ b/kern/sparc64/cache.S
@@ -0,0 +1,41 @@
+/* cache.S - Flush the processor cache for a specific region.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+        .file   "cache.S"
+
+        .text
+
+/*
+ * void grub_arch_sync_caches (void *address, grub_size_t len)
+ */
+FUNCTION(grub_arch_sync_caches)
+	brz,pn		%o1, 2f
+	 add		%o0, %o1, %o1
+	add		%o1, 7, %o1
+	andn		%o1, 7, %o1
+	andn		%o0, 7, %o0
+	sub		%o1, %o0, %o1
+1:	subcc		%o1, 8, %o1
+	bne,pt		%icc, 1b
+	 flush		%o0 + %o1
+2:	retl
+	 nop
+
diff --git a/kern/sparc64/dl.c b/kern/sparc64/dl.c
new file mode 100644
index 0000000..a4d99ff
--- /dev/null
+++ b/kern/sparc64/dl.c
@@ -0,0 +1,142 @@
+/* dl.c - arch-dependent part of loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+
+/* Check if EHDR is a valid ELF header.  */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+  if (e->e_ident[EI_CLASS] != ELFCLASS64
+      || e->e_ident[EI_DATA] != ELFDATA2MSB
+      || e->e_machine != EM_SPARCV9)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+  Elf_Shdr *s;
+  Elf_Word entsize;
+  unsigned i;
+
+  /* Find a symbol table.  */
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
+
+  entsize = s->sh_entsize;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_RELA)
+      {
+	grub_dl_segment_t seg;
+
+	/* Find the target segment.  */
+	for (seg = mod->segment; seg; seg = seg->next)
+	  if (seg->section == s->sh_info)
+	    break;
+
+	if (seg)
+	  {
+	    Elf_Rela *rel, *max;
+
+	    for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
+		   max = rel + s->sh_size / s->sh_entsize;
+		 rel < max;
+		 rel++)
+	      {
+		Elf_Word *addr;
+		Elf_Sym *sym;
+		Elf_Addr value;
+
+		if (seg->size < rel->r_offset)
+		  return grub_error (GRUB_ERR_BAD_MODULE,
+				     "reloc offset is out of the segment");
+
+		addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
+		sym = (Elf_Sym *) ((char *) mod->symtab
+				     + entsize * ELF_R_SYM (rel->r_info));
+
+		value = sym->st_value + rel->r_addend;
+		switch (ELF_R_TYPE (rel->r_info) & 0xff)
+		  {
+                  case R_SPARC_32: /* 3 V-word32 */
+                    if (value & 0xFFFFFFFF00000000)
+                      return grub_error (GRUB_ERR_BAD_MODULE,
+                                         "Address out of 32 bits range");
+                    *addr = value;
+                    break;
+                  case R_SPARC_WDISP30: /* 7 V-disp30 */
+                    if (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000) &&
+                        (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000)
+			 != 0xFFFFFFFF00000000))
+                      return grub_error (GRUB_ERR_BAD_MODULE,
+                                         "Displacement out of 30 bits range");
+                    *addr = (*addr & 0xC0000000) |
+                      (((grub_int32_t) ((value - (Elf_Addr) addr) >> 2)) &
+                       0x3FFFFFFF);
+                    break;
+                  case R_SPARC_HI22: /* 9 V-imm22 */
+                    if (((grub_int32_t) value) & 0xFF00000000)
+                      return grub_error (GRUB_ERR_BAD_MODULE,
+                                         "High address out of 22 bits range");
+                    *addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF);
+                    break;
+                  case R_SPARC_LO10: /* 12 T-simm13 */
+                    *addr = (*addr & 0xFFFFFC00) | (value & 0x3FF);
+                    break;
+                  case R_SPARC_64: /* 32 V-xwords64 */
+                    *(Elf_Xword *) addr = value;
+                    break;
+		  case R_SPARC_OLO10:
+		    *addr = (*addr & ~0x1fff)
+		      | (((value & 0x3ff) +
+			  (ELF_R_TYPE (rel->r_info) >> 8))
+			 & 0x1fff);
+		    break;
+		  default:
+		    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+				       "This relocation (%d) is not implemented yet",
+				       ELF_R_TYPE (rel->r_info));
+		  }
+	      }
+	  }
+      }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/kern/sparc64/ieee1275/crt0.S b/kern/sparc64/ieee1275/crt0.S
new file mode 100644
index 0000000..4e67cbc
--- /dev/null
+++ b/kern/sparc64/ieee1275/crt0.S
@@ -0,0 +1,77 @@
+/* crt0.S - Startup code for the Sparc64.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <grub/symbol.h>
+#include <grub/machine/kernel.h>
+
+	.text
+	.align	4
+	.globl	_start
+_start:
+	ba	codestart
+	 nop
+
+	. = EXT_C(_start) + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
+
+VARIABLE(grub_total_module_size)
+	.word	0
+VARIABLE(grub_kernel_image_size)
+	.word	0
+VARIABLE(grub_compressed_size)
+	.word	0
+VARIABLE(grub_prefix)
+	/* to be filled by grub-mkimage */
+
+	/*
+	 *  Leave some breathing room for the prefix.
+	 */
+
+	. = EXT_C(_start) + GRUB_KERNEL_MACHINE_DATA_END
+
+codestart:
+	/* Copy the modules past the end of the kernel image.
+	 * They are currently sitting in the BSS.
+	 */
+	sethi	%hi(__bss_start), %o2
+	or	%o2, %lo(__bss_start), %o2
+	sethi	%hi(_end), %o3
+	or	%o3, %lo(_end), %o3
+	sethi	%hi(grub_total_module_size), %o4
+	lduw	[%o4 + %lo(grub_total_module_size)], %o4
+1:	lduw	[%o2], %o5
+	stw	%o5, [%o3]
+	subcc	%o4, 4, %o4
+	add	%o2, 4, %o2
+	bne,pt	%icc, 1b
+	 add	%o3, 4, %o3
+
+	/* Now it's safe to clear out the BSS.  */
+	sethi	%hi(__bss_start), %o2
+	or	%o2, %lo(__bss_start), %o2
+	sethi	%hi(_end), %o3
+	or	%o3, %lo(_end), %o3
+1:	stx	%g0, [%o2]
+	add	%o2, 8, %o2
+	cmp	%o2, %o3
+	blt,pt	%xcc, 1b
+	 nop
+	sethi	%hi(grub_ieee1275_entry_fn), %o2
+	stx	%o0, [%o2 + %lo(grub_ieee1275_entry_fn)]
+	call	grub_main
+	 nop
+1:	ba,a	1b
diff --git a/kern/sparc64/ieee1275/ieee1275.c b/kern/sparc64/ieee1275/ieee1275.c
new file mode 100644
index 0000000..438a171
--- /dev/null
+++ b/kern/sparc64/ieee1275/ieee1275.c
@@ -0,0 +1,124 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/types.h>
+
+/* Sun specific ieee1275 interfaces used by GRUB.  */
+
+int
+grub_ieee1275_map_physical (grub_addr_t paddr, grub_addr_t vaddr,
+			    grub_size_t size, grub_uint32_t mode)
+{
+  struct map_physical_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t method;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t mode;
+    grub_ieee1275_cell_t size;
+    grub_ieee1275_cell_t virt;
+    grub_ieee1275_cell_t phys_high;
+    grub_ieee1275_cell_t phys_low;
+    grub_ieee1275_cell_t catch_result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 7, 1);
+  args.method = (grub_ieee1275_cell_t) "map";
+  args.ihandle = grub_ieee1275_mmu;
+  args.mode = mode;
+  args.size = size;
+  args.virt = vaddr;
+  args.phys_high = 0;
+  args.phys_low = paddr;
+  args.catch_result = (grub_ieee1275_cell_t) -1;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  return args.catch_result;
+}
+
+int
+grub_ieee1275_claim_vaddr (grub_addr_t vaddr, grub_size_t size)
+{
+  struct claim_vaddr_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t method;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t align;
+    grub_ieee1275_cell_t size;
+    grub_ieee1275_cell_t virt;
+    grub_ieee1275_cell_t catch_result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 5, 2);
+  args.method = (grub_ieee1275_cell_t) "claim";
+  args.ihandle = grub_ieee1275_mmu;
+  args.align = 0;
+  args.size = size;
+  args.virt = vaddr;
+  args.catch_result = (grub_ieee1275_cell_t) -1;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  return args.catch_result;
+}
+
+int
+grub_ieee1275_alloc_physmem (grub_addr_t *paddr, grub_size_t size,
+			     grub_uint32_t align)
+{
+  grub_uint32_t memory_ihandle;
+  struct alloc_physmem_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t method;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t align;
+    grub_ieee1275_cell_t size;
+    grub_ieee1275_cell_t catch_result;
+    grub_ieee1275_cell_t phys_high;
+    grub_ieee1275_cell_t phys_low;
+  }
+  args;
+  grub_ssize_t actual = 0;
+
+  grub_ieee1275_get_property (grub_ieee1275_chosen, "memory",
+			      &memory_ihandle, sizeof (memory_ihandle),
+			      &actual);
+  if (actual != sizeof (memory_ihandle))
+    return -1;
+
+  if (!align)
+    align = 1;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 3);
+  args.method = (grub_ieee1275_cell_t) "claim";
+  args.ihandle = memory_ihandle;
+  args.align = (align ? align : 1);
+  args.size = size;
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+
+  *paddr = args.phys_low;
+
+  return args.catch_result;
+}
diff --git a/kern/sparc64/ieee1275/init.c b/kern/sparc64/ieee1275/init.c
new file mode 100644
index 0000000..699f963
--- /dev/null
+++ b/kern/sparc64/ieee1275/init.c
@@ -0,0 +1,172 @@
+/*  init.c -- Initialize GRUB on SPARC64.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/time.h>
+#include <grub/machine/console.h>
+#include <grub/machine/kernel.h>
+#include <grub/machine/time.h>
+#include <grub/ieee1275/ofdisk.h>
+#include <grub/ieee1275/ieee1275.h>
+
+void
+grub_exit (void)
+{
+  grub_ieee1275_exit ();
+}
+
+static grub_uint64_t
+ieee1275_get_time_ms (void)
+{
+  grub_uint32_t msecs = 0;
+
+  grub_ieee1275_milliseconds (&msecs);
+
+  return msecs;
+}
+
+grub_uint32_t
+grub_get_rtc (void)
+{
+  return ieee1275_get_time_ms ();
+}
+
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  extern char _end[];
+  return (grub_addr_t) _end;
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  if (grub_prefix[0] != '(')
+    {
+      char bootpath[IEEE1275_MAX_PATH_LEN];
+      char *prefix, *path, *colon;
+      grub_ssize_t actual;
+
+      if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath",
+				      &bootpath, sizeof (bootpath), &actual))
+	{
+	  /* Should never happen.  */
+	  grub_printf ("/chosen/bootpath property missing!\n");
+	  grub_env_set ("prefix", "");
+	  return;
+	}
+
+      /* Transform an OF device path to a GRUB path.  */
+      colon = grub_strchr (bootpath, ':');
+      if (colon)
+	{
+	  char *part = colon + 1;
+
+	  /* Consistently provide numbered partitions to GRUB.
+	     OpenBOOT traditionally uses alphabetical partition
+	     specifiers.  */
+	  if (part[0] >= 'a' && part[0] <= 'z')
+	    part[0] = '1' + (part[0] - 'a');
+	}
+      prefix = grub_ieee1275_encode_devname (bootpath);
+
+      path = grub_malloc (grub_strlen (grub_prefix)
+			  + grub_strlen (prefix)
+			  + 2);
+      grub_sprintf(path, "%s%s", prefix, grub_prefix);
+
+      grub_strcpy (grub_prefix, path);
+
+      grub_free (path);
+      grub_free (prefix);
+    }
+
+  grub_env_set ("prefix", grub_prefix);
+}
+
+static void
+grub_heap_init (void)
+{
+  grub_mm_init_region ((void *)(long)0x4000UL, 0x200000 - 0x4000);
+}
+
+static void
+grub_parse_cmdline (void)
+{
+  grub_ssize_t actual;
+  char args[256];
+
+  if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
+				  sizeof args, &actual) == 0
+      && actual > 1)
+    {
+      int i = 0;
+
+      while (i < actual)
+	{
+	  char *command = &args[i];
+	  char *end;
+	  char *val;
+
+	  end = grub_strchr (command, ';');
+	  if (end == 0)
+	    i = actual; /* No more commands after this one.  */
+	  else
+	    {
+	      *end = '\0';
+	      i += end - command + 1;
+	      while (grub_isspace(args[i]))
+		i++;
+	    }
+
+	  /* Process command.  */
+	  val = grub_strchr (command, '=');
+	  if (val)
+	    {
+	      *val = '\0';
+	      grub_env_set (command, val + 1);
+	    }
+	}
+    }
+}
+
+void
+grub_machine_init (void)
+{
+  grub_ieee1275_init ();
+  grub_console_init ();
+  grub_heap_init ();
+
+  grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
+  grub_ofdisk_init ();
+
+  grub_parse_cmdline ();
+  grub_install_get_time_ms (ieee1275_get_time_ms);
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_ofdisk_fini ();
+  grub_console_fini ();
+}
diff --git a/kern/term.c b/kern/term.c
new file mode 100644
index 0000000..94d5a9e
--- /dev/null
+++ b/kern/term.c
@@ -0,0 +1,239 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+
+/* The amount of lines counted by the pager.  */
+static int grub_more_lines;
+
+/* If the more pager is active.  */
+static int grub_more;
+
+/* The current cursor state.  */
+static int cursor_state = 1;
+
+struct grub_handler_class grub_term_input_class =
+  {
+    .name = "terminal_input"
+  };
+
+struct grub_handler_class grub_term_output_class =
+  {
+    .name = "terminal_output"
+  };
+
+#define grub_cur_term_input	grub_term_get_current_input ()
+#define grub_cur_term_output	grub_term_get_current_output ()
+
+/* Put a Unicode character.  */
+void
+grub_putcode (grub_uint32_t code)
+{
+  int height = grub_getwh () & 255;
+
+  if (code == '\t' && grub_cur_term_output->getxy)
+    {
+      int n;
+
+      n = 8 - ((grub_getxy () >> 8) & 7);
+      while (n--)
+	grub_putcode (' ');
+
+      return;
+    }
+
+  (grub_cur_term_output->putchar) (code);
+
+  if (code == '\n')
+    {
+      grub_putcode ('\r');
+
+      grub_more_lines++;
+
+      if (grub_more && grub_more_lines == height - 1)
+	{
+	  char key;
+	  int pos = grub_getxy ();
+
+	  /* Show --MORE-- on the lower left side of the screen.  */
+	  grub_gotoxy (1, height - 1);
+	  grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
+	  grub_printf ("--MORE--");
+	  grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
+
+	  key = grub_getkey ();
+
+	  /* Remove the message.  */
+	  grub_gotoxy (1, height - 1);
+	  grub_printf ("        ");
+	  grub_gotoxy (pos >> 8, pos & 0xFF);
+
+	  /* Scroll one lines or an entire page, depending on the key.  */
+	  if (key == '\r' || key =='\n')
+	    grub_more_lines--;
+	  else
+	    grub_more_lines = 0;
+	}
+    }
+}
+
+/* Put a character. C is one byte of a UTF-8 stream.
+   This function gathers bytes until a valid Unicode character is found.  */
+void
+grub_putchar (int c)
+{
+  static grub_size_t size = 0;
+  static grub_uint8_t buf[6];
+  grub_uint32_t code;
+  grub_ssize_t ret;
+
+  buf[size++] = c;
+  ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0);
+
+  if (ret > 0)
+    {
+      size = 0;
+      grub_putcode (code);
+    }
+  else if (ret < 0)
+    {
+      size = 0;
+      grub_putcode ('?');
+    }
+}
+
+/* Return the number of columns occupied by the character code CODE.  */
+grub_ssize_t
+grub_getcharwidth (grub_uint32_t code)
+{
+  return (grub_cur_term_output->getcharwidth) (code);
+}
+
+int
+grub_getkey (void)
+{
+  return (grub_cur_term_input->getkey) ();
+}
+
+int
+grub_checkkey (void)
+{
+  return (grub_cur_term_input->checkkey) ();
+}
+
+int
+grub_getkeystatus (void)
+{
+  if (grub_cur_term_input->getkeystatus)
+    return (grub_cur_term_input->getkeystatus) ();
+  else
+    return 0;
+}
+
+grub_uint16_t
+grub_getxy (void)
+{
+  return (grub_cur_term_output->getxy) ();
+}
+
+grub_uint16_t
+grub_getwh (void)
+{
+  return (grub_cur_term_output->getwh) ();
+}
+
+void
+grub_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  (grub_cur_term_output->gotoxy) (x, y);
+}
+
+void
+grub_cls (void)
+{
+  if ((grub_cur_term_output->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
+    {
+      grub_putchar ('\n');
+      grub_refresh ();
+    }
+  else
+    (grub_cur_term_output->cls) ();
+}
+
+void
+grub_setcolorstate (grub_term_color_state state)
+{
+  if (grub_cur_term_output->setcolorstate)
+    (grub_cur_term_output->setcolorstate) (state);
+}
+
+void
+grub_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
+{
+  if (grub_cur_term_output->setcolor)
+    (grub_cur_term_output->setcolor) (normal_color, highlight_color);
+}
+
+void
+grub_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
+{
+  if (grub_cur_term_output->getcolor)
+    (grub_cur_term_output->getcolor) (normal_color, highlight_color);
+}
+
+int
+grub_setcursor (int on)
+{
+  int ret = cursor_state;
+
+  if (grub_cur_term_output->setcursor)
+    {
+      (grub_cur_term_output->setcursor) (on);
+      cursor_state = on;
+    }
+
+  return ret;
+}
+
+int
+grub_getcursor (void)
+{
+  return cursor_state;
+}
+
+void
+grub_refresh (void)
+{
+  if (grub_cur_term_output->refresh)
+    (grub_cur_term_output->refresh) ();
+}
+
+void
+grub_set_more (int onoff)
+{
+  if (onoff == 1)
+    grub_more++;
+  else
+    grub_more--;
+
+  grub_more_lines = 0;
+}
diff --git a/kern/time.c b/kern/time.c
new file mode 100644
index 0000000..6521ec6
--- /dev/null
+++ b/kern/time.c
@@ -0,0 +1,37 @@
+/* time.c - kernel time functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/time.h>
+
+typedef grub_uint64_t (*get_time_ms_func_t) (void);
+
+/* Function pointer to the implementation in use.  */
+static get_time_ms_func_t get_time_ms_func;
+
+grub_uint64_t
+grub_get_time_ms (void)
+{
+  return get_time_ms_func ();
+}
+
+void
+grub_install_get_time_ms (get_time_ms_func_t func)
+{
+  get_time_ms_func = func;
+}
diff --git a/kern/x86_64/dl.c b/kern/x86_64/dl.c
new file mode 100644
index 0000000..73a7337
--- /dev/null
+++ b/kern/x86_64/dl.c
@@ -0,0 +1,119 @@
+/* dl-x86_64.c - arch-dependent part of loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+
+/* Check if EHDR is a valid ELF header.  */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  Elf64_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+  if (e->e_ident[EI_CLASS] != ELFCLASS64
+      || e->e_ident[EI_DATA] != ELFDATA2LSB
+      || e->e_machine != EM_X86_64)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  Elf64_Ehdr *e = ehdr;
+  Elf64_Shdr *s;
+  Elf64_Word entsize;
+  unsigned i;
+
+  /* Find a symbol table.  */
+  for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
+
+  entsize = s->sh_entsize;
+
+  for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_RELA)
+      {
+	grub_dl_segment_t seg;
+
+	/* Find the target segment.  */
+	for (seg = mod->segment; seg; seg = seg->next)
+	  if (seg->section == s->sh_info)
+	    break;
+
+	if (seg)
+	  {
+	    Elf64_Rela *rel, *max;
+
+	    for (rel = (Elf64_Rela *) ((char *) e + s->sh_offset),
+		   max = rel + s->sh_size / s->sh_entsize;
+		 rel < max;
+		 rel++)
+	      {
+		Elf64_Word *addr32;
+		Elf64_Xword *addr64;
+		Elf64_Sym *sym;
+
+		if (seg->size < rel->r_offset)
+		  return grub_error (GRUB_ERR_BAD_MODULE,
+				     "reloc offset is out of the segment");
+
+		addr32 = (Elf64_Word *) ((char *) seg->addr + rel->r_offset);
+		addr64 = (Elf64_Xword *) addr32;
+		sym = (Elf64_Sym *) ((char *) mod->symtab
+				     + entsize * ELF_R_SYM (rel->r_info));
+
+		switch (ELF_R_TYPE (rel->r_info))
+		  {
+		  case R_X86_64_64:
+		    *addr64 += rel->r_addend + sym->st_value;
+		    break;
+
+		  case R_X86_64_PC32:
+		    *addr32 += rel->r_addend + sym->st_value -
+		              (Elf64_Xword) seg->addr - rel->r_offset;
+		    break;
+
+                  case R_X86_64_32:
+                  case R_X86_64_32S:
+                    *addr32 += rel->r_addend + sym->st_value;
+                    break;
+
+                  default:
+                    grub_fatal ("Unrecognized relocation: %d\n", ELF_R_TYPE (rel->r_info));
+		  }
+	      }
+	  }
+      }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/kern/x86_64/efi/callwrap.S b/kern/x86_64/efi/callwrap.S
new file mode 100644
index 0000000..1946732
--- /dev/null
+++ b/kern/x86_64/efi/callwrap.S
@@ -0,0 +1,116 @@
+/* callwrap.S - wrapper for x86_64 efi calls */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/boot.h>
+
+/*
+ * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use
+ * different call conversion, so we need to do some conversion.
+ *
+ * gcc:
+ *   %rdi,  %esi,  %rdx,  %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ...
+ *
+ * efi:
+ *   %rcx,  %rdx,  %r8,  %r9,  32(%rsp), 40(%rsp), 48(%rsp), ...
+ *
+ */
+
+        .file   "callwrap.S"
+        .text
+
+FUNCTION(efi_wrap_0)
+	subq $40, %rsp
+	call *%rdi
+	addq $40, %rsp
+	ret
+
+FUNCTION(efi_wrap_1)
+	subq $40, %rsp
+	mov  %rsi, %rcx
+	call *%rdi
+	addq $40, %rsp
+	ret
+
+FUNCTION(efi_wrap_2)
+	subq $40, %rsp
+	mov  %rsi, %rcx
+	call *%rdi
+	addq $40, %rsp
+	ret
+
+FUNCTION(efi_wrap_3)
+	subq $40, %rsp
+	mov  %rcx, %r8
+	mov  %rsi, %rcx
+	call *%rdi
+	addq $40, %rsp
+	ret
+
+FUNCTION(efi_wrap_4)
+	subq $40, %rsp
+	mov %r8, %r9
+	mov %rcx, %r8
+	mov %rsi, %rcx
+	call *%rdi
+	addq $40, %rsp
+	ret
+
+FUNCTION(efi_wrap_5)
+	subq $40, %rsp
+	mov %r9, 32(%rsp)
+	mov %r8, %r9
+	mov %rcx, %r8
+	mov %rsi, %rcx
+	call *%rdi
+	addq $40, %rsp
+	ret
+
+FUNCTION(efi_wrap_6)
+	subq $56, %rsp
+	mov 56+8(%rsp), %rax
+	mov %rax, 40(%rsp)
+	mov %r9, 32(%rsp)
+	mov %r8, %r9
+	mov %rcx, %r8
+	mov %rsi, %rcx
+	call *%rdi
+	addq $56, %rsp
+	ret
+
+FUNCTION(efi_wrap_10)
+	subq $88, %rsp
+	mov 88+40(%rsp), %rax
+	mov %rax, 72(%rsp)
+	mov 88+32(%rsp), %rax
+	mov %rax, 64(%rsp)
+	mov 88+24(%rsp), %rax
+	mov %rax, 56(%rsp)
+	mov 88+16(%rsp), %rax
+	mov %rax, 48(%rsp)
+	mov 88+8(%rsp), %rax
+	mov %rax, 40(%rsp)
+	mov %r9, 32(%rsp)
+	mov %r8, %r9
+	mov %rcx, %r8
+	mov %rsi, %rcx
+	call *%rdi
+	addq $88, %rsp
+	ret
diff --git a/kern/x86_64/efi/startup.S b/kern/x86_64/efi/startup.S
new file mode 100644
index 0000000..fb4fc7b
--- /dev/null
+++ b/kern/x86_64/efi/startup.S
@@ -0,0 +1,63 @@
+/* startup.S - bootstrap GRUB itself */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/boot.h>
+
+        .file   "startup.S"
+        .text
+        .globl  start, _start
+        .code64
+
+start:
+_start:
+	jmp codestart
+
+        /*
+         *  Compatibility version number
+         *
+         *  These MUST be at byte offset 6 and 7 of the executable
+         *  DO NOT MOVE !!!
+         */
+        . = _start + 0x6
+        .byte   GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
+
+        /*
+         *  This is a special data area 8 bytes from the beginning.
+         */
+
+        . = _start + 0x8
+
+VARIABLE(grub_prefix)
+	/* to be filled by grub-mkimage */
+
+        /*
+         *  Leave some breathing room for the prefix.
+         */
+
+        . = _start + 0x50
+
+codestart:
+	movq	%rcx, EXT_C(grub_efi_image_handle)(%rip)
+	movq	%rdx, EXT_C(grub_efi_system_table)(%rip)
+
+	call	EXT_C(grub_main)
+	ret
+
diff --git a/lib/LzFind.c b/lib/LzFind.c
new file mode 100644
index 0000000..cd7a1cb
--- /dev/null
+++ b/lib/LzFind.c
@@ -0,0 +1,774 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#include <string.h>
+
+#include <grub/lib/LzFind.h>
+#include <grub/lib/LzHash.h>
+
+#define kEmptyHashValue 0
+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
+#define kNormalizeMask (~(kNormalizeStepMin - 1))
+#define kMaxHistorySize ((UInt32)3 << 30)
+
+#define kStartMaxLen 3
+
+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+  if (!p->directInput)
+  {
+    alloc->Free(alloc, p->bufferBase);
+    p->bufferBase = 0;
+  }
+}
+
+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
+
+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
+{
+  UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
+  if (p->directInput)
+  {
+    p->blockSize = blockSize;
+    return 1;
+  }
+  if (p->bufferBase == 0 || p->blockSize != blockSize)
+  {
+    LzInWindow_Free(p, alloc);
+    p->blockSize = blockSize;
+    p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
+  }
+  return (p->bufferBase != 0);
+}
+
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
+
+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
+
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
+{
+  p->posLimit -= subValue;
+  p->pos -= subValue;
+  p->streamPos -= subValue;
+}
+
+static void MatchFinder_ReadBlock(CMatchFinder *p)
+{
+  if (p->streamEndWasReached || p->result != SZ_OK)
+    return;
+  for (;;)
+  {
+    Byte *dest = p->buffer + (p->streamPos - p->pos);
+    size_t size = (p->bufferBase + p->blockSize - dest);
+    if (size == 0)
+      return;
+    p->result = p->stream->Read(p->stream, dest, &size);
+    if (p->result != SZ_OK)
+      return;
+    if (size == 0)
+    {
+      p->streamEndWasReached = 1;
+      return;
+    }
+    p->streamPos += (UInt32)size;
+    if (p->streamPos - p->pos > p->keepSizeAfter)
+      return;
+  }
+}
+
+void MatchFinder_MoveBlock(CMatchFinder *p)
+{
+  memmove(p->bufferBase,
+    p->buffer - p->keepSizeBefore,
+    (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
+  p->buffer = p->bufferBase + p->keepSizeBefore;
+}
+
+int MatchFinder_NeedMove(CMatchFinder *p)
+{
+  /* if (p->streamEndWasReached) return 0; */
+  return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
+}
+
+void MatchFinder_ReadIfRequired(CMatchFinder *p)
+{
+  if (p->streamEndWasReached)
+    return;
+  if (p->keepSizeAfter >= p->streamPos - p->pos)
+    MatchFinder_ReadBlock(p);
+}
+
+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
+{
+  if (MatchFinder_NeedMove(p))
+    MatchFinder_MoveBlock(p);
+  MatchFinder_ReadBlock(p);
+}
+
+static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
+{
+  p->cutValue = 32;
+  p->btMode = 1;
+  p->numHashBytes = 4;
+  /* p->skipModeBits = 0; */
+  p->directInput = 0;
+  p->bigHash = 0;
+}
+
+#define kCrcPoly 0xEDB88320
+
+void MatchFinder_Construct(CMatchFinder *p)
+{
+  UInt32 i;
+  p->bufferBase = 0;
+  p->directInput = 0;
+  p->hash = 0;
+  MatchFinder_SetDefaultSettings(p);
+
+  for (i = 0; i < 256; i++)
+  {
+    UInt32 r = i;
+    int j;
+    for (j = 0; j < 8; j++)
+      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+    p->crc[i] = r;
+  }
+}
+
+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->hash);
+  p->hash = 0;
+}
+
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+  MatchFinder_FreeThisClassMemory(p, alloc);
+  LzInWindow_Free(p, alloc);
+}
+
+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
+{
+  size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
+  if (sizeInBytes / sizeof(CLzRef) != num)
+    return 0;
+  return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
+}
+
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+    ISzAlloc *alloc)
+{
+  UInt32 sizeReserv;
+  if (historySize > kMaxHistorySize)
+  {
+    MatchFinder_Free(p, alloc);
+    return 0;
+  }
+  sizeReserv = historySize >> 1;
+  if (historySize > ((UInt32)2 << 30))
+    sizeReserv = historySize >> 2;
+  sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
+
+  p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
+  p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
+  /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
+  if (LzInWindow_Create(p, sizeReserv, alloc))
+  {
+    UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
+    UInt32 hs;
+    p->matchMaxLen = matchMaxLen;
+    {
+      p->fixedHashSize = 0;
+      if (p->numHashBytes == 2)
+        hs = (1 << 16) - 1;
+      else
+      {
+        hs = historySize - 1;
+        hs |= (hs >> 1);
+        hs |= (hs >> 2);
+        hs |= (hs >> 4);
+        hs |= (hs >> 8);
+        hs >>= 1;
+        /* hs >>= p->skipModeBits; */
+        hs |= 0xFFFF; /* don't change it! It's required for Deflate */
+        if (hs > (1 << 24))
+        {
+          if (p->numHashBytes == 3)
+            hs = (1 << 24) - 1;
+          else
+            hs >>= 1;
+        }
+      }
+      p->hashMask = hs;
+      hs++;
+      if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
+      if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
+      if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
+      hs += p->fixedHashSize;
+    }
+
+    {
+      UInt32 prevSize = p->hashSizeSum + p->numSons;
+      UInt32 newSize;
+      p->historySize = historySize;
+      p->hashSizeSum = hs;
+      p->cyclicBufferSize = newCyclicBufferSize;
+      p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
+      newSize = p->hashSizeSum + p->numSons;
+      if (p->hash != 0 && prevSize == newSize)
+        return 1;
+      MatchFinder_FreeThisClassMemory(p, alloc);
+      p->hash = AllocRefs(newSize, alloc);
+      if (p->hash != 0)
+      {
+        p->son = p->hash + p->hashSizeSum;
+        return 1;
+      }
+    }
+  }
+  MatchFinder_Free(p, alloc);
+  return 0;
+}
+
+static void MatchFinder_SetLimits(CMatchFinder *p)
+{
+  UInt32 limit = kMaxValForNormalize - p->pos;
+  UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
+  if (limit2 < limit)
+    limit = limit2;
+  limit2 = p->streamPos - p->pos;
+  if (limit2 <= p->keepSizeAfter)
+  {
+    if (limit2 > 0)
+      limit2 = 1;
+  }
+  else
+    limit2 -= p->keepSizeAfter;
+  if (limit2 < limit)
+    limit = limit2;
+  {
+    UInt32 lenLimit = p->streamPos - p->pos;
+    if (lenLimit > p->matchMaxLen)
+      lenLimit = p->matchMaxLen;
+    p->lenLimit = lenLimit;
+  }
+  p->posLimit = p->pos + limit;
+}
+
+void MatchFinder_Init(CMatchFinder *p)
+{
+  UInt32 i;
+  for(i = 0; i < p->hashSizeSum; i++)
+    p->hash[i] = kEmptyHashValue;
+  p->cyclicBufferPos = 0;
+  p->buffer = p->bufferBase;
+  p->pos = p->streamPos = p->cyclicBufferSize;
+  p->result = SZ_OK;
+  p->streamEndWasReached = 0;
+  MatchFinder_ReadBlock(p);
+  MatchFinder_SetLimits(p);
+}
+
+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
+{
+  return (p->pos - p->historySize - 1) & kNormalizeMask;
+}
+
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
+{
+  UInt32 i;
+  for (i = 0; i < numItems; i++)
+  {
+    UInt32 value = items[i];
+    if (value <= subValue)
+      value = kEmptyHashValue;
+    else
+      value -= subValue;
+    items[i] = value;
+  }
+}
+
+static void MatchFinder_Normalize(CMatchFinder *p)
+{
+  UInt32 subValue = MatchFinder_GetSubValue(p);
+  MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
+  MatchFinder_ReduceOffsets(p, subValue);
+}
+
+static void MatchFinder_CheckLimits(CMatchFinder *p)
+{
+  if (p->pos == kMaxValForNormalize)
+    MatchFinder_Normalize(p);
+  if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
+    MatchFinder_CheckAndMoveAndRead(p);
+  if (p->cyclicBufferPos == p->cyclicBufferSize)
+    p->cyclicBufferPos = 0;
+  MatchFinder_SetLimits(p);
+}
+
+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+    UInt32 *distances, UInt32 maxLen)
+{
+  son[_cyclicBufferPos] = curMatch;
+  for (;;)
+  {
+    UInt32 delta = pos - curMatch;
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+      return distances;
+    {
+      const Byte *pb = cur - delta;
+      curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
+      if (pb[maxLen] == cur[maxLen] && *pb == *cur)
+      {
+        UInt32 len = 0;
+        while(++len != lenLimit)
+          if (pb[len] != cur[len])
+            break;
+        if (maxLen < len)
+        {
+          *distances++ = maxLen = len;
+          *distances++ = delta - 1;
+          if (len == lenLimit)
+            return distances;
+        }
+      }
+    }
+  }
+}
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+    UInt32 *distances, UInt32 maxLen)
+{
+  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+  UInt32 len0 = 0, len1 = 0;
+  for (;;)
+  {
+    UInt32 delta = pos - curMatch;
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+    {
+      *ptr0 = *ptr1 = kEmptyHashValue;
+      return distances;
+    }
+    {
+      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+      const Byte *pb = cur - delta;
+      UInt32 len = (len0 < len1 ? len0 : len1);
+      if (pb[len] == cur[len])
+      {
+        if (++len != lenLimit && pb[len] == cur[len])
+          while(++len != lenLimit)
+            if (pb[len] != cur[len])
+              break;
+        if (maxLen < len)
+        {
+          *distances++ = maxLen = len;
+          *distances++ = delta - 1;
+          if (len == lenLimit)
+          {
+            *ptr1 = pair[0];
+            *ptr0 = pair[1];
+            return distances;
+          }
+        }
+      }
+      if (pb[len] < cur[len])
+      {
+        *ptr1 = curMatch;
+        ptr1 = pair + 1;
+        curMatch = *ptr1;
+        len1 = len;
+      }
+      else
+      {
+        *ptr0 = curMatch;
+        ptr0 = pair;
+        curMatch = *ptr0;
+        len0 = len;
+      }
+    }
+  }
+}
+
+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
+{
+  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+  UInt32 len0 = 0, len1 = 0;
+  for (;;)
+  {
+    UInt32 delta = pos - curMatch;
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+    {
+      *ptr0 = *ptr1 = kEmptyHashValue;
+      return;
+    }
+    {
+      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+      const Byte *pb = cur - delta;
+      UInt32 len = (len0 < len1 ? len0 : len1);
+      if (pb[len] == cur[len])
+      {
+        while(++len != lenLimit)
+          if (pb[len] != cur[len])
+            break;
+        {
+          if (len == lenLimit)
+          {
+            *ptr1 = pair[0];
+            *ptr0 = pair[1];
+            return;
+          }
+        }
+      }
+      if (pb[len] < cur[len])
+      {
+        *ptr1 = curMatch;
+        ptr1 = pair + 1;
+        curMatch = *ptr1;
+        len1 = len;
+      }
+      else
+      {
+        *ptr0 = curMatch;
+        ptr0 = pair;
+        curMatch = *ptr0;
+        len0 = len;
+      }
+    }
+  }
+}
+
+#define MOVE_POS \
+  ++p->cyclicBufferPos; \
+  p->buffer++; \
+  if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
+
+#define MOVE_POS_RET MOVE_POS return offset;
+
+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
+
+#define GET_MATCHES_HEADER2(minLen, ret_op) \
+  UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
+  lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
+  cur = p->buffer;
+
+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
+#define SKIP_HEADER(minLen)        GET_MATCHES_HEADER2(minLen, continue)
+
+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
+
+#define GET_MATCHES_FOOTER(offset, maxLen) \
+  offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
+  distances + offset, maxLen) - distances); MOVE_POS_RET;
+
+#define SKIP_FOOTER \
+  SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
+
+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 offset;
+  GET_MATCHES_HEADER(2)
+  HASH2_CALC;
+  curMatch = p->hash[hashValue];
+  p->hash[hashValue] = p->pos;
+  offset = 0;
+  GET_MATCHES_FOOTER(offset, 1)
+}
+
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 offset;
+  GET_MATCHES_HEADER(3)
+  HASH_ZIP_CALC;
+  curMatch = p->hash[hashValue];
+  p->hash[hashValue] = p->pos;
+  offset = 0;
+  GET_MATCHES_FOOTER(offset, 2)
+}
+
+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 hash2Value, delta2, maxLen, offset;
+  GET_MATCHES_HEADER(3)
+
+  HASH3_CALC;
+
+  delta2 = p->pos - p->hash[hash2Value];
+  curMatch = p->hash[kFix3HashSize + hashValue];
+
+  p->hash[hash2Value] =
+  p->hash[kFix3HashSize + hashValue] = p->pos;
+
+
+  maxLen = 2;
+  offset = 0;
+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+  {
+    for (; maxLen != lenLimit; maxLen++)
+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+        break;
+    distances[0] = maxLen;
+    distances[1] = delta2 - 1;
+    offset = 2;
+    if (maxLen == lenLimit)
+    {
+      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+      MOVE_POS_RET;
+    }
+  }
+  GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+  GET_MATCHES_HEADER(4)
+
+  HASH4_CALC;
+
+  delta2 = p->pos - p->hash[                hash2Value];
+  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
+  curMatch = p->hash[kFix4HashSize + hashValue];
+
+  p->hash[                hash2Value] =
+  p->hash[kFix3HashSize + hash3Value] =
+  p->hash[kFix4HashSize + hashValue] = p->pos;
+
+  maxLen = 1;
+  offset = 0;
+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+  {
+    distances[0] = maxLen = 2;
+    distances[1] = delta2 - 1;
+    offset = 2;
+  }
+  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+  {
+    maxLen = 3;
+    distances[offset + 1] = delta3 - 1;
+    offset += 2;
+    delta2 = delta3;
+  }
+  if (offset != 0)
+  {
+    for (; maxLen != lenLimit; maxLen++)
+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+        break;
+    distances[offset - 2] = maxLen;
+    if (maxLen == lenLimit)
+    {
+      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+      MOVE_POS_RET;
+    }
+  }
+  if (maxLen < 3)
+    maxLen = 3;
+  GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+  GET_MATCHES_HEADER(4)
+
+  HASH4_CALC;
+
+  delta2 = p->pos - p->hash[                hash2Value];
+  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
+  curMatch = p->hash[kFix4HashSize + hashValue];
+
+  p->hash[                hash2Value] =
+  p->hash[kFix3HashSize + hash3Value] =
+  p->hash[kFix4HashSize + hashValue] = p->pos;
+
+  maxLen = 1;
+  offset = 0;
+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+  {
+    distances[0] = maxLen = 2;
+    distances[1] = delta2 - 1;
+    offset = 2;
+  }
+  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+  {
+    maxLen = 3;
+    distances[offset + 1] = delta3 - 1;
+    offset += 2;
+    delta2 = delta3;
+  }
+  if (offset != 0)
+  {
+    for (; maxLen != lenLimit; maxLen++)
+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+        break;
+    distances[offset - 2] = maxLen;
+    if (maxLen == lenLimit)
+    {
+      p->son[p->cyclicBufferPos] = curMatch;
+      MOVE_POS_RET;
+    }
+  }
+  if (maxLen < 3)
+    maxLen = 3;
+  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+    distances + offset, maxLen) - (distances));
+  MOVE_POS_RET
+}
+
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 offset;
+  GET_MATCHES_HEADER(3)
+  HASH_ZIP_CALC;
+  curMatch = p->hash[hashValue];
+  p->hash[hashValue] = p->pos;
+  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+    distances, 2) - (distances));
+  MOVE_POS_RET
+}
+
+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    SKIP_HEADER(2)
+    HASH2_CALC;
+    curMatch = p->hash[hashValue];
+    p->hash[hashValue] = p->pos;
+    SKIP_FOOTER
+  }
+  while (--num != 0);
+}
+
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    SKIP_HEADER(3)
+    HASH_ZIP_CALC;
+    curMatch = p->hash[hashValue];
+    p->hash[hashValue] = p->pos;
+    SKIP_FOOTER
+  }
+  while (--num != 0);
+}
+
+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    UInt32 hash2Value;
+    SKIP_HEADER(3)
+    HASH3_CALC;
+    curMatch = p->hash[kFix3HashSize + hashValue];
+    p->hash[hash2Value] =
+    p->hash[kFix3HashSize + hashValue] = p->pos;
+    SKIP_FOOTER
+  }
+  while (--num != 0);
+}
+
+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    UInt32 hash2Value, hash3Value;
+    SKIP_HEADER(4)
+    HASH4_CALC;
+    curMatch = p->hash[kFix4HashSize + hashValue];
+    p->hash[                hash2Value] =
+    p->hash[kFix3HashSize + hash3Value] = p->pos;
+    p->hash[kFix4HashSize + hashValue] = p->pos;
+    SKIP_FOOTER
+  }
+  while (--num != 0);
+}
+
+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    UInt32 hash2Value, hash3Value;
+    SKIP_HEADER(4)
+    HASH4_CALC;
+    curMatch = p->hash[kFix4HashSize + hashValue];
+    p->hash[                hash2Value] =
+    p->hash[kFix3HashSize + hash3Value] =
+    p->hash[kFix4HashSize + hashValue] = p->pos;
+    p->son[p->cyclicBufferPos] = curMatch;
+    MOVE_POS
+  }
+  while (--num != 0);
+}
+
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    SKIP_HEADER(3)
+    HASH_ZIP_CALC;
+    curMatch = p->hash[hashValue];
+    p->hash[hashValue] = p->pos;
+    p->son[p->cyclicBufferPos] = curMatch;
+    MOVE_POS
+  }
+  while (--num != 0);
+}
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
+{
+  vTable->Init = (Mf_Init_Func)MatchFinder_Init;
+  vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
+  vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
+  vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
+  if (!p->btMode)
+  {
+    vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
+    vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
+  }
+  else if (p->numHashBytes == 2)
+  {
+    vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
+    vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
+  }
+  else if (p->numHashBytes == 3)
+  {
+    vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
+    vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
+  }
+  else
+  {
+    vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
+    vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
+  }
+}
diff --git a/lib/LzmaDec.c b/lib/LzmaDec.c
new file mode 100644
index 0000000..62ebee6
--- /dev/null
+++ b/lib/LzmaDec.c
@@ -0,0 +1,1035 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#include <grub/lib/LzmaDec.h>
+
+#include <string.h>
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_INIT_SIZE 5
+
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
+  { UPDATE_0(p); i = (i + i); A0; } else \
+  { UPDATE_1(p); i = (i + i) + 1; A1; }
+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
+
+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
+#define TREE_DECODE(probs, limit, i) \
+  { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
+
+/* #define _LZMA_SIZE_OPT */
+
+#ifdef _LZMA_SIZE_OPT
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
+#else
+#define TREE_6_DECODE(probs, i) \
+  { i = 1; \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  i -= 0x40; }
+#endif
+
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0_CHECK range = bound;
+#define UPDATE_1_CHECK range -= bound; code -= bound;
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
+  { UPDATE_0_CHECK; i = (i + i); A0; } else \
+  { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
+#define TREE_DECODE_CHECK(probs, limit, i) \
+  { i = 1; do { GET_BIT_CHECK(probs + i, i) } while(i < limit); i -= limit; }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+/*
+#define LZMA_STREAM_WAS_FINISHED_ID (-1)
+#define LZMA_SPEC_LEN_OFFSET (-3)
+*/
+
+Byte kLiteralNextStates[kNumStates * 2] =
+{
+  0, 0, 0, 0, 1, 2, 3,  4,  5,  6,  4,  5,
+  7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
+};
+
+#define LZMA_DIC_MIN (1 << 12)
+
+/* First LZMA-symbol is always decoded.
+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
+Out:
+  Result:
+    0 - OK
+    1 - Error
+  p->remainLen:
+    < kMatchSpecLenStart : normal remain
+    = kMatchSpecLenStart : finished
+    = kMatchSpecLenStart + 1 : Flush marker
+    = kMatchSpecLenStart + 2 : State Init Marker
+*/
+
+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+  CLzmaProb *probs = p->probs;
+
+  unsigned state = p->state;
+  UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
+  unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
+  unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
+  unsigned lc = p->prop.lc;
+
+  Byte *dic = p->dic;
+  SizeT dicBufSize = p->dicBufSize;
+  SizeT dicPos = p->dicPos;
+
+  UInt32 processedPos = p->processedPos;
+  UInt32 checkDicSize = p->checkDicSize;
+  unsigned len = 0;
+
+  const Byte *buf = p->buf;
+  UInt32 range = p->range;
+  UInt32 code = p->code;
+
+  do
+  {
+    CLzmaProb *prob;
+    UInt32 bound;
+    unsigned ttt;
+    unsigned posState = processedPos & pbMask;
+
+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+    IF_BIT_0(prob)
+    {
+      unsigned symbol;
+      UPDATE_0(prob);
+      prob = probs + Literal;
+      if (checkDicSize != 0 || processedPos != 0)
+        prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
+        (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+
+      if (state < kNumLitStates)
+      {
+        symbol = 1;
+        do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
+      }
+      else
+      {
+        unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+        unsigned offs = 0x100;
+        symbol = 1;
+        do
+        {
+          unsigned bit;
+          CLzmaProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & offs);
+          probLit = prob + offs + bit + symbol;
+          GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
+        }
+        while (symbol < 0x100);
+      }
+      dic[dicPos++] = (Byte)symbol;
+      processedPos++;
+
+      state = kLiteralNextStates[state];
+      /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
+      continue;
+    }
+    else
+    {
+      UPDATE_1(prob);
+      prob = probs + IsRep + state;
+      IF_BIT_0(prob)
+      {
+        UPDATE_0(prob);
+        state += kNumStates;
+        prob = probs + LenCoder;
+      }
+      else
+      {
+        UPDATE_1(prob);
+        if (checkDicSize == 0 && processedPos == 0)
+          return SZ_ERROR_DATA;
+        prob = probs + IsRepG0 + state;
+        IF_BIT_0(prob)
+        {
+          UPDATE_0(prob);
+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IF_BIT_0(prob)
+          {
+            UPDATE_0(prob);
+            dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+            dicPos++;
+            processedPos++;
+            state = state < kNumLitStates ? 9 : 11;
+            continue;
+          }
+          UPDATE_1(prob);
+        }
+        else
+        {
+          UInt32 distance;
+          UPDATE_1(prob);
+          prob = probs + IsRepG1 + state;
+          IF_BIT_0(prob)
+          {
+            UPDATE_0(prob);
+            distance = rep1;
+          }
+          else
+          {
+            UPDATE_1(prob);
+            prob = probs + IsRepG2 + state;
+            IF_BIT_0(prob)
+            {
+              UPDATE_0(prob);
+              distance = rep2;
+            }
+            else
+            {
+              UPDATE_1(prob);
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        state = state < kNumLitStates ? 8 : 11;
+        prob = probs + RepLenCoder;
+      }
+      {
+        unsigned limit, offset;
+        CLzmaProb *probLen = prob + LenChoice;
+        IF_BIT_0(probLen)
+        {
+          UPDATE_0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          limit = (1 << kLenNumLowBits);
+        }
+        else
+        {
+          UPDATE_1(probLen);
+          probLen = prob + LenChoice2;
+          IF_BIT_0(probLen)
+          {
+            UPDATE_0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            limit = (1 << kLenNumMidBits);
+          }
+          else
+          {
+            UPDATE_1(probLen);
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            limit = (1 << kLenNumHighBits);
+          }
+        }
+        TREE_DECODE(probLen, limit, len);
+        len += offset;
+      }
+
+      if (state >= kNumStates)
+      {
+        UInt32 distance;
+        prob = probs + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
+        TREE_6_DECODE(prob, distance);
+        if (distance >= kStartPosModelIndex)
+        {
+          unsigned posSlot = (unsigned)distance;
+          int numDirectBits = (int)(((distance >> 1) - 1));
+          distance = (2 | (distance & 1));
+          if (posSlot < kEndPosModelIndex)
+          {
+            distance <<= numDirectBits;
+            prob = probs + SpecPos + distance - posSlot - 1;
+            {
+              UInt32 mask = 1;
+              unsigned i = 1;
+              do
+              {
+                GET_BIT2(prob + i, i, ; , distance |= mask);
+                mask <<= 1;
+              }
+              while(--numDirectBits != 0);
+            }
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              NORMALIZE
+              range >>= 1;
+
+              {
+                UInt32 t;
+                code -= range;
+                t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
+                distance = (distance << 1) + (t + 1);
+                code += range & t;
+              }
+              /*
+              distance <<= 1;
+              if (code >= range)
+              {
+                code -= range;
+                distance |= 1;
+              }
+              */
+            }
+            while (--numDirectBits != 0);
+            prob = probs + Align;
+            distance <<= kNumAlignBits;
+            {
+              unsigned i = 1;
+              GET_BIT2(prob + i, i, ; , distance |= 1);
+              GET_BIT2(prob + i, i, ; , distance |= 2);
+              GET_BIT2(prob + i, i, ; , distance |= 4);
+              GET_BIT2(prob + i, i, ; , distance |= 8);
+            }
+            if (distance == (UInt32)0xFFFFFFFF)
+            {
+              len += kMatchSpecLenStart;
+              state -= kNumStates;
+              break;
+            }
+          }
+        }
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        rep0 = distance + 1;
+        if (checkDicSize == 0)
+        {
+          if (distance >= processedPos)
+            return SZ_ERROR_DATA;
+        }
+        else if (distance >= checkDicSize)
+          return SZ_ERROR_DATA;
+        state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
+        /* state = kLiteralNextStates[state]; */
+      }
+
+      len += kMatchMinLen;
+
+      {
+        SizeT rem = limit - dicPos;
+        unsigned curLen = ((rem < len) ? (unsigned)rem : len);
+        SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
+
+        processedPos += curLen;
+
+        len -= curLen;
+        if (pos + curLen <= dicBufSize)
+        {
+          Byte *dest = dic + dicPos;
+          ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
+          const Byte *lim = dest + curLen;
+          dicPos += curLen;
+          do
+            *(dest) = (Byte)*(dest + src);
+          while (++dest != lim);
+        }
+        else
+        {
+          do
+          {
+            dic[dicPos++] = dic[pos];
+            if (++pos == dicBufSize)
+              pos = 0;
+          }
+          while (--curLen != 0);
+        }
+      }
+    }
+  }
+  while (dicPos < limit && buf < bufLimit);
+  NORMALIZE;
+  p->buf = buf;
+  p->range = range;
+  p->code = code;
+  p->remainLen = len;
+  p->dicPos = dicPos;
+  p->processedPos = processedPos;
+  p->reps[0] = rep0;
+  p->reps[1] = rep1;
+  p->reps[2] = rep2;
+  p->reps[3] = rep3;
+  p->state = state;
+
+  return SZ_OK;
+}
+
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
+{
+  if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
+  {
+    Byte *dic = p->dic;
+    SizeT dicPos = p->dicPos;
+    SizeT dicBufSize = p->dicBufSize;
+    unsigned len = p->remainLen;
+    UInt32 rep0 = p->reps[0];
+    if (limit - dicPos < len)
+      len = (unsigned)(limit - dicPos);
+
+    if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
+      p->checkDicSize = p->prop.dicSize;
+
+    p->processedPos += len;
+    p->remainLen -= len;
+    while (len-- != 0)
+    {
+      dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+      dicPos++;
+    }
+    p->dicPos = dicPos;
+  }
+}
+
+/* LzmaDec_DecodeReal2 decodes LZMA-symbols and sets p->needFlush and p->needInit, if required. */
+
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+  do
+  {
+    SizeT limit2 = limit;
+    if (p->checkDicSize == 0)
+    {
+      UInt32 rem = p->prop.dicSize - p->processedPos;
+      if (limit - p->dicPos > rem)
+        limit2 = p->dicPos + rem;
+    }
+    RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
+    if (p->processedPos >= p->prop.dicSize)
+      p->checkDicSize = p->prop.dicSize;
+    LzmaDec_WriteRem(p, limit);
+  }
+  while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
+
+  if (p->remainLen > kMatchSpecLenStart)
+  {
+    p->remainLen = kMatchSpecLenStart;
+  }
+  return 0;
+}
+
+typedef enum
+{
+  DUMMY_ERROR, /* unexpected end of input stream */
+  DUMMY_LIT,
+  DUMMY_MATCH,
+  DUMMY_REP
+} ELzmaDummy;
+
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
+{
+  UInt32 range = p->range;
+  UInt32 code = p->code;
+  const Byte *bufLimit = buf + inSize;
+  CLzmaProb *probs = p->probs;
+  unsigned state = p->state;
+  ELzmaDummy res;
+
+  {
+    CLzmaProb *prob;
+    UInt32 bound;
+    unsigned ttt;
+    unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
+
+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+    IF_BIT_0_CHECK(prob)
+    {
+      UPDATE_0_CHECK
+
+      /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
+
+      prob = probs + Literal;
+      if (p->checkDicSize != 0 || p->processedPos != 0)
+        prob += (LZMA_LIT_SIZE *
+          ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
+          (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
+
+      if (state < kNumLitStates)
+      {
+        unsigned symbol = 1;
+        do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
+      }
+      else
+      {
+        unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
+            ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
+        unsigned offs = 0x100;
+        unsigned symbol = 1;
+        do
+        {
+          unsigned bit;
+          CLzmaProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & offs);
+          probLit = prob + offs + bit + symbol;
+          GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
+        }
+        while (symbol < 0x100);
+      }
+      res = DUMMY_LIT;
+    }
+    else
+    {
+      unsigned len;
+      UPDATE_1_CHECK;
+
+      prob = probs + IsRep + state;
+      IF_BIT_0_CHECK(prob)
+      {
+        UPDATE_0_CHECK;
+        state = 0;
+        prob = probs + LenCoder;
+        res = DUMMY_MATCH;
+      }
+      else
+      {
+        UPDATE_1_CHECK;
+        res = DUMMY_REP;
+        prob = probs + IsRepG0 + state;
+        IF_BIT_0_CHECK(prob)
+        {
+          UPDATE_0_CHECK;
+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IF_BIT_0_CHECK(prob)
+          {
+            UPDATE_0_CHECK;
+            NORMALIZE_CHECK;
+            return DUMMY_REP;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+          }
+        }
+        else
+        {
+          UPDATE_1_CHECK;
+          prob = probs + IsRepG1 + state;
+          IF_BIT_0_CHECK(prob)
+          {
+            UPDATE_0_CHECK;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+            prob = probs + IsRepG2 + state;
+            IF_BIT_0_CHECK(prob)
+            {
+              UPDATE_0_CHECK;
+            }
+            else
+            {
+              UPDATE_1_CHECK;
+            }
+          }
+        }
+        state = kNumStates;
+        prob = probs + RepLenCoder;
+      }
+      {
+        unsigned limit, offset;
+        CLzmaProb *probLen = prob + LenChoice;
+        IF_BIT_0_CHECK(probLen)
+        {
+          UPDATE_0_CHECK;
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          limit = 1 << kLenNumLowBits;
+        }
+        else
+        {
+          UPDATE_1_CHECK;
+          probLen = prob + LenChoice2;
+          IF_BIT_0_CHECK(probLen)
+          {
+            UPDATE_0_CHECK;
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            limit = 1 << kLenNumMidBits;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            limit = 1 << kLenNumHighBits;
+          }
+        }
+        TREE_DECODE_CHECK(probLen, limit, len);
+        len += offset;
+      }
+
+      if (state < 4)
+      {
+        unsigned posSlot;
+        prob = probs + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+            kNumPosSlotBits);
+        TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+
+          /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
+
+          if (posSlot < kEndPosModelIndex)
+          {
+            prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              NORMALIZE_CHECK
+              range >>= 1;
+              code -= range & (((code - range) >> 31) - 1);
+              /* if (code >= range) code -= range; */
+            }
+            while (--numDirectBits != 0);
+            prob = probs + Align;
+            numDirectBits = kNumAlignBits;
+          }
+          {
+            unsigned i = 1;
+            do
+            {
+              GET_BIT_CHECK(prob + i, i);
+            }
+            while(--numDirectBits != 0);
+          }
+        }
+      }
+    }
+  }
+  NORMALIZE_CHECK;
+  return res;
+}
+
+
+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
+{
+  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
+  p->range = 0xFFFFFFFF;
+  p->needFlush = 0;
+}
+
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
+{
+  p->needFlush = 1;
+  p->remainLen = 0;
+  p->tempBufSize = 0;
+
+  if (initDic)
+  {
+    p->processedPos = 0;
+    p->checkDicSize = 0;
+    p->needInitState = 1;
+  }
+  if (initState)
+    p->needInitState = 1;
+}
+
+void LzmaDec_Init(CLzmaDec *p)
+{
+  p->dicPos = 0;
+  LzmaDec_InitDicAndState(p, True, True);
+}
+
+static void LzmaDec_InitStateReal(CLzmaDec *p)
+{
+  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
+  UInt32 i;
+  CLzmaProb *probs = p->probs;
+  for (i = 0; i < numProbs; i++)
+    probs[i] = kBitModelTotal >> 1;
+  p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
+  p->state = 0;
+  p->needInitState = 0;
+}
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
+    ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+  SizeT inSize = *srcLen;
+  (*srcLen) = 0;
+  LzmaDec_WriteRem(p, dicLimit);
+
+  *status = LZMA_STATUS_NOT_SPECIFIED;
+
+  while (p->remainLen != kMatchSpecLenStart)
+  {
+      int checkEndMarkNow;
+
+      if (p->needFlush != 0)
+      {
+        for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
+          p->tempBuf[p->tempBufSize++] = *src++;
+        if (p->tempBufSize < RC_INIT_SIZE)
+        {
+          *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+          return SZ_OK;
+        }
+        if (p->tempBuf[0] != 0)
+          return SZ_ERROR_DATA;
+
+        LzmaDec_InitRc(p, p->tempBuf);
+        p->tempBufSize = 0;
+      }
+
+      checkEndMarkNow = 0;
+      if (p->dicPos >= dicLimit)
+      {
+        if (p->remainLen == 0 && p->code == 0)
+        {
+          *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
+          return SZ_OK;
+        }
+        if (finishMode == LZMA_FINISH_ANY)
+        {
+          *status = LZMA_STATUS_NOT_FINISHED;
+          return SZ_OK;
+        }
+        if (p->remainLen != 0)
+        {
+          *status = LZMA_STATUS_NOT_FINISHED;
+          return SZ_ERROR_DATA;
+        }
+        checkEndMarkNow = 1;
+      }
+
+      if (p->needInitState)
+        LzmaDec_InitStateReal(p);
+
+      if (p->tempBufSize == 0)
+      {
+        SizeT processed;
+        const Byte *bufLimit;
+        if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+        {
+          int dummyRes = LzmaDec_TryDummy(p, src, inSize);
+          if (dummyRes == DUMMY_ERROR)
+          {
+            memcpy(p->tempBuf, src, inSize);
+            p->tempBufSize = (unsigned)inSize;
+            (*srcLen) += inSize;
+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+            return SZ_OK;
+          }
+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+          {
+            *status = LZMA_STATUS_NOT_FINISHED;
+            return SZ_ERROR_DATA;
+          }
+          bufLimit = src;
+        }
+        else
+          bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
+        p->buf = src;
+        if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
+          return SZ_ERROR_DATA;
+        processed = p->buf - src;
+        (*srcLen) += processed;
+        src += processed;
+        inSize -= processed;
+      }
+      else
+      {
+        unsigned rem = p->tempBufSize, lookAhead = 0;
+        while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
+          p->tempBuf[rem++] = src[lookAhead++];
+        p->tempBufSize = rem;
+        if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+        {
+          int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
+          if (dummyRes == DUMMY_ERROR)
+          {
+            (*srcLen) += lookAhead;
+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+            return SZ_OK;
+          }
+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+          {
+            *status = LZMA_STATUS_NOT_FINISHED;
+            return SZ_ERROR_DATA;
+          }
+        }
+        p->buf = p->tempBuf;
+        if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
+          return SZ_ERROR_DATA;
+        lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
+        (*srcLen) += lookAhead;
+        src += lookAhead;
+        inSize -= lookAhead;
+        p->tempBufSize = 0;
+      }
+  }
+  if (p->code == 0)
+    *status = LZMA_STATUS_FINISHED_WITH_MARK;
+  return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
+}
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+  SizeT outSize = *destLen;
+  SizeT inSize = *srcLen;
+  *srcLen = *destLen = 0;
+  for (;;)
+  {
+    SizeT inSizeCur = inSize, outSizeCur, dicPos;
+    ELzmaFinishMode curFinishMode;
+    SRes res;
+    if (p->dicPos == p->dicBufSize)
+      p->dicPos = 0;
+    dicPos = p->dicPos;
+    if (outSize > p->dicBufSize - dicPos)
+    {
+      outSizeCur = p->dicBufSize;
+      curFinishMode = LZMA_FINISH_ANY;
+    }
+    else
+    {
+      outSizeCur = dicPos + outSize;
+      curFinishMode = finishMode;
+    }
+
+    res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
+    src += inSizeCur;
+    inSize -= inSizeCur;
+    *srcLen += inSizeCur;
+    outSizeCur = p->dicPos - dicPos;
+    memcpy(dest, p->dic + dicPos, outSizeCur);
+    dest += outSizeCur;
+    outSize -= outSizeCur;
+    *destLen += outSizeCur;
+    if (res != 0)
+      return res;
+    if (outSizeCur == 0 || outSize == 0)
+      return SZ_OK;
+  }
+}
+
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->probs);
+  p->probs = 0;
+}
+
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->dic);
+  p->dic = 0;
+}
+
+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
+{
+  LzmaDec_FreeProbs(p, alloc);
+  LzmaDec_FreeDict(p, alloc);
+}
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
+{
+  UInt32 dicSize;
+  Byte d;
+
+  if (size < LZMA_PROPS_SIZE)
+    return SZ_ERROR_UNSUPPORTED;
+  else
+    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
+
+  if (dicSize < LZMA_DIC_MIN)
+    dicSize = LZMA_DIC_MIN;
+  p->dicSize = dicSize;
+
+  d = data[0];
+  if (d >= (9 * 5 * 5))
+    return SZ_ERROR_UNSUPPORTED;
+
+  p->lc = d % 9;
+  d /= 9;
+  p->pb = d / 5;
+  p->lp = d % 5;
+
+  return SZ_OK;
+}
+
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
+{
+  UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
+  if (p->probs == 0 || numProbs != p->numProbs)
+  {
+    LzmaDec_FreeProbs(p, alloc);
+    p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
+    p->numProbs = numProbs;
+    if (p->probs == 0)
+      return SZ_ERROR_MEM;
+  }
+  return SZ_OK;
+}
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+  CLzmaProps propNew;
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+  p->prop = propNew;
+  return SZ_OK;
+}
+
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+  CLzmaProps propNew;
+  SizeT dicBufSize;
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+  dicBufSize = propNew.dicSize;
+  if (p->dic == 0 || dicBufSize != p->dicBufSize)
+  {
+    LzmaDec_FreeDict(p, alloc);
+    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
+    if (p->dic == 0)
+    {
+      LzmaDec_FreeProbs(p, alloc);
+      return SZ_ERROR_MEM;
+    }
+  }
+  p->dicBufSize = dicBufSize;
+  p->prop = propNew;
+  return SZ_OK;
+}
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+    ELzmaStatus *status, ISzAlloc *alloc)
+{
+  CLzmaDec p;
+  SRes res;
+  SizeT inSize = *srcLen;
+  SizeT outSize = *destLen;
+  *srcLen = *destLen = 0;
+  if (inSize < RC_INIT_SIZE)
+    return SZ_ERROR_INPUT_EOF;
+
+  LzmaDec_Construct(&p);
+  res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
+  if (res != 0)
+    return res;
+  p.dic = dest;
+  p.dicBufSize = outSize;
+
+  LzmaDec_Init(&p);
+
+  *srcLen = inSize;
+  res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
+
+  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
+    res = SZ_ERROR_INPUT_EOF;
+
+  (*destLen) = p.dicPos;
+  LzmaDec_FreeProbs(&p, alloc);
+  return res;
+}
diff --git a/lib/LzmaEnc.c b/lib/LzmaEnc.c
new file mode 100644
index 0000000..842d43a
--- /dev/null
+++ b/lib/LzmaEnc.c
@@ -0,0 +1,2355 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grub/lib/LzmaEnc.h>
+
+#include <grub/lib/LzFind.h>
+#ifdef COMPRESS_MF_MT
+#include <grub/lib/LzFindMt.h>
+#endif
+
+/* #define SHOW_STAT */
+/* #define SHOW_STAT2 */
+
+#ifdef SHOW_STAT
+static int ttt = 0;
+#endif
+
+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
+
+#define kBlockSize (9 << 10)
+#define kUnpackBlockSize (1 << 18)
+#define kMatchArraySize (1 << 21)
+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
+
+#define kNumMaxDirectBits (31)
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+#define kProbInitValue (kBitModelTotal >> 1)
+
+#define kNumMoveReducingBits 4
+#define kNumBitPriceShiftBits 4
+#define kBitPrice (1 << kNumBitPriceShiftBits)
+
+void LzmaEncProps_Init(CLzmaEncProps *p)
+{
+  p->level = 5;
+  p->dictSize = p->mc = 0;
+  p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
+  p->writeEndMark = 0;
+}
+
+void LzmaEncProps_Normalize(CLzmaEncProps *p)
+{
+  int level = p->level;
+  if (level < 0) level = 5;
+  p->level = level;
+  if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
+  if (p->lc < 0) p->lc = 3;
+  if (p->lp < 0) p->lp = 0;
+  if (p->pb < 0) p->pb = 2;
+  if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
+  if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
+  if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
+  if (p->numHashBytes < 0) p->numHashBytes = 4;
+  if (p->mc == 0)  p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
+  if (p->numThreads < 0) p->numThreads = ((p->btMode && p->algo) ? 2 : 1);
+}
+
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
+{
+  CLzmaEncProps props = *props2;
+  LzmaEncProps_Normalize(&props);
+  return props.dictSize;
+}
+
+/* #define LZMA_LOG_BSR */
+/* Define it for Intel's CPU */
+
+
+#ifdef LZMA_LOG_BSR
+
+#define kDicLogSizeMaxCompress 30
+
+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
+
+UInt32 GetPosSlot1(UInt32 pos)
+{
+  UInt32 res;
+  BSR2_RET(pos, res);
+  return res;
+}
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
+
+#else
+
+#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
+
+void LzmaEnc_FastPosInit(Byte *g_FastPos)
+{
+  int c = 2, slotFast;
+  g_FastPos[0] = 0;
+  g_FastPos[1] = 1;
+
+  for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
+  {
+    UInt32 k = (1 << ((slotFast >> 1) - 1));
+    UInt32 j;
+    for (j = 0; j < k; j++, c++)
+      g_FastPos[c] = (Byte)slotFast;
+  }
+}
+
+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
+  (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
+  res = p->g_FastPos[pos >> i] + (i * 2); }
+/*
+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
+  p->g_FastPos[pos >> 6] + 12 : \
+  p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
+*/
+
+#define GetPosSlot1(pos) p->g_FastPos[pos]
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
+
+#endif
+
+
+#define LZMA_NUM_REPS 4
+
+typedef unsigned CState;
+
+typedef struct _COptimal
+{
+  UInt32 price;
+
+  CState state;
+  int prev1IsChar;
+  int prev2;
+
+  UInt32 posPrev2;
+  UInt32 backPrev2;
+
+  UInt32 posPrev;
+  UInt32 backPrev;
+  UInt32 backs[LZMA_NUM_REPS];
+} COptimal;
+
+#define kNumOpts (1 << 12)
+
+#define kNumLenToPosStates 4
+#define kNumPosSlotBits 6
+#define kDicLogSizeMin 0
+#define kDicLogSizeMax 32
+#define kDistTableSizeMax (kDicLogSizeMax * 2)
+
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+#define kAlignMask (kAlignTableSize - 1)
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
+
+#define kNumFullDistances (1 << (kEndPosModelIndex / 2))
+
+#ifdef _LZMA_PROB32
+#define CLzmaProb UInt32
+#else
+#define CLzmaProb UInt16
+#endif
+
+#define LZMA_PB_MAX 4
+#define LZMA_LC_MAX 8
+#define LZMA_LP_MAX 4
+
+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
+
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define LZMA_MATCH_LEN_MIN 2
+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
+
+#define kNumStates 12
+
+typedef struct
+{
+  CLzmaProb choice;
+  CLzmaProb choice2;
+  CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
+  CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
+  CLzmaProb high[kLenNumHighSymbols];
+} CLenEnc;
+
+typedef struct
+{
+  CLenEnc p;
+  UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
+  UInt32 tableSize;
+  UInt32 counters[LZMA_NUM_PB_STATES_MAX];
+} CLenPriceEnc;
+
+typedef struct _CRangeEnc
+{
+  UInt32 range;
+  Byte cache;
+  UInt64 low;
+  UInt64 cacheSize;
+  Byte *buf;
+  Byte *bufLim;
+  Byte *bufBase;
+  ISeqOutStream *outStream;
+  UInt64 processed;
+  SRes res;
+} CRangeEnc;
+
+typedef struct _CSeqInStreamBuf
+{
+  ISeqInStream funcTable;
+  const Byte *data;
+  SizeT rem;
+} CSeqInStreamBuf;
+
+static SRes MyRead(void *pp, void *data, size_t *size)
+{
+  size_t curSize = *size;
+  CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp;
+  if (p->rem < curSize)
+    curSize = p->rem;
+  memcpy(data, p->data, curSize);
+  p->rem -= curSize;
+  p->data += curSize;
+  *size = curSize;
+  return SZ_OK;
+}
+
+typedef struct
+{
+  CLzmaProb *litProbs;
+
+  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+  CLzmaProb isRep[kNumStates];
+  CLzmaProb isRepG0[kNumStates];
+  CLzmaProb isRepG1[kNumStates];
+  CLzmaProb isRepG2[kNumStates];
+  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
+
+  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
+  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
+  CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+
+  CLenPriceEnc lenEnc;
+  CLenPriceEnc repLenEnc;
+
+  UInt32 reps[LZMA_NUM_REPS];
+  UInt32 state;
+} CSaveState;
+
+typedef struct _CLzmaEnc
+{
+  IMatchFinder matchFinder;
+  void *matchFinderObj;
+
+  #ifdef COMPRESS_MF_MT
+  Bool mtMode;
+  CMatchFinderMt matchFinderMt;
+  #endif
+
+  CMatchFinder matchFinderBase;
+
+  #ifdef COMPRESS_MF_MT
+  Byte pad[128];
+  #endif
+
+  UInt32 optimumEndIndex;
+  UInt32 optimumCurrentIndex;
+
+  Bool longestMatchWasFound;
+  UInt32 longestMatchLength;
+  UInt32 numDistancePairs;
+
+  COptimal opt[kNumOpts];
+
+  #ifndef LZMA_LOG_BSR
+  Byte g_FastPos[1 << kNumLogBits];
+  #endif
+
+  UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+  UInt32 matchDistances[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
+  UInt32 numFastBytes;
+  UInt32 additionalOffset;
+  UInt32 reps[LZMA_NUM_REPS];
+  UInt32 state;
+
+  UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
+  UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
+  UInt32 alignPrices[kAlignTableSize];
+  UInt32 alignPriceCount;
+
+  UInt32 distTableSize;
+
+  unsigned lc, lp, pb;
+  unsigned lpMask, pbMask;
+
+  CLzmaProb *litProbs;
+
+  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+  CLzmaProb isRep[kNumStates];
+  CLzmaProb isRepG0[kNumStates];
+  CLzmaProb isRepG1[kNumStates];
+  CLzmaProb isRepG2[kNumStates];
+  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
+
+  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
+  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
+  CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+
+  CLenPriceEnc lenEnc;
+  CLenPriceEnc repLenEnc;
+
+  unsigned lclp;
+
+  Bool fastMode;
+
+  CRangeEnc rc;
+
+  Bool writeEndMark;
+  UInt64 nowPos64;
+  UInt32 matchPriceCount;
+  Bool finished;
+  Bool multiThread;
+
+  SRes result;
+  UInt32 dictSize;
+  UInt32 matchFinderCycles;
+
+  ISeqInStream *inStream;
+  CSeqInStreamBuf seqBufInStream;
+
+  CSaveState saveState;
+} CLzmaEnc;
+
+void LzmaEnc_SaveState(CLzmaEncHandle pp)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  CSaveState *dest = &p->saveState;
+  int i;
+  dest->lenEnc = p->lenEnc;
+  dest->repLenEnc = p->repLenEnc;
+  dest->state = p->state;
+
+  for (i = 0; i < kNumStates; i++)
+  {
+    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
+    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
+  }
+  for (i = 0; i < kNumLenToPosStates; i++)
+    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
+  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
+  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
+  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
+  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
+  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
+  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
+  memcpy(dest->reps, p->reps, sizeof(p->reps));
+  memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
+}
+
+void LzmaEnc_RestoreState(CLzmaEncHandle pp)
+{
+  CLzmaEnc *dest = (CLzmaEnc *)pp;
+  const CSaveState *p = &dest->saveState;
+  int i;
+  dest->lenEnc = p->lenEnc;
+  dest->repLenEnc = p->repLenEnc;
+  dest->state = p->state;
+
+  for (i = 0; i < kNumStates; i++)
+  {
+    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
+    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
+  }
+  for (i = 0; i < kNumLenToPosStates; i++)
+    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
+  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
+  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
+  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
+  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
+  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
+  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
+  memcpy(dest->reps, p->reps, sizeof(p->reps));
+  memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
+}
+
+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  CLzmaEncProps props = *props2;
+  LzmaEncProps_Normalize(&props);
+
+  if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
+      props.dictSize > (1U << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
+    return SZ_ERROR_PARAM;
+  p->dictSize = props.dictSize;
+  p->matchFinderCycles = props.mc;
+  {
+    unsigned fb = props.fb;
+    if (fb < 5)
+      fb = 5;
+    if (fb > LZMA_MATCH_LEN_MAX)
+      fb = LZMA_MATCH_LEN_MAX;
+    p->numFastBytes = fb;
+  }
+  p->lc = props.lc;
+  p->lp = props.lp;
+  p->pb = props.pb;
+  p->fastMode = (props.algo == 0);
+  p->matchFinderBase.btMode = props.btMode;
+  {
+    UInt32 numHashBytes = 4;
+    if (props.btMode)
+    {
+      if (props.numHashBytes < 2)
+        numHashBytes = 2;
+      else if (props.numHashBytes < 4)
+        numHashBytes = props.numHashBytes;
+    }
+    p->matchFinderBase.numHashBytes = numHashBytes;
+  }
+
+  p->matchFinderBase.cutValue = props.mc;
+
+  p->writeEndMark = props.writeEndMark;
+
+  #ifdef COMPRESS_MF_MT
+  /*
+  if (newMultiThread != _multiThread)
+  {
+    ReleaseMatchFinder();
+    _multiThread = newMultiThread;
+  }
+  */
+  p->multiThread = (props.numThreads > 1);
+  #endif
+
+  return SZ_OK;
+}
+
+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};
+static const int kMatchNextStates[kNumStates]   = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+static const int kRepNextStates[kNumStates]     = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+/*
+  void UpdateChar() { Index = kLiteralNextStates[Index]; }
+  void UpdateMatch() { Index = kMatchNextStates[Index]; }
+  void UpdateRep() { Index = kRepNextStates[Index]; }
+  void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
+*/
+
+#define IsCharState(s) ((s) < 7)
+
+
+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
+
+#define kInfinityPrice (1 << 30)
+
+static void RangeEnc_Construct(CRangeEnc *p)
+{
+  p->outStream = 0;
+  p->bufBase = 0;
+}
+
+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
+
+#define RC_BUF_SIZE (1 << 16)
+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
+{
+  if (p->bufBase == 0)
+  {
+    p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
+    if (p->bufBase == 0)
+      return 0;
+    p->bufLim = p->bufBase + RC_BUF_SIZE;
+  }
+  return 1;
+}
+
+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->bufBase);
+  p->bufBase = 0;
+}
+
+static void RangeEnc_Init(CRangeEnc *p)
+{
+  /* Stream.Init(); */
+  p->low = 0;
+  p->range = 0xFFFFFFFF;
+  p->cacheSize = 1;
+  p->cache = 0;
+
+  p->buf = p->bufBase;
+
+  p->processed = 0;
+  p->res = SZ_OK;
+}
+
+static void RangeEnc_FlushStream(CRangeEnc *p)
+{
+  size_t num;
+  if (p->res != SZ_OK)
+    return;
+  num = p->buf - p->bufBase;
+  if (num != p->outStream->Write(p->outStream, p->bufBase, num))
+    p->res = SZ_ERROR_WRITE;
+  p->processed += num;
+  p->buf = p->bufBase;
+}
+
+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
+{
+  if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
+  {
+    Byte temp = p->cache;
+    do
+    {
+      Byte *buf = p->buf;
+      *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
+      p->buf = buf;
+      if (buf == p->bufLim)
+        RangeEnc_FlushStream(p);
+      temp = 0xFF;
+    }
+    while (--p->cacheSize != 0);
+    p->cache = (Byte)((UInt32)p->low >> 24);
+  }
+  p->cacheSize++;
+  p->low = (UInt32)p->low << 8;
+}
+
+static void RangeEnc_FlushData(CRangeEnc *p)
+{
+  int i;
+  for (i = 0; i < 5; i++)
+    RangeEnc_ShiftLow(p);
+}
+
+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
+{
+  do
+  {
+    p->range >>= 1;
+    p->low += p->range & (0 - ((value >> --numBits) & 1));
+    if (p->range < kTopValue)
+    {
+      p->range <<= 8;
+      RangeEnc_ShiftLow(p);
+    }
+  }
+  while (numBits != 0);
+}
+
+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
+{
+  UInt32 ttt = *prob;
+  UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
+  if (symbol == 0)
+  {
+    p->range = newBound;
+    ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
+  }
+  else
+  {
+    p->low += newBound;
+    p->range -= newBound;
+    ttt -= ttt >> kNumMoveBits;
+  }
+  *prob = (CLzmaProb)ttt;
+  if (p->range < kTopValue)
+  {
+    p->range <<= 8;
+    RangeEnc_ShiftLow(p);
+  }
+}
+
+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
+{
+  symbol |= 0x100;
+  do
+  {
+    RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
+    symbol <<= 1;
+  }
+  while (symbol < 0x10000);
+}
+
+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
+{
+  UInt32 offs = 0x100;
+  symbol |= 0x100;
+  do
+  {
+    matchByte <<= 1;
+    RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
+    symbol <<= 1;
+    offs &= ~(matchByte ^ symbol);
+  }
+  while (symbol < 0x10000);
+}
+
+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
+{
+  UInt32 i;
+  for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
+  {
+    const int kCyclesBits = kNumBitPriceShiftBits;
+    UInt32 w = i;
+    UInt32 bitCount = 0;
+    int j;
+    for (j = 0; j < kCyclesBits; j++)
+    {
+      w = w * w;
+      bitCount <<= 1;
+      while (w >= ((UInt32)1 << 16))
+      {
+        w >>= 1;
+        bitCount++;
+      }
+    }
+    ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
+  }
+}
+
+
+#define GET_PRICE(prob, symbol) \
+  p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+
+#define GET_PRICEa(prob, symbol) \
+  ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+
+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
+{
+  UInt32 price = 0;
+  symbol |= 0x100;
+  do
+  {
+    price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
+    symbol <<= 1;
+  }
+  while (symbol < 0x10000);
+  return price;
+};
+
+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
+{
+  UInt32 price = 0;
+  UInt32 offs = 0x100;
+  symbol |= 0x100;
+  do
+  {
+    matchByte <<= 1;
+    price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
+    symbol <<= 1;
+    offs &= ~(matchByte ^ symbol);
+  }
+  while (symbol < 0x10000);
+  return price;
+};
+
+
+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
+{
+  UInt32 m = 1;
+  int i;
+  for (i = numBitLevels; i != 0 ;)
+  {
+    UInt32 bit;
+    i--;
+    bit = (symbol >> i) & 1;
+    RangeEnc_EncodeBit(rc, probs + m, bit);
+    m = (m << 1) | bit;
+  }
+};
+
+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
+{
+  UInt32 m = 1;
+  int i;
+  for (i = 0; i < numBitLevels; i++)
+  {
+    UInt32 bit = symbol & 1;
+    RangeEnc_EncodeBit(rc, probs + m, bit);
+    m = (m << 1) | bit;
+    symbol >>= 1;
+  }
+}
+
+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+{
+  UInt32 price = 0;
+  symbol |= (1 << numBitLevels);
+  while (symbol != 1)
+  {
+    price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
+    symbol >>= 1;
+  }
+  return price;
+}
+
+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+{
+  UInt32 price = 0;
+  UInt32 m = 1;
+  int i;
+  for (i = numBitLevels; i != 0; i--)
+  {
+    UInt32 bit = symbol & 1;
+    symbol >>= 1;
+    price += GET_PRICEa(probs[m], bit);
+    m = (m << 1) | bit;
+  }
+  return price;
+}
+
+
+static void LenEnc_Init(CLenEnc *p)
+{
+  unsigned i;
+  p->choice = p->choice2 = kProbInitValue;
+  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
+    p->low[i] = kProbInitValue;
+  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
+    p->mid[i] = kProbInitValue;
+  for (i = 0; i < kLenNumHighSymbols; i++)
+    p->high[i] = kProbInitValue;
+}
+
+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
+{
+  if (symbol < kLenNumLowSymbols)
+  {
+    RangeEnc_EncodeBit(rc, &p->choice, 0);
+    RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
+  }
+  else
+  {
+    RangeEnc_EncodeBit(rc, &p->choice, 1);
+    if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
+    {
+      RangeEnc_EncodeBit(rc, &p->choice2, 0);
+      RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
+    }
+    else
+    {
+      RangeEnc_EncodeBit(rc, &p->choice2, 1);
+      RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
+    }
+  }
+}
+
+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
+{
+  UInt32 a0 = GET_PRICE_0a(p->choice);
+  UInt32 a1 = GET_PRICE_1a(p->choice);
+  UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
+  UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
+  UInt32 i = 0;
+  for (i = 0; i < kLenNumLowSymbols; i++)
+  {
+    if (i >= numSymbols)
+      return;
+    prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
+  }
+  for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
+  {
+    if (i >= numSymbols)
+      return;
+    prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
+  }
+  for (; i < numSymbols; i++)
+    prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
+}
+
+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
+{
+  LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
+  p->counters[posState] = p->tableSize;
+}
+
+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
+{
+  UInt32 posState;
+  for (posState = 0; posState < numPosStates; posState++)
+    LenPriceEnc_UpdateTable(p, posState, ProbPrices);
+}
+
+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
+{
+  LenEnc_Encode(&p->p, rc, symbol, posState);
+  if (updatePrice)
+    if (--p->counters[posState] == 0)
+      LenPriceEnc_UpdateTable(p, posState, ProbPrices);
+}
+
+
+
+
+static void MovePos(CLzmaEnc *p, UInt32 num)
+{
+  #ifdef SHOW_STAT
+  ttt += num;
+  printf("\n MovePos %d", num);
+  #endif
+  if (num != 0)
+  {
+    p->additionalOffset += num;
+    p->matchFinder.Skip(p->matchFinderObj, num);
+  }
+}
+
+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
+{
+  UInt32 lenRes = 0, numDistancePairs;
+  numDistancePairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matchDistances);
+  #ifdef SHOW_STAT
+  printf("\n i = %d numPairs = %d    ", ttt, numDistancePairs / 2);
+  if (ttt >= 61994)
+    ttt = ttt;
+
+  ttt++;
+  {
+    UInt32 i;
+  for (i = 0; i < numDistancePairs; i += 2)
+    printf("%2d %6d   | ", p->matchDistances[i], p->matchDistances[i + 1]);
+  }
+  #endif
+  if (numDistancePairs > 0)
+  {
+    lenRes = p->matchDistances[numDistancePairs - 2];
+    if (lenRes == p->numFastBytes)
+    {
+      UInt32 numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) + 1;
+      const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+      UInt32 distance = p->matchDistances[numDistancePairs - 1] + 1;
+      if (numAvail > LZMA_MATCH_LEN_MAX)
+        numAvail = LZMA_MATCH_LEN_MAX;
+
+      {
+        const Byte *pby2 = pby - distance;
+        for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
+      }
+    }
+  }
+  p->additionalOffset++;
+  *numDistancePairsRes = numDistancePairs;
+  return lenRes;
+}
+
+
+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
+#define IsShortRep(p) ((p)->backPrev == 0)
+
+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
+{
+  return
+    GET_PRICE_0(p->isRepG0[state]) +
+    GET_PRICE_0(p->isRep0Long[state][posState]);
+}
+
+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
+{
+  UInt32 price;
+  if (repIndex == 0)
+  {
+    price = GET_PRICE_0(p->isRepG0[state]);
+    price += GET_PRICE_1(p->isRep0Long[state][posState]);
+  }
+  else
+  {
+    price = GET_PRICE_1(p->isRepG0[state]);
+    if (repIndex == 1)
+      price += GET_PRICE_0(p->isRepG1[state]);
+    else
+    {
+      price += GET_PRICE_1(p->isRepG1[state]);
+      price += GET_PRICE(p->isRepG2[state], repIndex - 2);
+    }
+  }
+  return price;
+}
+
+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
+{
+  return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
+    GetPureRepPrice(p, repIndex, state, posState);
+}
+
+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
+{
+  UInt32 posMem = p->opt[cur].posPrev;
+  UInt32 backMem = p->opt[cur].backPrev;
+  p->optimumEndIndex = cur;
+  do
+  {
+    if (p->opt[cur].prev1IsChar)
+    {
+      MakeAsChar(&p->opt[posMem])
+      p->opt[posMem].posPrev = posMem - 1;
+      if (p->opt[cur].prev2)
+      {
+        p->opt[posMem - 1].prev1IsChar = False;
+        p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
+        p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
+      }
+    }
+    {
+      UInt32 posPrev = posMem;
+      UInt32 backCur = backMem;
+
+      backMem = p->opt[posPrev].backPrev;
+      posMem = p->opt[posPrev].posPrev;
+
+      p->opt[posPrev].backPrev = backCur;
+      p->opt[posPrev].posPrev = cur;
+      cur = posPrev;
+    }
+  }
+  while (cur != 0);
+  *backRes = p->opt[0].backPrev;
+  p->optimumCurrentIndex  = p->opt[0].posPrev;
+  return p->optimumCurrentIndex;
+}
+
+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
+
+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
+{
+  UInt32 numAvailableBytes, lenMain, numDistancePairs;
+  const Byte *data;
+  UInt32 reps[LZMA_NUM_REPS];
+  UInt32 repLens[LZMA_NUM_REPS];
+  UInt32 repMaxIndex, i;
+  UInt32 *matchDistances;
+  Byte currentByte, matchByte;
+  UInt32 posState;
+  UInt32 matchPrice, repMatchPrice;
+  UInt32 lenEnd;
+  UInt32 len;
+  UInt32 normalMatchPrice;
+  UInt32 cur;
+  if (p->optimumEndIndex != p->optimumCurrentIndex)
+  {
+    const COptimal *opt = &p->opt[p->optimumCurrentIndex];
+    UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
+    *backRes = opt->backPrev;
+    p->optimumCurrentIndex = opt->posPrev;
+    return lenRes;
+  }
+  p->optimumCurrentIndex = p->optimumEndIndex = 0;
+
+  numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+
+  if (!p->longestMatchWasFound)
+  {
+    lenMain = ReadMatchDistances(p, &numDistancePairs);
+  }
+  else
+  {
+    lenMain = p->longestMatchLength;
+    numDistancePairs = p->numDistancePairs;
+    p->longestMatchWasFound = False;
+  }
+
+  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+  if (numAvailableBytes < 2)
+  {
+    *backRes = (UInt32)(-1);
+    return 1;
+  }
+  if (numAvailableBytes > LZMA_MATCH_LEN_MAX)
+    numAvailableBytes = LZMA_MATCH_LEN_MAX;
+
+  repMaxIndex = 0;
+  for (i = 0; i < LZMA_NUM_REPS; i++)
+  {
+    UInt32 lenTest;
+    const Byte *data2;
+    reps[i] = p->reps[i];
+    data2 = data - (reps[i] + 1);
+    if (data[0] != data2[0] || data[1] != data2[1])
+    {
+      repLens[i] = 0;
+      continue;
+    }
+    for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++);
+    repLens[i] = lenTest;
+    if (lenTest > repLens[repMaxIndex])
+      repMaxIndex = i;
+  }
+  if (repLens[repMaxIndex] >= p->numFastBytes)
+  {
+    UInt32 lenRes;
+    *backRes = repMaxIndex;
+    lenRes = repLens[repMaxIndex];
+    MovePos(p, lenRes - 1);
+    return lenRes;
+  }
+
+  matchDistances = p->matchDistances;
+  if (lenMain >= p->numFastBytes)
+  {
+    *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS;
+    MovePos(p, lenMain - 1);
+    return lenMain;
+  }
+  currentByte = *data;
+  matchByte = *(data - (reps[0] + 1));
+
+  if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
+  {
+    *backRes = (UInt32)-1;
+    return 1;
+  }
+
+  p->opt[0].state = (CState)p->state;
+
+  posState = (position & p->pbMask);
+
+  {
+    const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+    p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
+        (!IsCharState(p->state) ?
+          LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) :
+          LitEnc_GetPrice(probs, currentByte, p->ProbPrices));
+  }
+
+  MakeAsChar(&p->opt[1]);
+
+  matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
+  repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
+
+  if (matchByte == currentByte)
+  {
+    UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
+    if (shortRepPrice < p->opt[1].price)
+    {
+      p->opt[1].price = shortRepPrice;
+      MakeAsShortRep(&p->opt[1]);
+    }
+  }
+  lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
+
+  if (lenEnd < 2)
+  {
+    *backRes = p->opt[1].backPrev;
+    return 1;
+  }
+
+  p->opt[1].posPrev = 0;
+  for (i = 0; i < LZMA_NUM_REPS; i++)
+    p->opt[0].backs[i] = reps[i];
+
+  len = lenEnd;
+  do
+    p->opt[len--].price = kInfinityPrice;
+  while (len >= 2);
+
+  for (i = 0; i < LZMA_NUM_REPS; i++)
+  {
+    UInt32 repLen = repLens[i];
+    UInt32 price;
+    if (repLen < 2)
+      continue;
+    price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
+    do
+    {
+      UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
+      COptimal *opt = &p->opt[repLen];
+      if (curAndLenPrice < opt->price)
+      {
+        opt->price = curAndLenPrice;
+        opt->posPrev = 0;
+        opt->backPrev = i;
+        opt->prev1IsChar = False;
+      }
+    }
+    while (--repLen >= 2);
+  }
+
+  normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
+
+  len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+  if (len <= lenMain)
+  {
+    UInt32 offs = 0;
+    while (len > matchDistances[offs])
+      offs += 2;
+    for (; ; len++)
+    {
+      COptimal *opt;
+      UInt32 distance = matchDistances[offs + 1];
+
+      UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
+      UInt32 lenToPosState = GetLenToPosState(len);
+      if (distance < kNumFullDistances)
+        curAndLenPrice += p->distancesPrices[lenToPosState][distance];
+      else
+      {
+        UInt32 slot;
+        GetPosSlot2(distance, slot);
+        curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
+      }
+      opt = &p->opt[len];
+      if (curAndLenPrice < opt->price)
+      {
+        opt->price = curAndLenPrice;
+        opt->posPrev = 0;
+        opt->backPrev = distance + LZMA_NUM_REPS;
+        opt->prev1IsChar = False;
+      }
+      if (len == matchDistances[offs])
+      {
+        offs += 2;
+        if (offs == numDistancePairs)
+          break;
+      }
+    }
+  }
+
+  cur = 0;
+
+    #ifdef SHOW_STAT2
+    if (position >= 0)
+    {
+      unsigned i;
+      printf("\n pos = %4X", position);
+      for (i = cur; i <= lenEnd; i++)
+      printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
+    }
+    #endif
+
+  for (;;)
+  {
+    UInt32 numAvailableBytesFull, newLen, numDistancePairs;
+    COptimal *curOpt;
+    UInt32 posPrev;
+    UInt32 state;
+    UInt32 curPrice;
+    Bool nextIsChar;
+    const Byte *data;
+    Byte currentByte, matchByte;
+    UInt32 posState;
+    UInt32 curAnd1Price;
+    COptimal *nextOpt;
+    UInt32 matchPrice, repMatchPrice;
+    UInt32 numAvailableBytes;
+    UInt32 startLen;
+
+    cur++;
+    if (cur == lenEnd)
+      return Backward(p, backRes, cur);
+
+    numAvailableBytesFull = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+    newLen = ReadMatchDistances(p, &numDistancePairs);
+    if (newLen >= p->numFastBytes)
+    {
+      p->numDistancePairs = numDistancePairs;
+      p->longestMatchLength = newLen;
+      p->longestMatchWasFound = True;
+      return Backward(p, backRes, cur);
+    }
+    position++;
+    curOpt = &p->opt[cur];
+    posPrev = curOpt->posPrev;
+    if (curOpt->prev1IsChar)
+    {
+      posPrev--;
+      if (curOpt->prev2)
+      {
+        state = p->opt[curOpt->posPrev2].state;
+        if (curOpt->backPrev2 < LZMA_NUM_REPS)
+          state = kRepNextStates[state];
+        else
+          state = kMatchNextStates[state];
+      }
+      else
+        state = p->opt[posPrev].state;
+      state = kLiteralNextStates[state];
+    }
+    else
+      state = p->opt[posPrev].state;
+    if (posPrev == cur - 1)
+    {
+      if (IsShortRep(curOpt))
+        state = kShortRepNextStates[state];
+      else
+        state = kLiteralNextStates[state];
+    }
+    else
+    {
+      UInt32 pos;
+      const COptimal *prevOpt;
+      if (curOpt->prev1IsChar && curOpt->prev2)
+      {
+        posPrev = curOpt->posPrev2;
+        pos = curOpt->backPrev2;
+        state = kRepNextStates[state];
+      }
+      else
+      {
+        pos = curOpt->backPrev;
+        if (pos < LZMA_NUM_REPS)
+          state = kRepNextStates[state];
+        else
+          state = kMatchNextStates[state];
+      }
+      prevOpt = &p->opt[posPrev];
+      if (pos < LZMA_NUM_REPS)
+      {
+        UInt32 i;
+        reps[0] = prevOpt->backs[pos];
+        for (i = 1; i <= pos; i++)
+          reps[i] = prevOpt->backs[i - 1];
+        for (; i < LZMA_NUM_REPS; i++)
+          reps[i] = prevOpt->backs[i];
+      }
+      else
+      {
+        UInt32 i;
+        reps[0] = (pos - LZMA_NUM_REPS);
+        for (i = 1; i < LZMA_NUM_REPS; i++)
+          reps[i] = prevOpt->backs[i - 1];
+      }
+    }
+    curOpt->state = (CState)state;
+
+    curOpt->backs[0] = reps[0];
+    curOpt->backs[1] = reps[1];
+    curOpt->backs[2] = reps[2];
+    curOpt->backs[3] = reps[3];
+
+    curPrice = curOpt->price;
+    nextIsChar = False;
+    data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+    currentByte = *data;
+    matchByte = *(data - (reps[0] + 1));
+
+    posState = (position & p->pbMask);
+
+    curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
+    {
+      const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+      curAnd1Price +=
+        (!IsCharState(state) ?
+          LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) :
+          LitEnc_GetPrice(probs, currentByte, p->ProbPrices));
+    }
+
+    nextOpt = &p->opt[cur + 1];
+
+    if (curAnd1Price < nextOpt->price)
+    {
+      nextOpt->price = curAnd1Price;
+      nextOpt->posPrev = cur;
+      MakeAsChar(nextOpt);
+      nextIsChar = True;
+    }
+
+    matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
+    repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
+
+    if (matchByte == currentByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
+    {
+      UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
+      if (shortRepPrice <= nextOpt->price)
+      {
+        nextOpt->price = shortRepPrice;
+        nextOpt->posPrev = cur;
+        MakeAsShortRep(nextOpt);
+        nextIsChar = True;
+      }
+    }
+
+    {
+      UInt32 temp = kNumOpts - 1 - cur;
+      if (temp <  numAvailableBytesFull)
+        numAvailableBytesFull = temp;
+    }
+    numAvailableBytes = numAvailableBytesFull;
+
+    if (numAvailableBytes < 2)
+      continue;
+    if (numAvailableBytes > p->numFastBytes)
+      numAvailableBytes = p->numFastBytes;
+    if (!nextIsChar && matchByte != currentByte) /* speed optimization */
+    {
+      /* try Literal + rep0 */
+      UInt32 temp;
+      UInt32 lenTest2;
+      const Byte *data2 = data - (reps[0] + 1);
+      UInt32 limit = p->numFastBytes + 1;
+      if (limit > numAvailableBytesFull)
+        limit = numAvailableBytesFull;
+
+      for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
+      lenTest2 = temp - 1;
+      if (lenTest2 >= 2)
+      {
+        UInt32 state2 = kLiteralNextStates[state];
+        UInt32 posStateNext = (position + 1) & p->pbMask;
+        UInt32 nextRepMatchPrice = curAnd1Price +
+            GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+            GET_PRICE_1(p->isRep[state2]);
+        /* for (; lenTest2 >= 2; lenTest2--) */
+        {
+          UInt32 curAndLenPrice;
+          COptimal *opt;
+          UInt32 offset = cur + 1 + lenTest2;
+          while (lenEnd < offset)
+            p->opt[++lenEnd].price = kInfinityPrice;
+          curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+          opt = &p->opt[offset];
+          if (curAndLenPrice < opt->price)
+          {
+            opt->price = curAndLenPrice;
+            opt->posPrev = cur + 1;
+            opt->backPrev = 0;
+            opt->prev1IsChar = True;
+            opt->prev2 = False;
+          }
+        }
+      }
+    }
+
+    startLen = 2; /* speed optimization */
+    {
+    UInt32 repIndex;
+    for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
+    {
+      UInt32 lenTest;
+      UInt32 lenTestTemp;
+      UInt32 price;
+      const Byte *data2 = data - (reps[repIndex] + 1);
+      if (data[0] != data2[0] || data[1] != data2[1])
+        continue;
+      for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++);
+      while (lenEnd < cur + lenTest)
+        p->opt[++lenEnd].price = kInfinityPrice;
+      lenTestTemp = lenTest;
+      price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
+      do
+      {
+        UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
+        COptimal *opt = &p->opt[cur + lenTest];
+        if (curAndLenPrice < opt->price)
+        {
+          opt->price = curAndLenPrice;
+          opt->posPrev = cur;
+          opt->backPrev = repIndex;
+          opt->prev1IsChar = False;
+        }
+      }
+      while (--lenTest >= 2);
+      lenTest = lenTestTemp;
+
+      if (repIndex == 0)
+        startLen = lenTest + 1;
+
+      /* if (_maxMode) */
+        {
+          UInt32 lenTest2 = lenTest + 1;
+          UInt32 limit = lenTest2 + p->numFastBytes;
+          UInt32 nextRepMatchPrice;
+          if (limit > numAvailableBytesFull)
+            limit = numAvailableBytesFull;
+          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+          lenTest2 -= lenTest + 1;
+          if (lenTest2 >= 2)
+          {
+            UInt32 state2 = kRepNextStates[state];
+            UInt32 posStateNext = (position + lenTest) & p->pbMask;
+            UInt32 curAndLenCharPrice =
+                price + p->repLenEnc.prices[posState][lenTest - 2] +
+                GET_PRICE_0(p->isMatch[state2][posStateNext]) +
+                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+                    data[lenTest], data2[lenTest], p->ProbPrices);
+            state2 = kLiteralNextStates[state2];
+            posStateNext = (position + lenTest + 1) & p->pbMask;
+            nextRepMatchPrice = curAndLenCharPrice +
+                GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+                GET_PRICE_1(p->isRep[state2]);
+
+            /* for (; lenTest2 >= 2; lenTest2--) */
+            {
+              UInt32 curAndLenPrice;
+              COptimal *opt;
+              UInt32 offset = cur + lenTest + 1 + lenTest2;
+              while (lenEnd < offset)
+                p->opt[++lenEnd].price = kInfinityPrice;
+              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+              opt = &p->opt[offset];
+              if (curAndLenPrice < opt->price)
+              {
+                opt->price = curAndLenPrice;
+                opt->posPrev = cur + lenTest + 1;
+                opt->backPrev = 0;
+                opt->prev1IsChar = True;
+                opt->prev2 = True;
+                opt->posPrev2 = cur;
+                opt->backPrev2 = repIndex;
+              }
+            }
+          }
+        }
+    }
+    }
+    /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
+    if (newLen > numAvailableBytes)
+    {
+      newLen = numAvailableBytes;
+      for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2);
+      matchDistances[numDistancePairs] = newLen;
+      numDistancePairs += 2;
+    }
+    if (newLen >= startLen)
+    {
+      UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
+      UInt32 offs, curBack, posSlot;
+      UInt32 lenTest;
+      while (lenEnd < cur + newLen)
+        p->opt[++lenEnd].price = kInfinityPrice;
+
+      offs = 0;
+      while (startLen > matchDistances[offs])
+        offs += 2;
+      curBack = matchDistances[offs + 1];
+      GetPosSlot2(curBack, posSlot);
+      for (lenTest = /*2*/ startLen; ; lenTest++)
+      {
+        UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
+        UInt32 lenToPosState = GetLenToPosState(lenTest);
+        COptimal *opt;
+        if (curBack < kNumFullDistances)
+          curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
+        else
+          curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
+
+        opt = &p->opt[cur + lenTest];
+        if (curAndLenPrice < opt->price)
+        {
+          opt->price = curAndLenPrice;
+          opt->posPrev = cur;
+          opt->backPrev = curBack + LZMA_NUM_REPS;
+          opt->prev1IsChar = False;
+        }
+
+        if (/*_maxMode && */lenTest == matchDistances[offs])
+        {
+          /* Try Match + Literal + Rep0 */
+          const Byte *data2 = data - (curBack + 1);
+          UInt32 lenTest2 = lenTest + 1;
+          UInt32 limit = lenTest2 + p->numFastBytes;
+          UInt32 nextRepMatchPrice;
+          if (limit > numAvailableBytesFull)
+            limit = numAvailableBytesFull;
+          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+          lenTest2 -= lenTest + 1;
+          if (lenTest2 >= 2)
+          {
+            UInt32 state2 = kMatchNextStates[state];
+            UInt32 posStateNext = (position + lenTest) & p->pbMask;
+            UInt32 curAndLenCharPrice = curAndLenPrice +
+                GET_PRICE_0(p->isMatch[state2][posStateNext]) +
+                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+                    data[lenTest], data2[lenTest], p->ProbPrices);
+            state2 = kLiteralNextStates[state2];
+            posStateNext = (posStateNext + 1) & p->pbMask;
+            nextRepMatchPrice = curAndLenCharPrice +
+                GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+                GET_PRICE_1(p->isRep[state2]);
+
+            /* for (; lenTest2 >= 2; lenTest2--) */
+            {
+              UInt32 offset = cur + lenTest + 1 + lenTest2;
+              UInt32 curAndLenPrice;
+              COptimal *opt;
+              while (lenEnd < offset)
+                p->opt[++lenEnd].price = kInfinityPrice;
+              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+              opt = &p->opt[offset];
+              if (curAndLenPrice < opt->price)
+              {
+                opt->price = curAndLenPrice;
+                opt->posPrev = cur + lenTest + 1;
+                opt->backPrev = 0;
+                opt->prev1IsChar = True;
+                opt->prev2 = True;
+                opt->posPrev2 = cur;
+                opt->backPrev2 = curBack + LZMA_NUM_REPS;
+              }
+            }
+          }
+          offs += 2;
+          if (offs == numDistancePairs)
+            break;
+          curBack = matchDistances[offs + 1];
+          if (curBack >= kNumFullDistances)
+            GetPosSlot2(curBack, posSlot);
+        }
+      }
+    }
+  }
+}
+
+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
+
+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
+{
+  UInt32 numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+  UInt32 lenMain, numDistancePairs;
+  const Byte *data;
+  UInt32 repLens[LZMA_NUM_REPS];
+  UInt32 repMaxIndex, i;
+  UInt32 *matchDistances;
+  UInt32 backMain;
+
+  if (!p->longestMatchWasFound)
+  {
+    lenMain = ReadMatchDistances(p, &numDistancePairs);
+  }
+  else
+  {
+    lenMain = p->longestMatchLength;
+    numDistancePairs = p->numDistancePairs;
+    p->longestMatchWasFound = False;
+  }
+
+  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+  if (numAvailableBytes > LZMA_MATCH_LEN_MAX)
+    numAvailableBytes = LZMA_MATCH_LEN_MAX;
+  if (numAvailableBytes < 2)
+  {
+    *backRes = (UInt32)(-1);
+    return 1;
+  }
+
+  repMaxIndex = 0;
+
+  for (i = 0; i < LZMA_NUM_REPS; i++)
+  {
+    const Byte *data2 = data - (p->reps[i] + 1);
+    UInt32 len;
+    if (data[0] != data2[0] || data[1] != data2[1])
+    {
+      repLens[i] = 0;
+      continue;
+    }
+    for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
+    if (len >= p->numFastBytes)
+    {
+      *backRes = i;
+      MovePos(p, len - 1);
+      return len;
+    }
+    repLens[i] = len;
+    if (len > repLens[repMaxIndex])
+      repMaxIndex = i;
+  }
+  matchDistances = p->matchDistances;
+  if (lenMain >= p->numFastBytes)
+  {
+    *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS;
+    MovePos(p, lenMain - 1);
+    return lenMain;
+  }
+
+  backMain = 0; /* for GCC */
+  if (lenMain >= 2)
+  {
+    backMain = matchDistances[numDistancePairs - 1];
+    while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1)
+    {
+      if (!ChangePair(matchDistances[numDistancePairs - 3], backMain))
+        break;
+      numDistancePairs -= 2;
+      lenMain = matchDistances[numDistancePairs - 2];
+      backMain = matchDistances[numDistancePairs - 1];
+    }
+    if (lenMain == 2 && backMain >= 0x80)
+      lenMain = 1;
+  }
+
+  if (repLens[repMaxIndex] >= 2)
+  {
+    if (repLens[repMaxIndex] + 1 >= lenMain ||
+        (repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9))) ||
+        (repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15))))
+    {
+      UInt32 lenRes;
+      *backRes = repMaxIndex;
+      lenRes = repLens[repMaxIndex];
+      MovePos(p, lenRes - 1);
+      return lenRes;
+    }
+  }
+
+  if (lenMain >= 2 && numAvailableBytes > 2)
+  {
+    UInt32 i;
+    numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+    p->longestMatchLength = ReadMatchDistances(p, &p->numDistancePairs);
+    if (p->longestMatchLength >= 2)
+    {
+      UInt32 newDistance = matchDistances[p->numDistancePairs - 1];
+      if ((p->longestMatchLength >= lenMain && newDistance < backMain) ||
+          (p->longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance)) ||
+          (p->longestMatchLength > lenMain + 1) ||
+          (p->longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain)))
+      {
+        p->longestMatchWasFound = True;
+        *backRes = (UInt32)(-1);
+        return 1;
+      }
+    }
+    data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+    for (i = 0; i < LZMA_NUM_REPS; i++)
+    {
+      UInt32 len;
+      const Byte *data2 = data - (p->reps[i] + 1);
+      if (data[1] != data2[1] || data[2] != data2[2])
+      {
+        repLens[i] = 0;
+        continue;
+      }
+      for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
+      if (len + 1 >= lenMain)
+      {
+        p->longestMatchWasFound = True;
+        *backRes = (UInt32)(-1);
+        return 1;
+      }
+    }
+    *backRes = backMain + LZMA_NUM_REPS;
+    MovePos(p, lenMain - 2);
+    return lenMain;
+  }
+  *backRes = (UInt32)(-1);
+  return 1;
+}
+
+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
+{
+  UInt32 len;
+  RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
+  RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
+  p->state = kMatchNextStates[p->state];
+  len = LZMA_MATCH_LEN_MIN;
+  LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+  RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
+  RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
+  RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
+}
+
+static SRes CheckErrors(CLzmaEnc *p)
+{
+  if (p->result != SZ_OK)
+    return p->result;
+  if (p->rc.res != SZ_OK)
+    p->result = SZ_ERROR_WRITE;
+  if (p->matchFinderBase.result != SZ_OK)
+    p->result = SZ_ERROR_READ;
+  if (p->result != SZ_OK)
+    p->finished = True;
+  return p->result;
+}
+
+static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
+{
+  /* ReleaseMFStream(); */
+  p->finished = True;
+  if (p->writeEndMark)
+    WriteEndMarker(p, nowPos & p->pbMask);
+  RangeEnc_FlushData(&p->rc);
+  RangeEnc_FlushStream(&p->rc);
+  return CheckErrors(p);
+}
+
+static void FillAlignPrices(CLzmaEnc *p)
+{
+  UInt32 i;
+  for (i = 0; i < kAlignTableSize; i++)
+    p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
+  p->alignPriceCount = 0;
+}
+
+static void FillDistancesPrices(CLzmaEnc *p)
+{
+  UInt32 tempPrices[kNumFullDistances];
+  UInt32 i, lenToPosState;
+  for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
+  {
+    UInt32 posSlot = GetPosSlot1(i);
+    UInt32 footerBits = ((posSlot >> 1) - 1);
+    UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+    tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
+  }
+
+  for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+  {
+    UInt32 posSlot;
+    const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
+    UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
+    for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
+      posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
+    for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
+      posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
+
+    {
+      UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
+      UInt32 i;
+      for (i = 0; i < kStartPosModelIndex; i++)
+        distancesPrices[i] = posSlotPrices[i];
+      for (; i < kNumFullDistances; i++)
+        distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
+    }
+  }
+  p->matchPriceCount = 0;
+}
+
+void LzmaEnc_Construct(CLzmaEnc *p)
+{
+  RangeEnc_Construct(&p->rc);
+  MatchFinder_Construct(&p->matchFinderBase);
+  #ifdef COMPRESS_MF_MT
+  MatchFinderMt_Construct(&p->matchFinderMt);
+  p->matchFinderMt.MatchFinder = &p->matchFinderBase;
+  #endif
+
+  {
+    CLzmaEncProps props;
+    LzmaEncProps_Init(&props);
+    LzmaEnc_SetProps(p, &props);
+  }
+
+  #ifndef LZMA_LOG_BSR
+  LzmaEnc_FastPosInit(p->g_FastPos);
+  #endif
+
+  LzmaEnc_InitPriceTables(p->ProbPrices);
+  p->litProbs = 0;
+  p->saveState.litProbs = 0;
+}
+
+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
+{
+  void *p;
+  p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
+  if (p != 0)
+    LzmaEnc_Construct((CLzmaEnc *)p);
+  return p;
+}
+
+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->litProbs);
+  alloc->Free(alloc, p->saveState.litProbs);
+  p->litProbs = 0;
+  p->saveState.litProbs = 0;
+}
+
+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  #ifdef COMPRESS_MF_MT
+  MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
+  #endif
+  MatchFinder_Free(&p->matchFinderBase, allocBig);
+  LzmaEnc_FreeLits(p, alloc);
+  RangeEnc_Free(&p->rc, alloc);
+}
+
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
+  alloc->Free(alloc, p);
+}
+
+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
+{
+  UInt32 nowPos32, startPos32;
+  if (p->inStream != 0)
+  {
+    p->matchFinderBase.stream = p->inStream;
+    p->matchFinder.Init(p->matchFinderObj);
+    p->inStream = 0;
+  }
+
+  if (p->finished)
+    return p->result;
+  RINOK(CheckErrors(p));
+
+  nowPos32 = (UInt32)p->nowPos64;
+  startPos32 = nowPos32;
+
+  if (p->nowPos64 == 0)
+  {
+    UInt32 numDistancePairs;
+    Byte curByte;
+    if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
+      return Flush(p, nowPos32);
+    ReadMatchDistances(p, &numDistancePairs);
+    RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
+    p->state = kLiteralNextStates[p->state];
+    curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
+    LitEnc_Encode(&p->rc, p->litProbs, curByte);
+    p->additionalOffset--;
+    nowPos32++;
+  }
+
+  if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
+  for (;;)
+  {
+    UInt32 pos, len, posState;
+
+    if (p->fastMode)
+      len = GetOptimumFast(p, &pos);
+    else
+      len = GetOptimum(p, nowPos32, &pos);
+
+    #ifdef SHOW_STAT2
+    printf("\n pos = %4X,   len = %d   pos = %d", nowPos32, len, pos);
+    #endif
+
+    posState = nowPos32 & p->pbMask;
+    if (len == 1 && pos == 0xFFFFFFFF)
+    {
+      Byte curByte;
+      CLzmaProb *probs;
+      const Byte *data;
+
+      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
+      data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+      curByte = *data;
+      probs = LIT_PROBS(nowPos32, *(data - 1));
+      if (IsCharState(p->state))
+        LitEnc_Encode(&p->rc, probs, curByte);
+      else
+        LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
+      p->state = kLiteralNextStates[p->state];
+    }
+    else
+    {
+      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
+      if (pos < LZMA_NUM_REPS)
+      {
+        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
+        if (pos == 0)
+        {
+          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
+          RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
+        }
+        else
+        {
+          UInt32 distance = p->reps[pos];
+          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
+          if (pos == 1)
+            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
+          else
+          {
+            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
+            RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
+            if (pos == 3)
+              p->reps[3] = p->reps[2];
+            p->reps[2] = p->reps[1];
+          }
+          p->reps[1] = p->reps[0];
+          p->reps[0] = distance;
+        }
+        if (len == 1)
+          p->state = kShortRepNextStates[p->state];
+        else
+        {
+          LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+          p->state = kRepNextStates[p->state];
+        }
+      }
+      else
+      {
+        UInt32 posSlot;
+        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
+        p->state = kMatchNextStates[p->state];
+        LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+        pos -= LZMA_NUM_REPS;
+        GetPosSlot(pos, posSlot);
+        RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
+
+        if (posSlot >= kStartPosModelIndex)
+        {
+          UInt32 footerBits = ((posSlot >> 1) - 1);
+          UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+          UInt32 posReduced = pos - base;
+
+          if (posSlot < kEndPosModelIndex)
+            RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
+          else
+          {
+            RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+            RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
+            p->alignPriceCount++;
+          }
+        }
+        p->reps[3] = p->reps[2];
+        p->reps[2] = p->reps[1];
+        p->reps[1] = p->reps[0];
+        p->reps[0] = pos;
+        p->matchPriceCount++;
+      }
+    }
+    p->additionalOffset -= len;
+    nowPos32 += len;
+    if (p->additionalOffset == 0)
+    {
+      UInt32 processed;
+      if (!p->fastMode)
+      {
+        if (p->matchPriceCount >= (1 << 7))
+          FillDistancesPrices(p);
+        if (p->alignPriceCount >= kAlignTableSize)
+          FillAlignPrices(p);
+      }
+      if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
+        break;
+      processed = nowPos32 - startPos32;
+      if (useLimits)
+      {
+        if (processed + kNumOpts + 300 >= maxUnpackSize ||
+            RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
+          break;
+      }
+      else if (processed >= (1 << 15))
+      {
+        p->nowPos64 += nowPos32 - startPos32;
+        return CheckErrors(p);
+      }
+    }
+  }
+  p->nowPos64 += nowPos32 - startPos32;
+  return Flush(p, nowPos32);
+}
+
+#define kBigHashDicLimit ((UInt32)1 << 24)
+
+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  UInt32 beforeSize = kNumOpts;
+  Bool btMode;
+  if (!RangeEnc_Alloc(&p->rc, alloc))
+    return SZ_ERROR_MEM;
+  btMode = (p->matchFinderBase.btMode != 0);
+  #ifdef COMPRESS_MF_MT
+  p->mtMode = (p->multiThread && !p->fastMode && btMode);
+  #endif
+
+  {
+    unsigned lclp = p->lc + p->lp;
+    if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
+    {
+      LzmaEnc_FreeLits(p, alloc);
+      p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
+      p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
+      if (p->litProbs == 0 || p->saveState.litProbs == 0)
+      {
+        LzmaEnc_FreeLits(p, alloc);
+        return SZ_ERROR_MEM;
+      }
+      p->lclp = lclp;
+    }
+  }
+
+  p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
+
+  if (beforeSize + p->dictSize < keepWindowSize)
+    beforeSize = keepWindowSize - p->dictSize;
+
+  #ifdef COMPRESS_MF_MT
+  if (p->mtMode)
+  {
+    RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
+    p->matchFinderObj = &p->matchFinderMt;
+    MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
+  }
+  else
+  #endif
+  {
+    if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
+      return SZ_ERROR_MEM;
+    p->matchFinderObj = &p->matchFinderBase;
+    MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
+  }
+  return SZ_OK;
+}
+
+void LzmaEnc_Init(CLzmaEnc *p)
+{
+  UInt32 i;
+  p->state = 0;
+  for(i = 0 ; i < LZMA_NUM_REPS; i++)
+    p->reps[i] = 0;
+
+  RangeEnc_Init(&p->rc);
+
+
+  for (i = 0; i < kNumStates; i++)
+  {
+    UInt32 j;
+    for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
+    {
+      p->isMatch[i][j] = kProbInitValue;
+      p->isRep0Long[i][j] = kProbInitValue;
+    }
+    p->isRep[i] = kProbInitValue;
+    p->isRepG0[i] = kProbInitValue;
+    p->isRepG1[i] = kProbInitValue;
+    p->isRepG2[i] = kProbInitValue;
+  }
+
+  {
+    UInt32 num = 0x300 << (p->lp + p->lc);
+    for (i = 0; i < num; i++)
+      p->litProbs[i] = kProbInitValue;
+  }
+
+  {
+    for (i = 0; i < kNumLenToPosStates; i++)
+    {
+      CLzmaProb *probs = p->posSlotEncoder[i];
+      UInt32 j;
+      for (j = 0; j < (1 << kNumPosSlotBits); j++)
+        probs[j] = kProbInitValue;
+    }
+  }
+  {
+    for(i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+      p->posEncoders[i] = kProbInitValue;
+  }
+
+  LenEnc_Init(&p->lenEnc.p);
+  LenEnc_Init(&p->repLenEnc.p);
+
+  for (i = 0; i < (1 << kNumAlignBits); i++)
+    p->posAlignEncoder[i] = kProbInitValue;
+
+  p->longestMatchWasFound = False;
+  p->optimumEndIndex = 0;
+  p->optimumCurrentIndex = 0;
+  p->additionalOffset = 0;
+
+  p->pbMask = (1 << p->pb) - 1;
+  p->lpMask = (1 << p->lp) - 1;
+}
+
+void LzmaEnc_InitPrices(CLzmaEnc *p)
+{
+  if (!p->fastMode)
+  {
+    FillDistancesPrices(p);
+    FillAlignPrices(p);
+  }
+
+  p->lenEnc.tableSize =
+  p->repLenEnc.tableSize =
+      p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
+  LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
+  LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
+}
+
+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  UInt32 i;
+  for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
+    if (p->dictSize <= ((UInt32)1 << i))
+      break;
+  p->distTableSize = i * 2;
+
+  p->finished = False;
+  p->result = SZ_OK;
+  RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
+  LzmaEnc_Init(p);
+  LzmaEnc_InitPrices(p);
+  p->nowPos64 = 0;
+  return SZ_OK;
+}
+
+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream,
+    ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  p->inStream = inStream;
+  p->rc.outStream = outStream;
+  return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
+}
+
+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
+    ISeqInStream *inStream, UInt32 keepWindowSize,
+    ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  p->inStream = inStream;
+  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+
+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
+{
+  p->seqBufInStream.funcTable.Read = MyRead;
+  p->seqBufInStream.data = src;
+  p->seqBufInStream.rem = srcLen;
+}
+
+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
+    UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  LzmaEnc_SetInputBuf(p, src, srcLen);
+  p->inStream = &p->seqBufInStream.funcTable;
+  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+
+void LzmaEnc_Finish(CLzmaEncHandle pp)
+{
+  #ifdef COMPRESS_MF_MT
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  if (p->mtMode)
+    MatchFinderMt_ReleaseStream(&p->matchFinderMt);
+  #else
+  (void)pp;
+  #endif
+}
+
+typedef struct _CSeqOutStreamBuf
+{
+  ISeqOutStream funcTable;
+  Byte *data;
+  SizeT rem;
+  Bool overflow;
+} CSeqOutStreamBuf;
+
+static size_t MyWrite(void *pp, const void *data, size_t size)
+{
+  CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
+  if (p->rem < size)
+  {
+    size = p->rem;
+    p->overflow = True;
+  }
+  memcpy(p->data, data, size);
+  p->rem -= size;
+  p->data += size;
+  return size;
+}
+
+
+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
+{
+  const CLzmaEnc *p = (CLzmaEnc *)pp;
+  return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+}
+
+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
+{
+  const CLzmaEnc *p = (CLzmaEnc *)pp;
+  return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+}
+
+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
+    Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  UInt64 nowPos64;
+  SRes res;
+  CSeqOutStreamBuf outStream;
+
+  outStream.funcTable.Write = MyWrite;
+  outStream.data = dest;
+  outStream.rem = *destLen;
+  outStream.overflow = False;
+
+  p->writeEndMark = False;
+  p->finished = False;
+  p->result = SZ_OK;
+
+  if (reInit)
+    LzmaEnc_Init(p);
+  LzmaEnc_InitPrices(p);
+  nowPos64 = p->nowPos64;
+  RangeEnc_Init(&p->rc);
+  p->rc.outStream = &outStream.funcTable;
+
+  res = LzmaEnc_CodeOneBlock(pp, True, desiredPackSize, *unpackSize);
+
+  *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
+  *destLen -= outStream.rem;
+  if (outStream.overflow)
+    return SZ_ERROR_OUTPUT_EOF;
+
+  return res;
+}
+
+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
+    ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  SRes res = SZ_OK;
+
+  #ifdef COMPRESS_MF_MT
+  Byte allocaDummy[0x300];
+  int i = 0;
+  for (i = 0; i < 16; i++)
+    allocaDummy[i] = (Byte)i;
+  #endif
+
+  RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig));
+
+  for (;;)
+  {
+    res = LzmaEnc_CodeOneBlock(pp, False, 0, 0);
+    if (res != SZ_OK || p->finished != 0)
+      break;
+    if (progress != 0)
+    {
+      res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
+      if (res != SZ_OK)
+      {
+        res = SZ_ERROR_PROGRESS;
+        break;
+      }
+    }
+  }
+  LzmaEnc_Finish(pp);
+  return res;
+}
+
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  int i;
+  UInt32 dictSize = p->dictSize;
+  if (*size < LZMA_PROPS_SIZE)
+    return SZ_ERROR_PARAM;
+  *size = LZMA_PROPS_SIZE;
+  props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
+
+  for (i = 11; i <= 30; i++)
+  {
+    if (dictSize <= ((UInt32)2 << i))
+    {
+      dictSize = (2 << i);
+      break;
+    }
+    if (dictSize <= ((UInt32)3 << i))
+    {
+      dictSize = (3 << i);
+      break;
+    }
+  }
+
+  for (i = 0; i < 4; i++)
+    props[1 + i] = (Byte)(dictSize >> (8 * i));
+  return SZ_OK;
+}
+
+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  SRes res;
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+
+  CSeqOutStreamBuf outStream;
+
+  LzmaEnc_SetInputBuf(p, src, srcLen);
+
+  outStream.funcTable.Write = MyWrite;
+  outStream.data = dest;
+  outStream.rem = *destLen;
+  outStream.overflow = False;
+
+  p->writeEndMark = writeEndMark;
+  res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable,
+      progress, alloc, allocBig);
+
+  *destLen -= outStream.rem;
+  if (outStream.overflow)
+    return SZ_ERROR_OUTPUT_EOF;
+  return res;
+}
+
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
+  SRes res;
+  if (p == 0)
+    return SZ_ERROR_MEM;
+
+  res = LzmaEnc_SetProps(p, props);
+  if (res == SZ_OK)
+  {
+    res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
+    if (res == SZ_OK)
+      res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
+          writeEndMark, progress, alloc, allocBig);
+  }
+
+  LzmaEnc_Destroy(p, alloc, allocBig);
+  return res;
+}
diff --git a/lib/arg.c b/lib/arg.c
new file mode 100644
index 0000000..ed37986
--- /dev/null
+++ b/lib/arg.c
@@ -0,0 +1,402 @@
+/* arg.c - argument parser */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/term.h>
+#include <grub/extcmd.h>
+
+/* Built-in parser for default options.  */
+#define SHORT_ARG_HELP	-100
+#define SHORT_ARG_USAGE	-101
+
+static const struct grub_arg_option help_options[] =
+  {
+    {"help", SHORT_ARG_HELP, 0,
+     "display this help and exit", 0, ARG_TYPE_NONE},
+    {"usage", SHORT_ARG_USAGE, 0,
+     "display the usage of this command and exit", 0, ARG_TYPE_NONE},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static struct grub_arg_option *
+find_short (const struct grub_arg_option *options, char c)
+{
+  struct grub_arg_option *found = 0;
+  auto struct grub_arg_option *fnd_short (const struct grub_arg_option *opt);
+
+  struct grub_arg_option *fnd_short (const struct grub_arg_option *opt)
+    {
+      while (opt->doc)
+	{
+	  if (opt->shortarg == c)
+	    return (struct grub_arg_option *) opt;
+	  opt++;
+	}
+      return 0;
+    }
+
+  if (options)
+    found = fnd_short (options);
+
+  if (! found)
+    {
+      switch (c)
+	{
+	case 'h':
+	  found = (struct grub_arg_option *) help_options;
+	  break;
+
+	case 'u':
+	  found = (struct grub_arg_option *) (help_options + 1);
+	  break;
+
+	default:
+	  break;
+	}
+    }
+
+  return found;
+}
+
+static struct grub_arg_option *
+find_long (const struct grub_arg_option *options, const char *s, int len)
+{
+  struct grub_arg_option *found = 0;
+  auto struct grub_arg_option *fnd_long (const struct grub_arg_option *opt);
+
+  struct grub_arg_option *fnd_long (const struct grub_arg_option *opt)
+    {
+      while (opt->doc)
+	{
+	  if (opt->longarg && ! grub_strncmp (opt->longarg, s, len) &&
+	      opt->longarg[len] == '\0')
+	    return (struct grub_arg_option *) opt;
+	  opt++;
+	}
+      return 0;
+    }
+
+  if (options)
+    found = fnd_long (options);
+
+  if (! found)
+    found = fnd_long (help_options);
+
+  return found;
+}
+
+static void
+show_usage (grub_extcmd_t cmd)
+{
+  grub_printf ("Usage: %s\n", cmd->cmd->summary);
+}
+
+void
+grub_arg_show_help (grub_extcmd_t cmd)
+{
+  auto void showargs (const struct grub_arg_option *opt);
+  int h_is_used = 0;
+  int u_is_used = 0;
+
+  auto void showargs (const struct grub_arg_option *opt)
+    {
+      for (; opt->doc; opt++)
+	{
+	  int spacing = 20;
+
+	  if (opt->shortarg && grub_isgraph (opt->shortarg))
+	    grub_printf ("-%c%c ", opt->shortarg, opt->longarg ? ',':' ');
+	  else if (opt->shortarg == SHORT_ARG_HELP && ! h_is_used)
+	    grub_printf ("-h, ");
+	  else if (opt->shortarg == SHORT_ARG_USAGE && ! u_is_used)
+	    grub_printf ("-u, ");
+	  else
+	    grub_printf ("    ");
+
+	  if (opt->longarg)
+	    {
+	      grub_printf ("--%s", opt->longarg);
+	      spacing -= grub_strlen (opt->longarg) + 2;
+
+	      if (opt->arg)
+		{
+		  grub_printf ("=%s", opt->arg);
+		  spacing -= grub_strlen (opt->arg) + 1;
+		}
+	    }
+
+	  const char *doc = opt->doc;
+	  for (;;)
+	    {
+	      while (spacing-- > 0)
+		grub_putchar (' ');
+
+	      while (*doc && *doc != '\n')
+		grub_putchar (*doc++);
+	      grub_putchar ('\n');
+
+	      if (! *doc)
+		break;
+	      doc++;
+	      spacing = 4 + 20;
+	    }
+
+	  switch (opt->shortarg)
+	    {
+	    case 'h':
+	      h_is_used = 1;
+	      break;
+
+	    case 'u':
+	      u_is_used = 1;
+	      break;
+
+	    default:
+	      break;
+	    }
+	}
+    }
+
+  show_usage (cmd);
+  grub_printf ("%s\n\n", cmd->cmd->description);
+  if (cmd->options)
+    showargs (cmd->options);
+  showargs (help_options);
+#if 0
+  grub_printf ("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
+#endif
+}
+
+
+static int
+parse_option (grub_extcmd_t cmd, int key, char *arg, struct grub_arg_list *usr)
+{
+  switch (key)
+    {
+    case SHORT_ARG_HELP:
+      grub_arg_show_help (cmd);
+      return -1;
+
+    case SHORT_ARG_USAGE:
+      show_usage (cmd);
+      return -1;
+
+    default:
+      {
+	int found = -1;
+	int i = 0;
+	const struct grub_arg_option *opt = cmd->options;
+
+	while (opt->doc)
+	  {
+	    if (opt->shortarg && key == opt->shortarg)
+	      {
+		found = i;
+		break;
+	      }
+	    opt++;
+	    i++;
+	  }
+
+	if (found == -1)
+	  return -1;
+
+	usr[found].set = 1;
+	usr[found].arg = arg;
+      }
+    }
+
+  return 0;
+}
+
+int
+grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
+		struct grub_arg_list *usr, char ***args, int *argnum)
+{
+  int curarg;
+  int arglen;
+  int complete = 0;
+  char **argl = 0;
+  int num = 0;
+  auto grub_err_t add_arg (char *s);
+
+  grub_err_t add_arg (char *s)
+    {
+      argl = grub_realloc (argl, (++num) * sizeof (char *));
+      if (! argl)
+	return grub_errno;
+      argl[num - 1] = s;
+      return 0;
+    }
+
+
+  for (curarg = 0; curarg < argc; curarg++)
+    {
+      char *arg = argv[curarg];
+      struct grub_arg_option *opt;
+      char *option = 0;
+
+      /* No option is used.  */
+      if (arg[0] != '-' || grub_strlen (arg) == 1)
+	{
+	  if (add_arg (arg) != 0)
+	    goto fail;
+
+	  continue;
+	}
+
+      /* One or more short options.  */
+      if (arg[1] != '-')
+	{
+	  char *curshort = arg + 1;
+
+	  while (1)
+	    {
+	      opt = find_short (cmd->options, *curshort);
+	      if (! opt)
+		{
+		  grub_error (GRUB_ERR_BAD_ARGUMENT,
+			      "Unknown argument `-%c'\n", *curshort);
+		  goto fail;
+		}
+
+	      curshort++;
+
+	      /* Parse all arguments here except the last one because
+		 it can have an argument value.  */
+	      if (*curshort)
+		{
+		  if (parse_option (cmd, opt->shortarg, 0, usr) || grub_errno)
+		    goto fail;
+		}
+	      else
+		{
+		  if (opt->type != ARG_TYPE_NONE)
+		    {
+		      if (curarg + 1 < argc)
+			{
+			  char *nextarg = argv[curarg + 1];
+			  if (!(opt->flags & GRUB_ARG_OPTION_OPTIONAL)
+			      || (grub_strlen (nextarg) < 2 || nextarg[0] != '-'))
+			    option = argv[++curarg];
+			}
+		    }
+		  break;
+		}
+	    }
+
+	}
+      else /* The argument starts with "--".  */
+	{
+	  /* If the argument "--" is used just pass the other
+	     arguments.  */
+	  if (grub_strlen (arg) == 2)
+	    {
+	      for (curarg++; curarg < argc; curarg++)
+		if (add_arg (argv[curarg]) != 0)
+		  goto fail;
+	      break;
+	    }
+
+	  option = grub_strchr (arg, '=');
+	  if (option) {
+	    arglen = option - arg - 2;
+	    option++;
+	  } else
+	    arglen = grub_strlen (arg) - 2;
+
+	  opt = find_long (cmd->options, arg + 2, arglen);
+	  if (! opt)
+	    {
+	      grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown argument `%s'\n", arg);
+	      goto fail;
+	    }
+	}
+
+      if (! (opt->type == ARG_TYPE_NONE
+	     || (! option && (opt->flags & GRUB_ARG_OPTION_OPTIONAL))))
+	{
+	  if (! option)
+	    {
+	      grub_error (GRUB_ERR_BAD_ARGUMENT,
+			  "Missing mandatory option for `%s'\n", opt->longarg);
+	      goto fail;
+	    }
+
+	  switch (opt->type)
+	    {
+	    case ARG_TYPE_NONE:
+	      /* This will never happen.  */
+	      break;
+
+	    case ARG_TYPE_STRING:
+		  /* No need to do anything.  */
+	      break;
+
+	    case ARG_TYPE_INT:
+	      {
+		char *tail;
+
+		grub_strtoul (option, &tail, 0);
+		if (tail == 0 || tail == option || *tail != '\0' || grub_errno)
+		  {
+		    grub_error (GRUB_ERR_BAD_ARGUMENT,
+				"The argument `%s' requires an integer.",
+				arg);
+
+		    goto fail;
+		  }
+		break;
+	      }
+
+	    case ARG_TYPE_DEVICE:
+	    case ARG_TYPE_DIR:
+	    case ARG_TYPE_FILE:
+	    case ARG_TYPE_PATHNAME:
+	      /* XXX: Not implemented.  */
+	      break;
+	    }
+	  if (parse_option (cmd, opt->shortarg, option, usr) || grub_errno)
+	    goto fail;
+	}
+      else
+	{
+	  if (option)
+	    {
+	      grub_error (GRUB_ERR_BAD_ARGUMENT,
+			  "A value was assigned to the argument `%s' while it "
+			  "doesn't require an argument\n", arg);
+	      goto fail;
+	    }
+
+	  if (parse_option (cmd, opt->shortarg, 0, usr) || grub_errno)
+	    goto fail;
+	}
+    }
+
+  complete = 1;
+
+  *args = argl;
+  *argnum = num;
+
+ fail:
+  return complete;
+}
diff --git a/lib/crc.c b/lib/crc.c
new file mode 100644
index 0000000..bc0d8aa
--- /dev/null
+++ b/lib/crc.c
@@ -0,0 +1,75 @@
+/* crc.c - crc function  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/lib/crc.h>
+
+static grub_uint32_t crc32_table [256];
+
+static void
+init_crc32_table (void)
+{
+  auto grub_uint32_t reflect (grub_uint32_t ref, int len);
+  grub_uint32_t reflect (grub_uint32_t ref, int len)
+    {
+      grub_uint32_t result = 0;
+      int i;
+
+      for (i = 1; i <= len; i++)
+        {
+          if (ref & 1)
+            result |= 1 << (len - i);
+          ref >>= 1;
+        }
+
+      return result;
+    }
+
+  grub_uint32_t polynomial = 0x04c11db7;
+  int i, j;
+
+  for(i = 0; i < 256; i++)
+    {
+      crc32_table[i] = reflect(i, 8) << 24;
+      for (j = 0; j < 8; j++)
+        crc32_table[i] = (crc32_table[i] << 1) ^
+            (crc32_table[i] & (1 << 31) ? polynomial : 0);
+      crc32_table[i] = reflect(crc32_table[i], 32);
+    }
+}
+
+grub_uint32_t
+grub_getcrc32 (grub_uint32_t crc, void *buf, int size)
+{
+  int i;
+  grub_uint8_t *data = buf;
+
+  if (! crc32_table[1])
+    init_crc32_table ();
+
+  crc^= 0xffffffff;
+
+  for (i = 0; i < size; i++)
+    {
+      crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *data];
+      data++;
+    }
+
+  return crc ^ 0xffffffff;
+}
diff --git a/lib/efi/datetime.c b/lib/efi/datetime.c
new file mode 100644
index 0000000..0a91c34
--- /dev/null
+++ b/lib/efi/datetime.c
@@ -0,0 +1,79 @@
+/* kern/efi/datetime.c - efi datetime function.
+ *
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/datetime.h>
+
+grub_err_t
+grub_get_datetime (struct grub_datetime *datetime)
+{
+  grub_efi_status_t status;
+  struct grub_efi_time efi_time;
+
+  status = efi_call_2 (grub_efi_system_table->runtime_services->get_time,
+                       &efi_time, 0);
+
+  if (status)
+    return grub_error (GRUB_ERR_INVALID_COMMAND,
+                       "can\'t get datetime using efi");
+  else
+    {
+      datetime->year = efi_time.year;
+      datetime->month = efi_time.month;
+      datetime->day = efi_time.day;
+      datetime->hour = efi_time.hour;
+      datetime->minute = efi_time.minute;
+      datetime->second = efi_time.second;
+    }
+
+  return 0;
+}
+
+grub_err_t
+grub_set_datetime (struct grub_datetime *datetime)
+{
+  grub_efi_status_t status;
+  struct grub_efi_time efi_time;
+
+  status = efi_call_2 (grub_efi_system_table->runtime_services->get_time,
+                       &efi_time, 0);
+
+  if (status)
+    return grub_error (GRUB_ERR_INVALID_COMMAND,
+                       "can\'t get datetime using efi");
+
+  efi_time.year = datetime->year;
+  efi_time.month = datetime->month;
+  efi_time.day = datetime->day;
+  efi_time.hour = datetime->hour;
+  efi_time.minute = datetime->minute;
+  efi_time.second = datetime->second;
+
+  status = efi_call_1 (grub_efi_system_table->runtime_services->set_time,
+                       &efi_time);
+
+  if (status)
+    return grub_error (GRUB_ERR_INVALID_COMMAND,
+                       "can\'t set datetime using efi");
+
+  return 0;
+}
diff --git a/lib/envblk.c b/lib/envblk.c
new file mode 100644
index 0000000..311927b
--- /dev/null
+++ b/lib/envblk.c
@@ -0,0 +1,296 @@
+/* envblk.c - Common functions for environment block.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/lib/envblk.h>
+
+grub_envblk_t
+grub_envblk_open (char *buf, grub_size_t size)
+{
+  grub_envblk_t envblk;
+
+  if (size < sizeof (GRUB_ENVBLK_SIGNATURE)
+      || grub_memcmp (buf, GRUB_ENVBLK_SIGNATURE,
+                      sizeof (GRUB_ENVBLK_SIGNATURE) - 1))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
+      return 0;
+    }
+
+  envblk = grub_malloc (sizeof (*envblk));
+  if (envblk)
+    {
+      envblk->buf = buf;
+      envblk->size = size;
+    }
+
+  return envblk;
+}
+
+void
+grub_envblk_close (grub_envblk_t envblk)
+{
+  grub_free (envblk->buf);
+  grub_free (envblk);
+}
+
+static int
+escaped_value_len (const char *value)
+{
+  int n = 0;
+  char *p;
+
+  for (p = (char *) value; *p; p++)
+    {
+      if (*p == '\\' || *p == '\n')
+        n += 2;
+      else
+        n++;
+    }
+
+  return n;
+}
+
+static char *
+find_next_line (char *p, const char *pend)
+{
+  while (p < pend)
+    {
+      if (*p == '\\')
+        p += 2;
+      else if (*p == '\n')
+        break;
+      else
+        p++;
+    }
+
+  return p + 1;
+}
+
+int
+grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value)
+{
+  char *p, *pend;
+  char *space;
+  int found = 0;
+  int nl;
+  int vl;
+  int i;
+
+  nl = grub_strlen (name);
+  vl = escaped_value_len (value);
+  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
+  pend = envblk->buf + envblk->size;
+
+  /* First, look at free space.  */
+  for (space = pend - 1; *space == '#'; space--)
+    ;
+
+  if (*space != '\n')
+    /* Broken.  */
+    return 0;
+
+  space++;
+
+  while (p + nl + 1 < space)
+    {
+      if (grub_memcmp (p, name, nl) == 0 && p[nl] == '=')
+        {
+          int len;
+
+          /* Found the same name.  */
+          p += nl + 1;
+
+          /* Check the length of the current value.  */
+          len = 0;
+          while (p + len < pend && p[len] != '\n')
+            {
+              if (p[len] == '\\')
+                len += 2;
+              else
+                len++;
+            }
+
+          if (p + len >= pend)
+            /* Broken.  */
+            return 0;
+
+          if (pend - space < vl - len)
+            /* No space.  */
+            return 0;
+
+          if (vl < len)
+            {
+              /* Move the following characters backward, and fill the new
+                 space with harmless characters.  */
+              grub_memmove (p + vl, p + len, pend - (p + len));
+              grub_memset (space + len - vl, '#', len - vl);
+            }
+          else
+            /* Move the following characters forward.  */
+            grub_memmove (p + vl, p + len, pend - (p + vl));
+
+          found = 1;
+          break;
+        }
+
+      p = find_next_line (p, pend);
+    }
+
+  if (! found)
+    {
+      /* Append a new variable.  */
+
+      if (pend - space < nl + 1 + vl + 1)
+        /* No space.  */
+        return 0;
+
+      grub_memcpy (space, name, nl);
+      p = space + nl;
+      *p++ = '=';
+    }
+
+  /* Write the value.  */
+  for (i = 0; value[i]; i++)
+    {
+      if (value[i] == '\\' || value[i] == '\n')
+        *p++ = '\\';
+
+      *p++ = value[i];
+    }
+
+  *p = '\n';
+  return 1;
+}
+
+void
+grub_envblk_delete (grub_envblk_t envblk, const char *name)
+{
+  char *p, *pend;
+  int nl;
+
+  nl = grub_strlen (name);
+  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
+  pend = envblk->buf + envblk->size;
+
+  while (p + nl + 1 < pend)
+    {
+      if (grub_memcmp (p, name, nl) == 0 && p[nl] == '=')
+        {
+          /* Found.  */
+          int len = nl + 1;
+
+          while (p + len < pend)
+            {
+              if (p[len] == '\n')
+                break;
+              else if (p[len] == '\\')
+                len += 2;
+              else
+                len++;
+            }
+
+          if (p + len >= pend)
+            /* Broken.  */
+            return;
+
+          len++;
+          grub_memmove (p, p + len, pend - (p + len));
+          grub_memset (pend - len, '#', len);
+          break;
+        }
+
+      p = find_next_line (p, pend);
+    }
+}
+
+void
+grub_envblk_iterate (grub_envblk_t envblk,
+                     int hook (const char *name, const char *value))
+{
+  char *p, *pend;
+
+  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
+  pend = envblk->buf + envblk->size;
+
+  while (p < pend)
+    {
+      if (*p != '#')
+        {
+          char *name;
+          char *value;
+          char *name_start, *name_end, *value_start;
+          char *q;
+          int ret;
+
+          name_start = p;
+          while (p < pend && *p != '=')
+            p++;
+          if (p == pend)
+            /* Broken.  */
+            return;
+          name_end = p;
+
+          p++;
+          value_start = p;
+          while (p < pend)
+            {
+              if (*p == '\n')
+                break;
+              else if (*p == '\\')
+                p += 2;
+              else
+                p++;
+            }
+
+          if (p >= pend)
+            /* Broken.  */
+            return;
+
+          name = grub_malloc (p - name_start + 1);
+          if (! name)
+            /* out of memory.  */
+            return;
+
+          value = name + (value_start - name_start);
+
+          grub_memcpy (name, name_start, name_end - name_start);
+          name[name_end - name_start] = '\0';
+
+          for (p = value_start, q = value; *p != '\n'; ++p)
+            {
+              if (*p == '\\')
+                *q++ = *++p;
+              else
+                *q++ = *p;
+            }
+          *q = '\0';
+
+          ret = hook (name, value);
+          grub_free (name);
+          if (ret)
+            return;
+        }
+
+      p = find_next_line (p, pend);
+    }
+}
diff --git a/lib/hexdump.c b/lib/hexdump.c
new file mode 100644
index 0000000..c69cb09
--- /dev/null
+++ b/lib/hexdump.c
@@ -0,0 +1,84 @@
+/* hexdump.c - hexdump function */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/lib/hexdump.h>
+
+void
+hexdump (unsigned long bse, char *buf, int len)
+{
+  int pos;
+  char line[80];
+
+  while (len > 0)
+    {
+      int cnt, i;
+
+      pos = grub_sprintf (line, "%08lx  ", bse);
+      cnt = 16;
+      if (cnt > len)
+	cnt = len;
+
+      for (i = 0; i < cnt; i++)
+	{
+	  pos += grub_sprintf (&line[pos], "%02x ", (unsigned char) buf[i]);
+	  if ((i & 7) == 7)
+	    line[pos++] = ' ';
+	}
+
+      for (; i < 16; i++)
+	{
+	  pos += grub_sprintf (&line[pos], "   ");
+	  if ((i & 7) == 7)
+	    line[pos++] = ' ';
+	}
+
+      line[pos++] = '|';
+
+      for (i = 0; i < cnt; i++)
+	line[pos++] = ((buf[i] >= 32) && (buf[i] < 127)) ? buf[i] : '.';
+
+      line[pos++] = '|';
+
+      line[pos] = 0;
+
+      grub_printf ("%s\n", line);
+
+      /* Print only first and last line if more than 3 lines are identical.  */
+      if (len >= 4 * 16
+	  && ! grub_memcmp (buf, buf + 1 * 16, 16)
+	  && ! grub_memcmp (buf, buf + 2 * 16, 16)
+	  && ! grub_memcmp (buf, buf + 3 * 16, 16))
+	{
+	  grub_printf ("*\n");
+	  do
+	    {
+	      bse += 16;
+	      buf += 16;
+	      len -= 16;
+	    }
+	  while (len >= 3 * 16 && ! grub_memcmp (buf, buf + 2 * 16, 16));
+	}
+
+      bse += 16;
+      buf += 16;
+      len -= cnt;
+    }
+}
diff --git a/lib/i386/datetime.c b/lib/i386/datetime.c
new file mode 100644
index 0000000..63858ed
--- /dev/null
+++ b/lib/i386/datetime.c
@@ -0,0 +1,155 @@
+/* kern/i386/datetime.c - x86 CMOS datetime function.
+ *
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/datetime.h>
+#include <grub/i386/cmos.h>
+
+grub_err_t
+grub_get_datetime (struct grub_datetime *datetime)
+{
+  int is_bcd, is_12hour;
+  grub_uint8_t value, flag;
+
+  flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B);
+
+  is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY);
+
+  value = grub_cmos_read (GRUB_CMOS_INDEX_YEAR);
+  if (is_bcd)
+    value = grub_bcd_to_num (value);
+
+  datetime->year = value;
+  datetime->year += (value < 80) ? 2000 : 1900;
+
+  value = grub_cmos_read (GRUB_CMOS_INDEX_MONTH);
+  if (is_bcd)
+    value = grub_bcd_to_num (value);
+
+  datetime->month = value;
+
+  value = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH);
+  if (is_bcd)
+    value = grub_bcd_to_num (value);
+
+  datetime->day = value;
+
+  is_12hour = ! (flag & GRUB_CMOS_STATUS_B_24HOUR);
+
+  value = grub_cmos_read (GRUB_CMOS_INDEX_HOUR);
+  if (is_12hour)
+    {
+      is_12hour = (value & 0x80);
+
+      value &= 0x7F;
+      value--;
+    }
+
+  if (is_bcd)
+    value = grub_bcd_to_num (value);
+
+  if (is_12hour)
+    value += 12;
+
+  datetime->hour = value;
+
+  value = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE);
+  if (is_bcd)
+    value = grub_bcd_to_num (value);
+
+  datetime->minute = value;
+
+  value = grub_cmos_read (GRUB_CMOS_INDEX_SECOND);
+  if (is_bcd)
+    value = grub_bcd_to_num (value);
+
+  datetime->second = value;
+
+  return 0;
+}
+
+grub_err_t
+grub_set_datetime (struct grub_datetime *datetime)
+{
+  int is_bcd, is_12hour;
+  grub_uint8_t value, flag;
+
+  flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B);
+
+  is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY);
+
+  value = ((datetime->year >= 2000) ? datetime->year - 2000 :
+           datetime->year - 1900);
+
+  if (is_bcd)
+    value = grub_num_to_bcd (value);
+
+  grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value);
+
+  value = datetime->month;
+
+  if (is_bcd)
+    value = grub_num_to_bcd (value);
+
+  grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value);
+
+  value = datetime->day;
+
+  if (is_bcd)
+    value = grub_num_to_bcd (value);
+
+  grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value);
+
+  value = datetime->hour;
+
+  is_12hour = (! (flag & GRUB_CMOS_STATUS_B_24HOUR));
+
+  if (is_12hour)
+    {
+      value++;
+
+      if (value > 12)
+        value -= 12;
+      else
+        is_12hour = 0;
+    }
+
+  if (is_bcd)
+    value = grub_num_to_bcd (value);
+
+  if (is_12hour)
+    value |= 0x80;
+
+  grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value);
+
+  value = datetime->minute;
+
+  if (is_bcd)
+    value = grub_num_to_bcd (value);
+
+  grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value);
+
+  value = datetime->second;
+
+  if (is_bcd)
+    value = grub_num_to_bcd (value);
+
+  grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value);
+
+  return 0;
+}
diff --git a/lib/i386/pc/biosnum.c b/lib/i386/pc/biosnum.c
new file mode 100644
index 0000000..1f9b5f3
--- /dev/null
+++ b/lib/i386/pc/biosnum.c
@@ -0,0 +1,46 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+
+static int
+grub_get_root_biosnumber_default (void)
+{
+  char *biosnum;
+  int ret = -1;
+  grub_device_t dev;
+
+  biosnum = grub_env_get ("biosnum");
+
+  if (biosnum)
+    return grub_strtoul (biosnum, 0, 0);
+
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->dev 
+      && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID)
+    ret = (int) dev->disk->id;
+
+  if (dev)
+    grub_device_close (dev);
+
+  return ret;
+}
+
+int (*grub_get_root_biosnumber) (void) = grub_get_root_biosnumber_default;
diff --git a/lib/i386/setjmp.S b/lib/i386/setjmp.S
new file mode 100644
index 0000000..a2002ae
--- /dev/null
+++ b/lib/i386/setjmp.S
@@ -0,0 +1,56 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+	.file	"setjmp.S"
+
+	.text
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+	movl	%ebx, 0(%eax)	/* EBX */
+	movl	%esi, 4(%eax)	/* ESI */
+	movl	%edi, 8(%eax)	/* EDI */
+	movl	%ebp, 12(%eax)	/* EBP */
+	popl	%ecx
+	movl	%esp, 16(%eax)	/* ESP */
+	movl	%ecx, 20(%eax)	/* EIP */
+	xorl	%eax, %eax
+	jmp	*%ecx
+
+
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+	movl	0(%eax), %ebx
+	movl	4(%eax), %esi
+	movl	8(%eax), %edi
+	movl	12(%eax), %ebp
+	movl	16(%eax), %esp
+	movl	20(%eax), %ecx
+
+	movl	%edx, %eax
+	testl	%eax, %eax
+	jnz	1f
+	incl	%eax
+1:	jmp	*%ecx
+
diff --git a/lib/powerpc/setjmp.S b/lib/powerpc/setjmp.S
new file mode 100644
index 0000000..25cbaa3
--- /dev/null
+++ b/lib/powerpc/setjmp.S
@@ -0,0 +1,84 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+	.file	"setjmp.S"
+
+	.text
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+	stw	1, 0(3)
+	stw	14, 4(3)
+	stw	15, 8(3)
+	stw	16, 12(3)
+	stw	17, 16(3)
+	stw	18, 20(3)
+	stw	19, 24(3)
+	stw	20, 28(3)
+	stw	21, 32(3)
+	stw	22, 36(3)
+	stw	23, 40(3)
+	stw	24, 44(3)
+	stw	25, 48(3)
+	stw	26, 52(3)
+	stw	27, 56(3)
+	stw	28, 60(3)
+	stw	29, 64(3)
+	stw	30, 68(3)
+	mflr	4
+	stw	4, 72(3)
+	mfcr	4
+	stw	4, 76(3)
+	li	3, 0
+	blr
+
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+	lwz	1, 0(3)
+	lwz	14, 4(3)
+	lwz	15, 8(3)
+	lwz	16, 12(3)
+	lwz	17, 16(3)
+	lwz	18, 20(3)
+	lwz	19, 24(3)
+	lwz	20, 28(3)
+	lwz	21, 32(3)
+	lwz	22, 36(3)
+	lwz	23, 40(3)
+	lwz	24, 44(3)
+	lwz	25, 48(3)
+	lwz	26, 52(3)
+	lwz	27, 56(3)
+	lwz	28, 60(3)
+	lwz	29, 64(3)
+	lwz	30, 68(3)
+	lwz	5, 72(3)
+	mtlr	5
+	lwz	5, 76(3)
+	mtcr	5
+	mr.	3, 4
+	bne	1f
+	li	3, 1
+1:	blr
+
diff --git a/lib/sparc64/setjmp.S b/lib/sparc64/setjmp.S
new file mode 100644
index 0000000..0e23ecf
--- /dev/null
+++ b/lib/sparc64/setjmp.S
@@ -0,0 +1,47 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+        .file   "setjmp.S"
+
+        .text
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+	stx	%o7, [%o0 + 0x00]
+	stx	%sp, [%o0 + 0x08]
+	stx	%fp, [%o0 + 0x10]
+	retl
+	 clr	%o0
+
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+	ldx	[%o0 + 0x10], %g1
+	movrz	%o1, 1, %o1
+	flushw
+	ldx	[%o0 + 0x00], %o7
+	ldx	[%o0 + 0x08], %fp
+	sub	%fp, 192, %sp
+	stx	%g1, [%sp + 2047 + (14 * 8)]
+	retl
+	 restore %o1, 0, %o0
diff --git a/lib/x86_64/setjmp.S b/lib/x86_64/setjmp.S
new file mode 100644
index 0000000..621b09b
--- /dev/null
+++ b/lib/x86_64/setjmp.S
@@ -0,0 +1,65 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+	.file	"setjmp.S"
+
+	.text
+
+/*
+ *  jmp_buf:
+ *   rbx rsp rbp r12 r13 r14 r15 rip
+ *   0   8   16  24  32  40  48  56
+ */
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+	pop	%rsi		/* Return address, and adjust the stack */
+	xorq	%rax, %rax
+	movq	%rbx, 0(%rdi)	/* RBX */
+	movq	%rsp, 8(%rdi)   /* RSP */
+	push	%rsi
+	movq	%rbp, 16(%rdi)	/* RBP */
+	movq	%r12, 24(%rdi)	/* R12 */
+	movq	%r13, 32(%rdi)	/* R13 */
+	movq	%r14, 40(%rdi)	/* R14 */
+	movq	%r15, 48(%rdi)	/* R15 */
+	movq	%rsi, 56(%rdi)	/* RSI */
+	ret
+
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+	movl	%esi, %eax
+	orl	%eax, %eax
+	jnz	1f
+	incl	%eax
+1:
+
+	movq	(%rdi), %rbx
+	movq	8(%rdi), %rsp
+	movq	16(%rdi), %rbp
+	movq	24(%rdi), %r12
+	movq    32(%rdi), %r13
+	movq    40(%rdi), %r14
+	movq    48(%rdi), %r15
+	jmp	*56(%rdi)
diff --git a/loader/aout.c b/loader/aout.c
new file mode 100644
index 0000000..0254b6a
--- /dev/null
+++ b/loader/aout.c
@@ -0,0 +1,62 @@
+/*
+ *  Copyright (C) 2008 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/aout.h>
+
+int
+grub_aout_get_type (union grub_aout_header *header)
+{
+  int magic;
+
+  magic = AOUT_GETMAGIC (header->aout32);
+  if ((magic == AOUT32_OMAGIC) || (magic == AOUT32_NMAGIC) ||
+      (magic == AOUT32_ZMAGIC) || (magic == AOUT32_QMAGIC))
+    return AOUT_TYPE_AOUT32;
+  else if ((magic == AOUT64_OMAGIC) || (magic == AOUT64_NMAGIC) ||
+	   (magic == AOUT64_ZMAGIC))
+    return AOUT_TYPE_AOUT64;
+  else
+    return AOUT_TYPE_NONE;
+}
+
+grub_err_t
+grub_aout_load (grub_file_t file, int offset,
+                grub_addr_t load_addr,
+		int load_size,
+                grub_addr_t bss_end_addr)
+{
+  if ((grub_file_seek (file, offset)) == (grub_off_t) - 1)
+    return grub_errno;
+
+  if (!load_size)
+    load_size = file->size - offset;
+
+  grub_file_read (file, (void *) load_addr, load_size);
+
+  if (grub_errno)
+    return grub_errno;
+
+  if (bss_end_addr)
+    grub_memset ((char *) load_addr + load_size, 0,
+                 bss_end_addr - load_addr - load_size);
+
+  return GRUB_ERR_NONE;
+}
diff --git a/loader/efi/appleloader.c b/loader/efi/appleloader.c
new file mode 100644
index 0000000..94d501b
--- /dev/null
+++ b/loader/efi/appleloader.c
@@ -0,0 +1,218 @@
+/* appleloader.c - apple legacy boot loader.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/command.h>
+
+static grub_dl_t my_mod;
+
+static grub_efi_handle_t image_handle;
+static grub_efi_char16_t *cmdline;
+
+static grub_err_t
+grub_appleloader_unload (void)
+{
+  grub_efi_boot_services_t *b;
+
+  b = grub_efi_system_table->boot_services;
+  efi_call_1 (b->unload_image, image_handle);
+
+  grub_free (cmdline);
+  cmdline = 0;
+
+  grub_dl_unref (my_mod);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_appleloader_boot (void)
+{
+  grub_efi_boot_services_t *b;
+
+  b = grub_efi_system_table->boot_services;
+  efi_call_3 (b->start_image, image_handle, 0, 0);
+
+  grub_appleloader_unload ();
+
+  return grub_errno;
+}
+
+/* early 2006 Core Duo / Core Solo models  */
+static grub_uint8_t devpath_1[] =
+{
+  0x01, 0x03, 0x18, 0x00, 0x0B, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00,
+  0xFF, 0xFF, 0xF9, 0xFF, 0x00, 0x00, 0x00, 0x00,
+  0x04, 0x06, 0x14, 0x00, 0xEB, 0x85, 0x05, 0x2B,
+  0xB8, 0xD8, 0xA9, 0x49, 0x8B, 0x8C, 0xE2, 0x1B,
+  0x01, 0xAE, 0xF2, 0xB7, 0x7F, 0xFF, 0x04, 0x00,
+};
+
+/* mid-2006 Mac Pro (and probably other Core 2 models)  */
+static grub_uint8_t devpath_2[] =
+{
+  0x01, 0x03, 0x18, 0x00, 0x0B, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00,
+  0xFF, 0xFF, 0xF7, 0xFF, 0x00, 0x00, 0x00, 0x00,
+  0x04, 0x06, 0x14, 0x00, 0xEB, 0x85, 0x05, 0x2B,
+  0xB8, 0xD8, 0xA9, 0x49, 0x8B, 0x8C, 0xE2, 0x1B,
+  0x01, 0xAE, 0xF2, 0xB7, 0x7F, 0xFF, 0x04, 0x00,
+};
+
+/* mid-2007 MBP ("Santa Rosa" based models)  */
+static grub_uint8_t devpath_3[] =
+{
+  0x01, 0x03, 0x18, 0x00, 0x0B, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00,
+  0xFF, 0xFF, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00,
+  0x04, 0x06, 0x14, 0x00, 0xEB, 0x85, 0x05, 0x2B,
+  0xB8, 0xD8, 0xA9, 0x49, 0x8B, 0x8C, 0xE2, 0x1B,
+  0x01, 0xAE, 0xF2, 0xB7, 0x7F, 0xFF, 0x04, 0x00,
+};
+
+/* early-2008 MBA  */
+static grub_uint8_t devpath_4[] =
+{
+  0x01, 0x03, 0x18, 0x00, 0x0B, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x00,
+  0xFF, 0xFF, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00,
+  0x04, 0x06, 0x14, 0x00, 0xEB, 0x85, 0x05, 0x2B,
+  0xB8, 0xD8, 0xA9, 0x49, 0x8B, 0x8C, 0xE2, 0x1B,
+  0x01, 0xAE, 0xF2, 0xB7, 0x7F, 0xFF, 0x04, 0x00,
+};
+
+/* late-2008 MB/MBP (NVidia chipset)  */
+static grub_uint8_t devpath_5[] = {
+    0x01, 0x03, 0x18, 0x00, 0x0B, 0x00, 0x00, 0x00,
+    0x00, 0x40, 0xCB, 0xFF, 0x00, 0x00, 0x00, 0x00,
+    0xFF, 0xBF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+    0x04, 0x06, 0x14, 0x00, 0xEB, 0x85, 0x05, 0x2B,
+    0xB8, 0xD8, 0xA9, 0x49, 0x8B, 0x8C, 0xE2, 0x1B,
+    0x01, 0xAE, 0xF2, 0xB7, 0x7F, 0xFF, 0x04, 0x00,
+};
+
+struct devdata
+{
+  char *model;
+  grub_efi_device_path_t *devpath;
+};
+
+struct devdata devs[] =
+{
+  {"Core Duo/Solo", (grub_efi_device_path_t *) devpath_1},
+  {"Mac Pro", (grub_efi_device_path_t *) devpath_2},
+  {"MBP", (grub_efi_device_path_t *) devpath_3},
+  {"MBA", (grub_efi_device_path_t *) devpath_4},
+  {"MB NV", (grub_efi_device_path_t *) devpath_5},
+  {NULL, NULL},
+};
+
+static grub_err_t
+grub_cmd_appleloader (grub_command_t cmd __attribute__ ((unused)),
+                      int argc, char *argv[])
+{
+  grub_efi_boot_services_t *b;
+  grub_efi_loaded_image_t *loaded_image;
+  struct devdata *pdev;
+
+  grub_dl_ref (my_mod);
+
+  /* Initialize some global variables.  */
+  image_handle = 0;
+
+  b = grub_efi_system_table->boot_services;
+
+  for (pdev = devs ; pdev->devpath ; pdev++)
+    if (efi_call_6 (b->load_image, 0, grub_efi_image_handle, pdev->devpath,
+                    NULL, 0, &image_handle) == GRUB_EFI_SUCCESS)
+      break;
+
+  if (! pdev->devpath)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "can't find model");
+      goto fail;
+    }
+
+  grub_printf ("Model : %s\n", pdev->model);
+
+  loaded_image = grub_efi_get_loaded_image (image_handle);
+  if (! loaded_image)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
+      goto fail;
+    }
+
+  if (argc > 0)
+    {
+      int i, len;
+      grub_efi_char16_t *p16;
+
+      for (i = 0, len = 0; i < argc; i++)
+        len += grub_strlen (argv[i]) + 1;
+
+      len *= sizeof (grub_efi_char16_t);
+      cmdline = p16 = grub_malloc (len);
+      if (! cmdline)
+        goto fail;
+
+      for (i = 0; i < argc; i++)
+        {
+          char *p8;
+
+          p8 = argv[i];
+          while (*p8)
+            *(p16++) = *(p8++);
+
+          *(p16++) = ' ';
+        }
+      *(--p16) = 0;
+
+      loaded_image->load_options = cmdline;
+      loaded_image->load_options_size = len;
+    }
+
+  grub_loader_set (grub_appleloader_boot, grub_appleloader_unload, 0);
+
+  return 0;
+
+ fail:
+
+  grub_dl_unref (my_mod);
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(appleloader)
+{
+  cmd = grub_register_command ("appleloader", grub_cmd_appleloader,
+			       "appleloader [OPTS]", "Boot legacy system.");
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(appleloader)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/loader/efi/chainloader.c b/loader/efi/chainloader.c
new file mode 100644
index 0000000..01acc41
--- /dev/null
+++ b/loader/efi/chainloader.c
@@ -0,0 +1,345 @@
+/* chainloader.c - boot another boot loader */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* TODO: support load options.  */
+
+#include <grub/loader.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/disk.h>
+#include <grub/command.h>
+
+static grub_dl_t my_mod;
+
+static grub_efi_physical_address_t address;
+static grub_efi_uintn_t pages;
+static grub_efi_device_path_t *file_path;
+static grub_efi_handle_t image_handle;
+static grub_efi_char16_t *cmdline;
+
+static grub_err_t
+grub_chainloader_unload (void)
+{
+  grub_efi_boot_services_t *b;
+
+  b = grub_efi_system_table->boot_services;
+  efi_call_1 (b->unload_image, image_handle);
+  efi_call_2 (b->free_pages, address, pages);
+
+  grub_free (file_path);
+  grub_free (cmdline);
+  cmdline = 0;
+
+  grub_dl_unref (my_mod);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_chainloader_boot (void)
+{
+  grub_efi_boot_services_t *b;
+  grub_efi_status_t status;
+  grub_efi_uintn_t exit_data_size;
+  grub_efi_char16_t *exit_data;
+
+  b = grub_efi_system_table->boot_services;
+  status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      if (exit_data)
+	{
+	  char *buf;
+
+	  buf = grub_malloc (exit_data_size * 4 + 1);
+	  if (buf)
+	    {
+	      *grub_utf16_to_utf8 ((grub_uint8_t *) buf,
+				   exit_data, exit_data_size) = 0;
+
+	      grub_error (GRUB_ERR_BAD_OS, buf);
+	      grub_free (buf);
+	    }
+	  else
+	    grub_error (GRUB_ERR_BAD_OS, "unknown error");
+	}
+    }
+
+  if (exit_data)
+    efi_call_1 (b->free_pool, exit_data);
+
+  grub_chainloader_unload ();
+
+  return grub_errno;
+}
+
+static void
+copy_file_path (grub_efi_file_path_device_path_t *fp,
+		const char *str, grub_efi_uint16_t len)
+{
+  grub_efi_char16_t *p;
+  grub_efi_uint16_t size;
+
+  fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
+  fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
+  size = len * sizeof (grub_efi_char16_t) + sizeof (*fp);
+  fp->header.length[0] = (grub_efi_uint8_t) (size & 0xff);
+  fp->header.length[1] = (grub_efi_uint8_t) (size >> 8);
+  for (p = fp->path_name; len > 0; len--, p++, str++)
+    {
+      /* FIXME: this assumes that the path is in ASCII.  */
+      *p = (grub_efi_char16_t) (*str == '/' ? '\\' : *str);
+    }
+}
+
+static grub_efi_device_path_t *
+make_file_path (grub_efi_device_path_t *dp, const char *filename)
+{
+  char *dir_start;
+  char *dir_end;
+  grub_size_t size;
+  grub_efi_device_path_t *d;
+
+  dir_start = grub_strchr (filename, ')');
+  if (! dir_start)
+    dir_start = (char *) filename;
+  else
+    dir_start++;
+
+  dir_end = grub_strrchr (dir_start, '/');
+  if (! dir_end)
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "invalid EFI file path");
+      return 0;
+    }
+
+  size = 0;
+  d = dp;
+  while (1)
+    {
+      size += GRUB_EFI_DEVICE_PATH_LENGTH (d);
+      if ((GRUB_EFI_END_ENTIRE_DEVICE_PATH (d)))
+	break;
+      d = GRUB_EFI_NEXT_DEVICE_PATH (d);
+    }
+
+  file_path = grub_malloc (size
+			   + ((grub_strlen (dir_start) + 1)
+			      * sizeof (grub_efi_char16_t))
+			   + sizeof (grub_efi_file_path_device_path_t) * 2);
+  if (! file_path)
+    return 0;
+
+  grub_memcpy (file_path, dp, size);
+
+  /* Fill the file path for the directory.  */
+  d = (grub_efi_device_path_t *) ((char *) file_path
+				  + ((char *) d - (char *) dp));
+  grub_efi_print_device_path (d);
+  copy_file_path ((grub_efi_file_path_device_path_t *) d,
+		  dir_start, dir_end - dir_start);
+
+  /* Fill the file path for the file.  */
+  d = GRUB_EFI_NEXT_DEVICE_PATH (d);
+  copy_file_path ((grub_efi_file_path_device_path_t *) d,
+		  dir_end + 1, grub_strlen (dir_end + 1));
+
+  /* Fill the end of device path nodes.  */
+  d = GRUB_EFI_NEXT_DEVICE_PATH (d);
+  d->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+  d->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+  d->length[0] = sizeof (*d);
+  d->length[1] = 0;
+
+  return file_path;
+}
+
+static grub_err_t
+grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
+		      int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_efi_status_t status;
+  grub_efi_boot_services_t *b;
+  grub_efi_handle_t dev_handle = 0;
+  grub_device_t dev = 0;
+  grub_efi_device_path_t *dp = 0;
+  grub_efi_loaded_image_t *loaded_image;
+  char *filename;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+  filename = argv[0];
+
+  grub_dl_ref (my_mod);
+
+  /* Initialize some global variables.  */
+  address = 0;
+  image_handle = 0;
+  file_path = 0;
+
+  b = grub_efi_system_table->boot_services;
+
+  file = grub_file_open (filename);
+  if (! file)
+    goto fail;
+
+  /* Get the root device's device path.  */
+  dev = grub_device_open (0);
+  if (! dev)
+    goto fail;
+
+  if (dev->disk)
+    {
+      dev_handle = grub_efidisk_get_device_handle (dev->disk);
+      if (dev_handle)
+	dp = grub_efi_get_device_path (dev_handle);
+    }
+
+  if (! dev->disk || ! dev_handle || ! dp)
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device");
+      goto fail;
+    }
+
+  file_path = make_file_path (dp, filename);
+  if (! file_path)
+    goto fail;
+
+  grub_printf ("file path: ");
+  grub_efi_print_device_path (file_path);
+
+  size = grub_file_size (file);
+  pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12);
+
+  status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
+			      GRUB_EFI_LOADER_CODE,
+			      pages, &address);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate %u pages", pages);
+      goto fail;
+    }
+
+  if (grub_file_read (file, (void *) ((grub_addr_t) address), size) != size)
+    {
+      if (grub_errno == GRUB_ERR_NONE)
+	grub_error (GRUB_ERR_BAD_OS, "too small");
+
+      goto fail;
+    }
+
+  status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
+			  (void *) ((grub_addr_t) address), size,
+			  &image_handle);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      if (status == GRUB_EFI_OUT_OF_RESOURCES)
+	grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
+      else
+	grub_error (GRUB_ERR_BAD_OS, "cannot load image");
+
+      goto fail;
+    }
+
+  /* LoadImage does not set a device handler when the image is
+     loaded from memory, so it is necessary to set it explicitly here.
+     This is a mess.  */
+  loaded_image = grub_efi_get_loaded_image (image_handle);
+  if (! loaded_image)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
+      goto fail;
+    }
+  loaded_image->device_handle = dev_handle;
+
+  grub_file_close (file);
+
+  if (argc > 1)
+    {
+      int i, len;
+      grub_efi_char16_t *p16;
+
+      for (i = 1, len = 0; i < argc; i++)
+        len += grub_strlen (argv[i]) + 1;
+
+      len *= sizeof (grub_efi_char16_t);
+      cmdline = p16 = grub_malloc (len);
+      if (! cmdline)
+        goto fail;
+
+      for (i = 1; i < argc; i++)
+        {
+          char *p8;
+
+          p8 = argv[i];
+          while (*p8)
+            *(p16++) = *(p8++);
+
+          *(p16++) = ' ';
+        }
+      *(--p16) = 0;
+
+      loaded_image->load_options = cmdline;
+      loaded_image->load_options_size = len;
+    }
+
+  grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
+  return 0;
+
+ fail:
+
+  if (dev)
+    grub_device_close (dev);
+
+  if (file)
+    grub_file_close (file);
+
+  if (file_path)
+    grub_free (file_path);
+
+  if (address)
+    efi_call_2 (b->free_pages, address, pages);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(chainloader)
+{
+  cmd = grub_register_command ("chainloader", grub_cmd_chainloader,
+			       0, "load another boot loader");
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(chainloader)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c
new file mode 100644
index 0000000..acc653c
--- /dev/null
+++ b/loader/i386/bsd.c
@@ -0,0 +1,1323 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/cpu/loader.h>
+#include <grub/cpu/bsd.h>
+#include <grub/i386/cpuid.h>
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#include <grub/machine/machine.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/elfload.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/aout.h>
+#include <grub/command.h>
+#include <grub/extcmd.h>
+
+#ifdef GRUB_MACHINE_PCBIOS
+#include <grub/machine/biosnum.h>
+#endif
+#include <grub/disk.h>
+#include <grub/device.h>
+#include <grub/partition.h>
+
+#define ALIGN_DWORD(a)	ALIGN_UP (a, 4)
+#define ALIGN_QWORD(a)	ALIGN_UP (a, 8)
+#define ALIGN_VAR(a)	((is_64bit) ? (ALIGN_QWORD(a)) : (ALIGN_DWORD(a)))
+#define ALIGN_PAGE(a)	ALIGN_UP (a, 4096)
+
+#define MOD_BUF_ALLOC_UNIT	4096
+
+static int kernel_type = KERNEL_TYPE_NONE;
+static grub_dl_t my_mod;
+static grub_addr_t entry, entry_hi, kern_start, kern_end;
+static grub_uint32_t bootflags;
+static char *mod_buf;
+static grub_uint32_t mod_buf_len, mod_buf_max, kern_end_mdofs;
+static int is_elf_kernel, is_64bit;
+static char *netbsd_root = NULL;
+static grub_uint32_t openbsd_root;
+
+static const struct grub_arg_option freebsd_opts[] =
+  {
+    {"dual", 'D', 0, "Display output on all consoles.", 0, 0},
+    {"serial", 'h', 0, "Use serial console.", 0, 0},
+    {"askname", 'a', 0, "Ask for file name to reboot from.", 0, 0},
+    {"cdrom", 'C', 0, "Use cdrom as root.", 0, 0},
+    {"config", 'c', 0, "Invoke user configuration routing.", 0, 0},
+    {"kdb", 'd', 0, "Enter in KDB on boot.", 0, 0},
+    {"gdb", 'g', 0, "Use GDB remote debugger instead of DDB.", 0, 0},
+    {"mute", 'm', 0, "Disable all boot output.", 0, 0},
+    {"nointr", 'n', 0, "", 0, 0},
+    {"pause", 'p', 0, "Wait for keypress after every line of output.", 0, 0},
+    {"quiet", 'q', 0, "", 0, 0},
+    {"dfltroot", 'r', 0, "Use compiled-in rootdev.", 0, 0},
+    {"single", 's', 0, "Boot into single mode.", 0, 0},
+    {"verbose", 'v', 0, "Boot with verbose messages.", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static const grub_uint32_t freebsd_flags[] =
+{
+  FREEBSD_RB_DUAL, FREEBSD_RB_SERIAL, FREEBSD_RB_ASKNAME,
+  FREEBSD_RB_CDROM, FREEBSD_RB_CONFIG, FREEBSD_RB_KDB,
+  FREEBSD_RB_GDB, FREEBSD_RB_MUTE, FREEBSD_RB_NOINTR,
+  FREEBSD_RB_PAUSE, FREEBSD_RB_QUIET, FREEBSD_RB_DFLTROOT,
+  FREEBSD_RB_SINGLE, FREEBSD_RB_VERBOSE, 0
+};
+
+static const struct grub_arg_option openbsd_opts[] =
+  {
+    {"askname", 'a', 0, "Ask for file name to reboot from.", 0, 0},
+    {"halt", 'b', 0, "Don't reboot, just halt.", 0, 0},
+    {"config", 'c', 0, "Change configured devices.", 0, 0},
+    {"single", 's', 0, "Boot into single mode.", 0, 0},
+    {"kdb", 'd', 0, "Enter in KDB on boot.", 0, 0},
+    {"root", 'r', 0, "Set root device.", "wdXY", ARG_TYPE_STRING},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static const grub_uint32_t openbsd_flags[] =
+{
+  OPENBSD_RB_ASKNAME, OPENBSD_RB_HALT, OPENBSD_RB_CONFIG,
+  OPENBSD_RB_SINGLE, OPENBSD_RB_KDB, 0
+};
+
+#define OPENBSD_ROOT_ARG (ARRAY_SIZE (openbsd_flags) - 1)
+
+static const struct grub_arg_option netbsd_opts[] =
+  {
+    {"no-smp", '1', 0, "Disable SMP.", 0, 0},
+    {"no-acpi", '2', 0, "Disable ACPI.", 0, 0},
+    {"askname", 'a', 0, "Ask for file name to reboot from.", 0, 0},
+    {"halt", 'b', 0, "Don't reboot, just halt.", 0, 0},
+    {"config", 'c', 0, "Change configured devices.", 0, 0},
+    {"kdb", 'd', 0, "Enter in KDB on boot.", 0, 0},
+    {"miniroot", 'm', 0, "", 0, 0},
+    {"quiet", 'q', 0, "Don't display boot diagnostic messages.", 0, 0},
+    {"single", 's', 0, "Boot into single mode.", 0, 0},
+    {"verbose", 'v', 0, "Boot with verbose messages.", 0, 0},
+    {"debug", 'x', 0, "Boot with debug messages.", 0, 0},
+    {"silent", 'z', 0, "Supress normal output (warnings remain).", 0, 0},
+    {"root", 'r', 0, "Set root device.", "DEVICE", ARG_TYPE_STRING},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static const grub_uint32_t netbsd_flags[] =
+{
+  NETBSD_AB_NOSMP, NETBSD_AB_NOACPI, NETBSD_RB_ASKNAME,
+  NETBSD_RB_HALT, NETBSD_RB_USERCONFIG, NETBSD_RB_KDB,
+  NETBSD_RB_MINIROOT, NETBSD_AB_QUIET, NETBSD_RB_SINGLE,
+  NETBSD_AB_VERBOSE, NETBSD_AB_DEBUG, NETBSD_AB_SILENT, 0
+};
+
+#define NETBSD_ROOT_ARG (ARRAY_SIZE (netbsd_flags) - 1)
+
+static void
+grub_bsd_get_device (grub_uint32_t * biosdev,
+		     grub_uint32_t * unit,
+		     grub_uint32_t * slice, grub_uint32_t * part)
+{
+  char *p;
+  grub_device_t dev; 
+
+#ifdef GRUB_MACHINE_PCBIOS
+  *biosdev = grub_get_root_biosnumber () & 0xff;
+#else
+  *biosdev = 0xff;
+#endif
+  *unit = (*biosdev & 0x7f);
+  *slice = 0xff;
+  *part = 0xff;
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->partition)
+    {
+
+      p = dev->disk->partition->partmap->get_name (dev->disk->partition);
+      if (p)
+	{
+	  if ((p[0] >= '0') && (p[0] <= '9'))
+	    {
+	      *slice = grub_strtoul (p, &p, 0);
+
+	      if ((p) && (p[0] == ','))
+		p++;
+	    }
+
+	  if ((p[0] >= 'a') && (p[0] <= 'z'))
+	    *part = p[0] - 'a';
+	}
+    }
+  if (dev)
+    grub_device_close (dev);
+}
+
+grub_err_t
+grub_freebsd_add_meta (grub_uint32_t type, void *data, grub_uint32_t len)
+{
+  if (mod_buf_max < mod_buf_len + len + 8)
+    {
+      char *new_buf;
+
+      do
+	{
+	  mod_buf_max += MOD_BUF_ALLOC_UNIT;
+	}
+      while (mod_buf_max < mod_buf_len + len + 8);
+
+      new_buf = grub_malloc (mod_buf_max);
+      if (!new_buf)
+	return grub_errno;
+
+      grub_memcpy (new_buf, mod_buf, mod_buf_len);
+      grub_free (mod_buf);
+
+      mod_buf = new_buf;
+    }
+
+  *((grub_uint32_t *) (mod_buf + mod_buf_len)) = type;
+  *((grub_uint32_t *) (mod_buf + mod_buf_len + 4)) = len;
+  mod_buf_len += 8;
+
+  if (len)
+    grub_memcpy (mod_buf + mod_buf_len, data, len);
+
+  mod_buf_len = ALIGN_VAR (mod_buf_len + len);
+
+  return GRUB_ERR_NONE;
+}
+
+struct grub_e820_mmap
+{
+  grub_uint64_t addr;
+  grub_uint64_t size;
+  grub_uint32_t type;
+} __attribute__((packed));
+#define GRUB_E820_RAM        1
+#define GRUB_E820_RESERVED   2
+#define GRUB_E820_ACPI       3
+#define GRUB_E820_NVS        4
+#define GRUB_E820_EXEC_CODE  5
+
+static grub_err_t
+grub_freebsd_add_mmap (void)
+{
+  grub_size_t len = 0;
+  struct grub_e820_mmap *mmap_buf = 0;
+  struct grub_e820_mmap *mmap = 0;
+  int isfirstrun = 1;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+			     grub_uint32_t type)
+    {
+      /* FreeBSD assumes that first 64KiB are available.
+	 Not always true but try to prevent panic somehow. */
+      if (isfirstrun && addr != 0)
+	{
+	  if (mmap)
+	    {
+	      mmap->addr = 0;
+	      mmap->size = (addr < 0x10000) ? addr : 0x10000;
+	      mmap->type = GRUB_E820_RAM;
+	      mmap++;
+	    }
+	  else
+	    len += sizeof (struct grub_e820_mmap);
+	}
+      isfirstrun = 0;
+      if (mmap)
+	{
+	  mmap->addr = addr;
+	  mmap->size = size;
+	  switch (type)
+	    {
+	    case GRUB_MACHINE_MEMORY_AVAILABLE:
+	      mmap->type = GRUB_E820_RAM;
+	      break;
+
+#ifdef GRUB_MACHINE_MEMORY_ACPI
+	    case GRUB_MACHINE_MEMORY_ACPI:
+	      mmap->type = GRUB_E820_ACPI;
+	      break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_NVS
+	    case GRUB_MACHINE_MEMORY_NVS:
+	      mmap->type = GRUB_E820_NVS;
+	      break;
+#endif
+
+	    default:
+#ifdef GRUB_MACHINE_MEMORY_CODE
+	    case GRUB_MACHINE_MEMORY_CODE:
+#endif
+#ifdef GRUB_MACHINE_MEMORY_RESERVED
+	    case GRUB_MACHINE_MEMORY_RESERVED:
+#endif
+	      mmap->type = GRUB_E820_RESERVED;
+	      break;
+	    }
+
+	  /* Merge regions if possible. */
+	  if (mmap != mmap_buf && mmap->type == mmap[-1].type &&
+	      mmap->addr == mmap[-1].addr + mmap[-1].size)
+	    mmap[-1].size += mmap->size;
+	  else
+	    mmap++;
+	}
+      else
+	len += sizeof (struct grub_e820_mmap);
+
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+  mmap_buf = mmap = grub_malloc (len);
+  if (! mmap)
+    return grub_errno;
+
+  isfirstrun = 1;
+  grub_mmap_iterate (hook);
+
+  len = (mmap - mmap_buf) * sizeof (struct grub_e820_mmap);
+  int i;
+  for (i = 0; i < mmap - mmap_buf; i++)
+    grub_dprintf ("bsd", "smap %d, %d:%llx - %llx\n", i,
+		  mmap_buf[i].type,
+		  (unsigned long long) mmap_buf[i].addr,
+		  (unsigned long long) mmap_buf[i].size);
+
+  grub_dprintf ("bsd", "%d entries in smap\n", mmap - mmap_buf);
+  grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+			 FREEBSD_MODINFOMD_SMAP, mmap_buf, len);
+
+  grub_free (mmap_buf);
+
+  return grub_errno;
+}
+
+grub_err_t
+grub_freebsd_add_meta_module (char *filename, char *type, int argc, char **argv,
+			      grub_addr_t addr, grub_uint32_t size)
+{
+  char *name;
+  name = grub_strrchr (filename, '/');
+  if (name)
+    name++;
+  else
+    name = filename;
+  if (grub_strcmp (type, "/boot/zfs/zpool.cache") == 0)
+    name = "/boot/zfs/zpool.cache";
+
+  if (grub_freebsd_add_meta (FREEBSD_MODINFO_NAME, name,
+			     grub_strlen (name) + 1))
+    return grub_errno;
+
+  if (is_64bit)
+    {
+      grub_uint64_t addr64 = addr, size64 = size;
+      if ((grub_freebsd_add_meta (FREEBSD_MODINFO_TYPE, type,
+			      grub_strlen (type) + 1)) ||
+	  (grub_freebsd_add_meta (FREEBSD_MODINFO_ADDR, &addr64,
+				  sizeof (addr64))) ||
+	  (grub_freebsd_add_meta (FREEBSD_MODINFO_SIZE, &size64,
+				  sizeof (size64))))
+	return grub_errno;
+    }
+  else
+    {
+      if ((grub_freebsd_add_meta (FREEBSD_MODINFO_TYPE, type,
+				  grub_strlen (type) + 1)) ||
+	  (grub_freebsd_add_meta (FREEBSD_MODINFO_ADDR, &addr,
+				  sizeof (addr))) ||
+	  (grub_freebsd_add_meta (FREEBSD_MODINFO_SIZE, &size,
+				  sizeof (size))))
+	return grub_errno;
+    }
+
+  if (argc)
+    {
+      int i, n;
+
+      n = 0;
+      for (i = 0; i < argc; i++)
+	{
+	  n += grub_strlen (argv[i]) + 1;
+	}
+
+      if (n)
+	{
+	  char cmdline[n], *p;
+
+	  p = cmdline;
+	  for (i = 0; i < argc; i++)
+	    {
+	      grub_strcpy (p, argv[i]);
+	      p += grub_strlen (argv[i]);
+	      *(p++) = ' ';
+	    }
+	  *p = 0;
+
+	  if (grub_freebsd_add_meta (FREEBSD_MODINFO_ARGS, cmdline, n))
+	    return grub_errno;
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_freebsd_list_modules (void)
+{
+  grub_uint32_t pos = 0;
+
+  grub_printf ("  %-18s  %-18s%14s%14s\n", "name", "type", "addr", "size");
+  while (pos < mod_buf_len)
+    {
+      grub_uint32_t type, size;
+
+      type = *((grub_uint32_t *) (mod_buf + pos));
+      size = *((grub_uint32_t *) (mod_buf + pos + 4));
+      pos += 8;
+      switch (type)
+	{
+	case FREEBSD_MODINFO_NAME:
+	case FREEBSD_MODINFO_TYPE:
+	  grub_printf ("  %-18s", mod_buf + pos);
+	  break;
+	case FREEBSD_MODINFO_ADDR:
+	  {
+	    grub_addr_t addr;
+
+	    addr = *((grub_addr_t *) (mod_buf + pos));
+	    grub_printf ("    0x%08x", addr);
+	    break;
+	  }
+	case FREEBSD_MODINFO_SIZE:
+	  {
+	    grub_uint32_t len;
+
+	    len = *((grub_uint32_t *) (mod_buf + pos));
+	    grub_printf ("    0x%08x\n", len);
+	  }
+	}
+
+      pos = ALIGN_VAR (pos + size);
+    }
+}
+
+/* This function would be here but it's under different license. */
+#include "bsd_pagetable.c"
+
+struct gdt_descriptor
+{
+  grub_uint16_t limit;
+  void *base;
+} __attribute__ ((packed));
+
+static grub_err_t
+grub_freebsd_boot (void)
+{
+  struct grub_freebsd_bootinfo bi;
+  char *p;
+  grub_uint32_t bootdev, biosdev, unit, slice, part;
+
+  auto int iterate_env (struct grub_env_var *var);
+  int iterate_env (struct grub_env_var *var)
+  {
+    if ((!grub_memcmp (var->name, "kFreeBSD.", sizeof("kFreeBSD.") - 1)) && (var->name[sizeof("kFreeBSD.") - 1]))
+      {
+	grub_strcpy (p, &var->name[sizeof("kFreeBSD.") - 1]);
+	p += grub_strlen (p);
+	*(p++) = '=';
+	grub_strcpy (p, var->value);
+	p += grub_strlen (p) + 1;
+      }
+
+    return 0;
+  }
+
+  grub_memset (&bi, 0, sizeof (bi));
+  bi.bi_version = FREEBSD_BOOTINFO_VERSION;
+  bi.bi_size = sizeof (bi);
+
+  grub_bsd_get_device (&biosdev, &unit, &slice, &part);
+  bootdev = (FREEBSD_B_DEVMAGIC + ((slice + 1) << FREEBSD_B_SLICESHIFT) +
+	     (unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT));
+
+  bi.bi_bios_dev = biosdev;
+
+  p = (char *) kern_end;
+
+  grub_env_iterate (iterate_env);
+
+  if (p != (char *) kern_end)
+    {
+      *(p++) = 0;
+
+      bi.bi_envp = kern_end;
+      kern_end = ALIGN_PAGE ((grub_uint32_t) p);
+    }
+
+  if (is_elf_kernel)
+    {
+      grub_addr_t md_ofs;
+      int ofs;
+
+      if (grub_freebsd_add_meta (FREEBSD_MODINFO_END, 0, 0))
+	return grub_errno;
+
+      grub_memcpy ((char *) kern_end, mod_buf, mod_buf_len);
+      bi.bi_modulep = kern_end;
+
+      kern_end = ALIGN_PAGE (kern_end + mod_buf_len);
+
+      if (is_64bit)
+	kern_end += 4096 * 4;
+
+      md_ofs = bi.bi_modulep + kern_end_mdofs;
+      ofs = (is_64bit) ? 16 : 12;
+      *((grub_uint32_t *) md_ofs) = kern_end;
+      md_ofs -= ofs;
+      *((grub_uint32_t *) md_ofs) = bi.bi_envp;
+      md_ofs -= ofs;
+      *((grub_uint32_t *) md_ofs) = bootflags;
+    }
+
+  bi.bi_kernend = kern_end;
+
+  if (is_64bit)
+    {
+      grub_uint32_t *gdt;
+      grub_uint8_t *trampoline;
+      void (*launch_trampoline) (grub_addr_t entry_lo, ...)
+	__attribute__ ((cdecl, regparm (0)));
+      grub_uint8_t *pagetable;
+
+      struct gdt_descriptor *gdtdesc;
+
+      pagetable = (grub_uint8_t *) (kern_end - 16384);
+      fill_bsd64_pagetable (pagetable);
+
+      /* Create GDT. */
+      gdt = (grub_uint32_t *) (kern_end - 4096);
+      gdt[0] = 0;
+      gdt[1] = 0;
+      gdt[2] = 0;
+      gdt[3] = 0x00209800;
+      gdt[4] = 0;
+      gdt[5] = 0x00008000;
+
+      /* Create GDT descriptor. */
+      gdtdesc = (struct gdt_descriptor *) (kern_end - 4096 + 24);
+      gdtdesc->limit = 24;
+      gdtdesc->base = gdt;
+
+      /* Prepare trampoline. */
+      trampoline = (grub_uint8_t *) (kern_end - 4096 + 24
+				     + sizeof (struct gdt_descriptor));
+      launch_trampoline = (void  __attribute__ ((cdecl, regparm (0)))
+			   (*) (grub_addr_t entry_lo, ...)) trampoline;
+      grub_bsd64_trampoline_gdt = (grub_uint32_t) gdtdesc;
+      grub_bsd64_trampoline_selfjump
+	= (grub_uint32_t) (trampoline + 6
+			   + ((grub_uint8_t *) &grub_bsd64_trampoline_selfjump
+			      - &grub_bsd64_trampoline_start));
+
+      /* Copy trampoline. */
+      grub_memcpy (trampoline, &grub_bsd64_trampoline_start,
+		   &grub_bsd64_trampoline_end - &grub_bsd64_trampoline_start);
+
+      /* Launch trampoline. */
+      launch_trampoline (entry, entry_hi, pagetable, bi.bi_modulep,
+			 kern_end);
+    }
+  else
+    grub_unix_real_boot (entry, bootflags | FREEBSD_RB_BOOTINFO, bootdev,
+			 0, 0, 0, &bi, bi.bi_modulep, kern_end);
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_openbsd_boot (void)
+{
+  char *buf = (char *) GRUB_BSD_TEMP_BUFFER;
+  struct grub_openbsd_bios_mmap *pm;
+  struct grub_openbsd_bootargs *pa;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      pm->addr = addr;
+      pm->len = size;
+
+      switch (type)
+        {
+        case GRUB_MACHINE_MEMORY_AVAILABLE:
+	  pm->type = OPENBSD_MMAP_AVAILABLE;
+	  break;
+
+        case GRUB_MACHINE_MEMORY_ACPI:
+	  pm->type = OPENBSD_MMAP_ACPI;
+	  break;
+
+        case GRUB_MACHINE_MEMORY_NVS:
+	  pm->type = OPENBSD_MMAP_NVS;
+	  break;
+
+	default:
+	  pm->type = OPENBSD_MMAP_RESERVED;
+	  break;
+	}
+      pm++;
+
+      return 0;
+    }
+
+  pa = (struct grub_openbsd_bootargs *) buf;
+
+  pa->ba_type = OPENBSD_BOOTARG_MMAP;
+  pm = (struct grub_openbsd_bios_mmap *) (pa + 1);
+  grub_mmap_iterate (hook);
+
+  /* Memory map terminator.  */
+  pm->addr = 0;
+  pm->len = 0;
+  pm->type = 0;
+  pm++;
+
+  pa->ba_size = (char *) pm - (char *) pa;
+  pa->ba_next = (struct grub_openbsd_bootargs *) pm;
+  pa = pa->ba_next;
+  pa->ba_type = OPENBSD_BOOTARG_END;
+  pa++;
+
+  grub_unix_real_boot (entry, bootflags, openbsd_root, OPENBSD_BOOTARG_APIVER,
+		       0, (grub_uint32_t) (grub_mmap_get_upper () >> 10),
+		       (grub_uint32_t) (grub_mmap_get_lower () >> 10),
+		       (char *) pa - buf, buf);
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_netbsd_boot (void)
+{
+  struct grub_netbsd_bootinfo *bootinfo;
+  int count = 0;
+  struct grub_netbsd_btinfo_mmap_header *mmap;
+  struct grub_netbsd_btinfo_mmap_entry *pm;
+  void *curarg;
+
+  auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
+				   grub_uint64_t size __attribute__ ((unused)),
+				   grub_uint32_t type __attribute__ ((unused)))
+  {
+    count++;
+    return 0;
+  }
+
+  auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+  {
+    pm->addr = addr;
+    pm->len = size;
+
+    switch (type)
+      {
+      case GRUB_MACHINE_MEMORY_AVAILABLE:
+	pm->type = NETBSD_MMAP_AVAILABLE;
+	break;
+
+      case GRUB_MACHINE_MEMORY_ACPI:
+	pm->type = NETBSD_MMAP_ACPI;
+	break;
+
+      case GRUB_MACHINE_MEMORY_NVS:
+	pm->type = NETBSD_MMAP_NVS;
+	break;
+
+      default:
+	pm->type = NETBSD_MMAP_RESERVED;
+	break;
+      }
+    pm++;
+
+    return 0;
+  }
+
+  grub_mmap_iterate (count_hook);
+
+  if (kern_end + sizeof (struct grub_netbsd_btinfo_rootdevice)
+      + sizeof (struct grub_netbsd_bootinfo)
+      + sizeof (struct grub_netbsd_btinfo_mmap_header)
+      + count * sizeof (struct grub_netbsd_btinfo_mmap_entry)
+      > grub_os_area_addr + grub_os_area_size)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "No memory for boot info.");
+
+  curarg = mmap = (struct grub_netbsd_btinfo_mmap_header *) kern_end;
+  pm = (struct grub_netbsd_btinfo_mmap_entry *) (mmap + 1);
+
+  grub_mmap_iterate (fill_hook);
+  mmap->common.type = NETBSD_BTINFO_MEMMAP;
+  mmap->common.len = (char *) pm - (char *) mmap;
+  mmap->count = count;
+  curarg = pm;
+
+  if (netbsd_root)
+    {
+      struct grub_netbsd_btinfo_rootdevice *rootdev;
+
+      rootdev = (struct grub_netbsd_btinfo_rootdevice *) curarg;
+
+      rootdev->common.len = sizeof (struct grub_netbsd_btinfo_rootdevice);
+      rootdev->common.type = NETBSD_BTINFO_ROOTDEVICE;
+      grub_strncpy (rootdev->devname, netbsd_root, sizeof (rootdev->devname));
+
+      bootinfo = (struct grub_netbsd_bootinfo *) (rootdev + 1);
+      bootinfo->bi_count = 2;
+      bootinfo->bi_data[0] = mmap;
+      bootinfo->bi_data[1] = rootdev;
+    }
+  else
+    {
+      bootinfo = (struct grub_netbsd_bootinfo *) curarg;
+      bootinfo->bi_count = 1;
+      bootinfo->bi_data[0] = mmap;
+    }
+
+  grub_unix_real_boot (entry, bootflags, 0, bootinfo,
+		       0, (grub_uint32_t) (grub_mmap_get_upper () >> 10),
+		       (grub_uint32_t) (grub_mmap_get_lower () >> 10));
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_bsd_unload (void)
+{
+  if (mod_buf)
+    {
+      grub_free (mod_buf);
+      mod_buf = 0;
+      mod_buf_max = 0;
+    }
+
+  kernel_type = KERNEL_TYPE_NONE;
+  grub_dl_unref (my_mod);
+
+  grub_free (netbsd_root);
+  netbsd_root = NULL;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_bsd_load_aout (grub_file_t file)
+{
+  grub_addr_t load_addr, bss_end_addr;
+  int ofs, align_page;
+  union grub_aout_header ah;
+
+  if ((grub_file_seek (file, 0)) == (grub_off_t) - 1)
+    return grub_errno;
+
+  if (grub_file_read (file, &ah, sizeof (ah)) != sizeof (ah))
+    return grub_error (GRUB_ERR_READ_ERROR, "Cannot read the a.out header");
+
+  if (grub_aout_get_type (&ah) != AOUT_TYPE_AOUT32)
+    return grub_error (GRUB_ERR_BAD_OS, "Invalid a.out header");
+
+  entry = ah.aout32.a_entry & 0xFFFFFF;
+
+  if (AOUT_GETMAGIC (ah.aout32) == AOUT32_ZMAGIC)
+    {
+      load_addr = entry;
+      ofs = 0x1000;
+      align_page = 0;
+    }
+  else
+    {
+      load_addr = entry & 0xF00000;
+      ofs = sizeof (struct grub_aout32_header);
+      align_page = 1;
+    }
+
+  if (load_addr < 0x100000)
+    return grub_error (GRUB_ERR_BAD_OS, "Load address below 1M");
+
+  kern_start = load_addr;
+  kern_end = load_addr + ah.aout32.a_text + ah.aout32.a_data;
+  if (align_page)
+    kern_end = ALIGN_PAGE (kern_end);
+
+  if (ah.aout32.a_bss)
+    {
+      kern_end += ah.aout32.a_bss;
+      if (align_page)
+	kern_end = ALIGN_PAGE (kern_end);
+
+      bss_end_addr = kern_end;
+    }
+  else
+    bss_end_addr = 0;
+
+  return grub_aout_load (file, ofs, load_addr,
+			 ah.aout32.a_text + ah.aout32.a_data, bss_end_addr);
+}
+
+static grub_err_t
+grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load)
+{
+  Elf32_Addr paddr;
+
+  if (phdr->p_type != PT_LOAD
+      && phdr->p_type != PT_DYNAMIC)
+    {
+      *do_load = 0;
+      return 0;
+    }
+
+  *do_load = 1;
+  phdr->p_paddr &= 0xFFFFFF;
+  paddr = phdr->p_paddr;
+
+  if ((paddr < grub_os_area_addr)
+      || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range",
+		       paddr);
+
+  if ((!kern_start) || (paddr < kern_start))
+    kern_start = paddr;
+
+  if (paddr + phdr->p_memsz > kern_end)
+    kern_end = paddr + phdr->p_memsz;
+
+  *addr = paddr;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_bsd_elf64_hook (Elf64_Phdr * phdr, grub_addr_t * addr, int *do_load)
+{
+  Elf64_Addr paddr;
+
+  if (phdr->p_type != PT_LOAD
+      && phdr->p_type != PT_DYNAMIC)
+    {
+      *do_load = 0;
+      return 0;
+    }
+
+  *do_load = 1;
+  paddr = phdr->p_paddr & 0xffffff;
+
+  if ((paddr < grub_os_area_addr)
+      || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range",
+		       paddr);
+
+  if ((!kern_start) || (paddr < kern_start))
+    kern_start = paddr;
+
+  if (paddr + phdr->p_memsz > kern_end)
+    kern_end = paddr + phdr->p_memsz;
+
+  *addr = paddr;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_bsd_load_elf (grub_elf_t elf)
+{
+  kern_start = kern_end = 0;
+
+  if (grub_elf_is_elf32 (elf))
+    {
+      entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF;
+      return grub_elf32_load (elf, grub_bsd_elf32_hook, 0, 0);
+    }
+  else if (grub_elf_is_elf64 (elf))
+    {
+      is_64bit = 1;
+
+      if (! grub_cpuid_has_longmode)
+	return grub_error (GRUB_ERR_BAD_OS, "Your CPU does not implement AMD64 architecture.");
+
+      /* FreeBSD has 64-bit entry point.  */
+      if (kernel_type == KERNEL_TYPE_FREEBSD)
+	{
+	  entry = elf->ehdr.ehdr64.e_entry & 0xffffffff;
+	  entry_hi = (elf->ehdr.ehdr64.e_entry >> 32) & 0xffffffff;
+	}
+      else
+	{
+	  entry = elf->ehdr.ehdr64.e_entry & 0x0fffffff;
+	  entry_hi = 0;
+	}
+      return grub_elf64_load (elf, grub_bsd_elf64_hook, 0, 0);
+    }
+  else
+    return grub_error (GRUB_ERR_BAD_OS, "Invalid elf");
+}
+
+static grub_err_t
+grub_bsd_load (int argc, char *argv[])
+{
+  grub_file_t file;
+  grub_elf_t elf;
+
+  grub_dl_ref (my_mod);
+
+  grub_loader_unset ();
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (!file)
+    goto fail;
+
+  elf = grub_elf_file (file);
+  if (elf)
+    {
+      is_elf_kernel = 1;
+      grub_bsd_load_elf (elf);
+      grub_elf_close (elf);
+    }
+  else
+    {
+      is_elf_kernel = 0;
+      grub_errno = 0;
+      grub_bsd_load_aout (file);
+      grub_file_close (file);
+    }
+
+fail:
+
+  if (grub_errno != GRUB_ERR_NONE)
+    grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_uint32_t
+grub_bsd_parse_flags (const struct grub_arg_list *state,
+		      const grub_uint32_t * flags)
+{
+  grub_uint32_t result = 0;
+  unsigned i;
+
+  for (i = 0; flags[i]; i++)
+    if (state[i].set)
+      result |= flags[i];
+
+  return result;
+}
+
+static grub_err_t
+grub_cmd_freebsd (grub_extcmd_t cmd, int argc, char *argv[])
+{
+  kernel_type = KERNEL_TYPE_FREEBSD;
+  bootflags = grub_bsd_parse_flags (cmd->state, freebsd_flags);
+
+  if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
+    {
+      kern_end = ALIGN_PAGE (kern_end);
+      if (is_elf_kernel)
+	{
+	  grub_err_t err;
+	  grub_uint64_t data = 0;
+	  grub_file_t file;
+	  int len = is_64bit ? 8 : 4;
+
+	  err = grub_freebsd_add_meta_module (argv[0], is_64bit
+					      ? FREEBSD_MODTYPE_KERNEL64
+					      : FREEBSD_MODTYPE_KERNEL,
+					      argc - 1, argv + 1,
+					      kern_start,
+					      kern_end - kern_start);
+	  if (err)
+	    return err;
+
+	  file = grub_gzfile_open (argv[0], 1);
+	  if (! file)
+	    return grub_errno;
+
+	  if (is_64bit)
+	    err = grub_freebsd_load_elf_meta64 (file, &kern_end);
+	  else
+	    err = grub_freebsd_load_elf_meta32 (file, &kern_end);
+	  if (err)
+	    return err;
+
+	  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+				       FREEBSD_MODINFOMD_HOWTO, &data, 4);
+	  if (err)
+	    return err;
+
+	  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+				       FREEBSD_MODINFOMD_ENVP, &data, len);
+	  if (err)
+	    return err;
+
+	  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+				       FREEBSD_MODINFOMD_KERNEND, &data, len);
+	  if (err)
+	    return err;
+
+	  kern_end_mdofs = mod_buf_len - len;
+
+	  err = grub_freebsd_add_mmap ();
+	  if (err)
+	    return err;
+	}
+      grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 1);
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_openbsd (grub_extcmd_t cmd, int argc, char *argv[])
+{
+  grub_uint32_t bootdev;
+
+  kernel_type = KERNEL_TYPE_OPENBSD;
+  bootflags = grub_bsd_parse_flags (cmd->state, openbsd_flags);
+
+  if (cmd->state[OPENBSD_ROOT_ARG].set)
+    {
+      const char *arg = cmd->state[OPENBSD_ROOT_ARG].arg;
+      int unit, part;
+      if (*(arg++) != 'w' || *(arg++) != 'd')
+	return grub_error (GRUB_ERR_BAD_ARGUMENT,
+			   "Only device specifications of form "
+			   "wd<number><lowercase letter> are supported.");
+
+      unit = grub_strtoul (arg, (char **) &arg, 10);
+      if (! (arg && *arg >= 'a' && *arg <= 'z'))
+	return grub_error (GRUB_ERR_BAD_ARGUMENT,
+			   "Only device specifications of form "
+			   "wd<number><lowercase letter> are supported.");
+
+      part = *arg - 'a';
+
+      bootdev = (OPENBSD_B_DEVMAGIC + (unit << OPENBSD_B_UNITSHIFT) +
+		 (part << OPENBSD_B_PARTSHIFT));
+    }
+  else
+    bootdev = 0;
+
+  if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
+    {
+      grub_loader_set (grub_openbsd_boot, grub_bsd_unload, 1);
+      openbsd_root = bootdev;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_netbsd (grub_extcmd_t cmd, int argc, char *argv[])
+{
+  kernel_type = KERNEL_TYPE_NETBSD;
+  bootflags = grub_bsd_parse_flags (cmd->state, netbsd_flags);
+
+  if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
+    {
+      grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 1);
+      if (cmd->state[NETBSD_ROOT_ARG].set)
+	netbsd_root = grub_strdup (cmd->state[NETBSD_ROOT_ARG].arg);
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_freebsd_loadenv (grub_command_t cmd __attribute__ ((unused)),
+			  int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  char *buf = 0, *curr, *next;
+  int len;
+
+  if (kernel_type == KERNEL_TYPE_NONE)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "You need to load the kernel first.");
+
+  if (kernel_type != KERNEL_TYPE_FREEBSD)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "Only FreeBSD support environment");
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No filename");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if ((!file) || (!file->size))
+    goto fail;
+
+  len = file->size;
+  buf = grub_malloc (len + 1);
+  if (!buf)
+    goto fail;
+
+  if (grub_file_read (file, buf, len) != len)
+    goto fail;
+
+  buf[len] = 0;
+
+  next = buf;
+  while (next)
+    {
+      char *p;
+
+      curr = next;
+      next = grub_strchr (curr, '\n');
+      if (next)
+	{
+
+	  p = next - 1;
+	  while (p > curr)
+	    {
+	      if ((*p != '\r') && (*p != ' ') && (*p != '\t'))
+		break;
+	      p--;
+	    }
+
+	  if ((p > curr) && (*p == '"'))
+	    p--;
+
+	  *(p + 1) = 0;
+	  next++;
+	}
+
+      if (*curr == '#')
+	continue;
+
+      p = grub_strchr (curr, '=');
+      if (!p)
+	continue;
+
+      *(p++) = 0;
+
+      if (*curr)
+	{
+	  char name[grub_strlen (curr) + sizeof("kFreeBSD.")];
+
+	  if (*p == '"')
+	    p++;
+
+	  grub_sprintf (name, "kFreeBSD.%s", curr);
+	  if (grub_env_set (name, p))
+	    goto fail;
+	}
+    }
+
+fail:
+  grub_free (buf);
+
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)),
+			 int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_err_t err;
+  int modargc;
+  char **modargv;
+  char *type;
+
+  if (kernel_type == KERNEL_TYPE_NONE)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "You need to load the kernel first.");
+
+  if (kernel_type != KERNEL_TYPE_FREEBSD)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "Only FreeBSD support module");
+
+  if (!is_elf_kernel)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "Only ELF kernel support module");
+
+  /* List the current modules if no parameter.  */
+  if (!argc)
+    {
+      grub_freebsd_list_modules ();
+      return 0;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if ((!file) || (!file->size))
+    goto fail;
+
+  if (kern_end + file->size > grub_os_area_addr + grub_os_area_size)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "Not enough memory for the module");
+      goto fail;
+    }
+
+  grub_file_read (file, (void *) kern_end, file->size);
+  if (grub_errno)
+    goto fail;
+
+  modargc = argc - 1;
+  modargv = argv + 1;
+
+  if (modargc && (! grub_memcmp (modargv[0], "type=", 5)))
+    {
+      type = &modargv[0][5];
+      modargc--;
+      modargv++;
+    }
+  else
+    type = FREEBSD_MODTYPE_RAW;
+
+  err = grub_freebsd_add_meta_module (argv[0], type, modargc, modargv,
+				      kern_end, file->size);
+  if (err)
+    goto fail;
+
+  kern_end = ALIGN_PAGE (kern_end + file->size);
+
+fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_freebsd_module_elf (grub_command_t cmd __attribute__ ((unused)),
+			     int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_err_t err;
+
+  if (kernel_type == KERNEL_TYPE_NONE)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "You need to load the kernel first.");
+
+  if (kernel_type != KERNEL_TYPE_FREEBSD)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "Only FreeBSD support module");
+
+  if (! is_elf_kernel)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		       "Only ELF kernel support module");
+
+  /* List the current modules if no parameter.  */
+  if (! argc)
+    {
+      grub_freebsd_list_modules ();
+      return 0;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (!file)
+    return grub_errno;
+  if (!file->size)
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+  if (is_64bit)
+    err = grub_freebsd_load_elfmodule_obj64 (file, argc, argv, &kern_end);
+  else
+    err = grub_freebsd_load_elfmodule32 (file, argc, argv, &kern_end);
+  grub_file_close (file);
+
+  return err;
+}
+
+
+static grub_extcmd_t cmd_freebsd, cmd_openbsd, cmd_netbsd;
+static grub_command_t cmd_freebsd_loadenv, cmd_freebsd_module;
+static grub_command_t cmd_freebsd_module_elf;
+
+GRUB_MOD_INIT (bsd)
+{
+  cmd_freebsd = grub_register_extcmd ("kfreebsd", grub_cmd_freebsd,
+				      GRUB_COMMAND_FLAG_BOTH,
+				      "kfreebsd FILE", "Load kernel of FreeBSD.",
+				      freebsd_opts);
+  cmd_openbsd = grub_register_extcmd ("kopenbsd", grub_cmd_openbsd,
+				      GRUB_COMMAND_FLAG_BOTH,
+				      "kopenbsd FILE", "Load kernel of OpenBSD.",
+				      openbsd_opts);
+  cmd_netbsd = grub_register_extcmd ("knetbsd", grub_cmd_netbsd,
+				     GRUB_COMMAND_FLAG_BOTH,
+				     "knetbsd FILE", "Load kernel of NetBSD.",
+				     netbsd_opts);
+  cmd_freebsd_loadenv =
+    grub_register_command ("kfreebsd_loadenv", grub_cmd_freebsd_loadenv,
+			   0, "load FreeBSD env");
+  cmd_freebsd_module =
+    grub_register_command ("kfreebsd_module", grub_cmd_freebsd_module,
+			   0, "load FreeBSD kernel module");
+  cmd_freebsd_module_elf =
+    grub_register_command ("kfreebsd_module_elf", grub_cmd_freebsd_module_elf,
+			   0, "load FreeBSD kernel module (ELF)");
+
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI (bsd)
+{
+  grub_unregister_extcmd (cmd_freebsd);
+  grub_unregister_extcmd (cmd_openbsd);
+  grub_unregister_extcmd (cmd_netbsd);
+
+  grub_unregister_command (cmd_freebsd_loadenv);
+  grub_unregister_command (cmd_freebsd_module);
+  grub_unregister_command (cmd_freebsd_module_elf);
+
+  if (mod_buf)
+    {
+      grub_free (mod_buf);
+      mod_buf = 0;
+      mod_buf_max = 0;
+    }
+}
diff --git a/loader/i386/bsd32.c b/loader/i386/bsd32.c
new file mode 100644
index 0000000..26704c4
--- /dev/null
+++ b/loader/i386/bsd32.c
@@ -0,0 +1,6 @@
+#define SUFFIX(x) x ## 32
+#define GRUB_TARGET_WORDSIZE 32
+#define OBJSYM 0
+#include <grub/types.h>
+typedef grub_uint32_t grub_freebsd_addr_t;
+#include "bsdXX.c"
diff --git a/loader/i386/bsd64.c b/loader/i386/bsd64.c
new file mode 100644
index 0000000..f8aad1c
--- /dev/null
+++ b/loader/i386/bsd64.c
@@ -0,0 +1,6 @@
+#define SUFFIX(x) x ## 64
+#define GRUB_TARGET_WORDSIZE 64
+#define OBJSYM 1
+#include <grub/types.h>
+typedef grub_uint64_t grub_freebsd_addr_t;
+#include "bsdXX.c"
diff --git a/loader/i386/bsdXX.c b/loader/i386/bsdXX.c
new file mode 100644
index 0000000..aedc204
--- /dev/null
+++ b/loader/i386/bsdXX.c
@@ -0,0 +1,329 @@
+#include <grub/loader.h>
+#include <grub/cpu/bsd.h>
+#include <grub/mm.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/i386/loader.h>
+
+#define ALIGN_PAGE(a)	ALIGN_UP (a, 4096)
+
+static inline grub_err_t
+load (grub_file_t file, void *where, grub_off_t off, grub_size_t size)
+{
+  if (PTR_TO_UINT32 (where) + size > grub_os_area_addr + grub_os_area_size)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+		       "Not enough memory for the module");
+  if (grub_file_seek (file, off) == (grub_off_t) -1)
+    return grub_errno;
+  if (grub_file_read (file, where, size)
+      != (grub_ssize_t) size)
+    {
+      if (grub_errno)
+	return grub_errno;
+      else
+	return grub_error (GRUB_ERR_BAD_OS, "file is truncated");
+    }
+  return GRUB_ERR_NONE;
+}
+
+static inline grub_err_t
+read_headers (grub_file_t file, Elf_Ehdr *e, char **shdr)
+{
+ if (grub_file_seek (file, 0) == (grub_off_t) -1)
+    return grub_errno;
+
+  if (grub_file_read (file, (char *) e, sizeof (*e)) != sizeof (*e))
+    {
+      if (grub_errno)
+	return grub_errno;
+      else
+	return grub_error (GRUB_ERR_BAD_OS, "file is too short");
+    }
+
+  if (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_VERSION] != EV_CURRENT
+      || e->e_version != EV_CURRENT)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch independent ELF magic");
+
+  if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS))
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch dependent ELF magic");
+
+  *shdr = grub_malloc (e->e_shnum * e->e_shentsize);
+  if (! *shdr)
+    return grub_errno;
+
+  if (grub_file_seek (file, e->e_shoff) == (grub_off_t) -1)
+    return grub_errno;
+
+  if (grub_file_read (file, *shdr, e->e_shnum * e->e_shentsize)
+      != e->e_shnum * e->e_shentsize)
+    {
+      if (grub_errno)
+	return grub_errno;
+      else
+	return grub_error (GRUB_ERR_BAD_OS, "file is truncated");
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* On i386 FreeBSD uses "elf module" approarch for 32-bit variant
+   and "elf obj module" for 64-bit variant. However it may differ on other
+   platforms. So I keep both versions.  */
+#if OBJSYM
+grub_err_t
+SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc,
+					  char *argv[], grub_addr_t *kern_end)
+{
+  Elf_Ehdr e;
+  Elf_Shdr *s;
+  char *shdr;
+  grub_addr_t curload, module;
+  grub_err_t err;
+
+  err = read_headers (file, &e, &shdr);
+  if (err)
+    return err;
+
+  curload = module = ALIGN_PAGE (*kern_end);
+
+  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
+						+ e.e_shnum * e.e_shentsize);
+       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
+    {
+      if (s->sh_size == 0)
+	continue;
+
+      if (s->sh_addralign)
+	curload = ALIGN_UP (curload, s->sh_addralign);
+      s->sh_addr = curload;
+
+      grub_dprintf ("bsd", "loading section to %x, size %d, align %d\n",
+		    (unsigned) curload, (int) s->sh_size,
+		    (int) s->sh_addralign);
+
+      switch (s->sh_type)
+	{
+	default:
+	case SHT_PROGBITS:
+	  err = load (file, UINT_TO_PTR (curload), s->sh_offset, s->sh_size);
+	  if (err)
+	    return err;
+	  break;
+	case SHT_NOBITS:
+	  if (curload + s->sh_size > grub_os_area_addr + grub_os_area_size)
+	    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+			       "Not enough memory for the module");
+	  grub_memset (UINT_TO_PTR (curload), 0, s->sh_size);
+	  break;
+	}
+      curload += s->sh_size;
+    }
+
+  *kern_end = ALIGN_PAGE (curload);
+
+  err = grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE_OBJ,
+				      argc - 1, argv + 1, module,
+				      curload - module);
+  if (! err)
+    err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA
+				 | FREEBSD_MODINFOMD_ELFHDR,
+				 &e, sizeof (e));
+  if (! err)
+    err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA
+				 | FREEBSD_MODINFOMD_SHDR,
+				 shdr, e.e_shnum * e.e_shentsize);
+
+  return err;
+}
+
+#else
+
+grub_err_t
+SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[],
+				      grub_addr_t *kern_end)
+{
+  Elf_Ehdr e;
+  Elf_Shdr *s;
+  char *shdr;
+  grub_addr_t curload, module;
+  grub_err_t err;
+
+  err = read_headers (file, &e, &shdr);
+  if (err)
+    return err;
+
+  curload = module = ALIGN_PAGE (*kern_end);
+
+  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
+						+ e.e_shnum * e.e_shentsize);
+       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
+    {
+      if (s->sh_size == 0)
+	continue;
+
+      if (! (s->sh_flags & SHF_ALLOC))
+	continue;
+
+      grub_dprintf ("bsd", "loading section to %x, size %d, align %d\n",
+		    (unsigned) curload, (int) s->sh_size,
+		    (int) s->sh_addralign);
+
+      switch (s->sh_type)
+	{
+	default:
+	case SHT_PROGBITS:
+	  err = load (file, UINT_TO_PTR (module + s->sh_addr),
+		      s->sh_offset, s->sh_size);
+	  if (err)
+	    return err;
+	  break;
+	case SHT_NOBITS:
+	  if (module + s->sh_addr + s->sh_size
+	      > grub_os_area_addr + grub_os_area_size)
+	    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+			       "Not enough memory for the module");
+	  grub_memset (UINT_TO_PTR (module + s->sh_addr), 0, s->sh_size);
+	  break;
+	}
+      if (curload < module + s->sh_addr + s->sh_size)
+	curload = module + s->sh_addr + s->sh_size;
+    }
+
+  load (file, UINT_TO_PTR (module), 0, sizeof (e));
+  if (curload < module + sizeof (e))
+    curload = module + sizeof (e);
+
+  load (file, UINT_TO_PTR (curload), e.e_shoff,
+	e.e_shnum * e.e_shentsize);
+  e.e_shoff = curload - module;
+  curload +=  e.e_shnum * e.e_shentsize;
+
+  load (file, UINT_TO_PTR (curload), e.e_phoff,
+	e.e_phnum * e.e_phentsize);
+  e.e_phoff = curload - module;
+  curload +=  e.e_phnum * e.e_phentsize;
+
+  *kern_end = curload;
+
+  grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE,
+				argc - 1, argv + 1, module,
+				curload - module);
+  return SUFFIX (grub_freebsd_load_elf_meta) (file, kern_end);
+}
+
+#endif
+
+grub_err_t
+SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end)
+{
+  grub_err_t err;
+  Elf_Ehdr e;
+  Elf_Shdr *s;
+  char *shdr;
+  unsigned symoff, stroff, symsize, strsize;
+  grub_addr_t curload;
+  grub_freebsd_addr_t symstart, symend, symentsize, dynamic;
+  Elf_Sym *sym;
+  const char *str;
+  unsigned i;
+
+  err = read_headers (file, &e, &shdr);
+  if (err)
+    return err;
+
+  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+			       FREEBSD_MODINFOMD_ELFHDR, &e,
+			       sizeof (e));
+  if (err)
+    return err;
+
+  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
+						+ e.e_shnum * e.e_shentsize);
+       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
+      if (s->sh_type == SHT_SYMTAB)
+	break;
+  if (s >= (Elf_Shdr *) ((char *) shdr
+			+ e.e_shnum * e.e_shentsize))
+    return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
+  symoff = s->sh_offset;
+  symsize = s->sh_size;
+  symentsize = s->sh_entsize;
+  s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link);
+  stroff = s->sh_offset;
+  strsize = s->sh_size;
+
+  if (*kern_end + 4 * sizeof (grub_freebsd_addr_t) + symsize + strsize
+      > grub_os_area_addr + grub_os_area_size)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+		       "Not enough memory for kernel symbols");
+
+  symstart = curload = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
+  *((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = symsize;
+  curload += sizeof (grub_freebsd_addr_t);
+  if (grub_file_seek (file, symoff) == (grub_off_t) -1)
+    return grub_errno;
+  sym = (Elf_Sym *) UINT_TO_PTR (curload);
+  if (grub_file_read (file, UINT_TO_PTR (curload), symsize) !=
+      (grub_ssize_t) symsize)
+    {
+      if (! grub_errno)
+	return grub_error (GRUB_ERR_BAD_OS, "invalid elf");
+      return grub_errno;
+    }
+  curload += symsize;
+
+  *((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = strsize;
+  curload += sizeof (grub_freebsd_addr_t);
+  if (grub_file_seek (file, stroff) == (grub_off_t) -1)
+    return grub_errno;
+  str = (char *) UINT_TO_PTR (curload);
+  if (grub_file_read (file, UINT_TO_PTR (curload), strsize)
+      != (grub_ssize_t) strsize)
+    {
+      if (! grub_errno)
+	return grub_error (GRUB_ERR_BAD_OS, "invalid elf");
+      return grub_errno;
+    }
+  curload += strsize;
+  curload = ALIGN_UP (curload, sizeof (grub_freebsd_addr_t));
+  symend = curload;
+
+  for (i = 0;
+       i * symentsize < symsize;
+       i++, sym = (Elf_Sym *) ((char *) sym + symentsize))
+    {
+      const char *name = str + sym->st_name;
+      if (grub_strcmp (name, "_DYNAMIC") == 0)
+	break;
+    }
+
+  if (i * symentsize < symsize)
+    {
+      dynamic = sym->st_value;
+      grub_dprintf ("bsd", "dynamic = %llx\n", (unsigned long long) dynamic);
+      err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+				   FREEBSD_MODINFOMD_DYNAMIC, &dynamic,
+				   sizeof (dynamic));
+      if (err)
+	return err;
+    }
+
+  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+			       FREEBSD_MODINFOMD_SSYM, &symstart,
+			       sizeof (symstart));
+  if (err)
+    return err;
+
+  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+			       FREEBSD_MODINFOMD_ESYM, &symend,
+			       sizeof (symend));
+  if (err)
+    return err;
+  *kern_end = ALIGN_PAGE (curload);
+
+  return GRUB_ERR_NONE;
+}
diff --git a/loader/i386/bsd_helper.S b/loader/i386/bsd_helper.S
new file mode 100644
index 0000000..25aee3a
--- /dev/null
+++ b/loader/i386/bsd_helper.S
@@ -0,0 +1,45 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008, 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+	.p2align	2
+
+
+	.code32
+
+/*
+ * Use cdecl calling convention for *BSD kernels.
+ */
+
+FUNCTION(grub_unix_real_boot)
+
+	/* Interrupts should be disabled.  */
+        cli
+
+	/* Discard `grub_unix_real_boot' return address.  */
+        popl    %eax
+
+        /* Fetch `entry' address ...  */
+        popl	%eax
+
+        /*
+         * ... and put our return address in its place. The kernel will
+         * ignore it, but it expects %esp to point to it.
+         */
+        call	*%eax
diff --git a/loader/i386/bsd_pagetable.c b/loader/i386/bsd_pagetable.c
new file mode 100644
index 0000000..0fd3937
--- /dev/null
+++ b/loader/i386/bsd_pagetable.c
@@ -0,0 +1,88 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1998  Michael Smith <msmith@freebsd.org>
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Based on the code from FreeBSD originally distributed under the
+   following terms: */
+
+/*-
+ * Copyright (c) 1998  Michael Smith <msmith@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+
+static void
+fill_bsd64_pagetable (grub_uint8_t *target)
+{
+  grub_uint64_t *pt2, *pt3, *pt4;
+  int i;
+
+#define PG_V		0x001
+#define PG_RW		0x002
+#define PG_U		0x004
+#define PG_PS		0x080
+
+  pt4 = (grub_uint64_t *) target;
+  pt3 = (grub_uint64_t *) (target + 4096);
+  pt2 = (grub_uint64_t *) (target + 8192);
+
+  grub_memset ((char *) target, 0, 4096 * 3);
+
+  /*
+   * This is kinda brutal, but every single 1GB VM memory segment points to
+   * the same first 1GB of physical memory.  But it is how BSD expects
+   * it to be.
+   */
+  for (i = 0; i < 512; i++)
+    {
+      /* Each slot of the level 4 pages points to the same level 3 page */
+      pt4[i] = (grub_addr_t) &pt3[0];
+      pt4[i] |= PG_V | PG_RW | PG_U;
+
+      /* Each slot of the level 3 pages points to the same level 2 page */
+      pt3[i] = (grub_addr_t) &pt2[0];
+      pt3[i] |= PG_V | PG_RW | PG_U;
+
+      /* The level 2 page slots are mapped with 2MB pages for 1GB. */
+      pt2[i] = i * (2 * 1024 * 1024);
+      pt2[i] |= PG_V | PG_RW | PG_PS | PG_U;
+    }
+}
diff --git a/loader/i386/bsd_trampoline.S b/loader/i386/bsd_trampoline.S
new file mode 100644
index 0000000..a568fff
--- /dev/null
+++ b/loader/i386/bsd_trampoline.S
@@ -0,0 +1,124 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 2003  Peter Wemm <peter@FreeBSD.org>
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Based on the code from FreeBSD originally distributed under the
+   following terms: */
+
+/*-
+ * Copyright (c) 2003  Peter Wemm <peter@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+
+#define MSR_EFER	0xc0000080
+#define EFER_LME	0x00000100
+#define CR4_PAE		0x00000020
+#define CR4_PSE		0x00000010
+#define CR0_PG		0x80000000
+
+#include <grub/symbol.h>
+
+	.p2align	2
+
+	.code32
+
+
+VARIABLE(grub_bsd64_trampoline_start)
+
+	/* Discard `grub_unix_real_boot' return address.  */
+        popl    %eax
+
+        /* entry  */
+        popl	%edi
+
+        /* entry_hi  */
+        popl	%esi
+
+	cli
+
+	/* Turn on EFER.LME.  */
+	movl	$MSR_EFER, %ecx
+	rdmsr
+	orl	$EFER_LME, %eax
+        wrmsr
+
+	/* Turn on PAE.  */
+	movl	%cr4, %eax
+	orl	$(CR4_PAE | CR4_PSE), %eax
+	movl	%eax, %cr4
+
+	/* Set %cr3 for PT4.  */
+	popl	%eax
+	movl    %eax, %cr3
+
+	/* Push a dummy return address.  */
+	pushl	%eax
+
+	/* Turn on paging (implicitly sets EFER.LMA).  */
+	movl	%cr0, %eax
+	orl	$CR0_PG, %eax
+	movl	%eax, %cr0
+
+	/* Now we're in compatibility mode. set %cs for long mode.  */
+	/* lgdt */
+	.byte 0x0f
+	.byte 0x01
+	.byte 0x15
+VARIABLE (grub_bsd64_trampoline_gdt)
+	.long 0x0
+
+	/* ljmp */
+	.byte 0xea
+VARIABLE (grub_bsd64_trampoline_selfjump)
+	.long 0x0
+	.word 0x08
+
+	.code64
+
+bsd64_longmode:
+         /* We're still running V=P, jump to entry point.  */
+	movl	%esi, %eax
+	salq	$32, %rax
+	orq	%rdi, %rax
+	pushq	%rax
+	ret
+VARIABLE(grub_bsd64_trampoline_end)
diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c
new file mode 100644
index 0000000..f96c60e
--- /dev/null
+++ b/loader/i386/efi/linux.c
@@ -0,0 +1,1001 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/term.h>
+#include <grub/cpu/linux.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/uga_draw.h>
+#include <grub/pci.h>
+#include <grub/command.h>
+#include <grub/memory.h>
+
+#define GRUB_LINUX_CL_OFFSET		0x1000
+#define GRUB_LINUX_CL_END_OFFSET	0x2000
+
+#define NEXT_MEMORY_DESCRIPTOR(desc, size)      \
+  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+static grub_dl_t my_mod;
+
+static grub_size_t linux_mem_size;
+static int loaded;
+static void *real_mode_mem;
+static void *prot_mode_mem;
+static void *initrd_mem;
+static grub_efi_uintn_t real_mode_pages;
+static grub_efi_uintn_t prot_mode_pages;
+static grub_efi_uintn_t initrd_pages;
+static void *mmap_buf;
+
+static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
+  {
+    /* NULL.  */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    /* Reserved.  */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    /* Code segment.  */
+    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00,
+    /* Data segment.  */
+    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
+  };
+
+struct gdt_descriptor
+{
+  grub_uint16_t limit;
+  void *base;
+} __attribute__ ((packed));
+
+static struct gdt_descriptor gdt_desc =
+  {
+    sizeof (gdt) - 1,
+    gdt
+  };
+
+struct idt_descriptor
+{
+  grub_uint16_t limit;
+  void *base;
+} __attribute__ ((packed));
+
+static struct idt_descriptor idt_desc =
+  {
+    0,
+    0
+  };
+
+static inline grub_size_t
+page_align (grub_size_t size)
+{
+  return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
+}
+
+/* Find the optimal number of pages for the memory map. Is it better to
+   move this code to efi/mm.c?  */
+static grub_efi_uintn_t
+find_mmap_size (void)
+{
+  static grub_efi_uintn_t mmap_size = 0;
+
+  if (mmap_size != 0)
+    return mmap_size;
+
+  mmap_size = (1 << 12);
+  while (1)
+    {
+      int ret;
+      grub_efi_memory_descriptor_t *mmap;
+      grub_efi_uintn_t desc_size;
+
+      mmap = grub_malloc (mmap_size);
+      if (! mmap)
+	return 0;
+
+      ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
+      grub_free (mmap);
+
+      if (ret < 0)
+	grub_fatal ("cannot get memory map");
+      else if (ret > 0)
+	break;
+
+      mmap_size += (1 << 12);
+    }
+
+  /* Increase the size a bit for safety, because GRUB allocates more on
+     later, and EFI itself may allocate more.  */
+  mmap_size += (1 << 12);
+
+  return page_align (mmap_size);
+}
+
+static void
+free_pages (void)
+{
+  if (real_mode_mem)
+    {
+      grub_efi_free_pages ((grub_addr_t) real_mode_mem, real_mode_pages);
+      real_mode_mem = 0;
+    }
+
+  if (prot_mode_mem)
+    {
+      grub_efi_free_pages ((grub_addr_t) prot_mode_mem, prot_mode_pages);
+      prot_mode_mem = 0;
+    }
+
+  if (initrd_mem)
+    {
+      grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
+      initrd_mem = 0;
+    }
+}
+
+/* Allocate pages for the real mode code and the protected mode code
+   for linux as well as a memory map buffer.  */
+static int
+allocate_pages (grub_size_t prot_size)
+{
+  grub_efi_uintn_t desc_size;
+  grub_efi_memory_descriptor_t *mmap, *mmap_end;
+  grub_efi_uintn_t mmap_size, tmp_mmap_size;
+  grub_efi_memory_descriptor_t *desc;
+  grub_size_t real_size;
+
+  /* Make sure that each size is aligned to a page boundary.  */
+  real_size = GRUB_LINUX_CL_END_OFFSET;
+  prot_size = page_align (prot_size);
+  mmap_size = find_mmap_size ();
+
+  grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
+		(unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
+
+  /* Calculate the number of pages; Combine the real mode code with
+     the memory map buffer for simplicity.  */
+  real_mode_pages = ((real_size + mmap_size) >> 12);
+  prot_mode_pages = (prot_size >> 12);
+
+  /* Initialize the memory pointers with NULL for convenience.  */
+  real_mode_mem = 0;
+  prot_mode_mem = 0;
+
+  /* Read the memory map temporarily, to find free space.  */
+  mmap = grub_malloc (mmap_size);
+  if (! mmap)
+    return 0;
+
+  tmp_mmap_size = mmap_size;
+  if (grub_efi_get_memory_map (&tmp_mmap_size, mmap, 0, &desc_size, 0) <= 0)
+    grub_fatal ("cannot get memory map");
+
+  mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size);
+
+  /* First, find free pages for the real mode code
+     and the memory map buffer.  */
+  for (desc = mmap;
+       desc < mmap_end;
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      /* Probably it is better to put the real mode code in the traditional
+	 space for safety.  */
+      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
+	  && desc->physical_start <= 0x90000
+	  && desc->num_pages >= real_mode_pages)
+	{
+	  grub_efi_physical_address_t physical_end;
+	  grub_efi_physical_address_t addr;
+
+	  physical_end = desc->physical_start + (desc->num_pages << 12);
+	  if (physical_end > 0x90000)
+	    physical_end = 0x90000;
+
+	  grub_dprintf ("linux", "physical_start = %x, physical_end = %x\n",
+			(unsigned) desc->physical_start,
+			(unsigned) physical_end);
+	  addr = physical_end - real_size - mmap_size;
+	  if (addr < 0x10000)
+	    continue;
+
+	  grub_dprintf ("linux", "trying to allocate %u pages at %lx\n",
+			(unsigned) real_mode_pages, (unsigned long) addr);
+	  real_mode_mem = grub_efi_allocate_pages (addr, real_mode_pages);
+	  if (! real_mode_mem)
+	    grub_fatal ("cannot allocate pages");
+
+	  desc->num_pages -= real_mode_pages;
+	  break;
+	}
+    }
+
+  if (! real_mode_mem)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
+      goto fail;
+    }
+
+  mmap_buf = (void *) ((char *) real_mode_mem + real_size);
+
+  /* Next, find free pages for the protected mode code.  */
+  /* XXX what happens if anything is using this address?  */
+  prot_mode_mem = grub_efi_allocate_pages (0x100000, prot_mode_pages + 1);
+  if (! prot_mode_mem)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		  "cannot allocate protected mode pages");
+      goto fail;
+    }
+
+  grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
+		"prot_mode_mem = %lx, prot_mode_pages = %x\n",
+		(unsigned long) real_mode_mem, (unsigned) real_mode_pages,
+		(unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
+
+  grub_free (mmap);
+  return 1;
+
+ fail:
+  grub_free (mmap);
+  free_pages ();
+  return 0;
+}
+
+static void
+grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
+		      grub_uint64_t start, grub_uint64_t size,
+		      grub_uint32_t type)
+{
+  int n = *e820_num;
+
+  if (n >= GRUB_E820_MAX_ENTRY)
+    grub_fatal ("Too many e820 memory map entries");
+
+  if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) &&
+      (e820_map[n - 1].type == type))
+      e820_map[n - 1].size += size;
+  else
+    {
+      e820_map[n].addr = start;
+      e820_map[n].size = size;
+      e820_map[n].type = type;
+      (*e820_num)++;
+    }
+}
+
+#ifdef __x86_64__
+extern grub_uint8_t grub_linux_trampoline_start[];
+extern grub_uint8_t grub_linux_trampoline_end[];
+#endif
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  struct linux_kernel_params *params;
+  grub_efi_uintn_t mmap_size;
+  grub_efi_uintn_t map_key;
+  grub_efi_uintn_t desc_size;
+  grub_efi_uint32_t desc_version;
+  int e820_num;
+
+  params = real_mode_mem;
+
+  grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
+		(unsigned) params->code32_start,
+		(unsigned long) &(idt_desc.limit),
+		(unsigned long) &(gdt_desc.limit));
+  grub_dprintf ("linux", "idt = %x:%lx, gdt = %x:%lx\n",
+		(unsigned) idt_desc.limit, (unsigned long) idt_desc.base,
+		(unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base);
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      switch (type)
+        {
+        case GRUB_MACHINE_MEMORY_AVAILABLE:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				addr, size, GRUB_E820_RAM);
+	  break;
+
+#ifdef GRUB_MACHINE_MEMORY_ACPI
+        case GRUB_MACHINE_MEMORY_ACPI:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				addr, size, GRUB_E820_ACPI);
+	  break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_NVS
+        case GRUB_MACHINE_MEMORY_NVS:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				addr, size, GRUB_E820_NVS);
+	  break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_CODE
+        case GRUB_MACHINE_MEMORY_CODE:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				addr, size, GRUB_E820_EXEC_CODE);
+	  break;
+#endif
+
+        default:
+          grub_e820_add_region (params->e820_map, &e820_num,
+                                addr, size, GRUB_E820_RESERVED);
+        }
+      return 0;
+    }
+
+  e820_num = 0;
+  grub_mmap_iterate (hook);
+  params->mmap_size = e820_num;
+
+  mmap_size = find_mmap_size ();
+  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
+			       &desc_size, &desc_version) <= 0)
+    grub_fatal ("cannot get memory map");
+
+  if (! grub_efi_exit_boot_services (map_key))
+     grub_fatal ("cannot exit boot services");
+
+  /* Note that no boot services are available from here.  */
+
+  /* Pass EFI parameters.  */
+  if (grub_le_to_cpu16 (params->version) >= 0x0206)
+    {
+      params->v0206.efi_mem_desc_size = desc_size;
+      params->v0206.efi_mem_desc_version = desc_version;
+      params->v0206.efi_mmap = (grub_uint32_t) (unsigned long) mmap_buf;
+      params->v0206.efi_mmap_size = mmap_size;
+#ifdef __x86_64__
+      params->v0206.efi_mmap_hi = (grub_uint32_t) ((grub_uint64_t) mmap_buf >> 32);
+#endif
+    }
+  else if (grub_le_to_cpu16 (params->version) >= 0x0204)
+    {
+      params->v0204.efi_mem_desc_size = desc_size;
+      params->v0204.efi_mem_desc_version = desc_version;
+      params->v0204.efi_mmap = (grub_uint32_t) (unsigned long) mmap_buf;
+      params->v0204.efi_mmap_size = mmap_size;
+    }
+
+#ifdef __x86_64__
+
+  grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12),
+	       grub_linux_trampoline_start,
+	       grub_linux_trampoline_end - grub_linux_trampoline_start);
+
+  ((void (*) (unsigned long, void *)) ((char *) prot_mode_mem
+                                     + (prot_mode_pages << 12)))
+    (params->code32_start, real_mode_mem);
+
+#else
+
+  /* Hardware interrupts are not safe any longer.  */
+  asm volatile ("cli" : : );
+
+  /* Load the IDT and the GDT for the bootstrap.  */
+  asm volatile ("lidt %0" : : "m" (idt_desc));
+  asm volatile ("lgdt %0" : : "m" (gdt_desc));
+
+  /* Pass parameters.  */
+  asm volatile ("movl %0, %%ecx" : : "m" (params->code32_start));
+  asm volatile ("movl %0, %%esi" : : "m" (real_mode_mem));
+
+  asm volatile ("xorl %%ebx, %%ebx" : : );
+
+  /* Enter Linux.  */
+  asm volatile ("jmp *%%ecx" : : );
+
+#endif
+
+  /* Never reach here.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  free_pages ();
+  grub_dl_unref (my_mod);
+  loaded = 0;
+  return GRUB_ERR_NONE;
+}
+
+static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
+
+
+#define RGB_MASK	0xffffff
+#define RGB_MAGIC	0x121314
+#define LINE_MIN	800
+#define LINE_MAX	4096
+#define FBTEST_STEP	(0x10000 >> 2)
+#define FBTEST_COUNT	8
+
+static int
+find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+{
+  grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
+  int i;
+
+  for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
+    {
+      if ((*base & RGB_MASK) == RGB_MAGIC)
+	{
+	  int j;
+
+	  for (j = LINE_MIN; j <= LINE_MAX; j++)
+	    {
+	      if ((base[j] & RGB_MASK) == RGB_MAGIC)
+		{
+		  *fb_base = (grub_uint32_t) (grub_target_addr_t) base;
+		  *line_len = j << 2;
+
+		  return 1;
+		}
+	    }
+
+	  break;
+	}
+    }
+
+  return 0;
+}
+
+static int
+find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+{
+  int found = 0;
+
+  auto int NESTED_FUNC_ATTR find_card (int bus, int dev, int func,
+				       grub_pci_id_t pciid);
+
+  int NESTED_FUNC_ATTR find_card (int bus, int dev, int func,
+				  grub_pci_id_t pciid)
+    {
+      grub_pci_address_t addr;
+
+      addr = grub_pci_make_address (bus, dev, func, 2);
+      if (grub_pci_read (addr) >> 24 == 0x3)
+	{
+	  int i;
+
+	  grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n",
+		       bus, dev, func, pciid);
+	  addr += 8;
+	  for (i = 0; i < 6; i++, addr += 4)
+	    {
+	      grub_uint32_t old_bar1, old_bar2, type;
+	      grub_uint64_t base64;
+
+	      old_bar1 = grub_pci_read (addr);
+	      if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
+		continue;
+
+	      type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
+	      if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+		{
+		  if (i == 5)
+		    break;
+
+		  old_bar2 = grub_pci_read (addr + 4);
+		}
+	      else
+		old_bar2 = 0;
+
+	      base64 = old_bar2;
+	      base64 <<= 32;
+	      base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
+
+	      grub_printf ("%s(%d): 0x%llx\n",
+			   ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
+			    "VMEM" : "MMIO"), i,
+			   (unsigned long long) base64);
+
+	      if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
+		{
+		  *fb_base = base64;
+		  if (find_line_len (fb_base, line_len))
+		    found++;
+		}
+
+	      if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+		{
+		  i++;
+		  addr += 4;
+		}
+	    }
+	}
+
+      return found;
+    }
+
+  grub_pci_iterate (find_card);
+  return found;
+}
+
+static int
+grub_linux_setup_video (struct linux_kernel_params *params)
+{
+  grub_efi_uga_draw_protocol_t *c;
+  grub_uint32_t width, height, depth, rate, pixel, fb_base, line_len;
+  int ret;
+
+  c = grub_efi_locate_protocol (&uga_draw_guid, 0);
+  if (! c)
+    return 1;
+
+  if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
+    return 1;
+
+  grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate);
+
+  grub_efi_set_text_mode (0);
+  pixel = RGB_MAGIC;
+  efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
+	       GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
+  ret = find_framebuf (&fb_base, &line_len);
+  grub_efi_set_text_mode (1);
+
+  if (! ret)
+    {
+      grub_printf ("Can\'t find frame buffer address\n");
+      return 1;
+    }
+
+  grub_printf ("Frame buffer base: 0x%x\n", fb_base);
+  grub_printf ("Video line length: %d\n", line_len);
+
+  params->lfb_width = width;
+  params->lfb_height = height;
+  params->lfb_depth = depth;
+  params->lfb_line_len = line_len;
+
+  params->lfb_base = fb_base;
+  params->lfb_size = (line_len * params->lfb_height + 65535) >> 16;
+
+  params->red_mask_size = 8;
+  params->red_field_pos = 16;
+  params->green_mask_size = 8;
+  params->green_field_pos = 8;
+  params->blue_mask_size = 8;
+  params->blue_field_pos = 0;
+  params->reserved_mask_size = 8;
+  params->reserved_field_pos = 24;
+
+  params->have_vga = GRUB_VIDEO_TYPE_VLFB;
+  params->vid_mode = 0x338;  /* 1024x768x32  */
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+		int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  struct linux_kernel_header lh;
+  struct linux_kernel_params *params;
+  grub_uint8_t setup_sects;
+  grub_size_t real_size, prot_size;
+  grub_ssize_t len;
+  int i;
+  char *dest;
+
+  grub_dl_ref (my_mod);
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header");
+      goto fail;
+    }
+
+  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
+      goto fail;
+    }
+
+  if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "too many setup sectors");
+      goto fail;
+    }
+
+  /* EFI support is quite new, so reject old versions.  */
+  if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
+      || grub_le_to_cpu16 (lh.version) < 0x0203)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "too old version");
+      goto fail;
+    }
+
+  /* I'm not sure how to support zImage on EFI.  */
+  if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "zImage is not supported");
+      goto fail;
+    }
+
+  setup_sects = lh.setup_sects;
+
+  /* If SETUP_SECTS is not set, set it to the default (4).  */
+  if (! setup_sects)
+    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
+
+  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
+  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
+
+  if (! allocate_pages (prot_size))
+    goto fail;
+
+  params = (struct linux_kernel_params *) real_mode_mem;
+  grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET);
+  grub_memcpy (&params->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
+
+  params->ps_mouse = params->padding10 =  0;
+
+  len = 0x400 - sizeof (lh);
+  if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+  /* XXX Linux assumes that only elilo can boot Linux on EFI!!!  */
+  params->type_of_loader = (LINUX_LOADER_ID_ELILO << 4);
+
+  params->cl_magic = GRUB_LINUX_CL_MAGIC;
+  params->cl_offset = 0x1000;
+  params->cmd_line_ptr = (unsigned long) real_mode_mem + 0x1000;
+  params->ramdisk_image = 0;
+  params->ramdisk_size = 0;
+
+  params->heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET;
+  params->loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
+
+  /* These are not needed to be precise, because Linux uses these values
+     only to raise an error when the decompression code cannot find good
+     space.  */
+  params->ext_mem = ((32 * 0x100000) >> 10);
+  params->alt_mem = ((32 * 0x100000) >> 10);
+
+  params->video_cursor_x = grub_getxy () >> 8;
+  params->video_cursor_y = grub_getxy () & 0xff;
+  params->video_page = 0; /* ??? */
+  params->video_mode = grub_efi_system_table->con_out->mode->mode;
+  params->video_width = (grub_getwh () >> 8);
+  params->video_ega_bx = 0;
+  params->video_height = (grub_getwh () & 0xff);
+  params->have_vga = 0;
+  params->font_size = 16; /* XXX */
+
+  if (grub_le_to_cpu16 (params->version) >= 0x0206)
+    {
+      params->v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE;
+      params->v0206.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
+#ifdef __x86_64__
+      params->v0206.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32);
+#endif
+    }
+  else if (grub_le_to_cpu16 (params->version) >= 0x0204)
+    {
+      params->v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204;
+      params->v0204.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
+    }
+
+#if 0
+  /* The structure is zeroed already.  */
+
+  /* No VBE on EFI.  */
+  params->lfb_width = 0;
+  params->lfb_height = 0;
+  params->lfb_depth = 0;
+  params->lfb_base = 0;
+  params->lfb_size = 0;
+  params->lfb_line_len = 0;
+  params->red_mask_size = 0;
+  params->red_field_pos = 0;
+  params->green_mask_size = 0;
+  params->green_field_pos = 0;
+  params->blue_mask_size = 0;
+  params->blue_field_pos = 0;
+  params->reserved_mask_size = 0;
+  params->reserved_field_pos = 0;
+  params->vesapm_segment = 0;
+  params->vesapm_offset = 0;
+  params->lfb_pages = 0;
+  params->vesa_attrib = 0;
+
+  /* No APM on EFI.  */
+  params->apm_version = 0;
+  params->apm_code_segment = 0;
+  params->apm_entry = 0;
+  params->apm_16bit_code_segment = 0;
+  params->apm_data_segment = 0;
+  params->apm_flags = 0;
+  params->apm_code_len = 0;
+  params->apm_data_len = 0;
+
+  /* XXX is there any way to use SpeedStep on EFI?  */
+  params->ist_signature = 0;
+  params->ist_command = 0;
+  params->ist_event = 0;
+  params->ist_perf_level = 0;
+
+  /* Let the kernel probe the information.  */
+  grub_memset (params->hd0_drive_info, 0, sizeof (params->hd0_drive_info));
+  grub_memset (params->hd1_drive_info, 0, sizeof (params->hd1_drive_info));
+
+  /* No MCA on EFI.  */
+  params->rom_config_len = 0;
+
+  /* No need to fake the BIOS's memory map.  */
+  params->mmap_size = 0;
+
+  /* Let the kernel probe the information.  */
+  params->ps_mouse = 0;
+
+  /* Clear padding for future compatibility.  */
+  grub_memset (params->padding1, 0, sizeof (params->padding1));
+  grub_memset (params->padding2, 0, sizeof (params->padding2));
+  grub_memset (params->padding3, 0, sizeof (params->padding3));
+  grub_memset (params->padding4, 0, sizeof (params->padding4));
+  grub_memset (params->padding5, 0, sizeof (params->padding5));
+  grub_memset (params->padding6, 0, sizeof (params->padding6));
+  grub_memset (params->padding7, 0, sizeof (params->padding7));
+  grub_memset (params->padding8, 0, sizeof (params->padding8));
+  grub_memset (params->padding9, 0, sizeof (params->padding9));
+
+#endif
+
+  /* The other EFI parameters are filled when booting.  */
+
+  grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
+
+  /* XXX there is no way to know if the kernel really supports EFI.  */
+  grub_printf ("   [Linux-bzImage, setup=0x%x, size=0x%x]\n",
+	       (unsigned) real_size, (unsigned) prot_size);
+
+  grub_linux_setup_video (params);
+
+  /* Detect explicitly specified memory size, if any.  */
+  linux_mem_size = 0;
+  for (i = 1; i < argc; i++)
+    if (grub_memcmp (argv[i], "mem=", 4) == 0)
+      {
+	char *val = argv[i] + 4;
+
+	linux_mem_size = grub_strtoul (val, &val, 0);
+
+	if (grub_errno)
+	  {
+	    grub_errno = GRUB_ERR_NONE;
+	    linux_mem_size = 0;
+	  }
+	else
+	  {
+	    int shift = 0;
+
+	    switch (grub_tolower (val[0]))
+	      {
+	      case 'g':
+		shift += 10;
+	      case 'm':
+		shift += 10;
+	      case 'k':
+		shift += 10;
+	      default:
+		break;
+	      }
+
+	    /* Check an overflow.  */
+	    if (linux_mem_size > (~0UL >> shift))
+	      linux_mem_size = 0;
+	    else
+	      linux_mem_size <<= shift;
+	  }
+      }
+    else if (grub_memcmp (argv[i], "video=efifb", 11) == 0)
+      {
+	if (params->have_vga)
+	  params->have_vga = GRUB_VIDEO_TYPE_EFI;
+      }
+
+  /* Specify the boot file.  */
+  dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET,
+		      "BOOT_IMAGE=");
+  dest = grub_stpcpy (dest, argv[0]);
+
+  /* Copy kernel parameters.  */
+  for (i = 1;
+       i < argc
+	 && dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem
+						+ GRUB_LINUX_CL_END_OFFSET);
+       i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+  len = prot_size;
+  if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
+    grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
+      loaded = 1;
+    }
+
+ fail:
+
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_dl_unref (my_mod);
+      loaded = 0;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+		 int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_addr_t addr_min, addr_max;
+  grub_addr_t addr;
+  grub_efi_uintn_t mmap_size;
+  grub_efi_memory_descriptor_t *desc;
+  grub_efi_uintn_t desc_size;
+  struct linux_kernel_header *lh;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+      goto fail;
+    }
+
+  if (! loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  size = grub_file_size (file);
+  initrd_pages = (page_align (size) >> 12);
+
+  lh = (struct linux_kernel_header *) real_mode_mem;
+
+  addr_max = (grub_cpu_to_le32 (lh->initrd_addr_max) << 10);
+  if (linux_mem_size != 0 && linux_mem_size < addr_max)
+    addr_max = linux_mem_size;
+
+  /* Linux 2.3.xx has a bug in the memory range check, so avoid
+     the last page.
+     Linux 2.2.xx has a bug in the memory range check, which is
+     worse than that of Linux 2.3.xx, so avoid the last 64kb.  */
+  addr_max -= 0x10000;
+
+  /* Usually, the compression ratio is about 50%.  */
+  addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
+	     + page_align (size);
+
+  /* Find the highest address to put the initrd.  */
+  mmap_size = find_mmap_size ();
+  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0)
+    grub_fatal ("cannot get memory map");
+
+  addr = 0;
+  for (desc = mmap_buf;
+       desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
+	  && desc->num_pages >= initrd_pages)
+	{
+	  grub_efi_physical_address_t physical_end;
+
+	  physical_end = desc->physical_start + (desc->num_pages << 12);
+	  if (physical_end > addr_max)
+	    physical_end = addr_max;
+
+	  if (physical_end < page_align (size))
+	    continue;
+
+	  physical_end -= page_align (size);
+
+	  if ((physical_end >= addr_min) &&
+	      (physical_end >= desc->physical_start) &&
+	      (physical_end > addr))
+	    addr = physical_end;
+	}
+    }
+
+  if (addr == 0)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "no free pages available");
+      goto fail;
+    }
+
+  initrd_mem = grub_efi_allocate_pages (addr, initrd_pages);
+  if (! initrd_mem)
+    grub_fatal ("cannot allocate pages");
+
+  if (grub_file_read (file, initrd_mem, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+  grub_printf ("   [Initrd, addr=0x%x, size=0x%x]\n",
+	       (unsigned) addr, (unsigned) size);
+
+  lh->ramdisk_image = addr;
+  lh->ramdisk_size = size;
+  lh->root_dev = 0x0100; /* XXX */
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linux)
+{
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+				     0, "load linux");
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
+				      0, "load initrd");
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/loader/i386/efi/xnu.c b/loader/i386/efi/xnu.c
new file mode 100644
index 0000000..5085cdb
--- /dev/null
+++ b/loader/i386/efi/xnu.c
@@ -0,0 +1,177 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/xnu.h>
+#include <grub/cpu/xnu.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/uga_draw.h>
+#include <grub/pci.h>
+#include <grub/misc.h>
+
+/* Setup video for xnu. Big parts are copied from linux.c. */
+
+static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
+
+#define RGB_MASK	0xffffff
+#define RGB_MAGIC	0x121314
+#define LINE_MIN	800
+#define LINE_MAX	4096
+#define FBTEST_STEP	(0x10000 >> 2)
+#define FBTEST_COUNT	8
+
+static int
+find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+{
+  grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
+  int i;
+
+  for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
+    {
+      if ((*base & RGB_MASK) == RGB_MAGIC)
+	{
+	  int j;
+
+	  for (j = LINE_MIN; j <= LINE_MAX; j++)
+	    {
+	      if ((base[j] & RGB_MASK) == RGB_MAGIC)
+		{
+		  *fb_base = (grub_uint32_t) (grub_target_addr_t) base;
+		  *line_len = j << 2;
+
+		  return 1;
+		}
+	    }
+
+	  break;
+	}
+    }
+
+  return 0;
+}
+
+static int
+find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+{
+  int found = 0;
+
+  auto int NESTED_FUNC_ATTR find_card (int bus, int dev, int func,
+				       grub_pci_id_t pciid);
+
+  int NESTED_FUNC_ATTR find_card (int bus, int dev, int func,
+				  grub_pci_id_t pciid)
+    {
+      grub_pci_address_t addr;
+
+      addr = grub_pci_make_address (bus, dev, func, 2);
+      if (grub_pci_read (addr) >> 24 == 0x3)
+	{
+	  int i;
+
+	  grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n",
+		       bus, dev, func, pciid);
+	  addr += 8;
+	  for (i = 0; i < 6; i++, addr += 4)
+	    {
+	      grub_uint32_t old_bar1, old_bar2, type;
+	      grub_uint64_t base64;
+
+	      old_bar1 = grub_pci_read (addr);
+	      if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
+		continue;
+
+	      type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
+	      if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+		{
+		  if (i == 5)
+		    break;
+
+		  old_bar2 = grub_pci_read (addr + 4);
+		}
+	      else
+		old_bar2 = 0;
+
+	      base64 = old_bar2;
+	      base64 <<= 32;
+	      base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
+
+	      grub_printf ("%s(%d): 0x%llx\n",
+			   ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
+			    "VMEM" : "MMIO"), i,
+			   (unsigned long long) base64);
+
+	      if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
+		{
+		  *fb_base = base64;
+		  if (find_line_len (fb_base, line_len))
+		    found++;
+		}
+
+	      if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+		{
+		  i++;
+		  addr += 4;
+		}
+	    }
+	}
+
+      return found;
+    }
+
+  grub_pci_iterate (find_card);
+  return found;
+}
+
+grub_err_t
+grub_xnu_set_video (struct grub_xnu_boot_params *params)
+{
+  grub_efi_uga_draw_protocol_t *c;
+  grub_uint32_t width, height, depth, rate, pixel, fb_base, line_len;
+  int ret;
+
+  c = grub_efi_locate_protocol (&uga_draw_guid, 0);
+  if (! c)
+    return grub_error (GRUB_ERR_IO, "Couldn't find UGADraw");
+
+  if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
+    return grub_error (GRUB_ERR_IO, "Couldn't retrieve video mode");
+
+  grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate);
+
+  grub_efi_set_text_mode (0);
+  pixel = RGB_MAGIC;
+  efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
+	       GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
+  ret = find_framebuf (&fb_base, &line_len);
+  grub_efi_set_text_mode (1);
+
+  if (! ret)
+    return grub_error (GRUB_ERR_IO, "Can\'t find frame buffer address\n");
+
+  grub_printf ("Frame buffer base: 0x%x\n", fb_base);
+  grub_printf ("Video line length: %d\n", line_len);
+
+  params->lfb_width = width;
+  params->lfb_height = height;
+  params->lfb_depth = depth;
+  params->lfb_line_len = line_len;
+  params->lfb_mode = GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
+  params->lfb_base = fb_base;
+  return GRUB_ERR_NONE;
+}
diff --git a/loader/i386/ieee1275/linux.c b/loader/i386/ieee1275/linux.c
new file mode 100644
index 0000000..529d159
--- /dev/null
+++ b/loader/i386/ieee1275/linux.c
@@ -0,0 +1,289 @@
+/* linux.c - boot Linux zImage or bzImage */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/machine/memory.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/term.h>
+#include <grub/cpu/linux.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/command.h>
+
+#define GRUB_OFW_LINUX_PARAMS_ADDR	0x90000
+#define GRUB_OFW_LINUX_KERNEL_ADDR	0x100000
+#define GRUB_OFW_LINUX_INITRD_ADDR	0x800000
+
+#define GRUB_OFW_LINUX_CL_OFFSET	0x1e00
+#define GRUB_OFW_LINUX_CL_LENGTH	0x100
+
+static grub_dl_t my_mod;
+
+static grub_size_t kernel_size;
+static char *kernel_addr, *kernel_cmdline;
+static grub_size_t initrd_size;
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_free (kernel_cmdline);
+  grub_free (kernel_addr);
+  kernel_cmdline = 0;
+  kernel_addr = 0;
+  initrd_size = 0;
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+/*
+static int
+grub_ieee1275_debug (void)
+{
+  struct enter_args
+  {
+    struct grub_ieee1275_common_hdr common;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "enter", 0, 0);
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+
+  return 0;
+}
+*/
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  struct linux_kernel_params *params;
+  struct linux_kernel_header *lh;
+  char *prot_code;
+  char *bootpath;
+  grub_ssize_t len;
+
+  bootpath = grub_env_get ("root");
+  if (bootpath)
+    grub_ieee1275_set_property (grub_ieee1275_chosen,
+                                "bootpath", bootpath,
+                                grub_strlen (bootpath) + 1,
+                                &len);
+
+  params = (struct linux_kernel_params *) GRUB_OFW_LINUX_PARAMS_ADDR;
+  lh = (struct linux_kernel_header *) params;
+
+  grub_memset ((char *) params, 0, GRUB_OFW_LINUX_CL_OFFSET);
+
+  params->alt_mem = grub_mmap_get_upper () >> 10;
+  params->ext_mem = params->alt_mem;
+
+  lh->cmd_line_ptr = (char *)
+        (GRUB_OFW_LINUX_PARAMS_ADDR + GRUB_OFW_LINUX_CL_OFFSET);
+
+  params->cl_magic = GRUB_LINUX_CL_MAGIC;
+  params->cl_offset = GRUB_OFW_LINUX_CL_OFFSET;
+
+  params->video_width = (grub_getwh () >> 8);
+  params->video_height = (grub_getwh () & 0xff);
+  params->font_size = 16;
+
+  params->ofw_signature = GRUB_LINUX_OFW_SIGNATURE;
+  params->ofw_num_items = 1;
+  params->ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn;
+  params->ofw_idt = 0;
+
+  if (initrd_size)
+    {
+      lh->type_of_loader = 1;
+      lh->ramdisk_image = GRUB_OFW_LINUX_INITRD_ADDR;
+      lh->ramdisk_size = initrd_size;
+    }
+
+  if (kernel_cmdline)
+    grub_strcpy (lh->cmd_line_ptr, kernel_cmdline);
+
+  prot_code = (char *) GRUB_OFW_LINUX_KERNEL_ADDR;
+  grub_memcpy (prot_code, kernel_addr, kernel_size);
+
+  asm volatile ("movl %0, %%esi" : : "m" (params));
+  asm volatile ("movl %%esi, %%esp" : : );
+  asm volatile ("movl %0, %%ecx" : : "m" (prot_code));
+  asm volatile ("xorl %%ebx, %%ebx" : : );
+  asm volatile ("jmp *%%ecx" : : );
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+		int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  struct linux_kernel_header lh;
+  grub_uint8_t setup_sects;
+  grub_size_t real_size, prot_size;
+  int i;
+  char *dest;
+
+  grub_dl_ref (my_mod);
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header");
+      goto fail;
+    }
+
+  if ((lh.boot_flag != grub_cpu_to_le16 (0xaa55)) ||
+      (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
+      goto fail;
+    }
+
+  setup_sects = lh.setup_sects;
+  if (! setup_sects)
+    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
+
+  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
+  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
+
+  grub_printf ("   [Linux-%s, setup=0x%x, size=0x%x]\n",
+               "bzImage", real_size, prot_size);
+
+  grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
+  if (grub_errno)
+    goto fail;
+
+  kernel_cmdline = grub_malloc (GRUB_OFW_LINUX_CL_LENGTH);
+  if (! kernel_cmdline)
+    goto fail;
+
+  dest = kernel_cmdline;
+  for (i = 1;
+       i < argc
+       && dest + grub_strlen (argv[i]) + 1 < (kernel_cmdline
+                                              + GRUB_OFW_LINUX_CL_LENGTH);
+       i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+  kernel_addr = grub_malloc (prot_size);
+  if (! kernel_addr)
+    goto fail;
+
+  kernel_size = prot_size;
+  if (grub_file_read (file, kernel_addr, prot_size) != (int) prot_size)
+    grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+
+  if (grub_errno == GRUB_ERR_NONE)
+    grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
+
+fail:
+
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_free (kernel_cmdline);
+      grub_free (kernel_addr);
+      kernel_cmdline = 0;
+      kernel_addr = 0;
+
+      grub_dl_unref (my_mod);
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+		 int argc, char *argv[])
+{
+  grub_file_t file = 0;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+      goto fail;
+    }
+
+  if (! kernel_addr)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  initrd_size = grub_file_size (file);
+  if (grub_file_read (file, (void *) GRUB_OFW_LINUX_INITRD_ADDR,
+                      initrd_size) != (int) initrd_size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linux)
+{
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+				     0, "load linux");
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
+				      0, "load initrd");
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/loader/i386/linux.c b/loader/i386/linux.c
new file mode 100644
index 0000000..4bdb09b
--- /dev/null
+++ b/loader/i386/linux.c
@@ -0,0 +1,996 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/machine.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/loader.h>
+#include <grub/normal.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/term.h>
+#include <grub/cpu/linux.h>
+#include <grub/video.h>
+#include <grub/video_fb.h>
+#include <grub/command.h>
+#include <grub/i386/pc/vbe.h>
+
+#define GRUB_LINUX_CL_OFFSET		0x1000
+#define GRUB_LINUX_CL_END_OFFSET	0x2000
+
+static grub_dl_t my_mod;
+
+static grub_size_t linux_mem_size;
+static int loaded;
+static void *real_mode_mem;
+static void *prot_mode_mem;
+static void *initrd_mem;
+static grub_uint32_t real_mode_pages;
+static grub_uint32_t prot_mode_pages;
+static grub_uint32_t initrd_pages;
+
+static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
+  {
+    /* NULL.  */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    /* Reserved.  */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    /* Code segment.  */
+    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00,
+    /* Data segment.  */
+    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
+  };
+
+struct gdt_descriptor
+{
+  grub_uint16_t limit;
+  void *base;
+} __attribute__ ((packed));
+
+static struct gdt_descriptor gdt_desc =
+  {
+    sizeof (gdt) - 1,
+    gdt
+  };
+
+struct idt_descriptor
+{
+  grub_uint16_t limit;
+  void *base;
+} __attribute__ ((packed));
+
+static struct idt_descriptor idt_desc =
+  {
+    0,
+    0
+  };
+
+#ifdef GRUB_MACHINE_PCBIOS
+struct linux_vesafb_res
+{
+  grub_uint16_t width;
+  grub_uint16_t height;
+};
+
+struct linux_vesafb_mode
+{
+  grub_uint8_t res_index;
+  grub_uint8_t depth;
+};
+
+enum vga_modes
+  {
+    VGA_320_200,
+    VGA_640_400,
+    VGA_640_480,
+    VGA_800_500,
+    VGA_800_600,
+    VGA_896_672,
+    VGA_1024_640,
+    VGA_1024_768,
+    VGA_1152_720,
+    VGA_1280_1024,
+    VGA_1440_900,
+    VGA_1600_1200,
+  };
+
+static struct linux_vesafb_res linux_vesafb_res[] =
+  {
+    { 320, 200 },
+    { 640, 400 },
+    { 640, 480 },
+    { 800, 500 },
+    { 800, 600 },
+    { 896, 672 },
+    { 1024, 640 },
+    { 1024, 768 },
+    { 1152, 720 },
+    { 1280, 1024 },
+    { 1440, 900 },
+    { 1600, 1200 },
+  };
+
+/* This is the reverse of the table in [linux]/Documentation/fb/vesafb.txt
+   plus a few more modes based on the table in
+   http://en.wikipedia.org/wiki/VESA_BIOS_Extensions  */
+struct linux_vesafb_mode linux_vesafb_modes[] =
+  {
+    { VGA_640_400, 8 },		/* 0x300 */
+    { VGA_640_480, 8 },		/* 0x301 */
+    { VGA_800_600, 4 },		/* 0x302 */
+    { VGA_800_600, 8 },		/* 0x303 */
+    { VGA_1024_768, 4 },	/* 0x304 */
+    { VGA_1024_768, 8 },	/* 0x305 */
+    { VGA_1280_1024, 4 },	/* 0x306 */
+    { VGA_1280_1024, 8 },	/* 0x307 */
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { VGA_320_200, 15 },	/* 0x30d */
+    { VGA_320_200, 16 },	/* 0x30e */
+    { VGA_320_200, 24 },	/* 0x30f */
+    { VGA_640_480, 15 },	/* 0x310 */
+    { VGA_640_480, 16 },	/* 0x311 */
+    { VGA_640_480, 24 },	/* 0x312 */
+    { VGA_800_600, 15 },	/* 0x313 */
+    { VGA_800_600, 16 },	/* 0x314 */
+    { VGA_800_600, 24 },	/* 0x315 */
+    { VGA_1024_768, 15 },	/* 0x316 */
+    { VGA_1024_768, 16 },	/* 0x317 */
+    { VGA_1024_768, 24 },	/* 0x318 */
+    { VGA_1280_1024, 15 },	/* 0x319 */
+    { VGA_1280_1024, 16 },	/* 0x31a */
+    { VGA_1280_1024, 24 },	/* 0x31b */
+    { VGA_1600_1200, 8 },	/* 0x31c */
+    { VGA_1600_1200, 15 },	/* 0x31d */
+    { VGA_1600_1200, 16 },	/* 0x31e */
+    { VGA_1600_1200, 24 },	/* 0x31f */
+    { 0, 0 },
+    { VGA_640_400, 15 },	/* 0x321 */
+    { VGA_640_400, 16 },	/* 0x322 */
+    { VGA_640_400, 24 },	/* 0x323 */
+    { VGA_640_400, 32 },	/* 0x324 */
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { VGA_640_480, 32 },	/* 0x329 */
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { VGA_896_672, 8 },		/* 0x32f */
+    { VGA_896_672, 15 },	/* 0x330 */
+    { VGA_896_672, 16 },	/* 0x331 */
+    { VGA_896_672, 24 },	/* 0x332 */
+    { VGA_896_672, 32 },	/* 0x333 */
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { VGA_1600_1200, 32 },	/* 0x342 */
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { VGA_1440_900, 8 },	/* 0x360 */
+    { VGA_1440_900, 15 },	/* 0x361 */
+    { VGA_1440_900, 16 },	/* 0x362 */
+    { VGA_1440_900, 24 },	/* 0x363 */
+    { VGA_1440_900, 32 },	/* 0x364 */
+    { VGA_1152_720, 8 },	/* 0x365 */
+    { VGA_1152_720, 15 },	/* 0x366 */
+    { VGA_1152_720, 16 },	/* 0x367 */
+    { VGA_1152_720, 24 },	/* 0x368 */
+    { VGA_1152_720, 32 },	/* 0x369 */
+    { VGA_1024_640, 8 },	/* 0x36a */
+    { VGA_1024_640, 15 },	/* 0x36b */
+    { VGA_1024_640, 16 },	/* 0x36c */
+    { VGA_1024_640, 24 },	/* 0x36d */
+    { VGA_1024_640, 32 },	/* 0x36e */
+    { VGA_800_500, 8 },		/* 0x36f */
+    { VGA_800_500, 15 },	/* 0x370 */
+    { VGA_800_500, 16 },	/* 0x371 */
+    { VGA_800_500, 24 },	/* 0x372 */
+    { VGA_800_500, 32 },	/* 0x373 */
+  };
+#endif
+
+static inline grub_size_t
+page_align (grub_size_t size)
+{
+  return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
+}
+
+/* Find the optimal number of pages for the memory map. */
+static grub_size_t
+find_mmap_size (void)
+{
+  grub_size_t count = 0, mmap_size;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
+			     grub_uint64_t size __attribute__ ((unused)),
+			     grub_uint32_t type __attribute__ ((unused)))
+    {
+      count++;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+
+  mmap_size = count * sizeof (struct grub_e820_mmap);
+
+  /* Increase the size a bit for safety, because GRUB allocates more on
+     later.  */
+  mmap_size += (1 << 12);
+
+  return page_align (mmap_size);
+}
+
+static void
+free_pages (void)
+{
+  real_mode_mem = prot_mode_mem = initrd_mem = 0;
+}
+
+/* Allocate pages for the real mode code and the protected mode code
+   for linux as well as a memory map buffer.  */
+static int
+allocate_pages (grub_size_t prot_size)
+{
+  grub_size_t real_size, mmap_size;
+
+  /* Make sure that each size is aligned to a page boundary.  */
+  real_size = GRUB_LINUX_CL_END_OFFSET;
+  prot_size = page_align (prot_size);
+  mmap_size = find_mmap_size ();
+
+  grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
+		(unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
+
+  /* Calculate the number of pages; Combine the real mode code with
+     the memory map buffer for simplicity.  */
+  real_mode_pages = ((real_size + mmap_size) >> 12);
+  prot_mode_pages = (prot_size >> 12);
+
+  /* Initialize the memory pointers with NULL for convenience.  */
+  free_pages ();
+
+  /* FIXME: Should request low memory from the heap when this feature is
+     implemented.  */
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      /* We must put real mode code in the traditional space.  */
+
+      if (type == GRUB_MACHINE_MEMORY_AVAILABLE
+	  && addr <= 0x90000)
+	{
+	  if (addr < 0x10000)
+	    {
+	      size += addr - 0x10000;
+	      addr = 0x10000;
+	    }
+
+	  if (addr + size > 0x90000)
+	    size = 0x90000 - addr;
+
+	  if (real_size + mmap_size > size)
+	    return 0;
+
+	  real_mode_mem =
+	    (void *) (grub_size_t) ((addr + size) - (real_size + mmap_size));
+	  return 1;
+	}
+
+      return 0;
+    }
+  grub_mmap_iterate (hook);
+  if (! real_mode_mem)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
+      goto fail;
+    }
+
+  prot_mode_mem = (void *) 0x100000;
+
+  grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
+                "prot_mode_mem = %lx, prot_mode_pages = %x\n",
+                (unsigned long) real_mode_mem, (unsigned) real_mode_pages,
+                (unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
+
+  return 1;
+
+ fail:
+  free_pages ();
+  return 0;
+}
+
+static void
+grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
+                      grub_uint64_t start, grub_uint64_t size,
+                      grub_uint32_t type)
+{
+  int n = *e820_num;
+
+  if (n >= GRUB_E820_MAX_ENTRY)
+    grub_fatal ("Too many e820 memory map entries");
+
+  if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) &&
+      (e820_map[n - 1].type == type))
+      e820_map[n - 1].size += size;
+  else
+    {
+      e820_map[n].addr = start;
+      e820_map[n].size = size;
+      e820_map[n].type = type;
+      (*e820_num)++;
+    }
+}
+
+static int
+grub_linux_setup_video (struct linux_kernel_params *params)
+{
+  struct grub_video_mode_info mode_info;
+  void *framebuffer;
+  int ret;
+
+  ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
+
+  if (ret)
+    return 1;
+
+  params->lfb_width = mode_info.width;
+  params->lfb_height = mode_info.height;
+  params->lfb_depth = mode_info.bpp;
+  params->lfb_line_len = mode_info.pitch;
+
+  params->lfb_base = (grub_size_t) framebuffer;
+  params->lfb_size = (params->lfb_line_len * params->lfb_height + 65535) >> 16;
+
+  params->red_mask_size = mode_info.red_mask_size;
+  params->red_field_pos = mode_info.red_field_pos;
+  params->green_mask_size = mode_info.green_mask_size;
+  params->green_field_pos = mode_info.green_field_pos;
+  params->blue_mask_size = mode_info.blue_mask_size;
+  params->blue_field_pos = mode_info.blue_field_pos;
+  params->reserved_mask_size = mode_info.reserved_mask_size;
+  params->reserved_field_pos = mode_info.reserved_field_pos;
+
+
+#ifdef GRUB_MACHINE_PCBIOS
+  /* VESA packed modes may come with zeroed mask sizes, which need
+     to be set here according to DAC Palette width.  If we don't,
+     this results in Linux displaying a black screen.  */
+  if (mode_info.bpp <= 8)
+    {
+      struct grub_vbe_info_block controller_info;
+      int status;
+      int width = 8;
+
+      status = grub_vbe_bios_get_controller_info (&controller_info);
+
+      if (status == GRUB_VBE_STATUS_OK &&
+	  (controller_info.capabilities & GRUB_VBE_CAPABILITY_DACWIDTH))
+	status = grub_vbe_bios_set_dac_palette_width (&width);
+
+      if (status != GRUB_VBE_STATUS_OK)
+	/* 6 is default after mode reset.  */
+	width = 6;
+
+      params->red_mask_size = params->green_mask_size
+	= params->blue_mask_size = width;
+      params->reserved_mask_size = 0;
+    }
+#endif
+
+  return 0;
+}
+
+#ifdef __x86_64__
+extern grub_uint8_t grub_linux_trampoline_start[];
+extern grub_uint8_t grub_linux_trampoline_end[];
+#endif
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  struct linux_kernel_params *params;
+  int e820_num;
+  grub_err_t err = 0;
+  char *modevar, *tmp;
+
+  params = real_mode_mem;
+
+  grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
+		(unsigned) params->code32_start,
+                (unsigned long) &(idt_desc.limit),
+		(unsigned long) &(gdt_desc.limit));
+  grub_dprintf ("linux", "idt = %x:%lx, gdt = %x:%lx\n",
+		(unsigned) idt_desc.limit, (unsigned long) idt_desc.base,
+		(unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base);
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      switch (type)
+        {
+        case GRUB_MACHINE_MEMORY_AVAILABLE:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				addr, size, GRUB_E820_RAM);
+	  break;
+
+#ifdef GRUB_MACHINE_MEMORY_ACPI
+        case GRUB_MACHINE_MEMORY_ACPI:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				addr, size, GRUB_E820_ACPI);
+	  break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_NVS
+        case GRUB_MACHINE_MEMORY_NVS:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				addr, size, GRUB_E820_NVS);
+	  break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_CODE
+        case GRUB_MACHINE_MEMORY_CODE:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				addr, size, GRUB_E820_EXEC_CODE);
+	  break;
+#endif
+
+        default:
+          grub_e820_add_region (params->e820_map, &e820_num,
+                                addr, size, GRUB_E820_RESERVED);
+        }
+      return 0;
+    }
+
+  e820_num = 0;
+  grub_mmap_iterate (hook);
+  params->mmap_size = e820_num;
+
+  modevar = grub_env_get ("gfxpayload");
+
+  /* Now all graphical modes are acceptable.
+     May change in future if we have modes without framebuffer.  */
+  if (modevar && *modevar != 0)
+    {
+      tmp = grub_malloc (grub_strlen (modevar)
+			 + sizeof (";text"));
+      if (! tmp)
+	return grub_errno;
+      grub_sprintf (tmp, "%s;text", modevar);
+      err = grub_video_set_mode (tmp, 0);
+      grub_free (tmp);
+    }
+  else
+    err = grub_video_set_mode ("text", 0);
+
+  if (err)
+    {
+      grub_print_error ();
+      grub_printf ("Booting however\n");
+      grub_errno = GRUB_ERR_NONE;
+    }
+
+  if (! grub_linux_setup_video (params))
+    params->have_vga = GRUB_VIDEO_TYPE_VLFB;
+  else
+    {
+      params->have_vga = GRUB_VIDEO_TYPE_TEXT;
+      params->video_width = 80;
+      params->video_height = 25;
+    }
+
+  /* Initialize these last, because terminal position could be affected by printfs above.  */
+  if (params->have_vga == GRUB_VIDEO_TYPE_TEXT)
+    {
+      params->video_cursor_x = grub_getxy () >> 8;
+      params->video_cursor_y = grub_getxy () & 0xff;
+    }
+
+#ifdef __x86_64__
+
+  grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12),
+	       grub_linux_trampoline_start,
+	       grub_linux_trampoline_end - grub_linux_trampoline_start);
+
+  ((void (*) (unsigned long, void *)) ((char *) prot_mode_mem
+				       + (prot_mode_pages << 12)))
+    (params->code32_start, real_mode_mem);
+#else
+
+  /* Hardware interrupts are not safe any longer.  */
+  asm volatile ("cli" : : );
+
+  /* Load the IDT and the GDT for the bootstrap.  */
+  asm volatile ("lidt %0" : : "m" (idt_desc));
+  asm volatile ("lgdt %0" : : "m" (gdt_desc));
+
+  /* Enter Linux.  */
+  asm volatile ("jmp *%2" : : "b" (0), "S" (real_mode_mem), "g" (params->code32_start));
+
+#endif
+
+  /* Never reach here.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_dl_unref (my_mod);
+  loaded = 0;
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+		int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  struct linux_kernel_header lh;
+  struct linux_kernel_params *params;
+  grub_uint8_t setup_sects;
+  grub_size_t real_size, prot_size;
+  grub_ssize_t len;
+  int i;
+  char *dest;
+
+  grub_dl_ref (my_mod);
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header");
+      goto fail;
+    }
+
+  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
+      goto fail;
+    }
+
+  if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "too many setup sectors");
+      goto fail;
+    }
+
+  if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "zImage doesn't support 32-bit boot"
+#ifdef GRUB_MACHINE_PCBIOS
+		  " (try with `linux16')"
+#endif
+		  );
+      goto fail;
+    }
+
+  /* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and
+     still not support 32-bit boot.  */
+  if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
+      || grub_le_to_cpu16 (lh.version) < 0x0203)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "version too old for 32-bit boot"
+#ifdef GRUB_MACHINE_PCBIOS
+		  " (try with `linux16')"
+#endif
+		  );
+      goto fail;
+    }
+
+  setup_sects = lh.setup_sects;
+
+  /* If SETUP_SECTS is not set, set it to the default (4).  */
+  if (! setup_sects)
+    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
+
+  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
+  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
+
+  if (! allocate_pages (prot_size))
+    goto fail;
+
+  params = (struct linux_kernel_params *) real_mode_mem;
+  grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET);
+  grub_memcpy (&params->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
+
+  params->ps_mouse = params->padding10 =  0;
+
+  len = 0x400 - sizeof (lh);
+  if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+  params->type_of_loader = (LINUX_LOADER_ID_GRUB << 4);
+
+  /* These two are used (instead of cmd_line_ptr) by older versions of Linux,
+     and otherwise ignored.  */
+  params->cl_magic = GRUB_LINUX_CL_MAGIC;
+  params->cl_offset = 0x1000;
+
+  params->cmd_line_ptr = (unsigned long) real_mode_mem + 0x1000;
+  params->ramdisk_image = 0;
+  params->ramdisk_size = 0;
+
+  params->heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET;
+  params->loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
+
+  /* These are not needed to be precise, because Linux uses these values
+     only to raise an error when the decompression code cannot find good
+     space.  */
+  params->ext_mem = ((32 * 0x100000) >> 10);
+  params->alt_mem = ((32 * 0x100000) >> 10);
+
+  /* Ignored by Linux.  */
+  params->video_page = 0;
+
+  /* Must be non-zero even in text mode, or Linux will think there's no VGA.  */
+  params->video_mode = 0x3;
+
+  /* Only used when `video_mode == 0x7', otherwise ignored.  */
+  params->video_ega_bx = 0;
+
+  params->font_size = 16; /* XXX */
+
+  /* The other parameters are filled when booting.  */
+
+  grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
+
+  grub_printf ("   [Linux-bzImage, setup=0x%x, size=0x%x]\n",
+	       (unsigned) real_size, (unsigned) prot_size);
+
+  /* Look for memory size and video mode specified on the command line.  */
+  linux_mem_size = 0;
+  for (i = 1; i < argc; i++)
+#ifdef GRUB_MACHINE_PCBIOS
+    if (grub_memcmp (argv[i], "vga=", 4) == 0)
+      {
+	/* Video mode selection support.  */
+	char *val = argv[i] + 4;
+	unsigned vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
+	struct linux_vesafb_mode *linux_mode;
+	grub_err_t err;
+	char *buf;
+
+	if (grub_strcmp (val, "normal") == 0)
+	  vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
+	else if (grub_strcmp (val, "ext") == 0)
+	  vid_mode = GRUB_LINUX_VID_MODE_EXTENDED;
+	else if (grub_strcmp (val, "ask") == 0)
+	  {
+	    grub_printf ("Legacy `ask' parameter no longer supported.\n");
+
+	    /* We usually would never do this in a loader, but "vga=ask" means user
+	       requested interaction, so it can't hurt to request keyboard input.  */
+	    grub_wait_after_message ();
+
+	    goto fail;
+	  }
+	else
+	  vid_mode = (grub_uint16_t) grub_strtoul (val, 0, 0);
+
+	switch (vid_mode)
+	  {
+	  case 0:
+	  case GRUB_LINUX_VID_MODE_NORMAL:
+	    grub_env_set ("gfxpayload", "text");
+	    grub_printf ("%s is deprecated. "
+			 "Use set gfxpayload=text before "
+			 "linux command instead.\n",
+			 argv[i]);
+	    break;
+
+	  case 1:
+	  case GRUB_LINUX_VID_MODE_EXTENDED:
+	    /* FIXME: support 80x50 text. */
+	    grub_env_set ("gfxpayload", "text");
+	    grub_printf ("%s is deprecated. "
+			 "Use set gfxpayload=text before "
+			 "linux command instead.\n",
+			 argv[i]);
+	    break;
+	  default:
+	    /* Ignore invalid values.  */
+	    if (vid_mode < GRUB_LINUX_VID_MODE_VESA_START ||
+		vid_mode >= GRUB_LINUX_VID_MODE_VESA_START +
+		ARRAY_SIZE (linux_vesafb_modes))
+	      {
+		grub_env_set ("gfxpayload", "text");
+		grub_printf ("%s is deprecated. Mode %d isn't recognized. "
+			     "Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] before "
+			     "linux command instead.\n",
+			     argv[i], vid_mode);
+		break;
+	      }
+
+	    buf = grub_malloc (sizeof ("WWWWxHHHHxDD;WWWWxHHHH"));
+	    if (! buf)
+	      goto fail;
+
+	    linux_mode
+	      = &linux_vesafb_modes[vid_mode - GRUB_LINUX_VID_MODE_VESA_START];
+
+	    grub_sprintf (buf, "%ux%ux%u,%ux%u",
+			  linux_vesafb_res[linux_mode->res_index].width,
+			  linux_vesafb_res[linux_mode->res_index].height,
+			  linux_mode->depth,
+			  linux_vesafb_res[linux_mode->res_index].width,
+			  linux_vesafb_res[linux_mode->res_index].height);
+	    grub_printf ("%s is deprecated. "
+			 "Use set gfxpayload=%s before "
+			 "linux command instead.\n",
+			 argv[i], buf);
+	    err = grub_env_set ("gfxpayload", buf);
+	    grub_free (buf);
+	    if (err)
+	      goto fail;
+	  }
+      }
+    else
+#endif /* GRUB_MACHINE_PCBIOS */
+    if (grub_memcmp (argv[i], "mem=", 4) == 0)
+      {
+	char *val = argv[i] + 4;
+
+	linux_mem_size = grub_strtoul (val, &val, 0);
+
+	if (grub_errno)
+	  {
+	    grub_errno = GRUB_ERR_NONE;
+	    linux_mem_size = 0;
+	  }
+	else
+	  {
+	    int shift = 0;
+
+	    switch (grub_tolower (val[0]))
+	      {
+	      case 'g':
+		shift += 10;
+	      case 'm':
+		shift += 10;
+	      case 'k':
+		shift += 10;
+	      default:
+		break;
+	      }
+
+	    /* Check an overflow.  */
+	    if (linux_mem_size > (~0UL >> shift))
+	      linux_mem_size = 0;
+	    else
+	      linux_mem_size <<= shift;
+	  }
+      }
+    else if (grub_memcmp (argv[i], "quiet", sizeof ("quiet") - 1) == 0)
+      {
+	params->loadflags |= GRUB_LINUX_FLAG_QUIET;
+      }
+
+
+  /* Specify the boot file.  */
+  dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET,
+		      "BOOT_IMAGE=");
+  dest = grub_stpcpy (dest, argv[0]);
+
+  /* Copy kernel parameters.  */
+  for (i = 1;
+       i < argc
+	 && dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem
+						+ GRUB_LINUX_CL_END_OFFSET);
+       i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+  len = prot_size;
+  if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
+    grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      grub_loader_set (grub_linux_boot, grub_linux_unload,
+		       0 /* set noreturn=0 in order to avoid grub_console_fini() */);
+      loaded = 1;
+    }
+
+ fail:
+
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_dl_unref (my_mod);
+      loaded = 0;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+		 int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_addr_t addr_min, addr_max;
+  grub_addr_t addr;
+  struct linux_kernel_header *lh;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+      goto fail;
+    }
+
+  if (! loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  size = grub_file_size (file);
+  initrd_pages = (page_align (size) >> 12);
+
+  lh = (struct linux_kernel_header *) real_mode_mem;
+
+  /* Get the highest address available for the initrd.  */
+  if (grub_le_to_cpu16 (lh->version) >= 0x0203)
+    {
+      addr_max = grub_cpu_to_le32 (lh->initrd_addr_max);
+
+      /* XXX in reality, Linux specifies a bogus value, so
+	 it is necessary to make sure that ADDR_MAX does not exceed
+	 0x3fffffff.  */
+      if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
+	addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
+    }
+  else
+    addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
+
+  if (linux_mem_size != 0 && linux_mem_size < addr_max)
+    addr_max = linux_mem_size;
+
+  /* Linux 2.3.xx has a bug in the memory range check, so avoid
+     the last page.
+     Linux 2.2.xx has a bug in the memory range check, which is
+     worse than that of Linux 2.3.xx, so avoid the last 64kb.  */
+  addr_max -= 0x10000;
+
+  /* Usually, the compression ratio is about 50%.  */
+  addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
+             + page_align (size);
+
+  if (addr_max > grub_os_area_addr + grub_os_area_size)
+    addr_max = grub_os_area_addr + grub_os_area_size;
+
+  /* Put the initrd as high as possible, 4KiB aligned.  */
+  addr = (addr_max - size) & ~0xFFF;
+
+  if (addr < addr_min)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "The initrd is too big");
+      goto fail;
+    }
+
+  initrd_mem = (void *) addr;
+
+  if (grub_file_read (file, initrd_mem, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+  grub_printf ("   [Initrd, addr=0x%x, size=0x%x]\n",
+	       (unsigned) addr, (unsigned) size);
+
+  lh->ramdisk_image = addr;
+  lh->ramdisk_size = size;
+  lh->root_dev = 0x0100; /* XXX */
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linux)
+{
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+				     0, "load linux");
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
+				      0, "load initrd");
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/loader/i386/linux_trampoline.S b/loader/i386/linux_trampoline.S
new file mode 100644
index 0000000..4acea7b
--- /dev/null
+++ b/loader/i386/linux_trampoline.S
@@ -0,0 +1,129 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+
+	.p2align	4	/* force 16-byte alignment */
+VARIABLE(grub_linux_trampoline_start)
+	cli
+	/* %rdi contains protected memory start and %rsi
+	contains real memory start. */
+
+	mov %rsi, %rbx
+
+	call base
+base:
+	pop %rsi
+
+#ifdef APPLE_CC
+	lea (cont1 - base) (%esi, 1), %rax
+	mov %eax, (jump_vector - base) (%esi, 1)
+
+	lea (gdt - base) (%esi, 1), %rax
+	mov %rax, (gdtaddr - base) (%esi, 1)
+
+	/* Switch to compatibility mode. */
+
+	lidt (idtdesc - base) (%esi, 1)
+	lgdt (gdtdesc - base) (%esi, 1)
+
+	/* Update %cs. Thanks to David Miller for pointing this mistake out. */
+	ljmp *(jump_vector - base) (%esi, 1)
+#else
+	lea (cont1 - base) (%rsi, 1), %rax
+	mov %eax, (jump_vector - base) (%rsi, 1)
+
+	lea (gdt - base) (%rsi, 1), %rax
+	mov %rax, (gdtaddr - base) (%rsi, 1)
+
+	/* Switch to compatibility mode. */
+
+	lidt (idtdesc - base) (%rsi, 1)
+	lgdt (gdtdesc - base) (%rsi, 1)
+
+	/* Update %cs. Thanks to David Miller for pointing this mistake out. */
+	ljmp *(jump_vector - base) (%rsi, 1)
+#endif
+
+cont1:
+	.code32
+
+	/* Update other registers. */
+	mov $0x18, %eax
+	mov %eax, %ds
+	mov %eax, %es
+	mov %eax, %fs
+	mov %eax, %gs
+	mov %eax, %ss
+
+	/* Disable paging. */
+	mov %cr0, %eax
+	and $0x7fffffff, %eax
+	mov %eax, %cr0
+
+	/* Disable amd64. */
+	mov $0xc0000080, %ecx
+	rdmsr
+	and $0xfffffeff, %eax
+	wrmsr
+
+	/* Turn off PAE. */
+	movl %cr4, %eax
+	and $0xffffffcf, %eax
+	mov %eax, %cr4
+
+	jmp cont2
+cont2:
+	.code32
+
+	mov %ebx, %esi
+
+	jmp *%edi
+
+	/* GDT. */
+	.p2align 4
+gdt:
+	/* NULL.  */
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+	/* Reserved.  */
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+	/* Code segment.  */
+	.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
+
+	/* Data segment.  */
+	.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
+
+gdtdesc:
+	.word 31
+gdtaddr:
+	.quad gdt
+
+idtdesc:
+	.word 0
+idtaddr:
+	.quad 0
+
+	.p2align 4
+jump_vector:
+	/* Jump location. Is filled by the code */
+	.long 0
+	.long 0x10
+VARIABLE(grub_linux_trampoline_end)
diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c
new file mode 100644
index 0000000..8c3139b
--- /dev/null
+++ b/loader/i386/multiboot.c
@@ -0,0 +1,501 @@
+/* multiboot.c - boot a multiboot OS image. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ *  FIXME: The following features from the Multiboot specification still
+ *         need to be implemented:
+ *  - VBE support
+ *  - symbol table
+ *  - drives table
+ *  - ROM configuration table
+ *  - APM table
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/multiboot.h>
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/cpu/multiboot.h>
+#include <grub/elf.h>
+#include <grub/aout.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/env.h>
+#ifdef GRUB_MACHINE_PCBIOS
+#include <grub/machine/biosnum.h>
+#include <grub/disk.h>
+#include <grub/device.h>
+#include <grub/partition.h>
+#endif
+
+extern grub_dl_t my_mod;
+static struct grub_multiboot_info *mbi, *mbi_dest;
+static grub_addr_t entry;
+
+static char *playground = 0;
+static grub_size_t code_size;
+
+static grub_err_t
+grub_multiboot_boot (void)
+{
+  grub_multiboot_real_boot (entry, mbi_dest);
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_multiboot_unload (void)
+{
+  if (playground)
+    {
+      unsigned int i;
+      for (i = 0; i < mbi->mods_count; i++)
+	{
+	  grub_free ((void *)
+		     ((struct grub_mod_list *) mbi->mods_addr)[i].mod_start);
+	  grub_free ((void *)
+		     ((struct grub_mod_list *) mbi->mods_addr)[i].cmdline);
+	}
+      grub_free ((void *) mbi->mods_addr);
+      grub_free (playground);
+    }
+
+  mbi = NULL;
+  playground = NULL;
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Return the length of the Multiboot mmap that will be needed to allocate
+   our platform's map.  */
+static grub_uint32_t
+grub_get_multiboot_mmap_len (void)
+{
+  grub_size_t count = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
+			     grub_uint64_t size __attribute__ ((unused)),
+			     grub_uint32_t type __attribute__ ((unused)))
+    {
+      count++;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+
+  return count * sizeof (struct grub_multiboot_mmap_entry);
+}
+
+/* Fill previously allocated Multiboot mmap.  */
+static void
+grub_fill_multiboot_mmap (struct grub_multiboot_mmap_entry *first_entry)
+{
+  struct grub_multiboot_mmap_entry *mmap_entry = (struct grub_multiboot_mmap_entry *) first_entry;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      mmap_entry->addr = addr;
+      mmap_entry->len = size;
+      mmap_entry->type = type;
+      mmap_entry->size = sizeof (struct grub_multiboot_mmap_entry) - sizeof (mmap_entry->size);
+      mmap_entry++;
+
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+}
+
+#define MULTIBOOT_LOAD_ELF64
+#include "multiboot_elfxx.c"
+#undef MULTIBOOT_LOAD_ELF64
+
+#define MULTIBOOT_LOAD_ELF32
+#include "multiboot_elfxx.c"
+#undef MULTIBOOT_LOAD_ELF32
+
+/* Load ELF32 or ELF64.  */
+static grub_err_t
+grub_multiboot_load_elf (grub_file_t file, void *buffer)
+{
+  if (grub_multiboot_is_elf32 (buffer))
+    return grub_multiboot_load_elf32 (file, buffer);
+  else if (grub_multiboot_is_elf64 (buffer))
+    return grub_multiboot_load_elf64 (file, buffer);
+
+  return grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class");
+}
+
+static int
+grub_multiboot_get_bootdev (grub_uint32_t *bootdev)
+{
+#ifdef GRUB_MACHINE_PCBIOS
+  char *p;
+  grub_uint32_t biosdev, slice = ~0, part = ~0;
+  grub_device_t dev;
+
+  biosdev = grub_get_root_biosnumber ();
+
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->partition)
+    {
+
+      p = dev->disk->partition->partmap->get_name (dev->disk->partition);
+      if (p)
+	{
+	  if ((p[0] >= '0') && (p[0] <= '9'))
+	    {
+	      slice = grub_strtoul (p, &p, 0) - 1;
+
+	      if ((p) && (p[0] == ','))
+		p++;
+	    }
+
+	  if ((p[0] >= 'a') && (p[0] <= 'z'))
+	    part = p[0] - 'a';
+	}
+    }
+  if (dev)
+    grub_device_close (dev);
+
+  *bootdev = ((biosdev & 0xff) << 24) | ((slice & 0xff) << 16) 
+    | ((part & 0xff) << 8) | 0xff;
+  return (biosdev != ~0UL);
+#else
+  *bootdev = 0xffffffff;
+  return 0;
+#endif
+}
+
+void
+grub_multiboot (int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  char buffer[MULTIBOOT_SEARCH], *cmdline = 0, *p;
+  struct grub_multiboot_header *header;
+  grub_ssize_t len, cmdline_length, boot_loader_name_length;
+  grub_uint32_t mmap_length;
+  int i;
+  int cmdline_argc;
+  char **cmdline_argv;
+
+  grub_loader_unset ();
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file");
+      goto fail;
+    }
+
+  len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
+  if (len < 32)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "File too small");
+      goto fail;
+    }
+
+  /* Look for the multiboot header in the buffer.  The header should
+     be at least 12 bytes and aligned on a 4-byte boundary.  */
+  for (header = (struct grub_multiboot_header *) buffer;
+       ((char *) header <= buffer + len - 12) || (header = 0);
+       header = (struct grub_multiboot_header *) ((char *) header + 4))
+    {
+      if (header->magic == MULTIBOOT_MAGIC
+	  && !(header->magic + header->flags + header->checksum))
+	break;
+    }
+
+  if (header == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No multiboot header found");
+      goto fail;
+    }
+
+  if (header->flags & MULTIBOOT_UNSUPPORTED)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_OS,
+		  "Unsupported flag: 0x%x", header->flags);
+      goto fail;
+    }
+
+  if (playground)
+    {
+      grub_free (playground);
+      playground = NULL;
+    }
+
+  mmap_length = grub_get_multiboot_mmap_len ();
+
+  /* Figure out cmdline length.  */
+  /* Skip filename.  */
+  cmdline_argc = argc - 1;
+  cmdline_argv = argv + 1;
+
+  for (i = 0, cmdline_length = 0; i < cmdline_argc; i++)
+    cmdline_length += grub_strlen (cmdline_argv[i]) + 1;
+
+  if (cmdline_length == 0)
+    cmdline_length = 1;
+
+  boot_loader_name_length = sizeof(PACKAGE_STRING);
+
+#define cmdline_addr(x)		((void *) ((x) + code_size))
+#define boot_loader_name_addr(x) \
+				((void *) ((x) + code_size + cmdline_length))
+#define mbi_addr(x)		((void *) ((x) + code_size + cmdline_length + boot_loader_name_length))
+#define mmap_addr(x)		((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct grub_multiboot_info)))
+
+  grub_multiboot_payload_size = cmdline_length
+    /* boot_loader_name_length might need to grow for mbi,etc to be aligned (see below) */
+    + boot_loader_name_length + 3
+    + sizeof (struct grub_multiboot_info) + mmap_length;
+
+  if (header->flags & MULTIBOOT_AOUT_KLUDGE)
+    {
+      int offset = ((char *) header - buffer -
+		    (header->header_addr - header->load_addr));
+      int load_size = ((header->load_end_addr == 0) ? file->size - offset :
+		       header->load_end_addr - header->load_addr);
+
+      if (header->bss_end_addr)
+	code_size = (header->bss_end_addr - header->load_addr);
+      else
+	code_size = load_size;
+      grub_multiboot_payload_dest = header->load_addr;
+
+      grub_multiboot_payload_size += code_size;
+      playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
+      if (! playground)
+	goto fail;
+
+      grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward);
+
+      if ((grub_file_seek (file, offset)) == (grub_off_t) - 1)
+	goto fail;
+
+      grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size);
+      if (grub_errno)
+	goto fail;
+
+      if (header->bss_end_addr)
+	grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0,
+		     header->bss_end_addr - header->load_addr - load_size);
+
+      grub_multiboot_payload_entry_offset = header->entry_addr - header->load_addr;
+
+    }
+  else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE)
+    goto fail;
+
+  /* This provides alignment for the MBI, the memory map and the backward relocator.  */
+  boot_loader_name_length += (0x04 - ((unsigned long) mbi_addr (grub_multiboot_payload_dest) & 0x03));
+
+  mbi = mbi_addr (grub_multiboot_payload_orig);
+  mbi_dest = mbi_addr (grub_multiboot_payload_dest);
+  grub_memset (mbi, 0, sizeof (struct grub_multiboot_info));
+  mbi->mmap_length = mmap_length;
+
+  grub_fill_multiboot_mmap (mmap_addr (grub_multiboot_payload_orig));
+
+  /* FIXME: grub_uint32_t will break for addresses above 4 GiB, but is mandated
+     by the spec.  Is there something we can do about it?  */
+  mbi->mmap_addr = (grub_uint32_t) mmap_addr (grub_multiboot_payload_dest);
+  mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
+
+  if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig)
+    {
+      grub_memmove (playground, &grub_multiboot_forward_relocator, RELOCATOR_SIZEOF(forward));
+      entry = (grub_addr_t) playground;
+    }
+  else
+    {
+      grub_memmove ((char *) (grub_multiboot_payload_orig + grub_multiboot_payload_size),
+		    &grub_multiboot_backward_relocator, RELOCATOR_SIZEOF(backward));
+      entry = (grub_addr_t) grub_multiboot_payload_orig + grub_multiboot_payload_size;
+    }
+
+  grub_dprintf ("multiboot_loader", "dest=%p, size=0x%x, entry_offset=0x%x\n",
+		(void *) grub_multiboot_payload_dest,
+		grub_multiboot_payload_size,
+		grub_multiboot_payload_entry_offset);
+
+  /* Convert from bytes to kilobytes.  */
+  mbi->mem_lower = grub_mmap_get_lower () / 1024;
+  mbi->mem_upper = grub_mmap_get_upper () / 1024;
+  mbi->flags |= MULTIBOOT_INFO_MEMORY;
+
+  cmdline = p = cmdline_addr (grub_multiboot_payload_orig);
+  if (! cmdline)
+    goto fail;
+
+  for (i = 0; i < cmdline_argc; i++)
+    {
+      p = grub_stpcpy (p, cmdline_argv[i]);
+      *(p++) = ' ';
+    }
+
+  /* Remove the space after the last word.  */
+  if (p != cmdline)
+    p--;
+  *p = 0;
+
+  mbi->flags |= MULTIBOOT_INFO_CMDLINE;
+  mbi->cmdline = (grub_uint32_t) cmdline_addr (grub_multiboot_payload_dest);
+
+
+  grub_strcpy (boot_loader_name_addr (grub_multiboot_payload_orig), PACKAGE_STRING);
+  mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME;
+  mbi->boot_loader_name = (grub_uint32_t) boot_loader_name_addr (grub_multiboot_payload_dest);
+
+  if (grub_multiboot_get_bootdev (&mbi->boot_device))
+    mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
+
+  grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1);
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_free (cmdline);
+      grub_free (mbi);
+      grub_dl_unref (my_mod);
+    }
+}
+
+
+void
+grub_module  (int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size, len = 0;
+  char *module = 0, *cmdline = 0, *p;
+  int i;
+  int cmdline_argc;
+  char **cmdline_argv;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+      goto fail;
+    }
+
+  if (!mbi)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT,
+		  "You need to load the multiboot kernel first");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    goto fail;
+
+  size = grub_file_size (file);
+  module = grub_memalign (MULTIBOOT_MOD_ALIGN, size);
+  if (! module)
+    goto fail;
+
+  if (grub_file_read (file, module, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+  /* Skip module name.  */
+  cmdline_argc = argc - 1;
+  cmdline_argv = argv + 1;
+
+  for (i = 0; i < cmdline_argc; i++)
+    len += grub_strlen (cmdline_argv[i]) + 1;
+
+  if (len == 0)
+    len = 1;
+
+  cmdline = p = grub_malloc (len);
+  if (! cmdline)
+    goto fail;
+
+  for (i = 0; i < cmdline_argc; i++)
+    {
+      p = grub_stpcpy (p, cmdline_argv[i]);
+      *(p++) = ' ';
+    }
+
+  /* Remove the space after the last word.  */
+  if (p != cmdline)
+    p--;
+  *p = '\0';
+
+  if (mbi->flags & MULTIBOOT_INFO_MODS)
+    {
+      struct grub_mod_list *modlist = (struct grub_mod_list *) mbi->mods_addr;
+
+      modlist = grub_realloc (modlist, (mbi->mods_count + 1)
+			               * sizeof (struct grub_mod_list));
+      if (! modlist)
+	goto fail;
+      mbi->mods_addr = (grub_uint32_t) modlist;
+      modlist += mbi->mods_count;
+      modlist->mod_start = (grub_uint32_t) module;
+      modlist->mod_end = (grub_uint32_t) module + size;
+      modlist->cmdline = (grub_uint32_t) cmdline;
+      modlist->pad = 0;
+      mbi->mods_count++;
+    }
+  else
+    {
+      struct grub_mod_list *modlist = grub_zalloc (sizeof (struct grub_mod_list));
+      if (! modlist)
+	goto fail;
+      modlist->mod_start = (grub_uint32_t) module;
+      modlist->mod_end = (grub_uint32_t) module + size;
+      modlist->cmdline = (grub_uint32_t) cmdline;
+      mbi->mods_count = 1;
+      mbi->mods_addr = (grub_uint32_t) modlist;
+      mbi->flags |= MULTIBOOT_INFO_MODS;
+    }
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_free (module);
+      grub_free (cmdline);
+    }
+}
diff --git a/loader/i386/multiboot_elfxx.c b/loader/i386/multiboot_elfxx.c
new file mode 100644
index 0000000..77c4711
--- /dev/null
+++ b/loader/i386/multiboot_elfxx.c
@@ -0,0 +1,155 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if defined(MULTIBOOT_LOAD_ELF32)
+# define XX		32
+# define E_MACHINE	EM_386
+# define ELFCLASSXX	ELFCLASS32
+# define Elf_Ehdr	Elf32_Ehdr
+# define Elf_Phdr	Elf32_Phdr
+#elif defined(MULTIBOOT_LOAD_ELF64)
+# define XX		64
+# define E_MACHINE	EM_X86_64
+# define ELFCLASSXX	ELFCLASS64
+# define Elf_Ehdr	Elf64_Ehdr
+# define Elf_Phdr	Elf64_Phdr
+#else
+#error "I'm confused"
+#endif
+
+#define CONCAT(a,b)	CONCAT_(a, b)
+#define CONCAT_(a,b)	a ## b
+
+/* Check if BUFFER contains ELF32 (or ELF64).  */
+static int
+CONCAT(grub_multiboot_is_elf, XX) (void *buffer)
+{
+  Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
+
+  return ehdr->e_ident[EI_CLASS] == ELFCLASSXX;
+}
+
+static grub_err_t
+CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
+{
+  Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
+  char *phdr_base;
+  int lowest_segment = -1, highest_segment = -1;
+  int i;
+
+  if (ehdr->e_ident[EI_CLASS] != ELFCLASSXX)
+    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class");
+
+  if (ehdr->e_ident[EI_MAG0] != ELFMAG0
+      || ehdr->e_ident[EI_MAG1] != ELFMAG1
+      || ehdr->e_ident[EI_MAG2] != ELFMAG2
+      || ehdr->e_ident[EI_MAG3] != ELFMAG3
+      || ehdr->e_version != EV_CURRENT
+      || ehdr->e_ident[EI_DATA] != ELFDATA2LSB
+      || ehdr->e_machine != E_MACHINE)
+    return grub_error(GRUB_ERR_UNKNOWN_OS, "no valid ELF header found");
+
+  if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
+    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
+
+  /* FIXME: Should we support program headers at strange locations?  */
+  if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
+    return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
+
+#ifdef MULTIBOOT_LOAD_ELF64
+  /* We still in 32-bit mode.  */
+  if (ehdr->e_entry > 0xffffffff)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64");
+#endif
+
+  phdr_base = (char *) buffer + ehdr->e_phoff;
+#define phdr(i)			((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
+
+  for (i = 0; i < ehdr->e_phnum; i++)
+    if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
+      {
+	/* Beware that segment 0 isn't necessarily loadable */
+	if (lowest_segment == -1
+	    || phdr(i)->p_paddr < phdr(lowest_segment)->p_paddr)
+	  lowest_segment = i;
+	if (highest_segment == -1
+	    || phdr(i)->p_paddr > phdr(highest_segment)->p_paddr)
+	  highest_segment = i;
+      }
+
+  if (lowest_segment == -1)
+    return grub_error (GRUB_ERR_BAD_OS, "ELF contains no loadable segments");
+
+  code_size = (phdr(highest_segment)->p_paddr + phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr;
+  grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr;
+
+  grub_multiboot_payload_size += code_size;
+  playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
+  if (! playground)
+    return grub_errno;
+
+  grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward);
+
+  /* Load every loadable segment in memory.  */
+  for (i = 0; i < ehdr->e_phnum; i++)
+    {
+      if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
+        {
+	  char *load_this_module_at = (char *) (grub_multiboot_payload_orig + (long) (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr));
+
+	  grub_dprintf ("multiboot_loader", "segment %d: paddr=0x%lx, memsz=0x%lx, vaddr=0x%lx\n",
+			i, (long) phdr(i)->p_paddr, (long) phdr(i)->p_memsz, (long) phdr(i)->p_vaddr);
+
+	  if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
+	      == (grub_off_t) -1)
+	    return grub_error (GRUB_ERR_BAD_OS,
+			       "invalid offset in program header");
+
+          if (grub_file_read (file, load_this_module_at, phdr(i)->p_filesz)
+              != (grub_ssize_t) phdr(i)->p_filesz)
+	    return grub_error (GRUB_ERR_BAD_OS,
+			       "couldn't read segment from file");
+
+          if (phdr(i)->p_filesz < phdr(i)->p_memsz)
+            grub_memset (load_this_module_at + phdr(i)->p_filesz, 0,
+			 phdr(i)->p_memsz - phdr(i)->p_filesz);
+        }
+    }
+
+  for (i = 0; i < ehdr->e_phnum; i++)
+    if (phdr(i)->p_vaddr <= ehdr->e_entry
+	&& phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry)
+      {
+	grub_multiboot_payload_entry_offset = (ehdr->e_entry - phdr(i)->p_vaddr)
+	  + (phdr(i)->p_paddr  - phdr(lowest_segment)->p_paddr);
+	break;
+      }
+
+  if (i == ehdr->e_phnum)
+    return grub_error (GRUB_ERR_BAD_OS, "entry point isn't in a segment");
+
+#undef phdr
+
+  return grub_errno;
+}
+
+#undef XX
+#undef E_MACHINE
+#undef ELFCLASSXX
+#undef Elf_Ehdr
+#undef Elf_Phdr
diff --git a/loader/i386/multiboot_helper.S b/loader/i386/multiboot_helper.S
new file mode 100644
index 0000000..d109458
--- /dev/null
+++ b/loader/i386/multiboot_helper.S
@@ -0,0 +1,118 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <multiboot.h>
+#include <multiboot2.h>
+
+	.p2align	2	/* force 4-byte alignment */
+
+/*
+ * This starts the multiboot kernel.
+ */
+
+VARIABLE(grub_multiboot_payload_size)
+	.long	0
+VARIABLE(grub_multiboot_payload_orig)
+	.long	0
+VARIABLE(grub_multiboot_payload_dest)
+	.long	0
+VARIABLE(grub_multiboot_payload_entry_offset)
+	.long	0
+
+/*
+ * The relocators below understand the following parameters:
+ * ecx:	Size of the block to be copied.
+ * esi:	Where to copy from (always lowest address, even if we're relocating
+ *      backwards).
+ * edi:	Where to copy to (likewise).
+ * edx:	Offset of the entry point (relative to the beginning of the block).
+ */
+
+VARIABLE(grub_multiboot_forward_relocator)
+	/* Add entry offset.  */
+	addl	%edi, %edx
+
+	/* Forward copy.  */
+	cld
+	rep
+	movsb
+
+	jmp	*%edx
+VARIABLE(grub_multiboot_forward_relocator_end)
+
+VARIABLE(grub_multiboot_backward_relocator)
+	/* Add entry offset (before %edi is mangled).  */
+	addl	%edi, %edx
+
+	/* Backward movsb is implicitly off-by-one.  compensate that.  */
+	decl	%esi
+	decl	%edi
+
+	/* Backward copy.  */
+	std
+	addl	%ecx, %esi
+	addl	%ecx, %edi
+	rep
+	movsb
+
+	cld
+	jmp	*%edx
+VARIABLE(grub_multiboot_backward_relocator_end)
+
+FUNCTION(grub_multiboot_real_boot)
+	/* Push the entry address on the stack.  */
+	pushl	%eax
+	/* Move the address of the multiboot information structure to ebx.  */
+	movl	%edx,%ebx
+
+	/* Interrupts should be disabled.  */
+	cli
+
+	/* Where do we copy what from.  */
+	movl	EXT_C(grub_multiboot_payload_size), %ecx
+	movl	EXT_C(grub_multiboot_payload_orig), %esi
+	movl	EXT_C(grub_multiboot_payload_dest), %edi
+	movl	EXT_C(grub_multiboot_payload_entry_offset), %edx
+
+	/* Move the magic value into eax.  */
+	movl	$MULTIBOOT_MAGIC2, %eax
+
+	/* Jump to the relocator.  */
+	popl	%ebp
+	jmp 	*%ebp
+
+/*
+ * This starts the multiboot 2 kernel.
+ */
+
+FUNCTION(grub_multiboot2_real_boot)
+        /* Push the entry address on the stack.  */
+        pushl   %eax
+        /* Move the address of the multiboot information structure to ebx.  */
+        movl    %edx,%ebx
+
+        /* Interrupts should be disabled.  */
+        cli
+
+        /* Move the magic value into eax and jump to the kernel.  */
+        movl    $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
+        popl    %ecx
+
+        cld
+        jmp     *%ecx
diff --git a/loader/i386/pc/chainloader.c b/loader/i386/pc/chainloader.c
new file mode 100644
index 0000000..caf1450
--- /dev/null
+++ b/loader/i386/pc/chainloader.c
@@ -0,0 +1,156 @@
+/* chainloader.c - boot another boot loader */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/machine/chainloader.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/machine/init.h>
+#include <grub/partition.h>
+#include <grub/machine/memory.h>
+#include <grub/dl.h>
+#include <grub/command.h>
+#include <grub/machine/biosnum.h>
+
+static grub_dl_t my_mod;
+static int boot_drive;
+static void *boot_part_addr;
+
+static grub_err_t
+grub_chainloader_boot (void)
+{
+  grub_chainloader_real_boot (boot_drive, boot_part_addr);
+
+  /* Never reach here.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_chainloader_unload (void)
+{
+  grub_dl_unref (my_mod);
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
+{
+  grub_file_t file = 0;
+  grub_uint16_t signature;
+  grub_device_t dev;
+  int drive = -1;
+  void *part_addr = 0;
+
+  grub_dl_ref (my_mod);
+
+  file = grub_file_open (filename);
+  if (! file)
+    goto fail;
+
+  /* Read the first block.  */
+  if (grub_file_read (file, (void *) 0x7C00, GRUB_DISK_SECTOR_SIZE)
+      != GRUB_DISK_SECTOR_SIZE)
+    {
+      if (grub_errno == GRUB_ERR_NONE)
+	grub_error (GRUB_ERR_BAD_OS, "too small");
+
+      goto fail;
+    }
+
+  /* Check the signature.  */
+  signature = *((grub_uint16_t *) (0x7C00 + GRUB_DISK_SECTOR_SIZE - 2));
+  if (signature != grub_le_to_cpu16 (0xaa55)
+      && ! (flags & GRUB_CHAINLOADER_FORCE))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "invalid signature");
+      goto fail;
+    }
+
+  grub_file_close (file);
+
+  /* Obtain the partition table from the root device.  */
+  drive = grub_get_root_biosnumber ();
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->partition)
+    {
+      grub_disk_read (dev->disk, dev->disk->partition->offset, 446, 64,
+		      (void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR);
+      part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR
+			    + (dev->disk->partition->index << 4));
+    }
+
+  if (dev)
+    grub_device_close (dev);
+  
+  /* Ignore errors. Perhaps it's not fatal.  */
+  grub_errno = GRUB_ERR_NONE;
+
+  boot_drive = drive;
+  boot_part_addr = part_addr;
+
+  grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 1);
+  return;
+
+ fail:
+
+  if (file)
+    grub_file_close (file);
+
+  grub_dl_unref (my_mod);
+}
+
+static grub_err_t
+grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
+		      int argc, char *argv[])
+{
+  grub_chainloader_flags_t flags = 0;
+
+  if (argc > 0 && grub_strcmp (argv[0], "--force") == 0)
+    {
+      flags |= GRUB_CHAINLOADER_FORCE;
+      argc--;
+      argv++;
+    }
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+  else
+    grub_chainloader_cmd (argv[0], flags);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(chainloader)
+{
+  cmd = grub_register_command ("chainloader", grub_cmd_chainloader,
+			       0, "load another boot loader");
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(chainloader)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/loader/i386/pc/linux.c b/loader/i386/pc/linux.c
new file mode 100644
index 0000000..c5279f6
--- /dev/null
+++ b/loader/i386/pc/linux.c
@@ -0,0 +1,397 @@
+/* linux.c - boot Linux zImage or bzImage */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/dl.h>
+#include <grub/cpu/linux.h>
+#include <grub/command.h>
+
+#define GRUB_LINUX_CL_OFFSET		0x9000
+#define GRUB_LINUX_CL_END_OFFSET	0x90FF
+
+static grub_dl_t my_mod;
+
+static grub_size_t linux_mem_size;
+static int loaded;
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_dl_unref (my_mod);
+  loaded = 0;
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+		int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  struct linux_kernel_header lh;
+  grub_uint8_t setup_sects;
+  grub_size_t real_size, prot_size;
+  grub_ssize_t len;
+  int i;
+  char *dest;
+
+  grub_dl_ref (my_mod);
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  if ((grub_size_t) grub_file_size (file) > grub_os_area_size)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "too big kernel (0x%x > 0x%x)",
+		  (grub_size_t) grub_file_size (file),
+		  grub_os_area_size);
+      goto fail;
+    }
+
+  if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header");
+      goto fail;
+    }
+
+  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
+      goto fail;
+    }
+
+  if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "too many setup sectors");
+      goto fail;
+    }
+
+  grub_linux_is_bzimage = 0;
+  setup_sects = lh.setup_sects;
+  linux_mem_size = 0;
+
+  if (lh.header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
+      && grub_le_to_cpu16 (lh.version) >= 0x0200)
+    {
+      grub_linux_is_bzimage = (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL);
+      lh.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
+
+      /* Put the real mode part at as a high location as possible.  */
+      grub_linux_real_addr
+	= (char *) UINT_TO_PTR (grub_mmap_get_lower ()
+				- GRUB_LINUX_SETUP_MOVE_SIZE);
+      /* But it must not exceed the traditional area.  */
+      if (grub_linux_real_addr > (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR)
+	grub_linux_real_addr = (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR;
+
+      if (grub_le_to_cpu16 (lh.version) >= 0x0201)
+	{
+	  lh.heap_end_ptr = grub_cpu_to_le16 (GRUB_LINUX_HEAP_END_OFFSET);
+	  lh.loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
+	}
+
+      if (grub_le_to_cpu16 (lh.version) >= 0x0202)
+	lh.cmd_line_ptr = grub_linux_real_addr + GRUB_LINUX_CL_OFFSET;
+      else
+	{
+	  lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC);
+	  lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET);
+	  lh.setup_move_size = grub_cpu_to_le16 (GRUB_LINUX_SETUP_MOVE_SIZE);
+	}
+    }
+  else
+    {
+      /* Your kernel is quite old...  */
+      lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC);
+      lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET);
+
+      setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
+
+      grub_linux_real_addr = (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR;
+    }
+
+  /* If SETUP_SECTS is not set, set it to the default (4).  */
+  if (! setup_sects)
+    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
+
+  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
+  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
+
+  grub_linux_tmp_addr = (char *) GRUB_LINUX_BZIMAGE_ADDR + prot_size;
+
+  if (! grub_linux_is_bzimage
+      && ((char *) GRUB_LINUX_ZIMAGE_ADDR + prot_size > grub_linux_real_addr))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "too big zImage (0x%x > 0x%x), use bzImage instead",
+		  (char *) GRUB_LINUX_ZIMAGE_ADDR + prot_size,
+		  (grub_size_t) grub_linux_real_addr);
+      goto fail;
+    }
+
+  if (grub_linux_real_addr + GRUB_LINUX_SETUP_MOVE_SIZE
+      > (char *) UINT_TO_PTR (grub_mmap_get_lower ()))
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE,
+		 "too small lower memory (0x%x > 0x%x)",
+		  grub_linux_real_addr + GRUB_LINUX_SETUP_MOVE_SIZE,
+		  (int) grub_mmap_get_lower ());
+      goto fail;
+    }
+
+  grub_printf ("   [Linux-%s, setup=0x%x, size=0x%x]\n",
+	       grub_linux_is_bzimage ? "bzImage" : "zImage", real_size, prot_size);
+
+  for (i = 1; i < argc; i++)
+    if (grub_memcmp (argv[i], "vga=", 4) == 0)
+      {
+	/* Video mode selection support.  */
+	grub_uint16_t vid_mode;
+	char *val = argv[i] + 4;
+
+	if (grub_strcmp (val, "normal") == 0)
+	  vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
+	else if (grub_strcmp (val, "ext") == 0)
+	  vid_mode = GRUB_LINUX_VID_MODE_EXTENDED;
+	else if (grub_strcmp (val, "ask") == 0)
+	  vid_mode = GRUB_LINUX_VID_MODE_ASK;
+	else
+	  vid_mode = (grub_uint16_t) grub_strtoul (val, 0, 0);
+
+	if (grub_errno)
+	  goto fail;
+
+	lh.vid_mode = grub_cpu_to_le16 (vid_mode);
+      }
+    else if (grub_memcmp (argv[i], "mem=", 4) == 0)
+      {
+	char *val = argv[i] + 4;
+
+	linux_mem_size = grub_strtoul (val, &val, 0);
+
+	if (grub_errno)
+	  {
+	    grub_errno = GRUB_ERR_NONE;
+	    linux_mem_size = 0;
+	  }
+	else
+	  {
+	    int shift = 0;
+
+	    switch (grub_tolower (val[0]))
+	      {
+	      case 'g':
+		shift += 10;
+	      case 'm':
+		shift += 10;
+	      case 'k':
+		shift += 10;
+	      default:
+		break;
+	      }
+
+	    /* Check an overflow.  */
+	    if (linux_mem_size > (~0UL >> shift))
+	      linux_mem_size = 0;
+	    else
+	      linux_mem_size <<= shift;
+	  }
+      }
+
+  /* Put the real mode code at the temporary address.  */
+  grub_memmove (grub_linux_tmp_addr, &lh, sizeof (lh));
+
+  len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh);
+  if (grub_file_read (file, grub_linux_tmp_addr + sizeof (lh), len) != len)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+  if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
+      || grub_le_to_cpu16 (lh.version) < 0x0200)
+    /* Clear the heap space.  */
+    grub_memset (grub_linux_tmp_addr
+		 + ((setup_sects + 1) << GRUB_DISK_SECTOR_BITS),
+		 0,
+		 ((GRUB_LINUX_MAX_SETUP_SECTS - setup_sects - 1)
+		  << GRUB_DISK_SECTOR_BITS));
+
+  /* Specify the boot file.  */
+  dest = grub_stpcpy (grub_linux_tmp_addr + GRUB_LINUX_CL_OFFSET,
+		      "BOOT_IMAGE=");
+  dest = grub_stpcpy (dest, argv[0]);
+
+  /* Copy kernel parameters.  */
+  for (i = 1;
+       i < argc
+	 && dest + grub_strlen (argv[i]) + 1 < (grub_linux_tmp_addr
+						+ GRUB_LINUX_CL_END_OFFSET);
+       i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+  len = prot_size;
+  if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
+    grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      grub_linux_prot_size = prot_size;
+      grub_loader_set (grub_linux16_boot, grub_linux_unload, 1);
+      loaded = 1;
+    }
+
+ fail:
+
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_dl_unref (my_mod);
+      loaded = 0;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+		 int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_addr_t addr_max, addr_min, addr;
+  struct linux_kernel_header *lh;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+      goto fail;
+    }
+
+  if (!loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
+      goto fail;
+    }
+
+  lh = (struct linux_kernel_header *) grub_linux_tmp_addr;
+
+  if (!(lh->header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
+	&& grub_le_to_cpu16 (lh->version) >= 0x0200))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "The kernel is too old for initrd.");
+      goto fail;
+    }
+
+  /* Get the highest address available for the initrd.  */
+  if (grub_le_to_cpu16 (lh->version) >= 0x0203)
+    {
+      addr_max = grub_cpu_to_le32 (lh->initrd_addr_max);
+
+      /* XXX in reality, Linux specifies a bogus value, so
+	 it is necessary to make sure that ADDR_MAX does not exceed
+	 0x3fffffff.  */
+      if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
+	addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
+    }
+  else
+    addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
+
+  if (linux_mem_size != 0 && linux_mem_size < addr_max)
+    addr_max = linux_mem_size;
+
+  /* Linux 2.3.xx has a bug in the memory range check, so avoid
+     the last page.
+     Linux 2.2.xx has a bug in the memory range check, which is
+     worse than that of Linux 2.3.xx, so avoid the last 64kb.  */
+  addr_max -= 0x10000;
+
+  if (addr_max > grub_os_area_addr + grub_os_area_size)
+    addr_max = grub_os_area_addr + grub_os_area_size;
+
+  addr_min = (grub_addr_t) grub_linux_tmp_addr + GRUB_LINUX_CL_END_OFFSET;
+
+  file = grub_file_open (argv[0]);
+  if (!file)
+    goto fail;
+
+  size = grub_file_size (file);
+
+  /* Put the initrd as high as possible, 4KiB aligned.  */
+  addr = (addr_max - size) & ~0xFFF;
+
+  if (addr < addr_min)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "The initrd is too big");
+      goto fail;
+    }
+
+  if (grub_file_read (file, (void *) addr, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+  lh->ramdisk_image = addr;
+  lh->ramdisk_size = size;
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linux16)
+{
+  cmd_linux =
+    grub_register_command ("linux16", grub_cmd_linux,
+			   0, "load linux");
+  cmd_initrd =
+    grub_register_command ("initrd16", grub_cmd_initrd,
+			   0, "load initrd");
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux16)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/loader/i386/pc/multiboot2.c b/loader/i386/pc/multiboot2.c
new file mode 100644
index 0000000..3baf488
--- /dev/null
+++ b/loader/i386/pc/multiboot2.c
@@ -0,0 +1,119 @@
+/* multiboot2.c - boot a multiboot 2 OS image. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/multiboot2.h>
+#include <multiboot2.h>
+#include <grub/elf.h>
+#include <grub/err.h>
+#include <grub/machine/loader.h>
+#include <grub/mm.h>
+#include <grub/multiboot.h>
+#include <grub/cpu/multiboot.h>
+
+grub_err_t
+grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr,
+			  int *do_load)
+{
+  Elf32_Addr paddr = phdr->p_paddr;
+
+  if (phdr->p_type != PT_LOAD)
+    {
+      *do_load = 0;
+      return 0;
+    }
+  *do_load = 1;
+
+  if ((paddr < grub_os_area_addr)
+      || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
+    return grub_error(GRUB_ERR_OUT_OF_RANGE,"Address 0x%x is out of range",
+                      paddr);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr,
+			  int *do_load)
+{
+  Elf64_Addr paddr = phdr->p_paddr;
+
+  if (phdr->p_type != PT_LOAD)
+    {
+      *do_load = 0;
+      return 0;
+    }
+  *do_load = 1;
+
+  if ((paddr < grub_os_area_addr)
+      || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range",
+		       paddr);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
+{
+  grub_addr_t modaddr;
+
+  modaddr = (grub_addr_t) grub_memalign (MULTIBOOT2_MOD_ALIGN, size);
+  if (! modaddr)
+    return grub_errno;
+
+  *addr = modaddr;
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_arch_module_free (grub_addr_t addr, UNUSED grub_size_t size)
+{
+  grub_free((void *) addr);
+  return GRUB_ERR_NONE;
+}
+
+void
+grub_mb2_arch_boot (grub_addr_t entry, void *tags)
+{
+  grub_multiboot2_real_boot (entry, tags);
+}
+
+void
+grub_mb2_arch_unload (struct multiboot_tag_header *tags)
+{
+   struct multiboot_tag_header *tag;
+
+   /* Free all module memory in the tag list.  */
+   for_each_tag (tag, tags)
+     {
+       if (tag->key == MULTIBOOT2_TAG_MODULE)
+         {
+           struct multiboot_tag_module *module =
+              (struct multiboot_tag_module *) tag;
+           grub_free((void *) module->addr);
+         }
+     }
+}
+
+grub_err_t
+grub_mb2_tags_arch_create (void)
+{
+  /* XXX Create boot device et al. */
+  return GRUB_ERR_NONE;
+}
diff --git a/loader/i386/pc/xnu.c b/loader/i386/pc/xnu.c
new file mode 100644
index 0000000..ebb176b
--- /dev/null
+++ b/loader/i386/pc/xnu.c
@@ -0,0 +1,110 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/xnu.h>
+#include <grub/mm.h>
+#include <grub/cpu/xnu.h>
+#include <grub/video_fb.h>
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+#define DEFAULT_VIDEO_MODE "1024x768x32,800x600x32,640x480x32"
+
+static int NESTED_FUNC_ATTR video_hook (grub_video_adapter_t p __attribute__ ((unused)),
+					struct grub_video_mode_info *info)
+{
+  if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT)
+    return 0;
+
+  return 1;
+}
+
+/* Setup video for xnu. */
+grub_err_t
+grub_xnu_set_video (struct grub_xnu_boot_params *params)
+{
+  struct grub_video_mode_info mode_info;
+  int ret;
+  char *tmp, *modevar;
+  void *framebuffer;
+  grub_err_t err;
+
+  modevar = grub_env_get ("gfxpayload");
+  if (! modevar || *modevar == 0)
+    err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook);
+  else
+    {
+      tmp = grub_malloc (grub_strlen (modevar)
+			 + sizeof (DEFAULT_VIDEO_MODE) + 1);
+      if (! tmp)
+	return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			   "couldn't allocate temporary storag");
+      grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
+      err = grub_video_set_mode (tmp, video_hook);
+      grub_free (tmp);
+    }
+
+  if (err)
+    return err;
+
+  if (grub_xnu_bitmap)
+    {
+      int x, y;
+
+      x = mode_info.width - grub_xnu_bitmap->mode_info.width;
+      x /= 2;
+      y = mode_info.height - grub_xnu_bitmap->mode_info.height;
+      y /= 2;
+      err = grub_video_blit_bitmap (grub_xnu_bitmap,
+				    GRUB_VIDEO_BLIT_REPLACE,
+				    x > 0 ? x : 0,
+				    y > 0 ? y : 0,
+				    x < 0 ? -x : 0,
+				    y < 0 ? -y : 0,
+				    min (grub_xnu_bitmap->mode_info.width,
+					 mode_info.width),
+				    min (grub_xnu_bitmap->mode_info.height,
+					 mode_info.height));
+      if (err)
+	{
+	  grub_print_error ();
+	  grub_errno = GRUB_ERR_NONE;
+	  grub_xnu_bitmap = 0;
+	}
+      err = GRUB_ERR_NONE;
+    }
+
+  ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
+  if (ret)
+    return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
+
+  params->lfb_width = mode_info.width;
+  params->lfb_height = mode_info.height;
+  params->lfb_depth = mode_info.bpp;
+  params->lfb_line_len = mode_info.pitch;
+
+  params->lfb_base = PTR_TO_UINT32 (framebuffer);
+  params->lfb_mode = grub_xnu_bitmap
+    ? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
+
+  return GRUB_ERR_NONE;
+}
+
diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c
new file mode 100644
index 0000000..275b50d
--- /dev/null
+++ b/loader/i386/xnu.c
@@ -0,0 +1,575 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/xnu.h>
+#include <grub/cpu/xnu.h>
+#include <grub/mm.h>
+#include <grub/loader.h>
+#include <grub/autoefi.h>
+#include <grub/i386/tsc.h>
+#include <grub/i386/pit.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+
+char grub_xnu_cmdline[1024];
+
+/* Aliases set for some tables. */
+struct tbl_alias
+{
+  grub_efi_guid_t guid;
+  char *name;
+};
+
+struct tbl_alias table_aliases[] =
+  {
+    {GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI_20"},
+    {GRUB_EFI_ACPI_TABLE_GUID, "ACPI"},
+  };
+
+/* The following function is used to be able to debug xnu loader
+   with grub-emu. */
+#ifdef GRUB_UTIL
+static grub_err_t
+grub_xnu_launch (void)
+{
+  grub_printf ("Fake launch %x:%p:%p", grub_xnu_entry_point, grub_xnu_arg1,
+	       grub_xnu_stack);
+  grub_getkey ();
+  return 0;
+}
+#else
+static void (*grub_xnu_launch) (void) = 0;
+#endif
+
+static int
+utf16_strlen (grub_uint16_t *in)
+{
+  int i;
+  for (i = 0; in[i]; i++);
+  return i;
+}
+
+/* Read frequency from a string in MHz and return it in Hz. */
+static grub_uint64_t
+readfrequency (const char *str)
+{
+  grub_uint64_t num = 0;
+  int mul = 1000000;
+  int found = 0;
+
+  while (*str)
+    {
+      unsigned long digit;
+
+      digit = grub_tolower (*str) - '0';
+      if (digit > 9)
+	break;
+
+      found = 1;
+
+      num = num * 10 + digit;
+      str++;
+    }
+  num *= 1000000;
+  if (*str == '.')
+    {
+      str++;
+      while (*str)
+	{
+	  unsigned long digit;
+
+	  digit = grub_tolower (*str) - '0';
+	  if (digit > 9)
+	    break;
+
+	  found = 1;
+
+	  mul /= 10;
+	  num = num + mul * digit;
+	  str++;
+	}
+    }
+  if (! found)
+    return 0;
+
+  return num;
+}
+
+/* Thanks to Kabyl for precious information about Intel architecture. */
+static grub_uint64_t
+guessfsb (void)
+{
+  const grub_uint64_t sane_value = 100000000;
+  grub_uint32_t manufacturer[3], max_cpuid, capabilities, msrlow;
+  grub_uint64_t start_tsc;
+  grub_uint64_t end_tsc;
+  grub_uint64_t tsc_ticks_per_ms;
+
+  if (! grub_cpu_is_cpuid_supported ())
+    return sane_value;
+
+#ifdef APPLE_CC
+  asm volatile ("movl $0, %%eax\n"
+#ifdef __x86_64__
+		"push %%rbx\n"
+#else
+		"push %%ebx\n"
+#endif
+		"cpuid\n"
+#ifdef __x86_64__
+		"pop %%rbx\n"
+#else
+		"pop %%ebx\n"
+#endif
+		: "=a" (max_cpuid),
+		  "=d" (manufacturer[1]), "=c" (manufacturer[2]));
+
+  /* Only Intel for now is done. */
+  if (grub_memcmp (manufacturer + 1, "ineIntel", 12) != 0)
+    return sane_value;
+
+#else
+  asm volatile ("movl $0, %%eax\n"
+		"cpuid"
+		: "=a" (max_cpuid), "=b" (manufacturer[0]),
+		  "=d" (manufacturer[1]), "=c" (manufacturer[2]));
+
+  /* Only Intel for now is done. */
+  if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0)
+    return sane_value;
+#endif
+
+  /* Check Speedstep. */
+  if (max_cpuid < 1)
+    return sane_value;
+
+#ifdef APPLE_CC
+  asm volatile ("movl $1, %%eax\n"
+#ifdef __x86_64__
+		"push %%rbx\n"
+#else
+		"push %%ebx\n"
+#endif
+		"cpuid\n"
+#ifdef __x86_64__
+		"pop %%rbx\n"
+#else
+		"pop %%ebx\n"
+#endif
+		: "=c" (capabilities):
+		: "%rax", "%rdx");
+#else
+  asm volatile ("movl $1, %%eax\n"
+		"cpuid"
+		: "=c" (capabilities):
+		: "%rax", "%rbx", "%rdx");
+#endif
+
+  if (! (capabilities & (1 << 7)))
+    return sane_value;
+
+  /* Calibrate the TSC rate. */
+
+  start_tsc = grub_get_tsc ();
+  grub_pit_wait (0xffff);
+  end_tsc = grub_get_tsc ();
+
+  tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0);
+
+  /* Read the multiplier. */
+  asm volatile ("movl $0x198, %%ecx\n"
+		"rdmsr"
+		: "=d" (msrlow)
+		:
+		: "%ecx", "%eax");
+
+  return grub_divmod64 (2000 * tsc_ticks_per_ms,
+			((msrlow >> 7) & 0x3e) + ((msrlow >> 14) & 1), 0);
+}
+
+/* Fill device tree. */
+/* FIXME: some entries may be platform-agnostic. Move them to loader/xnu.c. */
+grub_err_t
+grub_cpu_xnu_fill_devicetree (void)
+{
+  struct grub_xnu_devtree_key *efikey;
+  struct grub_xnu_devtree_key *cfgtablekey;
+  struct grub_xnu_devtree_key *curval;
+  struct grub_xnu_devtree_key *runtimesrvkey;
+  struct grub_xnu_devtree_key *platformkey;
+  unsigned i, j;
+  grub_err_t err;
+
+  err = grub_autoefi_prepare ();
+  if (err)
+    return err;
+
+  /* The value "model". */
+  /* FIXME: may this value be sometimes different? */
+  curval = grub_xnu_create_value (&grub_xnu_devtree_root, "model");
+  if (! curval)
+    return grub_errno;
+  curval->datasize = sizeof ("ACPI");
+  curval->data = grub_strdup ("ACPI");
+  curval = grub_xnu_create_value (&grub_xnu_devtree_root, "compatible");
+  if (! curval)
+    return grub_errno;
+  curval->datasize = sizeof ("ACPI");
+  curval->data = grub_strdup ("ACPI");
+
+  /* The key "efi". */
+  efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi");
+  if (! efikey)
+    return grub_errno;
+
+  /* Information about firmware. */
+  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-revision");
+  if (! curval)
+    return grub_errno;
+  curval->datasize = (SYSTEM_TABLE_SIZEOF (firmware_revision));
+  curval->data = grub_malloc (curval->datasize);
+  if (! curval->data)
+    return grub_errno;
+  grub_memcpy (curval->data, (SYSTEM_TABLE_VAR(firmware_revision)),
+	       curval->datasize);
+
+  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-vendor");
+  if (! curval)
+    return grub_errno;
+  curval->datasize =
+    2 * (utf16_strlen (SYSTEM_TABLE_PTR (firmware_vendor)) + 1);
+  curval->data = grub_malloc (curval->datasize);
+  if (! curval->data)
+    return grub_errno;
+  grub_memcpy (curval->data, SYSTEM_TABLE_PTR (firmware_vendor),
+	       curval->datasize);
+
+  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-abi");
+  if (! curval)
+    return grub_errno;
+  curval->datasize = sizeof ("EFI32");
+  curval->data = grub_malloc (curval->datasize);
+  if (! curval->data)
+    return grub_errno;
+  if (SIZEOF_OF_UINTN == 4)
+    grub_memcpy (curval->data, "EFI32", curval->datasize);
+  else
+    grub_memcpy (curval->data, "EFI64", curval->datasize);
+
+  /* The key "platform". */
+  platformkey = grub_xnu_create_key (&(efikey->first_child),
+				     "platform");
+  if (! platformkey)
+    return grub_errno;
+
+  /* Pass FSB frequency to the kernel. */
+  curval = grub_xnu_create_value (&(platformkey->first_child), "FSBFrequency");
+  if (! curval)
+    return grub_errno;
+  curval->datasize = sizeof (grub_uint64_t);
+  curval->data = grub_malloc (curval->datasize);
+  if (!curval->data)
+    return grub_errno;
+
+  /* First see if user supplies the value. */
+  char *fsbvar = grub_env_get ("fsb");
+  if (! fsbvar)
+    *((grub_uint64_t *) curval->data) = 0;
+  else
+    *((grub_uint64_t *) curval->data) = readfrequency (fsbvar);
+  /* Try autodetect. */
+  if (! *((grub_uint64_t *) curval->data))
+    *((grub_uint64_t *) curval->data) = guessfsb ();
+  grub_dprintf ("xnu", "fsb autodetected as %llu\n",
+		(unsigned long long) *((grub_uint64_t *) curval->data));
+
+  cfgtablekey = grub_xnu_create_key (&(efikey->first_child),
+				     "configuration-table");
+  if (!cfgtablekey)
+    return grub_errno;
+
+  /* Fill "configuration-table" key. */
+  for (i = 0; i < SYSTEM_TABLE (num_table_entries); i++)
+    {
+      void *ptr;
+      struct grub_xnu_devtree_key *curkey;
+      grub_efi_guid_t guid;
+      char guidbuf[64];
+
+      /* Retrieve current key. */
+#ifdef GRUB_MACHINE_EFI
+      {
+	ptr = (void *)
+	  grub_efi_system_table->configuration_table[i].vendor_table;
+	guid = grub_efi_system_table->configuration_table[i].vendor_guid;
+      }
+#else
+      if (SIZEOF_OF_UINTN == 4)
+	{
+	  ptr = UINT_TO_PTR (((grub_efiemu_configuration_table32_t *)
+			      SYSTEM_TABLE_PTR (configuration_table))[i]
+			     .vendor_table);
+	  guid =
+	    ((grub_efiemu_configuration_table32_t *)
+	     SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
+	}
+      else
+	{
+	  ptr = UINT_TO_PTR (((grub_efiemu_configuration_table64_t *)
+			      SYSTEM_TABLE_PTR (configuration_table))[i]
+			     .vendor_table);
+	  guid =
+	    ((grub_efiemu_configuration_table64_t *)
+	     SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
+	}
+#endif
+
+      /* The name of key for new table. */
+      grub_sprintf (guidbuf, "%08x-%04x-%04x-%02x%02x-",
+		    guid.data1, guid.data2, guid.data3, guid.data4[0],
+		    guid.data4[1]);
+      for (j = 2; j < 8; j++)
+	grub_sprintf (guidbuf + grub_strlen (guidbuf), "%02x", guid.data4[j]);
+      /* For some reason GUID has to be in uppercase. */
+      for (j = 0; guidbuf[j] ; j++)
+	if (guidbuf[j] >= 'a' && guidbuf[j] <= 'f')
+	  guidbuf[j] += 'A' - 'a';
+      curkey = grub_xnu_create_key (&(cfgtablekey->first_child), guidbuf);
+      if (! curkey)
+	return grub_errno;
+
+      curval = grub_xnu_create_value (&(curkey->first_child), "guid");
+      if (! curval)
+	return grub_errno;
+      curval->datasize = sizeof (guid);
+      curval->data = grub_malloc (curval->datasize);
+      if (! curval->data)
+	return grub_errno;
+      grub_memcpy (curval->data, &guid, curval->datasize);
+
+      /* The value "table". */
+      curval = grub_xnu_create_value (&(curkey->first_child), "table");
+      if (! curval)
+	return grub_errno;
+      curval->datasize = SIZEOF_OF_UINTN;
+      curval->data = grub_malloc (curval->datasize);
+      if (! curval->data)
+	return grub_errno;
+      if (SIZEOF_OF_UINTN == 4)
+	*((grub_uint32_t *)curval->data) = PTR_TO_UINT32 (ptr);
+      else
+	*((grub_uint64_t *)curval->data) = PTR_TO_UINT64 (ptr);
+
+      /* Create alias. */
+      for (j = 0; j < sizeof (table_aliases) / sizeof (table_aliases[0]); j++)
+	if (grub_memcmp (&table_aliases[j].guid, &guid, sizeof (guid)) == 0)
+	  break;
+      if (j != sizeof (table_aliases) / sizeof (table_aliases[0]))
+	{
+	  curval = grub_xnu_create_value (&(curkey->first_child), "alias");
+	  if (!curval)
+	    return grub_errno;
+	  curval->datasize = grub_strlen (table_aliases[j].name) + 1;
+	  curval->data = grub_malloc (curval->datasize);
+	  if (!curval->data)
+	    return grub_errno;
+	  grub_memcpy (curval->data, table_aliases[j].name, curval->datasize);
+	}
+    }
+
+  /* Create and fill "runtime-services" key. */
+  runtimesrvkey = grub_xnu_create_key (&(efikey->first_child),
+				       "runtime-services");
+  if (! runtimesrvkey)
+    return grub_errno;
+  curval = grub_xnu_create_value (&(runtimesrvkey->first_child), "table");
+  if (! curval)
+    return grub_errno;
+  curval->datasize = SIZEOF_OF_UINTN;
+  curval->data = grub_malloc (curval->datasize);
+  if (! curval->data)
+    return grub_errno;
+  if (SIZEOF_OF_UINTN == 4)
+    *((grub_uint32_t *) curval->data)
+      = PTR_TO_UINT32 (SYSTEM_TABLE_PTR (runtime_services));
+  else
+    *((grub_uint64_t *) curval->data)
+      = PTR_TO_UINT64 (SYSTEM_TABLE_PTR (runtime_services));
+
+  return GRUB_ERR_NONE;
+}
+
+/* Boot xnu. */
+grub_err_t
+grub_xnu_boot (void)
+{
+  struct grub_xnu_boot_params *bootparams_relloc;
+  grub_off_t bootparams_relloc_off;
+  grub_off_t mmap_relloc_off;
+  grub_err_t err;
+  grub_efi_uintn_t memory_map_size = 0;
+  grub_efi_memory_descriptor_t *memory_map;
+  grub_efi_uintn_t map_key = 0;
+  grub_efi_uintn_t descriptor_size = 0;
+  grub_efi_uint32_t descriptor_version = 0;
+  grub_uint64_t firstruntimeaddr, lastruntimeaddr;
+  void *devtree;
+  grub_size_t devtreelen;
+  int i;
+
+  /* Page-align to avoid following parts to be inadvertently freed. */
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    return err;
+
+  /* Pass memory map to kernel. */
+  memory_map_size = 0;
+  memory_map = 0;
+  map_key = 0;
+  descriptor_size = 0;
+  descriptor_version = 0;
+
+  if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
+				   &map_key, &descriptor_size,
+				   &descriptor_version) < 0)
+    return grub_errno;
+
+  memory_map = grub_xnu_heap_malloc (memory_map_size);
+  if (! memory_map)
+    return grub_errno;
+
+  if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
+				   &map_key, &descriptor_size,
+				   &descriptor_version) <= 0)
+    return grub_errno;
+  mmap_relloc_off = (grub_uint8_t *) memory_map
+    - (grub_uint8_t *) grub_xnu_heap_start;
+
+  firstruntimeaddr = (grub_uint64_t) (-1);
+  lastruntimeaddr = 0;
+  for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++)
+    {
+      grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *)
+	((char *) memory_map + descriptor_size * i);
+
+      /* Some EFI implementations set physical_start to 0 which
+	 causes XNU crash. */
+      curdesc->virtual_start = curdesc->physical_start;
+
+      if (curdesc->type == GRUB_EFI_RUNTIME_SERVICES_DATA
+	  || curdesc->type == GRUB_EFI_RUNTIME_SERVICES_CODE)
+	{
+	  if (firstruntimeaddr > curdesc->physical_start)
+	    firstruntimeaddr = curdesc->physical_start;
+	  if (lastruntimeaddr < curdesc->physical_start
+	      + curdesc->num_pages * 4096)
+	    lastruntimeaddr = curdesc->physical_start
+	      + curdesc->num_pages * 4096;
+	}
+    }
+
+  /* Relocate the boot parameters to heap. */
+  bootparams_relloc = grub_xnu_heap_malloc (sizeof (*bootparams_relloc));
+  if (! bootparams_relloc)
+    return grub_errno;
+  bootparams_relloc_off = (grub_uint8_t *) bootparams_relloc
+    - (grub_uint8_t *) grub_xnu_heap_start;
+  err = grub_xnu_writetree_toheap (&devtree, &devtreelen);
+  if (err)
+    return err;
+  bootparams_relloc = (struct grub_xnu_boot_params *)
+    (bootparams_relloc_off + (grub_uint8_t *) grub_xnu_heap_start);
+
+  grub_memcpy (bootparams_relloc->cmdline, grub_xnu_cmdline,
+	       sizeof (bootparams_relloc->cmdline));
+
+  bootparams_relloc->devtree = ((char *) devtree - grub_xnu_heap_start)
+    + grub_xnu_heap_will_be_at;
+  bootparams_relloc->devtreelen = devtreelen;
+
+  bootparams_relloc->heap_start = grub_xnu_heap_will_be_at;
+  bootparams_relloc->heap_size = grub_xnu_heap_size;
+
+  bootparams_relloc->efi_mmap = grub_xnu_heap_will_be_at + mmap_relloc_off;
+  bootparams_relloc->efi_mmap_size = memory_map_size;
+  bootparams_relloc->efi_mem_desc_size = descriptor_size;
+  bootparams_relloc->efi_mem_desc_version = descriptor_version;
+
+  bootparams_relloc->efi_runtime_first_page = firstruntimeaddr
+    / GRUB_XNU_PAGESIZE;
+  bootparams_relloc->efi_runtime_npages
+    = ((lastruntimeaddr + GRUB_XNU_PAGESIZE - 1) / GRUB_XNU_PAGESIZE)
+    - (firstruntimeaddr / GRUB_XNU_PAGESIZE);
+  bootparams_relloc->efi_uintnbits = SIZEOF_OF_UINTN * 8;
+  bootparams_relloc->efi_system_table
+    = PTR_TO_UINT32 (grub_autoefi_system_table);
+
+  bootparams_relloc->verminor = GRUB_XNU_BOOTARGS_VERMINOR;
+  bootparams_relloc->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR;
+
+  /* Parameters for asm helper. */
+  grub_xnu_stack = bootparams_relloc->heap_start
+    + bootparams_relloc->heap_size + GRUB_XNU_PAGESIZE;
+  grub_xnu_arg1 = bootparams_relloc_off + grub_xnu_heap_will_be_at;
+#ifndef GRUB_UTIL
+  grub_xnu_launch = (void (*) (void))
+    (grub_xnu_heap_start + grub_xnu_heap_size);
+#endif
+  grub_dprintf ("xnu", "eip=%x\n", grub_xnu_entry_point);
+  grub_dprintf ("xnu", "launch=%p\n", grub_xnu_launch);
+
+  const char *debug = grub_env_get ("debug");
+
+  if (debug && (grub_strword (debug, "all") || grub_strword (debug, "xnu")))
+    {
+      grub_printf ("Press any key to launch xnu\n");
+      grub_getkey ();
+    }
+
+  /* Set video. */
+  err = grub_xnu_set_video (bootparams_relloc);
+  if (err != GRUB_ERR_NONE)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      grub_printf ("Booting in blind mode\n");
+
+      bootparams_relloc->lfb_mode = 0;
+      bootparams_relloc->lfb_width = 0;
+      bootparams_relloc->lfb_height = 0;
+      bootparams_relloc->lfb_depth = 0;
+      bootparams_relloc->lfb_line_len = 0;
+      bootparams_relloc->lfb_base = 0;
+    }
+
+  grub_memcpy (grub_xnu_heap_start + grub_xnu_heap_size,
+	       grub_xnu_launcher_start,
+	       grub_xnu_launcher_end - grub_xnu_launcher_start);
+
+
+  if (! grub_autoefi_finish_boot_services ())
+    return grub_error (GRUB_ERR_IO, "can't exit boot services");
+
+  grub_xnu_launch ();
+
+  /* Never reaches here. */
+  return 0;
+}
diff --git a/loader/i386/xnu_helper.S b/loader/i386/xnu_helper.S
new file mode 100644
index 0000000..4250c58
--- /dev/null
+++ b/loader/i386/xnu_helper.S
@@ -0,0 +1,211 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+
+	.p2align	4	/* force 16-byte alignment */
+
+VARIABLE(grub_xnu_launcher_start)
+base:
+	cli
+
+#ifndef __x86_64__
+	/* mov imm32, %eax */
+	.byte	0xb8
+VARIABLE(grub_xnu_heap_will_be_at)
+	.long 0
+	mov %eax, %edi
+
+	/* mov imm32, %eax */
+	.byte	0xb8
+VARIABLE(grub_xnu_heap_start)
+	.long 0
+	mov %eax, %esi
+
+	/* mov imm32, %ecx */
+	.byte	0xb9
+VARIABLE(grub_xnu_heap_size)
+	.long 0
+	mov %edi, %eax
+	add %ecx, %eax
+	/* %rax now contains our starting position after relocation. */
+	/* One more page to copy: ourselves. */
+	add $0x403, %ecx
+	shr $2, %ecx
+
+	/* Forward copy.  */
+	cld
+	rep
+	movsl
+
+	mov %eax, %esi
+	add $(cont0-base), %eax
+	jmp *%eax
+cont0:
+#else
+	xorq %rax, %rax
+
+	/* mov imm32, %eax */
+	.byte	0xb8
+VARIABLE(grub_xnu_heap_will_be_at)
+	.long 0
+	mov %rax, %rdi
+
+	/* mov imm32, %rax */
+	.byte	0x48
+	.byte	0xb8
+VARIABLE(grub_xnu_heap_start)
+	.long 0
+	.long 0
+	mov %rax, %rsi
+
+	/* mov imm32, %rcx */
+	.byte	0x48
+	.byte	0xb9
+VARIABLE(grub_xnu_heap_size)
+	.long 0
+	.long 0
+	mov %rdi, %rax
+	add %rcx, %rax
+	/* %rax now contains our starting position after relocation. */
+	/* One more page to copy: ourselves. */
+	add $0x403, %rcx
+	shr $2, %rcx
+
+	/* Forward copy.  */
+	cld
+	rep
+	movsl
+
+	mov %rax, %rsi
+#ifdef APPLE_CC
+	add $(cont0-base), %eax
+#else
+	add $(cont0-base), %rax
+#endif
+	jmp *%rax
+
+cont0:
+#ifdef APPLE_CC
+	lea (cont1 - base) (%esi, 1), %eax
+	mov %eax, (jump_vector - base) (%esi, 1)
+
+	lea (gdt - base) (%esi, 1), %eax
+	mov %eax, (gdt_addr - base) (%esi, 1)
+
+	/* Switch to compatibility mode. */
+
+	lgdt (gdtdesc - base) (%esi, 1)
+
+	/* Update %cs. Thanks to David Miller for pointing this mistake out. */
+	ljmp *(jump_vector - base) (%esi,1)
+#else
+	lea (cont1 - base) (%rsi, 1), %rax
+	mov %eax, (jump_vector - base) (%rsi, 1)
+
+	lea (gdt - base) (%rsi, 1), %rax
+	mov %rax, (gdt_addr - base) (%rsi, 1)
+
+	/* Switch to compatibility mode. */
+
+	lgdt (gdtdesc - base) (%rsi, 1)
+
+	/* Update %cs. Thanks to David Miller for pointing this mistake out. */
+	ljmp *(jump_vector - base) (%rsi, 1)
+#endif
+
+cont1:
+	.code32
+
+	/* Update other registers. */
+	mov $0x18, %eax
+	mov %eax, %ds
+	mov %eax, %es
+	mov %eax, %fs
+	mov %eax, %gs
+	mov %eax, %ss
+
+	/* Disable paging. */
+	mov %cr0, %eax
+	and $0x7fffffff, %eax
+	mov %eax, %cr0
+
+	/* Disable amd64. */
+	mov $0xc0000080, %ecx
+	rdmsr
+	and $0xfffffeff, %eax
+	wrmsr
+
+	/* Turn off PAE. */
+	movl %cr4, %eax
+	and $0xffffffcf, %eax
+	mov %eax, %cr4
+
+	jmp cont2
+cont2:
+#endif
+	.code32
+
+	/* Registers on XNU boot: eip, esp and eax. */
+	/* mov imm32, %ecx */
+	.byte	0xb9
+VARIABLE (grub_xnu_entry_point)
+	.long 0
+	/* mov imm32, %eax */
+	.byte	0xb8
+VARIABLE (grub_xnu_arg1)
+	.long 0
+	/* mov imm32, %ebx */
+	.byte	0xbb
+VARIABLE (grub_xnu_stack)
+	.long 0
+
+	movl %ebx, %esp
+
+	jmp *%ecx
+
+#ifdef __x86_64__
+	/* GDT. Copied from loader/i386/linux.c. */
+	.p2align 4
+gdt:
+	/* NULL.  */
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+	/* Reserved.  */
+	.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+	/* Code segment.  */
+	.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
+
+	/* Data segment.  */
+	.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
+
+gdtdesc:
+	.word 31
+gdt_addr:
+	/* Filled by the code. */
+	.quad 0
+
+	.p2align 4
+jump_vector:
+	/* Jump location. Is filled by the code */
+	.long 0
+	.long 0x10
+#endif
+VARIABLE(grub_xnu_launcher_end)
diff --git a/loader/ieee1275/multiboot2.c b/loader/ieee1275/multiboot2.c
new file mode 100644
index 0000000..fda62fc
--- /dev/null
+++ b/loader/ieee1275/multiboot2.c
@@ -0,0 +1,145 @@
+/* multiboot.c - boot a multiboot 2 OS image. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/multiboot2.h>
+#include <multiboot2.h>
+#include <grub/err.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/machine/kernel.h>
+#include <grub/machine/loader.h>
+#ifdef __i386__
+#include <grub/cpu/multiboot.h>
+#endif
+
+typedef void (*kernel_entry_t) (unsigned long, void *, int (void *),
+                                unsigned long, unsigned long);
+
+/* Claim the memory occupied by the multiboot kernel.  */
+grub_err_t
+grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr,
+			  int *do_load)
+{
+  int rc;
+
+  if (phdr->p_type != PT_LOAD)
+    {
+      *do_load = 0;
+      return 0;
+    }
+  *do_load = 1;
+
+  rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
+  if (rc)
+    return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim %x - %x",
+		      phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
+
+  grub_dprintf ("loader", "Loading segment at 0x%x - 0x%x\n", phdr->p_paddr,
+		phdr->p_paddr + phdr->p_memsz);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Claim the memory occupied by the multiboot kernel.  */
+grub_err_t
+grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr,
+			  int *do_load)
+{
+  int rc;
+
+  if (phdr->p_type != PT_LOAD)
+    {
+      *do_load = 0;
+      return 0;
+    }
+  *do_load = 1;
+
+  rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
+  if (rc)
+    return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim 0x%lx - 0x%lx",
+		      phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
+
+  grub_dprintf ("loader", "Loading segment at 0x%lx - 0x%lx\n",
+		(unsigned long) phdr->p_paddr,
+		(unsigned long) (phdr->p_paddr + phdr->p_memsz));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
+{
+  int rc;
+
+  /* XXX Will need to map on some firmwares.  */
+  rc = grub_ieee1275_claim (0, size, MULTIBOOT2_MOD_ALIGN, addr);
+  if (rc)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		       "Firmware couldn't allocate memory (size 0x%lx)", size);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_arch_module_free (grub_addr_t addr, grub_size_t size)
+{
+  grub_ieee1275_release (addr, size);
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_tags_arch_create (void)
+{
+  /* Nothing special.  */
+  return GRUB_ERR_NONE;
+}
+
+/* Release the memory we claimed from Open Firmware above.  */
+void
+grub_mb2_arch_unload (struct multiboot_tag_header *tags)
+{
+  struct multiboot_tag_header *tag;
+
+  /* Free all module memory in the tag list.  */
+  for_each_tag (tag, tags)
+    {
+      if (tag->key == MULTIBOOT2_TAG_MODULE)
+	{
+	  struct multiboot_tag_module *module =
+	      (struct multiboot_tag_module *) tag;
+	  grub_ieee1275_release (module->addr, module->size);
+	}
+    }
+}
+
+void
+grub_mb2_arch_boot (grub_addr_t entry_addr, void *tags)
+{
+#if defined(__powerpc__)
+  kernel_entry_t entry = (kernel_entry_t) entry_addr;
+  entry (MULTIBOOT2_BOOTLOADER_MAGIC, tags, grub_ieee1275_entry_fn, 0, 0);
+#elif defined(__i386__)
+  grub_multiboot2_real_boot (entry_addr, tags);
+#else
+#error
+#endif
+}
diff --git a/loader/macho.c b/loader/macho.c
new file mode 100644
index 0000000..bd460b8
--- /dev/null
+++ b/loader/macho.c
@@ -0,0 +1,395 @@
+/* macho.c - load Mach-O files. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This Mach-O loader is incomplete and can load only non-relocatable segments.
+   This is however enough to boot xnu (otool -l and Mach-O specs for more info).
+*/
+
+#include <grub/err.h>
+#include <grub/macho.h>
+#include <grub/cpu/macho.h>
+#include <grub/machoload.h>
+#include <grub/file.h>
+#include <grub/gzio.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+/* 32-bit. */
+
+int
+grub_macho_contains_macho32 (grub_macho_t macho)
+{
+  return macho->offset32 != -1;
+}
+
+static void
+grub_macho_parse32 (grub_macho_t macho)
+{
+  struct grub_macho_header32 head;
+
+  /* Is there any candidate at all? */
+  if (macho->offset32 == -1)
+    return;
+
+  /* Read header and check magic*/
+  if (grub_file_seek (macho->file, macho->offset32) == (grub_off_t) -1
+      || grub_file_read (macho->file, &head, sizeof (head))
+      != sizeof(head))
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header.");
+      macho->offset32 = -1;
+      return;
+    }
+  if (head.magic != GRUB_MACHO_MAGIC32)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O 32-bit header.");
+      macho->offset32 = -1;
+      return;
+    }
+
+  /* Read commands. */
+  macho->ncmds32 = head.ncmds;
+  macho->cmdsize32 = head.sizeofcmds;
+  macho->cmds32 = grub_malloc(macho->cmdsize32);
+  if (! macho->cmds32)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "not enough memory to read commands");
+      return;
+    }
+  if (grub_file_read (macho->file, macho->cmds32,
+		      (grub_size_t) macho->cmdsize32)
+      != (grub_ssize_t) macho->cmdsize32)
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header.");
+      macho->offset32 = -1;
+    }
+}
+
+typedef int NESTED_FUNC_ATTR (*grub_macho_iter_hook_t)
+(grub_macho_t , struct grub_macho_cmd *,
+	       void *);
+
+static grub_err_t
+grub_macho32_cmds_iterate (grub_macho_t macho,
+			   grub_macho_iter_hook_t hook,
+			   void *hook_arg)
+{
+  grub_uint8_t *hdrs = macho->cmds32;
+  int i;
+  if (! macho->cmds32)
+    return grub_error (GRUB_ERR_BAD_OS, "Couldn't find 32-bit Mach-O");
+  for (i = 0; i < macho->ncmds32; i++)
+    {
+      struct grub_macho_cmd *hdr = (struct grub_macho_cmd *) hdrs;
+      if (hook (macho, hdr, hook_arg))
+	break;
+      hdrs += hdr->cmdsize;
+    }
+
+  return grub_errno;
+}
+
+grub_size_t
+grub_macho32_filesize (grub_macho_t macho)
+{
+  if (grub_macho_contains_macho32 (macho))
+    return macho->end32 - macho->offset32;
+  return 0;
+}
+
+grub_err_t
+grub_macho32_readfile (grub_macho_t macho, void *dest)
+{
+  grub_ssize_t read;
+  if (! grub_macho_contains_macho32 (macho))
+    return grub_error (GRUB_ERR_BAD_OS,
+		       "Couldn't read architecture-specific part");
+
+  if (grub_file_seek (macho->file, macho->offset32) == (grub_off_t) -1)
+    {
+      grub_error_push ();
+      return grub_error (GRUB_ERR_BAD_OS,
+			 "Invalid offset in program header.");
+    }
+
+  read = grub_file_read (macho->file, dest,
+			 macho->end32 - macho->offset32);
+  if (read != (grub_ssize_t) (macho->end32 - macho->offset32))
+    {
+      grub_error_push ();
+      return grub_error (GRUB_ERR_BAD_OS,
+			 "Couldn't read architecture-specific part");
+    }
+  return GRUB_ERR_NONE;
+}
+
+/* Calculate the amount of memory spanned by the segments. */
+grub_err_t
+grub_macho32_size (grub_macho_t macho, grub_addr_t *segments_start,
+		   grub_addr_t *segments_end, int flags)
+{
+  int nr_phdrs = 0;
+
+  /* Run through the program headers to calculate the total memory size we
+     should claim.  */
+  auto int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho,
+				      struct grub_macho_cmd *phdr, void *_arg);
+  int NESTED_FUNC_ATTR calcsize (grub_macho_t UNUSED _macho,
+				 struct grub_macho_cmd *hdr0, void UNUSED *_arg)
+    {
+      struct grub_macho_segment32 *hdr = (struct grub_macho_segment32 *) hdr0;
+      if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT32)
+	return 0;
+      if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS))
+	return 0;
+
+      nr_phdrs++;
+      if (hdr->vmaddr < *segments_start)
+	*segments_start = hdr->vmaddr;
+      if (hdr->vmaddr + hdr->vmsize > *segments_end)
+	*segments_end = hdr->vmaddr + hdr->vmsize;
+      return 0;
+    }
+
+  *segments_start = (grub_uint32_t) -1;
+  *segments_end = 0;
+
+  grub_macho32_cmds_iterate (macho, calcsize, 0);
+
+  if (nr_phdrs == 0)
+    return grub_error (GRUB_ERR_BAD_OS, "No program headers present");
+
+  if (*segments_end < *segments_start)
+    /* Very bad addresses.  */
+    return grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Load every loadable segment into memory specified by `_load_hook'.  */
+grub_err_t
+grub_macho32_load (grub_macho_t macho, char *offset, int flags)
+{
+  grub_err_t err = 0;
+  auto int NESTED_FUNC_ATTR do_load(grub_macho_t _macho,
+			       struct grub_macho_cmd *hdr0,
+			       void UNUSED *_arg);
+  int NESTED_FUNC_ATTR do_load(grub_macho_t _macho,
+			       struct grub_macho_cmd *hdr0,
+			       void UNUSED *_arg)
+  {
+    struct grub_macho_segment32 *hdr = (struct grub_macho_segment32 *) hdr0;
+
+    if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT32)
+      return 0;
+
+    if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS))
+      return 0;
+    if (! hdr->vmsize)
+      return 0;
+
+    if (grub_file_seek (_macho->file, hdr->fileoff
+			+ _macho->offset32) == (grub_off_t) -1)
+      {
+	grub_error_push ();
+	grub_error (GRUB_ERR_BAD_OS,
+		    "Invalid offset in program header.");
+	return 1;
+      }
+
+    if (hdr->filesize)
+      {
+	grub_ssize_t read;
+	read = grub_file_read (_macho->file, offset + hdr->vmaddr,
+				   min (hdr->filesize, hdr->vmsize));
+	if (read != (grub_ssize_t) min (hdr->filesize, hdr->vmsize))
+	  {
+	    /* XXX How can we free memory from `load_hook'? */
+	    grub_error_push ();
+	    err=grub_error (GRUB_ERR_BAD_OS,
+			    "Couldn't read segment from file: "
+			    "wanted 0x%lx bytes; read 0x%lx bytes.",
+			    hdr->filesize, read);
+	    return 1;
+	  }
+      }
+
+    if (hdr->filesize < hdr->vmsize)
+      grub_memset (offset + hdr->vmaddr + hdr->filesize,
+		   0, hdr->vmsize - hdr->filesize);
+    return 0;
+  }
+
+  grub_macho32_cmds_iterate (macho, do_load, 0);
+
+  return err;
+}
+
+grub_uint32_t
+grub_macho32_get_entry_point (grub_macho_t macho)
+{
+  grub_uint32_t entry_point = 0;
+  auto int NESTED_FUNC_ATTR hook(grub_macho_t _macho,
+			       struct grub_macho_cmd *hdr,
+			       void UNUSED *_arg);
+  int NESTED_FUNC_ATTR hook(grub_macho_t UNUSED _macho,
+			       struct grub_macho_cmd *hdr,
+			       void UNUSED *_arg)
+  {
+    if (hdr->cmd == GRUB_MACHO_CMD_THREAD)
+      entry_point = ((struct grub_macho_thread32 *) hdr)->entry_point;
+    return 0;
+  }
+  grub_macho32_cmds_iterate (macho, hook, 0);
+  return entry_point;
+}
+
+
+grub_err_t
+grub_macho_close (grub_macho_t macho)
+{
+  grub_file_t file = macho->file;
+
+  grub_free (macho->cmds32);
+  grub_free (macho->cmds64);
+
+  grub_free (macho);
+
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+grub_macho_t
+grub_macho_file (grub_file_t file)
+{
+  grub_macho_t macho;
+  union grub_macho_filestart filestart;
+
+  macho = grub_malloc (sizeof (*macho));
+  if (! macho)
+    return 0;
+
+  macho->file = file;
+  macho->offset32 = -1;
+  macho->offset64 = -1;
+  macho->end32 = -1;
+  macho->end64 = -1;
+  macho->cmds32 = 0;
+  macho->cmds64 = 0;
+
+  if (grub_file_seek (macho->file, 0) == (grub_off_t) -1)
+    goto fail;
+
+  if (grub_file_read (macho->file, &filestart, sizeof (filestart))
+      != sizeof (filestart))
+    {
+      grub_error_push ();
+      grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header.");
+      goto fail;
+    }
+
+  /* Is it a fat file? */
+  if (filestart.fat.magic == grub_be_to_cpu32 (GRUB_MACHO_FAT_MAGIC))
+    {
+      struct grub_macho_fat_arch *archs;
+      int i, narchs;
+
+      /* Load architecture description. */
+      narchs = grub_be_to_cpu32 (filestart.fat.nfat_arch);
+      if (grub_file_seek (macho->file, sizeof (struct grub_macho_fat_header))
+	  == (grub_off_t) -1)
+	goto fail;
+      archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs);
+      if (!archs)
+	goto fail;
+      if (grub_file_read (macho->file, archs,
+			  sizeof (struct grub_macho_fat_arch) * narchs)
+	  != (grub_ssize_t)sizeof(struct grub_macho_fat_arch) * narchs)
+	{
+	  grub_free (archs);
+	  grub_error_push ();
+	  grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header.");
+	  goto fail;
+	}
+
+      for (i = 0; i < narchs; i++)
+	{
+	  if (GRUB_MACHO_CPUTYPE_IS_HOST32
+	      (grub_be_to_cpu32 (archs[i].cputype)))
+	    {
+	      macho->offset32 = grub_be_to_cpu32 (archs[i].offset);
+	      macho->end32 = grub_be_to_cpu32 (archs[i].offset)
+		+ grub_be_to_cpu32 (archs[i].size);
+	    }
+	  if (GRUB_MACHO_CPUTYPE_IS_HOST64
+	      (grub_be_to_cpu32 (archs[i].cputype)))
+	    {
+	      macho->offset64 = grub_be_to_cpu32 (archs[i].offset);
+	      macho->end64 = grub_be_to_cpu32 (archs[i].offset)
+		+ grub_be_to_cpu32 (archs[i].size);
+	    }
+	}
+      grub_free (archs);
+    }
+
+  /* Is it a thin 32-bit file? */
+  if (filestart.thin32.magic == GRUB_MACHO_MAGIC32)
+    {
+      macho->offset32 = 0;
+      macho->end32 = grub_file_size (file);
+    }
+
+  /* Is it a thin 64-bit file? */
+  if (filestart.thin64.magic == GRUB_MACHO_MAGIC64)
+    {
+      macho->offset64 = 0;
+      macho->end64 = grub_file_size (file);
+    }
+
+  grub_macho_parse32 (macho);
+  /* FIXME: implement 64-bit.*/
+  /*  grub_macho_parse64 (macho); */
+
+  return macho;
+
+fail:
+  grub_macho_close (macho);
+  return 0;
+}
+
+grub_macho_t
+grub_macho_open (const char *name)
+{
+  grub_file_t file;
+  grub_macho_t macho;
+
+  file = grub_gzfile_open (name, 1);
+  if (! file)
+    return 0;
+
+  macho = grub_macho_file (file);
+  if (! macho)
+    grub_file_close (file);
+
+  return macho;
+}
diff --git a/loader/multiboot2.c b/loader/multiboot2.c
new file mode 100644
index 0000000..62f923a
--- /dev/null
+++ b/loader/multiboot2.c
@@ -0,0 +1,460 @@
+/* multiboot2.c - boot a multiboot 2 OS image. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/multiboot2.h>
+#include <multiboot2.h>
+#include <grub/elfload.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+
+static grub_addr_t entry;
+extern grub_dl_t my_mod;
+
+static char *grub_mb2_tags;
+static char *grub_mb2_tags_pos;
+static grub_size_t grub_mb2_tags_len;
+static int grub_mb2_tags_count;
+
+static void
+grub_mb2_tags_free (void)
+{
+  grub_dprintf ("loader", "Freeing all tags...\n");
+  grub_free (grub_mb2_tags);
+  grub_mb2_tags = 0;
+  grub_mb2_tags_pos = 0;
+  grub_mb2_tags_len = 0;
+  grub_mb2_tags_count = 0;
+}
+
+grub_err_t
+grub_mb2_tag_alloc (grub_addr_t *addr, int key, grub_size_t len)
+{
+  struct multiboot_tag_header *tag;
+  grub_size_t used;
+  grub_size_t needed;
+
+  grub_dprintf ("loader", "Allocating tag: key 0x%x, size 0x%lx.\n",
+		key, (unsigned long) len);
+
+  used = grub_mb2_tags_pos - grub_mb2_tags;
+  len = ALIGN_UP (len, sizeof (multiboot_word));
+
+  needed = used + len;
+
+  if (needed > grub_mb2_tags_len)
+    {
+      /* Allocate new buffer.  */
+      grub_size_t newsize = needed * 2;
+      char *newarea;
+
+      grub_dprintf ("loader", "Reallocating tag buffer (new size 0x%lx).\n",
+		    (unsigned long) newsize);
+
+      newarea = grub_malloc (newsize);
+      if (! newarea)
+	return grub_errno;
+      grub_memcpy (newarea, grub_mb2_tags, grub_mb2_tags_len);
+      grub_free (grub_mb2_tags);
+
+      grub_mb2_tags_len = newsize;
+      grub_mb2_tags = newarea;
+      grub_mb2_tags_pos = newarea + used;
+    }
+
+  tag = (struct multiboot_tag_header *) grub_mb2_tags_pos;
+  grub_mb2_tags_pos += len;
+
+  tag->key = key;
+  tag->len = len;
+
+  if (addr)
+    *addr = (grub_addr_t) tag;
+
+  grub_mb2_tags_count++;
+
+  grub_dprintf ("loader", "Allocated tag %u at %p.\n", grub_mb2_tags_count, tag);
+
+  return 0;
+}
+
+static grub_err_t
+grub_mb2_tag_start_create (void)
+{
+  return grub_mb2_tag_alloc (0, MULTIBOOT2_TAG_START,
+			    sizeof (struct multiboot_tag_start));
+}
+
+static grub_err_t
+grub_mb2_tag_name_create (void)
+{
+  struct multiboot_tag_name *name;
+  grub_addr_t name_addr;
+  grub_err_t err;
+  const char *grub_version = PACKAGE_STRING;
+
+  err = grub_mb2_tag_alloc (&name_addr, MULTIBOOT2_TAG_NAME,
+			   sizeof (struct multiboot_tag_name) +
+			   sizeof (grub_version) + 1);
+  if (err)
+    return err;
+
+  name = (struct multiboot_tag_name *) name_addr;
+  grub_strcpy (name->name, grub_version);
+
+  return GRUB_ERR_NONE;
+}
+
+typedef grub_err_t (*tag_create_t) (void);
+static tag_create_t grub_mb2_tag_creators[] = {
+  grub_mb2_tag_start_create,
+  grub_mb2_tag_name_create,
+  grub_mb2_tags_arch_create,
+  0,
+};
+
+static grub_err_t
+grub_mb2_tags_create (void)
+{
+  tag_create_t *creator;
+  grub_err_t err;
+
+  for (creator = grub_mb2_tag_creators; *creator != 0; creator++)
+    {
+      err = (*creator) ();
+      if (err)
+	goto error;
+    }
+
+  return GRUB_ERR_NONE;
+
+error:
+  grub_error_push ();
+  grub_mb2_tags_free ();
+  grub_error_pop ();
+  return err;
+}
+
+static grub_err_t
+grub_mb2_tags_finish (void)
+{
+  struct multiboot_tag_start *start;
+  grub_err_t err;
+
+  /* Create the `end' tag.  */
+  err = grub_mb2_tag_alloc (0, MULTIBOOT2_TAG_END,
+			   sizeof (struct multiboot_tag_end));
+  if (err)
+    goto error;
+
+  /* We created the `start' tag first.  Update it now.  */
+  start = (struct multiboot_tag_start *) grub_mb2_tags;
+  start->size = grub_mb2_tags_pos - grub_mb2_tags;
+  return GRUB_ERR_NONE;
+
+error:
+  grub_error_push ();
+  grub_mb2_tags_free ();
+  grub_error_pop ();
+  return err;
+}
+
+static grub_err_t
+grub_mb2_boot (void)
+{
+  grub_mb2_tags_finish ();
+
+  grub_dprintf ("loader", "Tags at %p\n", grub_mb2_tags);
+  grub_mb2_arch_boot (entry, grub_mb2_tags);
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_mb2_unload (void)
+{
+  struct multiboot_tag_header *tag;
+  struct multiboot_tag_header *tags =
+    (struct multiboot_tag_header *) grub_mb2_tags;
+
+  /* Free all module memory in the tag list.  */
+  for_each_tag (tag, tags)
+    {
+      if (tag->key == MULTIBOOT2_TAG_MODULE)
+	{
+	  struct multiboot_tag_module *module =
+	      (struct multiboot_tag_module *) tag;
+	  grub_free ((void *) module->addr);
+	}
+    }
+
+  /* Allow architecture to un-reserve memory.  */
+  grub_mb2_arch_unload (tags);
+
+  /* Free the tags themselves.  */
+  grub_mb2_tags_free ();
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_mb2_load_other (UNUSED grub_file_t file, UNUSED void *buffer)
+{
+  /* XXX Create module tag here.  */
+  return grub_error (GRUB_ERR_UNKNOWN_OS, "currently only ELF is supported");
+}
+
+/* Create the tag containing the cmdline and the address of the module data.  */
+static grub_err_t
+grub_mb2_tag_module_create (grub_addr_t modaddr, grub_size_t modsize,
+			    char *type, int key, int argc, char *argv[])
+{
+  struct multiboot_tag_module *module;
+  grub_ssize_t argslen = 0;
+  grub_err_t err;
+  char *p;
+  grub_addr_t module_addr;
+  int i;
+
+  /* Allocate enough space for the arguments and spaces between them.  */
+  for (i = 0; i < argc; i++)
+    argslen += grub_strlen (argv[i]) + 1;
+
+  /* Note: includes implicit 1-byte cmdline.  */
+  err = grub_mb2_tag_alloc (&module_addr, key,
+			   sizeof (struct multiboot_tag_module) + argslen);
+  if (err)
+    return grub_errno;
+
+  module = (struct multiboot_tag_module *) module_addr;
+  module->addr = modaddr;
+  module->size = modsize;
+  grub_strcpy(module->type, type);
+
+  /* Fill in the command line.  */
+  p = module->cmdline;
+  for (i = 0; i < argc; i++)
+    {
+      p = grub_stpcpy (p, argv[i]);
+      *p++ = ' ';
+    }
+  module->cmdline[argslen] = '\0';
+
+  return GRUB_ERR_NONE;
+}
+
+/* Load ELF32 or ELF64.  */
+static grub_err_t
+grub_mb2_load_elf (grub_elf_t elf, int argc, char *argv[])
+{
+  grub_addr_t kern_base;
+  grub_size_t kern_size;
+  grub_err_t err;
+
+  if (grub_elf_is_elf32 (elf))
+    {
+      entry = elf->ehdr.ehdr32.e_entry;
+      err = grub_elf32_load (elf, grub_mb2_arch_elf32_hook, &kern_base,
+			     &kern_size);
+    }
+  else if (grub_elf_is_elf64 (elf))
+    {
+      entry = elf->ehdr.ehdr64.e_entry;
+      err = grub_elf64_load (elf, grub_mb2_arch_elf64_hook, &kern_base,
+			     &kern_size);
+    }
+  else
+    err = grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class");
+
+  if (err)
+    goto fail;
+
+  grub_dprintf ("loader", "Entry point is 0x%lx.\n", (unsigned long) entry);
+
+  grub_mb2_tag_module_create (kern_base, kern_size, "kernel",
+			     MULTIBOOT2_TAG_MODULE, argc, argv);
+
+fail:
+  return err;
+}
+
+void
+grub_multiboot2 (int argc, char *argv[])
+{
+  char *buffer;
+  grub_file_t file = 0;
+  grub_elf_t elf = 0;
+  struct multiboot_header *header = 0;
+  char *p;
+  grub_ssize_t len;
+  grub_err_t err;
+  int header_found = 0;
+
+  grub_loader_unset ();
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file");
+      goto fail;
+    }
+
+  buffer = grub_malloc (MULTIBOOT2_HEADER_SEARCH);
+  if (! buffer)
+    return;
+
+  len = grub_file_read (file, buffer, MULTIBOOT2_HEADER_SEARCH);
+  if (len < 32)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "File too small");
+      goto fail;
+    }
+
+  /* Look for the multiboot header in the buffer.  The header should
+     be at least 8 bytes and aligned on a 8-byte boundary.  */
+  for (p = buffer; p <= buffer + len - 8; p += 8)
+    {
+      header = (struct multiboot_header *) p;
+      if (header->magic == MULTIBOOT2_HEADER_MAGIC)
+	{
+	  header_found = 1;
+	  break;
+	}
+    }
+
+  if (! header_found)
+    grub_dprintf ("loader", "No multiboot 2 header found.\n");
+
+
+  /* Create the basic tags.  */
+  grub_dprintf ("loader", "Creating multiboot 2 tags\n");
+  grub_mb2_tags_create ();
+
+  /* Load the kernel and create its tag.  */
+  elf = grub_elf_file (file);
+  if (elf)
+    {
+      grub_dprintf ("loader", "Loading ELF multiboot 2 file.\n");
+      err = grub_mb2_load_elf (elf, argc-1, &argv[1]);
+      grub_elf_close (elf);
+    }
+  else
+    {
+      grub_errno = 0;
+      grub_dprintf ("loader", "Loading non-ELF multiboot 2 file.\n");
+
+      if (header)
+	err = grub_mb2_load_other (file, header);
+      else
+	err = grub_error (GRUB_ERR_BAD_OS,
+			  "Need multiboot 2 header to load non-ELF files.");
+      grub_file_close (file);
+    }
+
+  grub_free (buffer);
+
+  if (err)
+    goto fail;
+
+  /* Good to go.  */
+  grub_loader_set (grub_mb2_boot, grub_mb2_unload, 1);
+  return;
+
+fail:
+  grub_mb2_tags_free ();
+  grub_dl_unref (my_mod);
+}
+
+void
+grub_module2 (int argc, char *argv[])
+{
+  grub_file_t file;
+  grub_addr_t modaddr = 0;
+  grub_ssize_t modsize = 0;
+  grub_err_t err;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
+      return;
+    }
+
+  if (argc == 1)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module type specified");
+      return;
+    }
+
+  if (entry == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT,
+		  "You need to load the multiboot kernel first");
+      return;
+    }
+
+  /* Load module data.  */
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    goto out;
+
+  modsize = grub_file_size (file);
+  err = grub_mb2_arch_module_alloc (modsize, &modaddr);
+  if (err)
+    goto out;
+
+  grub_dprintf ("loader", "Loading module at 0x%x - 0x%x\n", modaddr,
+		modaddr + modsize);
+  if (grub_file_read (file, (void *) modaddr, modsize) != modsize)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto out;
+    }
+
+  /* Create the module tag.  */
+  err = grub_mb2_tag_module_create (modaddr, modsize,
+				   argv[1], MULTIBOOT2_TAG_MODULE,
+				   argc-2, &argv[2]);
+  if (err)
+    goto out;
+
+out:
+  grub_error_push ();
+
+  if (file)
+    grub_file_close (file);
+
+  if (modaddr)
+    grub_mb2_arch_module_free (modaddr, modsize);
+
+  grub_error_pop ();
+}
diff --git a/loader/multiboot_loader.c b/loader/multiboot_loader.c
new file mode 100644
index 0000000..986ee0b
--- /dev/null
+++ b/loader/multiboot_loader.c
@@ -0,0 +1,213 @@
+/* multiboot_loader.c - boot multiboot 1 or 2 OS image */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/machine.h>
+#include <grub/multiboot.h>
+#include <grub/multiboot2.h>
+#include <multiboot2.h>
+#include <grub/elf.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/command.h>
+
+grub_dl_t my_mod;
+
+/* This tracks which version of multiboot to use when using
+ * the module command. By default use multiboot version 1.
+ * values:
+ *      1 - Multiboot version 1
+ *      2 - Multiboot version 2
+ */
+
+static unsigned int module_version_status = 1;
+
+static int
+find_multi_boot1_header (grub_file_t file)
+{
+  struct grub_multiboot_header *header;
+  char buffer[MULTIBOOT_SEARCH];
+  int found_status = 0;
+  grub_ssize_t len;
+
+  len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
+  if (len < 32)
+    return found_status;
+
+  /* Look for the multiboot header in the buffer.  The header should
+     be at least 12 bytes and aligned on a 4-byte boundary.  */
+  for (header = (struct grub_multiboot_header *) buffer;
+      ((char *) header <= buffer + len - 12) || (header = 0);
+      header = (struct grub_multiboot_header *) ((char *) header + 4))
+    {
+      if (header->magic == MULTIBOOT_MAGIC
+          && !(header->magic + header->flags + header->checksum))
+        {
+           found_status = 1;
+           break;
+        }
+     }
+
+   return found_status;
+}
+
+static int
+find_multi_boot2_header (grub_file_t file)
+{
+  struct multiboot_header *header;
+  char buffer[MULTIBOOT_SEARCH];
+  int found_status = 0;
+  grub_ssize_t len;
+
+  len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
+  if (len < 32)
+    return found_status;
+
+  /* Look for the multiboot header in the buffer.  The header should
+     be at least 8 bytes and aligned on a 8-byte boundary.  */
+  for (header = (struct multiboot_header *) buffer;
+      ((char *) header <= buffer + len - 8) || (header = 0);
+      header = (struct multiboot_header *) ((char *) header + 8))
+    {
+      if (header->magic == MULTIBOOT2_HEADER_MAGIC)
+        {
+           found_status = 1;
+           break;
+        }
+     }
+
+   return found_status;
+}
+
+static grub_err_t
+grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)),
+			   int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  int header_multi_ver_found = 0;
+
+  grub_dl_ref (my_mod);
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file");
+      goto fail;
+    }
+
+  /* find which header is in the file */
+  if (find_multi_boot1_header (file))
+    header_multi_ver_found = 1;
+  else if (find_multi_boot2_header (file))
+    header_multi_ver_found = 2;
+  else
+    {
+      grub_error (GRUB_ERR_BAD_OS, "Multiboot header not found");
+      goto fail;
+    }
+
+  /* close file before calling functions */
+  if (file)
+    grub_file_close (file);
+
+  /* Launch multi boot with header */
+
+  /* XXX Find a better way to identify this.
+     This is for i386-pc */
+#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_COREBOOT) || \
+    defined(GRUB_MACHINE_QEMU)
+  if (header_multi_ver_found == 1)
+    {
+      grub_dprintf ("multiboot_loader",
+		    "Launching multiboot 1 grub_multiboot() function\n");
+      grub_multiboot (argc, argv);
+      module_version_status = 1;
+    }
+#endif
+  if (header_multi_ver_found == 0 || header_multi_ver_found == 2)
+    {
+      grub_dprintf ("multiboot_loader",
+		    "Launching multiboot 2 grub_multiboot2() function\n");
+      grub_multiboot2 (argc, argv);
+      module_version_status = 2;
+    }
+
+  return grub_errno;
+
+fail:
+  if (file)
+    grub_file_close (file);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_module_loader (grub_command_t cmd __attribute__ ((unused)),
+			int argc, char *argv[])
+{
+
+#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_COREBOOT) || \
+    defined(GRUB_MACHINE_QEMU)
+  if (module_version_status == 1)
+    {
+      grub_dprintf("multiboot_loader",
+           "Launching multiboot 1 grub_module() function\n");
+      grub_module (argc, argv);
+    }
+#endif
+  if (module_version_status == 2)
+    {
+      grub_dprintf("multiboot_loader",
+          "Launching multiboot 2 grub_module2() function\n");
+      grub_module2 (argc, argv);
+    }
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_multiboot, cmd_module;
+
+GRUB_MOD_INIT(multiboot)
+{
+  cmd_multiboot =
+    grub_register_command ("multiboot", grub_cmd_multiboot_loader,
+			   0, "load a multiboot kernel");
+  cmd_module =
+    grub_register_command ("module", grub_cmd_module_loader,
+			   0, "load a multiboot module");
+
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(multiboot)
+{
+  grub_unregister_command (cmd_multiboot);
+  grub_unregister_command (cmd_module);
+}
diff --git a/loader/powerpc/ieee1275/linux.c b/loader/powerpc/ieee1275/linux.c
new file mode 100644
index 0000000..79fbf0b
--- /dev/null
+++ b/loader/powerpc/ieee1275/linux.c
@@ -0,0 +1,362 @@
+/* linux.c - boot Linux */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005, 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/elf.h>
+#include <grub/elfload.h>
+#include <grub/loader.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/machine/loader.h>
+#include <grub/command.h>
+
+#define ELF32_LOADMASK (0xc0000000UL)
+#define ELF64_LOADMASK (0xc000000000000000ULL)
+
+static grub_dl_t my_mod;
+
+static int loaded;
+
+static grub_addr_t initrd_addr;
+static grub_size_t initrd_size;
+
+static grub_addr_t linux_addr;
+static grub_size_t linux_size;
+
+static char *linux_args;
+
+typedef void (*kernel_entry_t) (void *, unsigned long, int (void *),
+				unsigned long, unsigned long);
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  kernel_entry_t linuxmain;
+  grub_ssize_t actual;
+
+  /* Set the command line arguments.  */
+  grub_ieee1275_set_property (grub_ieee1275_chosen, "bootargs", linux_args,
+			      grub_strlen (linux_args) + 1, &actual);
+
+  grub_dprintf ("loader", "Entry point: 0x%x\n", linux_addr);
+  grub_dprintf ("loader", "Initrd at: 0x%x, size 0x%x\n", initrd_addr,
+		initrd_size);
+  grub_dprintf ("loader", "Boot arguments: %s\n", linux_args);
+  grub_dprintf ("loader", "Jumping to Linux...\n");
+
+  /* Boot the kernel.  */
+  linuxmain = (kernel_entry_t) linux_addr;
+  linuxmain ((void *) initrd_addr, initrd_size, grub_ieee1275_entry_fn, 0, 0);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_release_mem (void)
+{
+  grub_free (linux_args);
+  linux_args = 0;
+
+  if (linux_addr && grub_ieee1275_release (linux_addr, linux_size))
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not release memory");
+
+  if (initrd_addr && grub_ieee1275_release (initrd_addr, initrd_size))
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not release memory");
+
+  linux_addr = 0;
+  initrd_addr = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_err_t err;
+
+  err = grub_linux_release_mem ();
+  grub_dl_unref (my_mod);
+
+  loaded = 0;
+
+  return err;
+}
+
+static grub_err_t
+grub_linux_load32 (grub_elf_t elf)
+{
+  Elf32_Addr entry;
+  int found_addr = 0;
+
+  /* Linux's entry point incorrectly contains a virtual address.  */
+  entry = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK;
+  if (entry == 0)
+    entry = 0x01400000;
+
+  linux_size = grub_elf32_size (elf);
+  if (linux_size == 0)
+    return grub_errno;
+  /* Pad it; the kernel scribbles over memory beyond its load address.  */
+  linux_size += 0x100000;
+
+  /* On some systems, firmware occupies the memory we're trying to use.
+   * Happily, Linux can be loaded anywhere (it relocates itself).  Iterate
+   * until we find an open area.  */
+  for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 0x100000)
+    {
+      grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n",
+		    linux_addr, linux_size);
+      found_addr = grub_claimmap (linux_addr, linux_size);
+      if (found_addr != -1)
+	break;
+    }
+  if (found_addr == -1)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not claim memory.");
+
+  /* Now load the segments into the area we claimed.  */
+  auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load);
+  grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load)
+    {
+      if (phdr->p_type != PT_LOAD)
+	{
+	  *do_load = 0;
+	  return 0;
+	}
+      *do_load = 1;
+
+      /* Linux's program headers incorrectly contain virtual addresses.
+       * Translate those to physical, and offset to the area we claimed.  */
+      *addr = (phdr->p_paddr & ~ELF32_LOADMASK) + linux_addr;
+      return 0;
+    }
+  return grub_elf32_load (elf, offset_phdr, 0, 0);
+}
+
+static grub_err_t
+grub_linux_load64 (grub_elf_t elf)
+{
+  Elf64_Addr entry;
+  int found_addr = 0;
+
+  /* Linux's entry point incorrectly contains a virtual address.  */
+  entry = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK;
+  if (entry == 0)
+    entry = 0x01400000;
+
+  linux_size = grub_elf64_size (elf);
+  if (linux_size == 0)
+    return grub_errno;
+  /* Pad it; the kernel scribbles over memory beyond its load address.  */
+  linux_size += 0x100000;
+
+  /* On some systems, firmware occupies the memory we're trying to use.
+   * Happily, Linux can be loaded anywhere (it relocates itself).  Iterate
+   * until we find an open area.  */
+  for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 0x100000)
+    {
+      grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n",
+		    linux_addr, linux_size);
+      found_addr = grub_claimmap (linux_addr, linux_size);
+      if (found_addr != -1)
+	break;
+    }
+  if (found_addr == -1)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not claim memory.");
+
+  /* Now load the segments into the area we claimed.  */
+  auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load);
+  grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load)
+    {
+      if (phdr->p_type != PT_LOAD)
+	{
+	  *do_load = 0;
+	  return 0;
+	}
+      *do_load = 1;
+      /* Linux's program headers incorrectly contain virtual addresses.
+       * Translate those to physical, and offset to the area we claimed.  */
+      *addr = (phdr->p_paddr & ~ELF64_LOADMASK) + linux_addr;
+      return 0;
+    }
+  return grub_elf64_load (elf, offset_phdr, 0, 0);
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+		int argc, char *argv[])
+{
+  grub_elf_t elf = 0;
+  int i;
+  int size;
+  char *dest;
+
+  grub_dl_ref (my_mod);
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
+      goto out;
+    }
+
+  elf = grub_elf_open (argv[0]);
+  if (! elf)
+    goto out;
+
+  if (elf->ehdr.ehdr32.e_type != ET_EXEC)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_OS,
+		  "This ELF file is not of the right type\n");
+      goto out;
+    }
+
+  /* Release the previously used memory.  */
+  grub_loader_unset ();
+
+  if (grub_elf_is_elf32 (elf))
+    grub_linux_load32 (elf);
+  else
+  if (grub_elf_is_elf64 (elf))
+    grub_linux_load64 (elf);
+  else
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unknown ELF class");
+      goto out;
+    }
+
+  size = sizeof ("BOOT_IMAGE=") + grub_strlen (argv[0]);
+  for (i = 0; i < argc; i++)
+    size += grub_strlen (argv[i]) + 1;
+
+  linux_args = grub_malloc (size);
+  if (! linux_args)
+    goto out;
+
+  /* Specify the boot file.  */
+  dest = grub_stpcpy (linux_args, "BOOT_IMAGE=");
+  dest = grub_stpcpy (dest, argv[0]);
+
+  for (i = 1; i < argc; i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+out:
+
+  if (elf)
+    grub_elf_close (elf);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_linux_release_mem ();
+      grub_dl_unref (my_mod);
+      loaded = 0;
+    }
+  else
+    {
+      grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
+      initrd_addr = 0;
+      loaded = 1;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+		 int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_addr_t first_addr;
+  grub_addr_t addr;
+  int found_addr = 0;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
+      goto fail;
+    }
+
+  if (!loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  first_addr = linux_addr + linux_size;
+  size = grub_file_size (file);
+
+  /* Attempt to claim at a series of addresses until successful in
+     the same way that grub_rescue_cmd_linux does.  */
+  for (addr = first_addr; addr < first_addr + 200 * 0x100000; addr += 0x100000)
+    {
+      grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n",
+		    addr, size);
+      found_addr = grub_claimmap (addr, size);
+      if (found_addr != -1)
+	break;
+    }
+
+  if (found_addr == -1)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not claim memory");
+      goto fail;
+    }
+
+  grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size);
+
+  if (grub_file_read (file, (void *) addr, size) != size)
+    {
+      grub_ieee1275_release (addr, size);
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+  initrd_addr = addr;
+  initrd_size = size;
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linux)
+{
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+				     0, "load a linux kernel");
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
+				      0, "load an initrd");
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/loader/sparc64/ieee1275/linux.c b/loader/sparc64/ieee1275/linux.c
new file mode 100644
index 0000000..df420d8
--- /dev/null
+++ b/loader/sparc64/ieee1275/linux.c
@@ -0,0 +1,529 @@
+/* linux.c - boot Linux */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005, 2007, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/elf.h>
+#include <grub/elfload.h>
+#include <grub/loader.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/machine/loader.h>
+#include <grub/gzio.h>
+#include <grub/command.h>
+
+static grub_dl_t my_mod;
+
+static int loaded;
+
+/* /virtual-memory/translations property layout  */
+struct grub_ieee1275_translation {
+  grub_uint64_t vaddr;
+  grub_uint64_t size;
+  grub_uint64_t data;
+};
+
+static struct grub_ieee1275_translation *of_trans;
+static int of_num_trans;
+
+static grub_addr_t phys_base;
+static grub_addr_t grub_phys_start;
+static grub_addr_t grub_phys_end;
+
+static grub_addr_t initrd_addr;
+static grub_addr_t initrd_paddr;
+static grub_size_t initrd_size;
+
+static Elf64_Addr linux_entry;
+static grub_addr_t linux_addr;
+static grub_addr_t linux_paddr;
+static grub_size_t linux_size;
+
+static char *linux_args;
+
+typedef void (*kernel_entry_t) (unsigned long, unsigned long,
+				unsigned long, unsigned long, int (void *));
+
+struct linux_bootstr_info {
+	int len, valid;
+	char buf[];
+};
+
+struct linux_hdrs {
+	/* All HdrS versions support these fields.  */
+	unsigned int start_insns[2];
+	char magic[4]; /* "HdrS" */
+	unsigned int linux_kernel_version; /* LINUX_VERSION_CODE */
+	unsigned short hdrs_version;
+	unsigned short root_flags;
+	unsigned short root_dev;
+	unsigned short ram_flags;
+	unsigned int __deprecated_ramdisk_image;
+	unsigned int ramdisk_size;
+
+	/* HdrS versions 0x0201 and higher only */
+	char *reboot_command;
+
+	/* HdrS versions 0x0202 and higher only */
+	struct linux_bootstr_info *bootstr_info;
+
+	/* HdrS versions 0x0301 and higher only */
+	unsigned long ramdisk_image;
+};
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  struct linux_bootstr_info *bp;
+  kernel_entry_t linuxmain;
+  struct linux_hdrs *hp;
+  grub_addr_t addr;
+
+  hp = (struct linux_hdrs *) linux_addr;
+
+  /* Any pointer we dereference in the kernel image must be relocated
+     to where we actually loaded the kernel.  */
+  addr = (grub_addr_t) hp->bootstr_info;
+  addr += (linux_addr - linux_entry);
+  bp = (struct linux_bootstr_info *) addr;
+
+  /* Set the command line arguments, unless the kernel has been
+     built with a fixed CONFIG_CMDLINE.  */
+  if (!bp->valid)
+    {
+      int len = grub_strlen (linux_args) + 1;
+      if (bp->len < len)
+	len = bp->len;
+      memcpy(bp->buf, linux_args, len);
+      bp->buf[len-1] = '\0';
+      bp->valid = 1;
+    }
+
+  if (initrd_addr)
+    {
+      /* The kernel expects the physical address, adjusted relative
+	 to the lowest address advertised in "/memory"'s available
+	 property.
+
+	 The history of this is that back when the kernel only supported
+	 specifying a 32-bit ramdisk address, this was the way to still
+	 be able to specify the ramdisk physical address even if memory
+	 started at some place above 4GB.
+
+	 The magic 0x400000 is KERNBASE, I have no idea why SILO adds
+	 that term into the address, but it does and thus we have to do
+	 it too as this is what the kernel expects.  */
+      hp->ramdisk_image = initrd_paddr - phys_base + 0x400000;
+      hp->ramdisk_size = initrd_size;
+    }
+
+  grub_dprintf ("loader", "Entry point: 0x%lx\n", linux_addr);
+  grub_dprintf ("loader", "Initrd at: 0x%lx, size 0x%lx\n", initrd_addr,
+		initrd_size);
+  grub_dprintf ("loader", "Boot arguments: %s\n", linux_args);
+  grub_dprintf ("loader", "Jumping to Linux...\n");
+
+  /* Boot the kernel.  */
+  linuxmain = (kernel_entry_t) linux_addr;
+  linuxmain (0, 0, 0, 0, grub_ieee1275_entry_fn);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_release_mem (void)
+{
+  grub_free (linux_args);
+  linux_args = 0;
+  linux_addr = 0;
+  initrd_addr = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_err_t err;
+
+  err = grub_linux_release_mem ();
+  grub_dl_unref (my_mod);
+
+  loaded = 0;
+
+  return err;
+}
+
+#define FOUR_MB	(4 * 1024 * 1024)
+
+static grub_addr_t
+align_addr(grub_addr_t val, grub_addr_t align)
+{
+  return (val + (align - 1)) & ~(align - 1);
+}
+
+static grub_addr_t
+alloc_phys (grub_addr_t size)
+{
+  grub_addr_t ret = (grub_addr_t) -1;
+
+  auto int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type);
+  int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type)
+  {
+    grub_addr_t end = addr + len;
+
+    if (type != 1)
+      return 0;
+
+    addr = align_addr (addr, FOUR_MB);
+    if (addr >= end)
+      return 0;
+
+    if (addr >= grub_phys_start && addr < grub_phys_end)
+      {
+	addr = align_addr (grub_phys_end, FOUR_MB);
+	if (addr >= end)
+	  return 0;
+      }
+    if ((addr + size) >= grub_phys_start
+	&& (addr + size) < grub_phys_end)
+      {
+	addr = align_addr (grub_phys_end, FOUR_MB);
+	if (addr >= end)
+	  return 0;
+      }
+
+    if (loaded)
+      {
+	grub_addr_t linux_end = align_addr (linux_paddr + linux_size, FOUR_MB);
+
+	if (addr >= linux_paddr && addr < linux_end)
+	  {
+	    addr = linux_end;
+	    if (addr >= end)
+	      return 0;
+	  }
+	if ((addr + size) >= linux_paddr
+	    && (addr + size) < linux_end)
+	  {
+	    addr = linux_end;
+	    if (addr >= end)
+	      return 0;
+	  }
+      }
+
+    ret = addr;
+    return 1;
+  }
+
+  grub_machine_mmap_iterate (choose);
+
+  return ret;
+}
+
+static grub_err_t
+grub_linux_load64 (grub_elf_t elf)
+{
+  grub_addr_t off, paddr, base;
+  int ret;
+
+  linux_entry = elf->ehdr.ehdr64.e_entry;
+  linux_addr = 0x40004000;
+  off = 0x4000;
+  linux_size = grub_elf64_size (elf);
+  if (linux_size == 0)
+    return grub_errno;
+
+  grub_dprintf ("loader", "Attempting to claim at 0x%lx, size 0x%lx.\n",
+		linux_addr, linux_size);
+
+  paddr = alloc_phys (linux_size + off);
+  if (paddr == (grub_addr_t) -1)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		       "Could not allocate physical memory.");
+  ret = grub_ieee1275_map_physical (paddr, linux_addr - off,
+				    linux_size + off, IEEE1275_MAP_DEFAULT);
+  if (ret)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		       "Could not map physical memory.");
+
+  grub_dprintf ("loader", "Loading linux at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n",
+		linux_addr, paddr, linux_size);
+
+  linux_paddr = paddr;
+
+  base = linux_entry - off;
+
+  /* Now load the segments into the area we claimed.  */
+  auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load);
+  grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load)
+    {
+      if (phdr->p_type != PT_LOAD)
+	{
+	  *do_load = 0;
+	  return 0;
+	}
+      *do_load = 1;
+
+      /* Adjust the program load address to linux_addr.  */
+      *addr = (phdr->p_paddr - base) + (linux_addr - off);
+      return 0;
+    }
+  return grub_elf64_load (elf, offset_phdr, 0, 0);
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+		int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_elf_t elf = 0;
+  int i;
+  int size;
+  char *dest;
+
+  grub_dl_ref (my_mod);
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
+      goto out;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (!file)
+    goto out;
+
+  elf = grub_elf_file (file);
+  if (! elf)
+    goto out;
+
+  if (elf->ehdr.ehdr32.e_type != ET_EXEC)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_OS,
+		  "This ELF file is not of the right type\n");
+      goto out;
+    }
+
+  /* Release the previously used memory.  */
+  grub_loader_unset ();
+
+  if (grub_elf_is_elf64 (elf))
+    grub_linux_load64 (elf);
+  else
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unknown ELF class");
+      goto out;
+    }
+
+  size = sizeof ("BOOT_IMAGE=") + grub_strlen (argv[0]);
+  for (i = 0; i < argc; i++)
+    size += grub_strlen (argv[i]) + 1;
+
+  linux_args = grub_malloc (size);
+  if (! linux_args)
+    goto out;
+
+  /* Specify the boot file.  */
+  dest = grub_stpcpy (linux_args, "BOOT_IMAGE=");
+  dest = grub_stpcpy (dest, argv[0]);
+
+  for (i = 1; i < argc; i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+out:
+  if (elf)
+    grub_elf_close (elf);
+  else if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_linux_release_mem ();
+      grub_dl_unref (my_mod);
+      loaded = 0;
+    }
+  else
+    {
+      grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
+      initrd_addr = 0;
+      loaded = 1;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+		 int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_addr_t paddr;
+  grub_addr_t addr;
+  int ret;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
+      goto fail;
+    }
+
+  if (!loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  addr = 0x60000000;
+  size = grub_file_size (file);
+
+  paddr = alloc_phys (size);
+  if (paddr == (grub_addr_t) -1)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		  "Could not allocate physical memory.");
+      goto fail;
+    }
+  ret = grub_ieee1275_map_physical (paddr, addr, size, IEEE1275_MAP_DEFAULT);
+  if (ret)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		  "Could not map physical memory.");
+      goto fail;
+    }
+
+  grub_dprintf ("loader", "Loading initrd at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n",
+		addr, paddr, size);
+
+  if (grub_file_read (file, (void *) addr, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
+      goto fail;
+    }
+
+  initrd_addr = addr;
+  initrd_paddr = paddr;
+  initrd_size = size;
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static void
+determine_phys_base (void)
+{
+  auto int NESTED_FUNC_ATTR get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type);
+  int NESTED_FUNC_ATTR get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type)
+  {
+    if (type != 1)
+      return 0;
+    if (addr < phys_base)
+      phys_base = addr;
+    return 0;
+  }
+
+  phys_base = ~(grub_uint64_t) 0;
+  grub_machine_mmap_iterate (get_physbase);
+}
+
+static void
+fetch_translations (void)
+{
+  grub_ieee1275_phandle_t node;
+  grub_ssize_t actual;
+  int i;
+
+  if (grub_ieee1275_finddevice ("/virtual-memory", &node))
+    {
+      grub_printf ("Cannot find /virtual-memory node.\n");
+      return;
+    }
+
+  if (grub_ieee1275_get_property_length (node, "translations", &actual))
+    {
+      grub_printf ("Cannot find /virtual-memory/translations size.\n");
+      return;
+    }
+
+  of_trans = grub_malloc (actual);
+  if (!of_trans)
+    {
+      grub_printf ("Cannot allocate translations buffer.\n");
+      return;
+    }
+
+  if (grub_ieee1275_get_property (node, "translations", of_trans, actual, &actual))
+    {
+      grub_printf ("Cannot fetch /virtual-memory/translations property.\n");
+      return;
+    }
+
+  of_num_trans = actual / sizeof(struct grub_ieee1275_translation);
+
+  for (i = 0; i < of_num_trans; i++)
+    {
+      struct grub_ieee1275_translation *p = &of_trans[i];
+
+      if (p->vaddr == 0x2000)
+	{
+	  grub_addr_t phys, tte = p->data;
+
+	  phys = tte & ~(0xff00000000001fffULL);
+
+	  grub_phys_start = phys;
+	  grub_phys_end = grub_phys_start + p->size;
+	  grub_dprintf ("loader", "Grub lives at phys_start[%lx] phys_end[%lx]\n",
+			(unsigned long) grub_phys_start,
+			(unsigned long) grub_phys_end);
+	  break;
+	}
+    }
+}
+
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linux)
+{
+  determine_phys_base ();
+  fetch_translations ();
+
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+				     0, "load a linux kernel");
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
+				      0, "load an initrd");
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/loader/xnu.c b/loader/xnu.c
new file mode 100644
index 0000000..aac4ae3
--- /dev/null
+++ b/loader/xnu.c
@@ -0,0 +1,1360 @@
+/* xnu.c - load xnu kernel. Thanks to Florian Idelberger for all the
+   time he spent testing this
+ */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/xnu.h>
+#include <grub/cpu/xnu.h>
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/loader.h>
+#include <grub/machoload.h>
+#include <grub/macho.h>
+#include <grub/cpu/macho.h>
+#include <grub/gzio.h>
+#include <grub/command.h>
+#include <grub/misc.h>
+
+struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0;
+static int driverspackagenum = 0;
+static int driversnum = 0;
+
+/* Allocate heap by 32MB-blocks. */
+#define GRUB_XNU_HEAP_ALLOC_BLOCK 0x2000000
+
+static grub_err_t
+grub_xnu_register_memory (char *prefix, int *suffix,
+			  void *addr, grub_size_t size);
+void *
+grub_xnu_heap_malloc (int size)
+{
+  void *val;
+
+#if 0
+  /* This way booting is faster but less reliable.
+     Once we have advanced mm second way will be as fast as this one. */
+  val = grub_xnu_heap_start = (char *) 0x100000;
+#else
+  int oldblknum, newblknum;
+
+  /* The page after the heap is used for stack. Ensure it's usable. */
+  if (grub_xnu_heap_size)
+    oldblknum = (grub_xnu_heap_size + GRUB_XNU_PAGESIZE
+		 + GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK;
+  else
+    oldblknum = 0;
+  newblknum = (grub_xnu_heap_size + size + GRUB_XNU_PAGESIZE
+	       + GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK;
+  if (oldblknum != newblknum)
+    /* FIXME: instruct realloc to allocate at 1MB if possible once
+       advanced mm is ready. */
+    val = grub_realloc (grub_xnu_heap_start,
+			newblknum * GRUB_XNU_HEAP_ALLOC_BLOCK);
+  else
+    val = grub_xnu_heap_start;
+  if (! val)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		  "not enough space on xnu memory heap");
+      return 0;
+    }
+  grub_xnu_heap_start = val;
+#endif
+
+  val = (char *) grub_xnu_heap_start + grub_xnu_heap_size;
+  grub_xnu_heap_size += size;
+  grub_dprintf ("xnu", "val=%p\n", val);
+  return (char *) val;
+}
+
+/* Make sure next block of the heap will be aligned.
+   Please notice: aligned are pointers AFTER relocation
+   and not the current ones. */
+grub_err_t
+grub_xnu_align_heap (int align)
+{
+  int align_overhead = align - grub_xnu_heap_size % align;
+  if (align_overhead == align)
+    return GRUB_ERR_NONE;
+  if (! grub_xnu_heap_malloc (align_overhead))
+    return grub_errno;
+  return GRUB_ERR_NONE;
+}
+
+/* Free subtree pointed by CUR. */
+void
+grub_xnu_free_devtree (struct grub_xnu_devtree_key *cur)
+{
+  struct grub_xnu_devtree_key *d;
+  while (cur)
+    {
+      grub_free (cur->name);
+      if (cur->datasize == -1)
+	grub_xnu_free_devtree (cur->first_child);
+      else if (cur->data)
+	grub_free (cur->data);
+      d = cur->next;
+      grub_free (cur);
+      cur = d;
+    }
+}
+
+/* Compute the size of device tree in xnu format. */
+static grub_size_t
+grub_xnu_writetree_get_size (struct grub_xnu_devtree_key *start, char *name)
+{
+  grub_size_t ret;
+  struct grub_xnu_devtree_key *cur;
+
+  /* Key header. */
+  ret = 2 * sizeof (grub_uint32_t);
+
+  /* "name" value. */
+  ret += 32 + sizeof (grub_uint32_t)
+    + grub_strlen (name) + 4
+    - (grub_strlen (name) % 4);
+
+  for (cur = start; cur; cur = cur->next)
+    if (cur->datasize != -1)
+      {
+	int align_overhead;
+
+	align_overhead = 4 - (cur->datasize % 4);
+	if (align_overhead == 4)
+	  align_overhead = 0;
+	ret += 32 + sizeof (grub_uint32_t) + cur->datasize + align_overhead;
+      }
+    else
+      ret += grub_xnu_writetree_get_size (cur->first_child, cur->name);
+  return ret;
+}
+
+/* Write devtree in XNU format at curptr assuming the head is named NAME.*/
+static void *
+grub_xnu_writetree_toheap_real (void *curptr,
+				struct grub_xnu_devtree_key *start, char *name)
+{
+  struct grub_xnu_devtree_key *cur;
+  int nkeys = 0, nvals = 0;
+  for (cur = start; cur; cur = cur->next)
+    {
+      if (cur->datasize == -1)
+	nkeys++;
+      else
+	nvals++;
+    }
+  /* For the name. */
+  nvals++;
+
+  *((grub_uint32_t *) curptr) = nvals;
+  curptr = ((grub_uint32_t *) curptr) + 1;
+  *((grub_uint32_t *) curptr) = nkeys;
+  curptr = ((grub_uint32_t *) curptr) + 1;
+
+  /* First comes "name" value. */
+  grub_memset (curptr, 0, 32);
+  grub_memcpy (curptr, "name", 4);
+  curptr = ((grub_uint8_t *) curptr) + 32;
+  *((grub_uint32_t *)curptr) = grub_strlen (name) + 1;
+  curptr = ((grub_uint32_t *) curptr) + 1;
+  grub_memcpy (curptr, name, grub_strlen (name));
+  curptr = ((grub_uint8_t *) curptr) + grub_strlen (name);
+  grub_memset (curptr, 0, 4 - (grub_strlen (name) % 4));
+  curptr = ((grub_uint8_t *) curptr) + (4 - (grub_strlen (name) % 4));
+
+  /* Then the other values. */
+  for (cur = start; cur; cur = cur->next)
+    if (cur->datasize != -1)
+      {
+	int align_overhead;
+
+	align_overhead = 4 - (cur->datasize % 4);
+	if (align_overhead == 4)
+	  align_overhead = 0;
+	grub_memset (curptr, 0, 32);
+	grub_strncpy (curptr, cur->name, 31);
+	curptr = ((grub_uint8_t *) curptr) + 32;
+	*((grub_uint32_t *) curptr) = cur->datasize;
+	curptr = ((grub_uint32_t *) curptr) + 1;
+	grub_memcpy (curptr, cur->data, cur->datasize);
+	curptr = ((grub_uint8_t *) curptr) + cur->datasize;
+	grub_memset (curptr, 0, align_overhead);
+	curptr = ((grub_uint8_t *) curptr) + align_overhead;
+      }
+
+  /* And then the keys. Recursively use this function. */
+  for (cur = start; cur; cur = cur->next)
+    if (cur->datasize == -1)
+      if (!(curptr = grub_xnu_writetree_toheap_real (curptr,
+						     cur->first_child,
+						     cur->name)))
+	return 0;
+  return curptr;
+}
+
+grub_err_t
+grub_xnu_writetree_toheap (void **start, grub_size_t *size)
+{
+  struct grub_xnu_devtree_key *chosen;
+  struct grub_xnu_devtree_key *memorymap;
+  struct grub_xnu_devtree_key *driverkey;
+  struct grub_xnu_extdesc *extdesc;
+  grub_err_t err;
+
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    return err;
+
+  /* Device tree itself is in the memory map of device tree. */
+  /* Create a dummy value in memory-map. */
+  chosen = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
+  if (! chosen)
+    return grub_errno;
+  memorymap = grub_xnu_create_key (&(chosen->first_child), "memory-map");
+  if (! memorymap)
+    return grub_errno;
+
+  driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey));
+  if (! driverkey)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't write device tree");
+  driverkey->name = grub_strdup ("DeviceTree");
+  if (! driverkey->name)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't write device tree");
+  driverkey->datasize = sizeof (*extdesc);
+  driverkey->next = memorymap->first_child;
+  memorymap->first_child = driverkey;
+  driverkey->data = extdesc
+    = (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
+  if (! driverkey->data)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't write device tree");
+
+  /* Allocate the space based on the size with dummy value. */
+  *size = grub_xnu_writetree_get_size (grub_xnu_devtree_root, "/");
+  *start = grub_xnu_heap_malloc (*size + GRUB_XNU_PAGESIZE
+				 - *size % GRUB_XNU_PAGESIZE);
+
+  /* Put real data in the dummy. */
+  extdesc->addr = (char *) *start - grub_xnu_heap_start
+    + grub_xnu_heap_will_be_at;
+  extdesc->size = (grub_uint32_t) *size;
+
+  /* Write the tree to heap. */
+  grub_xnu_writetree_toheap_real (*start, grub_xnu_devtree_root, "/");
+  return GRUB_ERR_NONE;
+}
+
+/* Find a key or value in parent key. */
+struct grub_xnu_devtree_key *
+grub_xnu_find_key (struct grub_xnu_devtree_key *parent, char *name)
+{
+  struct grub_xnu_devtree_key *cur;
+  for (cur = parent; cur; cur = cur->next)
+    if (grub_strcmp (cur->name, name) == 0)
+      return cur;
+  return 0;
+}
+
+struct grub_xnu_devtree_key *
+grub_xnu_create_key (struct grub_xnu_devtree_key **parent, char *name)
+{
+  struct grub_xnu_devtree_key *ret;
+  ret = grub_xnu_find_key (*parent, name);
+  if (ret)
+    return ret;
+  ret = (struct grub_xnu_devtree_key *) grub_zalloc (sizeof (*ret));
+  if (! ret)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create key %s", name);
+      return 0;
+    }
+  ret->name = grub_strdup (name);
+  if (! ret->name)
+    {
+      grub_free (ret);
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create key %s", name);
+      return 0;
+    }
+  ret->datasize = -1;
+  ret->next = *parent;
+  *parent = ret;
+  return ret;
+}
+
+struct grub_xnu_devtree_key *
+grub_xnu_create_value (struct grub_xnu_devtree_key **parent, char *name)
+{
+  struct grub_xnu_devtree_key *ret;
+  ret = grub_xnu_find_key (*parent, name);
+  if (ret)
+    {
+      if (ret->datasize == -1)
+	grub_xnu_free_devtree (ret->first_child);
+      else if (ret->datasize)
+	grub_free (ret->data);
+      ret->datasize = 0;
+      ret->data = 0;
+      return ret;
+    }
+  ret = (struct grub_xnu_devtree_key *) grub_zalloc (sizeof (*ret));
+  if (! ret)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create value %s", name);
+      return 0;
+    }
+  ret->name = grub_strdup (name);
+  if (! ret->name)
+    {
+      grub_free (ret);
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create value %s", name);
+      return 0;
+    }
+  ret->next = *parent;
+  *parent = ret;
+  return ret;
+}
+
+static grub_err_t
+grub_xnu_unload (void)
+{
+  grub_xnu_free_devtree (grub_xnu_devtree_root);
+  grub_xnu_devtree_root = 0;
+
+  /* Free loaded image. */
+  driversnum = 0;
+  driverspackagenum = 0;
+  grub_free (grub_xnu_heap_start);
+  grub_xnu_heap_start = 0;
+  grub_xnu_heap_size = 0;
+  grub_xnu_unlock ();
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
+		     int argc, char *args[])
+{
+  grub_err_t err;
+  grub_macho_t macho;
+  grub_addr_t startcode, endcode;
+  int i;
+  char *ptr, *loadaddr;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  grub_xnu_unload ();
+
+  macho = grub_macho_open (args[0]);
+  if (! macho)
+    return grub_errno;
+  if (! grub_macho_contains_macho32 (macho))
+    {
+      grub_macho_close (macho);
+      return grub_error (GRUB_ERR_BAD_OS,
+			 "Kernel doesn't contain suitable architecture");
+    }
+
+  err = grub_macho32_size (macho, &startcode, &endcode, GRUB_MACHO_NOBSS);
+  if (err)
+    {
+      grub_macho_close (macho);
+      grub_xnu_unload ();
+      return err;
+    }
+
+  grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
+		(unsigned long) endcode, (unsigned long) startcode);
+
+  loadaddr = grub_xnu_heap_malloc (endcode - startcode);
+  grub_xnu_heap_will_be_at = startcode;
+
+  if (! loadaddr)
+    {
+      grub_macho_close (macho);
+      grub_xnu_unload ();
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			 "not enough memory to load kernel");
+    }
+
+  /* Load kernel. */
+  err = grub_macho32_load (macho, loadaddr - startcode, GRUB_MACHO_NOBSS);
+  if (err)
+    {
+      grub_macho_close (macho);
+      grub_xnu_unload ();
+      return err;
+    }
+
+  grub_xnu_entry_point = grub_macho32_get_entry_point (macho);
+  if (! grub_xnu_entry_point)
+    {
+      grub_macho_close (macho);
+      grub_xnu_unload ();
+      return grub_error (GRUB_ERR_BAD_OS, "couldn't find entry point");
+    }
+
+  grub_macho_close (macho);
+
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    {
+      grub_xnu_unload ();
+      return err;
+    }
+
+  /* Copy parameters to kernel command line. */
+  ptr = grub_xnu_cmdline;
+  for (i = 1; i < argc; i++)
+    {
+      if (ptr + grub_strlen (args[i]) + 1
+	  >= grub_xnu_cmdline + sizeof (grub_xnu_cmdline))
+	break;
+      grub_memcpy (ptr, args[i], grub_strlen (args[i]));
+      ptr += grub_strlen (args[i]);
+      *ptr = ' ';
+      ptr++;
+    }
+
+  /* Replace last space by '\0'. */
+  if (ptr != grub_xnu_cmdline)
+    *(ptr - 1) = 0;
+
+  err = grub_cpu_xnu_fill_devicetree ();
+  if (err)
+    return err;
+
+  grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0);
+
+  grub_xnu_lock ();
+  return 0;
+}
+
+/* Register a memory in a memory map under name PREFIXSUFFIX
+   and increment SUFFIX. */
+static grub_err_t
+grub_xnu_register_memory (char *prefix, int *suffix,
+			  void *addr, grub_size_t size)
+{
+  struct grub_xnu_devtree_key *chosen;
+  struct grub_xnu_devtree_key *memorymap;
+  struct grub_xnu_devtree_key *driverkey;
+  struct grub_xnu_extdesc *extdesc;
+
+  if (! grub_xnu_heap_size)
+    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
+
+  chosen = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
+  if (! chosen)
+    return grub_errno;
+  memorymap = grub_xnu_create_key (&(chosen->first_child), "memory-map");
+  if (! memorymap)
+    return grub_errno;
+
+  driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey));
+  if (! driverkey)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register memory");
+  if (suffix)
+    {
+      driverkey->name = grub_malloc (grub_strlen (prefix) + 10);
+      if (!driverkey->name)
+	return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register memory");
+      grub_sprintf (driverkey->name, "%s%d", prefix, (*suffix)++);
+    }
+  else
+    driverkey->name = grub_strdup (prefix);
+  if (! driverkey->name)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register extension");
+  driverkey->datasize = sizeof (*extdesc);
+  driverkey->next = memorymap->first_child;
+  memorymap->first_child = driverkey;
+  driverkey->data = extdesc
+    = (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
+  if (! driverkey->data)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register extension");
+  extdesc->addr = grub_xnu_heap_will_be_at +
+    ((grub_uint8_t *) addr - (grub_uint8_t *) grub_xnu_heap_start);
+  extdesc->size = (grub_uint32_t) size;
+  return GRUB_ERR_NONE;
+}
+
+/* Load .kext. */
+static grub_err_t
+grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
+{
+  grub_macho_t macho;
+  grub_err_t err;
+  grub_file_t infoplist;
+  struct grub_xnu_extheader *exthead;
+  int neededspace = sizeof (*exthead);
+  char *buf;
+  grub_size_t infoplistsize = 0, machosize = 0;
+
+  if (! grub_xnu_heap_size)
+    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
+
+  /* Compute the needed space. */
+  if (binaryfile)
+    {
+      macho = grub_macho_file (binaryfile);
+      if (! macho || ! grub_macho_contains_macho32 (macho))
+	{
+	  if (macho)
+	    grub_macho_close (macho);
+	  return grub_error (GRUB_ERR_BAD_OS,
+			     "Extension doesn't contain suitable architecture");
+	}
+      machosize = grub_macho32_filesize (macho);
+      neededspace += machosize;
+    }
+  else
+    macho = 0;
+
+  if (infoplistname)
+    infoplist = grub_gzfile_open (infoplistname, 1);
+  else
+    infoplist = 0;
+  grub_errno = GRUB_ERR_NONE;
+  if (infoplist)
+    {
+      infoplistsize = grub_file_size (infoplist);
+      neededspace += infoplistsize + 1;
+    }
+  else
+    infoplistsize = 0;
+
+  /* Allocate the space. */
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    return err;
+  buf = grub_xnu_heap_malloc (neededspace);
+
+  exthead = (struct grub_xnu_extheader *) buf;
+  grub_memset (exthead, 0, sizeof (*exthead));
+  buf += sizeof (*exthead);
+
+  /* Load the binary. */
+  if (macho)
+    {
+      exthead->binaryaddr = (buf - grub_xnu_heap_start)
+	+ grub_xnu_heap_will_be_at;
+      exthead->binarysize = machosize;
+      if ((err = grub_macho32_readfile (macho, buf)))
+	{
+	  grub_macho_close (macho);
+	  return err;
+	}
+      grub_macho_close (macho);
+      buf += machosize;
+    }
+  grub_errno = GRUB_ERR_NONE;
+
+  /* Load the plist. */
+  if (infoplist)
+    {
+      exthead->infoplistaddr = (buf - grub_xnu_heap_start)
+	+ grub_xnu_heap_will_be_at;
+      exthead->infoplistsize = infoplistsize + 1;
+      if (grub_file_read (infoplist, buf, infoplistsize)
+	  != (grub_ssize_t) (infoplistsize))
+	{
+	  grub_file_close (infoplist);
+	  grub_error_push ();
+	  return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s: ",
+			     infoplistname);
+	}
+      grub_file_close (infoplist);
+      buf[infoplistsize] = 0;
+    }
+  grub_errno = GRUB_ERR_NONE;
+
+  /* Announce to kernel */
+  return grub_xnu_register_memory ("Driver-", &driversnum, exthead,
+				   neededspace);
+}
+
+/* Load mkext. */
+static grub_err_t
+grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)),
+		    int argc, char *args[])
+{
+  grub_file_t file;
+  void *loadto;
+  grub_err_t err;
+  grub_off_t readoff = 0;
+  grub_ssize_t readlen = -1;
+  struct grub_macho_fat_header head;
+  struct grub_macho_fat_arch *archs;
+  int narchs, i;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  if (! grub_xnu_heap_size)
+    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
+
+  file = grub_gzfile_open (args[0], 1);
+  if (! file)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+		       "Couldn't load driver package");
+
+  /* Sometimes caches are fat binary. Errgh. */
+  if (grub_file_read (file, &head, sizeof (head))
+      != (grub_ssize_t) (sizeof (head)))
+    {
+      /* I don't know the internal structure of package but
+	 can hardly imagine a valid package shorter than 20 bytes. */
+      grub_file_close (file);
+      grub_error_push ();
+      return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", args[0]);
+    }
+
+  /* Find the corresponding architecture. */
+  if (grub_be_to_cpu32 (head.magic) == GRUB_MACHO_FAT_MAGIC)
+    {
+      narchs = grub_be_to_cpu32 (head.nfat_arch);
+      archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs);
+      if (! archs)
+	{
+	  grub_file_close (file);
+	  grub_error_push ();
+	  return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			     "Couldn't read file %s", args[0]);
+
+	}
+      if (grub_file_read (file, archs,
+			  sizeof (struct grub_macho_fat_arch) * narchs)
+	  != (grub_ssize_t) sizeof(struct grub_macho_fat_arch) * narchs)
+	{
+	  grub_free (archs);
+	  grub_error_push ();
+	  return grub_error (GRUB_ERR_READ_ERROR, "Cannot read fat header.");
+	}
+      for (i = 0; i < narchs; i++)
+	{
+	  if (GRUB_MACHO_CPUTYPE_IS_HOST32
+	      (grub_be_to_cpu32 (archs[i].cputype)))
+	    {
+	      readoff = grub_be_to_cpu32 (archs[i].offset);
+	      readlen = grub_be_to_cpu32 (archs[i].size);
+	    }
+	}
+      grub_free (archs);
+    }
+  else
+    {
+      /* It's a flat file. Some sane people still exist. */
+      readoff = 0;
+      readlen = grub_file_size (file);
+    }
+
+  if (readlen == -1)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_BAD_OS, "no suitable architecture is found");
+    }
+
+  /* Allocate space. */
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    {
+      grub_file_close (file);
+      return err;
+    }
+
+  loadto = grub_xnu_heap_malloc (readlen);
+  if (! loadto)
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+  /* Read the file. */
+  grub_file_seek (file, readoff);
+  if (grub_file_read (file, loadto, readlen) != (grub_ssize_t) (readlen))
+    {
+      grub_file_close (file);
+      grub_error_push ();
+      return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", args[0]);
+    }
+  grub_file_close (file);
+
+  /* Pass it to kernel. */
+  return grub_xnu_register_memory ("DriversPackage-", &driverspackagenum,
+				   loadto, readlen);
+}
+
+static grub_err_t
+grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)),
+		      int argc, char *args[])
+{
+  grub_file_t file;
+  void *loadto;
+  grub_err_t err;
+  grub_size_t size;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  if (! grub_xnu_heap_size)
+    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
+
+  file = grub_gzfile_open (args[0], 1);
+  if (! file)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+		       "Couldn't load ramdisk");
+
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    return err;
+
+  size = grub_file_size (file);
+
+  loadto = grub_xnu_heap_malloc (size);
+  if (! loadto)
+    return grub_errno;
+  if (grub_file_read (file, loadto, size)
+      != (grub_ssize_t) (size))
+    {
+      grub_file_close (file);
+      grub_error_push ();
+      return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", args[0]);
+    }
+  return grub_xnu_register_memory ("RAMDisk", 0, loadto, size);
+}
+
+/* Parse a devtree file. It uses the following format:
+   valuename:valuedata;
+   keyname{
+     contents
+   }
+   keyname, valuename and valuedata are in hex.
+ */
+static char *
+grub_xnu_parse_devtree (struct grub_xnu_devtree_key **parent,
+			char *start, char *end)
+{
+  char *ptr, *ptr2;
+  char *name, *data;
+  int namelen, datalen, i;
+  for (ptr = start; ptr && ptr < end; )
+    {
+      if (grub_isspace (*ptr))
+	{
+	  ptr++;
+	  continue;
+	}
+      if (*ptr == '}')
+	return ptr + 1;
+      namelen = 0;
+
+      /* Parse the name. */
+      for (ptr2 = ptr; ptr2 < end && (grub_isspace (*ptr2)
+				      || (*ptr2 >= '0' && *ptr2 <= '9')
+				      || (*ptr2 >= 'a' && *ptr2 <= 'f')
+				      || (*ptr2 >= 'A' && *ptr2 <= 'F'));
+	   ptr2++)
+	if (! grub_isspace (*ptr2))
+	  namelen++;
+      if (ptr2 == end)
+	return 0;
+      namelen /= 2;
+      name = grub_malloc (namelen + 1);
+      if (!name)
+	return 0;
+      for (i = 0; i < 2 * namelen; i++)
+	{
+	  int hex = 0;
+	  while (grub_isspace (*ptr))
+	    ptr++;
+	  if (*ptr >= '0' && *ptr <= '9')
+	    hex = *ptr - '0';
+	  if (*ptr >= 'a' && *ptr <= 'f')
+	    hex = *ptr - 'a' + 10;
+	  if (*ptr >= 'A' && *ptr <= 'F')
+	    hex = *ptr - 'A' + 10;
+
+	  if (i % 2 == 0)
+	    name[i / 2] = hex << 4;
+	  else
+	    name[i / 2] |= hex;
+	  ptr++;
+	}
+      name [namelen] = 0;
+      while (grub_isspace (*ptr))
+	ptr++;
+
+      /* If it describes a key recursively invoke the function. */
+      if (*ptr == '{')
+	{
+	  struct grub_xnu_devtree_key *newkey
+	    = grub_xnu_create_key (parent, name);
+	  grub_free (name);
+	  if (! newkey)
+	    return 0;
+	  ptr = grub_xnu_parse_devtree (&(newkey->first_child), ptr + 1, end);
+	  continue;
+	}
+
+      /* Parse the data. */
+      if (*ptr != ':')
+	return 0;
+      ptr++;
+      datalen = 0;
+      for (ptr2 = ptr; ptr2 < end && (grub_isspace (*ptr2)
+				      || (*ptr2 >= '0' && *ptr2 <= '9')
+				      || (*ptr2 >= 'a' && *ptr2 <= 'f')
+				      || (*ptr2 >= 'A' && *ptr2 <= 'F'));
+	   ptr2++)
+	if (! grub_isspace (*ptr2))
+	  datalen++;
+      if (ptr2 == end)
+	return 0;
+      datalen /= 2;
+      data = grub_malloc (datalen);
+      if (! data)
+	return 0;
+      for (i = 0; i < 2 * datalen; i++)
+	{
+	  int hex = 0;
+	  while (grub_isspace (*ptr))
+	    ptr++;
+	  if (*ptr >= '0' && *ptr <= '9')
+	    hex = *ptr - '0';
+	  if (*ptr >= 'a' && *ptr <= 'f')
+	    hex = *ptr - 'a' + 10;
+	  if (*ptr >= 'A' && *ptr <= 'F')
+	    hex = *ptr - 'A' + 10;
+
+	  if (i % 2 == 0)
+	    data[i / 2] = hex << 4;
+	  else
+	    data[i / 2] |= hex;
+	  ptr++;
+	}
+      while (ptr < end && grub_isspace (*ptr))
+	ptr++;
+      {
+	struct grub_xnu_devtree_key *newkey
+	  = grub_xnu_create_value (parent, name);
+	grub_free (name);
+	if (! newkey)
+	  return 0;
+	newkey->datasize = datalen;
+	newkey->data = data;
+      }
+      if (*ptr != ';')
+	return 0;
+      ptr++;
+    }
+  if (ptr >= end && *parent != grub_xnu_devtree_root)
+    return 0;
+  return ptr;
+}
+
+/* Returns true if the kext should be loaded according to plist
+   and osbundlereq. Also fill BINNAME. */
+static int
+grub_xnu_check_os_bundle_required (char *plistname, char *osbundlereq,
+				   char **binname)
+{
+  grub_file_t file;
+  char *buf = 0, *tagstart = 0, *ptr1 = 0, *keyptr = 0;
+  char *stringptr = 0, *ptr2 = 0;
+  grub_size_t size;
+  int depth = 0;
+  int ret;
+  int osbundlekeyfound = 0, binnamekeyfound = 0;
+  if (binname)
+    *binname = 0;
+
+  file = grub_gzfile_open (plistname, 1);
+  if (! file)
+    {
+      grub_file_close (file);
+      grub_error_push ();
+      grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", plistname);
+      return 0;
+    }
+
+  size = grub_file_size (file);
+  buf = grub_malloc (size);
+  if (! buf)
+    {
+      grub_file_close (file);
+      grub_error_push ();
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "Couldn't read file %s", plistname);
+      return 0;
+    }
+  if (grub_file_read (file, buf, size) != (grub_ssize_t) (size))
+    {
+      grub_file_close (file);
+      grub_error_push ();
+      grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", plistname);
+      return 0;
+    }
+  grub_file_close (file);
+
+  /* Set the return value for the case when no OSBundleRequired tag is found. */
+  if (osbundlereq)
+    ret = grub_strword (osbundlereq, "all") || grub_strword (osbundlereq, "-");
+  else
+    ret = 1;
+
+  /* Parse plist. It's quite dirty and inextensible but does its job. */
+  for (ptr1 = buf; ptr1 < buf + size; ptr1++)
+    switch (*ptr1)
+      {
+      case '<':
+	tagstart = ptr1;
+	*ptr1 = 0;
+	if (keyptr && depth == 4
+	    && grub_strcmp (keyptr, "OSBundleRequired") == 0)
+	  osbundlekeyfound = 1;
+	if (keyptr && depth == 4 &&
+	    grub_strcmp (keyptr, "CFBundleExecutable") == 0)
+	  binnamekeyfound = 1;
+	if (stringptr && osbundlekeyfound && osbundlereq && depth == 4)
+	  {
+	    for (ptr2 = stringptr; *ptr2; ptr2++)
+	      *ptr2 = grub_tolower (*ptr2);
+	    ret = grub_strword (osbundlereq, stringptr)
+	      || grub_strword (osbundlereq, "all");
+	  }
+	if (stringptr && binnamekeyfound && binname && depth == 4)
+	  {
+	    if (*binname)
+	      grub_free (*binname);
+	    *binname = grub_strdup (stringptr);
+	  }
+
+	*ptr1 = '<';
+	keyptr = 0;
+	stringptr = 0;
+	break;
+      case '>':
+	if (! tagstart)
+	  {
+	    grub_free (buf);
+	    grub_error (GRUB_ERR_BAD_OS, "can't parse %s", plistname);
+	    return 0;
+	  }
+	*ptr1 = 0;
+	if (tagstart[1] == '?' || ptr1[-1] == '/')
+	  {
+	    osbundlekeyfound = 0;
+	    *ptr1 = '>';
+	    break;
+	  }
+	if (depth == 3 && grub_strcmp (tagstart + 1, "key") == 0)
+	  keyptr = ptr1 + 1;
+	if (depth == 3 && grub_strcmp (tagstart + 1, "string") == 0)
+	  stringptr = ptr1 + 1;
+	else if (grub_strcmp (tagstart + 1, "/key") != 0)
+	  {
+	    osbundlekeyfound = 0;
+	    binnamekeyfound = 0;
+	  }
+	*ptr1 = '>';
+
+	if (tagstart[1] == '/')
+	  depth--;
+	else
+	  depth++;
+	break;
+      }
+  grub_free (buf);
+
+  return ret;
+}
+
+/* Load all loadable kexts placed under DIRNAME and matching OSBUNDLEREQUIRED */
+grub_err_t
+grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired,
+			     int maxrecursion)
+{
+  grub_device_t dev;
+  char *device_name;
+  grub_fs_t fs;
+  const char *path;
+
+  auto int load_hook (const char *filename,
+		      const struct grub_dirhook_info *info);
+  int load_hook (const char *filename, const struct grub_dirhook_info *info)
+  {
+    char *newdirname;
+    if (! info->dir)
+      return 0;
+    if (filename[0] == '.')
+      return 0;
+
+    if (grub_strlen (filename) < 5 ||
+	grub_memcmp (filename + grub_strlen (filename) - 5, ".kext", 5) != 0)
+      return 0;
+
+    newdirname
+      = grub_malloc (grub_strlen (dirname) + grub_strlen (filename) + 2);
+
+    /* It's a .kext. Try to load it. */
+    if (newdirname)
+      {
+	grub_strcpy (newdirname, dirname);
+	newdirname[grub_strlen (newdirname) + 1] = 0;
+	newdirname[grub_strlen (newdirname)] = '/';
+	grub_strcpy (newdirname + grub_strlen (newdirname), filename);
+	grub_xnu_load_kext_from_dir (newdirname, osbundlerequired,
+				     maxrecursion);
+	if (grub_errno == GRUB_ERR_BAD_OS)
+	  grub_errno = GRUB_ERR_NONE;
+	grub_free (newdirname);
+      }
+    return 0;
+  }
+
+  if (! grub_xnu_heap_size)
+    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
+
+  device_name = grub_file_get_device_name (dirname);
+  dev = grub_device_open (device_name);
+  if (dev)
+    {
+      fs = grub_fs_probe (dev);
+      path = grub_strchr (dirname, ')');
+      if (! path)
+	path = dirname;
+      else
+	path++;
+
+      if (fs)
+	(fs->dir) (dev, path, load_hook);
+      grub_device_close (dev);
+    }
+  grub_free (device_name);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Load extension DIRNAME. (extensions are directories in xnu) */
+grub_err_t
+grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
+			     int maxrecursion)
+{
+  grub_device_t dev;
+  char *plistname = 0;
+  char *newdirname;
+  char *newpath;
+  char *device_name;
+  grub_fs_t fs;
+  const char *path;
+  char *binsuffix;
+  int usemacos = 0;
+  grub_file_t binfile;
+
+  auto int load_hook (const char *filename,
+		      const struct grub_dirhook_info *info);
+
+  int load_hook (const char *filename, const struct grub_dirhook_info *info)
+  {
+    if (grub_strlen (filename) > 15)
+      return 0;
+    grub_strcpy (newdirname + grub_strlen (dirname) + 1, filename);
+
+    /* If the kext contains directory "Contents" all real stuff is in
+       this directory. */
+    if (info->dir && grub_strcasecmp (filename, "Contents") == 0)
+      grub_xnu_load_kext_from_dir (newdirname, osbundlerequired,
+				   maxrecursion - 1);
+
+    /* Directory "Plugins" contains nested kexts. */
+    if (info->dir && grub_strcasecmp (filename, "Plugins") == 0)
+      grub_xnu_scan_dir_for_kexts (newdirname, osbundlerequired,
+				   maxrecursion - 1);
+
+    /* Directory "MacOS" contains executable, otherwise executable is
+       on the top. */
+    if (info->dir && grub_strcasecmp (filename, "MacOS") == 0)
+      usemacos = 1;
+
+    /* Info.plist is the file which governs our future actions. */
+    if (! info->dir && grub_strcasecmp (filename, "Info.plist") == 0
+	&& ! plistname)
+      plistname = grub_strdup (newdirname);
+    return 0;
+  }
+
+  newdirname = grub_malloc (grub_strlen (dirname) + 20);
+  if (! newdirname)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate buffer");
+  grub_strcpy (newdirname, dirname);
+  newdirname[grub_strlen (dirname)] = '/';
+  newdirname[grub_strlen (dirname) + 1] = 0;
+  device_name = grub_file_get_device_name (dirname);
+  dev = grub_device_open (device_name);
+  if (dev)
+    {
+      fs = grub_fs_probe (dev);
+      path = grub_strchr (dirname, ')');
+      if (! path)
+	path = dirname;
+      else
+	path++;
+
+      newpath = grub_strchr (newdirname, ')');
+      if (! newpath)
+	newpath = newdirname;
+      else
+	newpath++;
+
+      /* Look at the directory. */
+      if (fs)
+	(fs->dir) (dev, path, load_hook);
+
+      if (plistname && grub_xnu_check_os_bundle_required
+	  (plistname, osbundlerequired, &binsuffix))
+	{
+	  if (binsuffix)
+	    {
+	      /* Open the binary. */
+	      char *binname = grub_malloc (grub_strlen (dirname)
+					   + grub_strlen (binsuffix)
+					   + sizeof ("/MacOS/"));
+	      grub_strcpy (binname, dirname);
+	      if (usemacos)
+		grub_strcpy (binname + grub_strlen (binname), "/MacOS/");
+	      else
+		grub_strcpy (binname + grub_strlen (binname), "/");
+	      grub_strcpy (binname + grub_strlen (binname), binsuffix);
+	      grub_dprintf ("xnu", "%s:%s\n", plistname, binname);
+	      binfile = grub_gzfile_open (binname, 1);
+	      if (! binfile)
+		grub_errno = GRUB_ERR_NONE;
+
+	      /* Load the extension. */
+	      grub_xnu_load_driver (plistname, binfile);
+	      grub_free (binname);
+	      grub_free (binsuffix);
+	    }
+	  else
+	    {
+	      grub_dprintf ("xnu", "%s:0\n", plistname);
+	      grub_xnu_load_driver (plistname, 0);
+	    }
+	}
+      grub_free (plistname);
+      grub_device_close (dev);
+    }
+  grub_free (device_name);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Load devtree file. */
+static grub_err_t
+grub_cmd_xnu_devtree (grub_command_t cmd __attribute__ ((unused)),
+		      int argc, char *args[])
+{
+  grub_file_t file;
+  char *data, *endret;
+  grub_size_t datalen;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Filename required");
+
+  if (! grub_xnu_heap_size)
+    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
+
+  /* Load the file. */
+  file = grub_gzfile_open (args[0], 1);
+  if (! file)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load device tree");
+  datalen = grub_file_size (file);
+  data = grub_malloc (datalen + 1);
+  if (! data)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			 "Could load device tree into memory");
+    }
+  if (grub_file_read (file, data, datalen) != (grub_ssize_t) datalen)
+    {
+      grub_file_close (file);
+      grub_free (data);
+      grub_error_push ();
+      return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", args[0]);
+    }
+  grub_file_close (file);
+  data[datalen] = 0;
+
+  /* Parse the file. */
+  endret = grub_xnu_parse_devtree (&grub_xnu_devtree_root,
+				   data, data + datalen);
+  grub_free (data);
+
+  if (! endret)
+    return grub_error (GRUB_ERR_BAD_OS, "Couldn't parse devtree");
+
+  return GRUB_ERR_NONE;
+}
+
+static int locked=0;
+static grub_dl_t my_mod;
+
+/* Load the kext. */
+static grub_err_t
+grub_cmd_xnu_kext (grub_command_t cmd __attribute__ ((unused)),
+		   int argc, char *args[])
+{
+  grub_file_t binfile = 0;
+  if (argc == 2)
+    {
+      /* User explicitly specified plist and binary. */
+      if (grub_strcmp (args[1], "-") != 0)
+	{
+	  binfile = grub_gzfile_open (args[1], 1);
+	  if (! binfile)
+	    {
+	      grub_error (GRUB_ERR_BAD_OS, "can't open file");
+	      return GRUB_ERR_NONE;
+	    }
+	}
+      return grub_xnu_load_driver (grub_strcmp (args[0], "-") ? args[0] : 0,
+				   binfile);
+    }
+
+  /* load kext normally. */
+  if (argc == 1)
+    return grub_xnu_load_kext_from_dir (args[0], 0, 10);
+
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+}
+
+/* Load a directory containing kexts. */
+static grub_err_t
+grub_cmd_xnu_kextdir (grub_command_t cmd __attribute__ ((unused)),
+		      int argc, char *args[])
+{
+  if (argc != 1 && argc != 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "directory name required");
+
+  if (argc == 1)
+    return grub_xnu_scan_dir_for_kexts (args[0],
+					"console,root,local-root,network-root",
+					10);
+  else
+    {
+      char *osbundlerequired = grub_strdup (args[1]), *ptr;
+      grub_err_t err;
+      if (! osbundlerequired)
+	return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			   "couldn't allocate string temporary space");
+      for (ptr = osbundlerequired; *ptr; ptr++)
+	*ptr = grub_tolower (*ptr);
+      err = grub_xnu_scan_dir_for_kexts (args[0], osbundlerequired, 10);
+      grub_free (osbundlerequired);
+      return err;
+    }
+}
+
+struct grub_video_bitmap *grub_xnu_bitmap = 0;
+
+static grub_err_t
+grub_cmd_xnu_splash (grub_command_t cmd __attribute__ ((unused)),
+		     int argc, char *args[])
+{
+  grub_err_t err;
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  err = grub_video_bitmap_load (&grub_xnu_bitmap, args[0]);
+  if (err)
+    grub_xnu_bitmap = 0;
+  return err;
+}
+
+
+#ifndef GRUB_UTIL
+static grub_err_t
+grub_cmd_xnu_resume (grub_command_t cmd __attribute__ ((unused)),
+		     int argc, char *args[])
+{
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  return grub_xnu_resume (args[0]);
+}
+#endif
+
+void
+grub_xnu_lock ()
+{
+  if (!locked)
+    grub_dl_ref (my_mod);
+  locked = 1;
+}
+
+void
+grub_xnu_unlock ()
+{
+  if (locked)
+    grub_dl_unref (my_mod);
+  locked = 0;
+}
+
+static grub_command_t cmd_kernel, cmd_mkext, cmd_kext, cmd_kextdir,
+  cmd_ramdisk, cmd_devtree, cmd_resume, cmd_splash;
+
+GRUB_MOD_INIT(xnu)
+{
+  cmd_kernel = grub_register_command ("xnu_kernel", grub_cmd_xnu_kernel, 0,
+				      "load a xnu kernel");
+  cmd_mkext = grub_register_command ("xnu_mkext", grub_cmd_xnu_mkext, 0,
+				     "Load XNU extension package.");
+  cmd_kext = grub_register_command ("xnu_kext", grub_cmd_xnu_kext, 0,
+				    "Load XNU extension.");
+  cmd_kextdir = grub_register_command ("xnu_kextdir", grub_cmd_xnu_kextdir,
+				       "xnu_kextdir DIRECTORY [OSBundleRequired]",
+				       "Load XNU extension directory");
+  cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0,
+				       "Load XNU ramdisk. "
+				       "It will be seen as md0");
+  cmd_devtree = grub_register_command ("xnu_devtree", grub_cmd_xnu_devtree, 0,
+				       "Load XNU devtree");
+  cmd_splash = grub_register_command ("xnu_splash", grub_cmd_xnu_splash, 0,
+				      "Load a splash image for XNU");
+
+#ifndef GRUB_UTIL
+  cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume,
+				      0, "Load XNU hibernate image.");
+#endif
+  my_mod=mod;
+}
+
+GRUB_MOD_FINI(xnu)
+{
+#ifndef GRUB_UTIL
+  grub_unregister_command (cmd_resume);
+#endif
+  grub_unregister_command (cmd_mkext);
+  grub_unregister_command (cmd_kext);
+  grub_unregister_command (cmd_kextdir);
+  grub_unregister_command (cmd_devtree);
+  grub_unregister_command (cmd_ramdisk);
+  grub_unregister_command (cmd_kernel);
+  grub_unregister_command (cmd_splash);
+}
diff --git a/loader/xnu_resume.c b/loader/xnu_resume.c
new file mode 100644
index 0000000..77f6887
--- /dev/null
+++ b/loader/xnu_resume.c
@@ -0,0 +1,136 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/xnu.h>
+#include <grub/cpu/xnu.h>
+#include <grub/mm.h>
+#include <grub/loader.h>
+
+static void *grub_xnu_hibernate_image;
+
+static grub_err_t
+grub_xnu_resume_unload (void)
+{
+  /* Free loaded image */
+  if (grub_xnu_hibernate_image)
+    grub_free (grub_xnu_hibernate_image);
+  grub_xnu_hibernate_image = 0;
+  grub_xnu_unlock ();
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_xnu_resume (char *imagename)
+{
+  grub_file_t file;
+  grub_size_t total_header_size;
+  struct grub_xnu_hibernate_header hibhead;
+  char *buf, *codetmp;
+
+  grub_uint32_t codedest;
+  grub_uint32_t codesize;
+
+  file = grub_file_open (imagename);
+  if (! file)
+    return 0;
+
+  /* Read the header. */
+  if (grub_file_read (file, &hibhead, sizeof (hibhead))
+      !=sizeof (hibhead))
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_READ_ERROR,
+			 "cannot read the hibernate header");
+    }
+
+  /* Check the header. */
+  if (hibhead.magic != GRUB_XNU_HIBERNATE_MAGIC)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_BAD_OS,
+			 "hibernate header has incorrect magic number");
+    }
+  if (hibhead.encoffset)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_BAD_OS,
+			 "encrypted images aren't supported yet");
+    }
+
+  codedest = hibhead.launchcode_target_page;
+  codedest *= GRUB_XNU_PAGESIZE;
+  codesize = hibhead.launchcode_numpages;
+  codesize *= GRUB_XNU_PAGESIZE;
+
+  /* FIXME: check that codedest..codedest+codesize is available. */
+
+  /* Calculate total size before pages to copy. */
+  total_header_size = hibhead.extmapsize + sizeof (hibhead);
+
+  /* Unload image if any. */
+  if (grub_xnu_hibernate_image)
+    grub_free (grub_xnu_hibernate_image);
+
+  /* Try to allocate necessary space.
+     FIXME: mm isn't good enough yet to handle huge allocations.
+   */
+  grub_xnu_hibernate_image = buf = grub_malloc (hibhead.image_size);
+  if (! buf)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			 "not enough memory to load image");
+    }
+
+  /* Read image. */
+  if (grub_file_seek (file, 0) == (grub_off_t)-1
+      || grub_file_read (file, buf, hibhead.image_size)
+      != (grub_ssize_t) hibhead.image_size)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_READ_ERROR, "Cannot read resume image.");
+    }
+  grub_file_close (file);
+
+  codetmp = grub_memalign (GRUB_XNU_PAGESIZE, codesize + GRUB_XNU_PAGESIZE);
+  /* Setup variables needed by asm helper. */
+  grub_xnu_heap_will_be_at = codedest;
+  grub_xnu_heap_start = codetmp;
+  grub_xnu_heap_size = codesize;
+  grub_xnu_stack = (codedest + hibhead.stack);
+  grub_xnu_entry_point = (codedest + hibhead.entry_point);
+  grub_xnu_arg1 = (long) buf;
+
+  /* Prepare asm helper. */
+  grub_memcpy (codetmp, ((grub_uint8_t *) buf) + total_header_size, codesize);
+  grub_memcpy (codetmp + codesize, grub_xnu_launcher_start,
+	       grub_xnu_launcher_end - grub_xnu_launcher_start);
+
+  /* We're ready now. */
+  grub_loader_set ((grub_err_t (*) (void)) (codetmp + codesize),
+		   grub_xnu_resume_unload, 0);
+
+  /* Prevent module from unloading. */
+  grub_xnu_lock ();
+  return GRUB_ERR_NONE;
+}
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755
index 0000000..ef7e16f
--- /dev/null
+++ b/mkinstalldirs
@@ -0,0 +1,161 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2006-05-11.19
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+IFS=" ""	$nl"
+errstatus=0
+dirmode=
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage"
+      exit $?
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --version)
+      echo "$0 $scriptversion"
+      exit $?
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe.  If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error.  This is a problem when calling mkinstalldirs
+# from a parallel make.  We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+  '')
+    if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    else
+      # On NextStep and OpenStep, the `mkdir' command does not
+      # recognize any option.  It will interpret all options as
+      # directories to create, and then abort because `.' already
+      # exists.
+      test -d ./-p && rmdir ./-p
+      test -d ./--version && rmdir ./--version
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+       test ! -d ./--version; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    else
+      # Clean up after NextStep and OpenStep mkdir.
+      for d in ./-m ./-p ./--version "./$dirmode";
+      do
+        test -d $d && rmdir $d
+      done
+    fi
+    ;;
+esac
+
+for file
+do
+  case $file in
+    /*) pathcomp=/ ;;
+    *)  pathcomp= ;;
+  esac
+  oIFS=$IFS
+  IFS=/
+  set fnord $file
+  shift
+  IFS=$oIFS
+
+  for d
+  do
+    test "x$d" = x && continue
+
+    pathcomp=$pathcomp$d
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+	errstatus=$lasterr
+      else
+	if test ! -z "$dirmode"; then
+	  echo "chmod $dirmode $pathcomp"
+	  lasterr=
+	  chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+	  if test ! -z "$lasterr"; then
+	    errstatus=$lasterr
+	  fi
+	fi
+      fi
+    fi
+
+    pathcomp=$pathcomp/
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/mmap/efi/mmap.c b/mmap/efi/mmap.c
new file mode 100644
index 0000000..316c997
--- /dev/null
+++ b/mmap/efi/mmap.c
@@ -0,0 +1,284 @@
+/* Mmap management. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#include <grub/err.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+#define NEXT_MEMORY_DESCRIPTOR(desc, size)      \
+  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+							 grub_uint64_t,
+							 grub_uint32_t))
+{
+  grub_efi_uintn_t mmap_size = 0;
+  grub_efi_memory_descriptor_t *map_buf = 0;
+  grub_efi_uintn_t map_key = 0;
+  grub_efi_uintn_t desc_size = 0;
+  grub_efi_uint32_t desc_version = 0;
+  grub_efi_memory_descriptor_t *desc;
+
+  if (grub_efi_get_memory_map (&mmap_size, map_buf,
+			       &map_key, &desc_size,
+			       &desc_version) < 0)
+    return grub_errno;
+
+  map_buf = grub_malloc (mmap_size);
+  if (! map_buf)
+    return grub_errno;
+
+  if (grub_efi_get_memory_map (&mmap_size, map_buf,
+			       &map_key, &desc_size,
+			       &desc_version) <= 0)
+    {
+      grub_free (map_buf);
+      return grub_errno;
+    }
+
+  for (desc = map_buf;
+       desc < NEXT_MEMORY_DESCRIPTOR (map_buf, mmap_size);
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      grub_dprintf ("mmap", "EFI memory region 0x%llx-0x%llx: %d\n",
+		    (unsigned long long) desc->physical_start,
+		    (unsigned long long) desc->physical_start
+		    + desc->num_pages * 4096, desc->type);
+      switch (desc->type)
+	{
+	case GRUB_EFI_RUNTIME_SERVICES_CODE:
+	  hook (desc->physical_start, desc->num_pages * 4096,
+		GRUB_MACHINE_MEMORY_CODE);
+	  break;
+
+	default:
+	  grub_printf ("Unknown memory type %d, considering reserved\n",
+		       desc->type);
+
+	case GRUB_EFI_RESERVED_MEMORY_TYPE:
+	case GRUB_EFI_RUNTIME_SERVICES_DATA:
+	case GRUB_EFI_UNUSABLE_MEMORY:
+	case GRUB_EFI_MEMORY_MAPPED_IO:
+	case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+	case GRUB_EFI_PAL_CODE:
+	  hook (desc->physical_start, desc->num_pages * 4096,
+		GRUB_MACHINE_MEMORY_RESERVED);
+	  break;
+
+	case GRUB_EFI_LOADER_CODE:
+	case GRUB_EFI_LOADER_DATA:
+	case GRUB_EFI_BOOT_SERVICES_CODE:
+	case GRUB_EFI_BOOT_SERVICES_DATA:
+	case GRUB_EFI_CONVENTIONAL_MEMORY:
+	  hook (desc->physical_start, desc->num_pages * 4096,
+		GRUB_MACHINE_MEMORY_AVAILABLE);
+	  break;
+
+	case GRUB_EFI_ACPI_RECLAIM_MEMORY:
+	  hook (desc->physical_start, desc->num_pages * 4096,
+		GRUB_MACHINE_MEMORY_ACPI);
+	  break;
+
+	case GRUB_EFI_ACPI_MEMORY_NVS:
+	  hook (desc->physical_start, desc->num_pages * 4096,
+		GRUB_MACHINE_MEMORY_NVS);
+	  break;
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static inline grub_efi_memory_type_t
+make_efi_memtype (int type)
+{
+  switch (type)
+    {
+    case GRUB_MACHINE_MEMORY_CODE:
+      return GRUB_EFI_RUNTIME_SERVICES_CODE;
+
+      /* No way to remove a chunk of memory from EFI mmap.
+	 So mark it as unusable. */
+    case GRUB_MACHINE_MEMORY_HOLE:
+
+    default:
+
+    case GRUB_MACHINE_MEMORY_RESERVED:
+      return GRUB_EFI_UNUSABLE_MEMORY;
+
+    case GRUB_MACHINE_MEMORY_AVAILABLE:
+      return GRUB_EFI_CONVENTIONAL_MEMORY;
+
+    case GRUB_MACHINE_MEMORY_ACPI:
+      return GRUB_EFI_ACPI_RECLAIM_MEMORY;
+
+    case GRUB_MACHINE_MEMORY_NVS:
+      return GRUB_EFI_ACPI_RECLAIM_MEMORY;
+
+    }
+
+}
+
+struct overlay
+{
+  struct overlay *next;
+  grub_efi_physical_address_t address;
+  grub_efi_uintn_t pages;
+  int handle;
+};
+
+static struct overlay *overlays = 0;
+static int curhandle = 1;
+
+int
+grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type)
+{
+  grub_uint64_t end = start + size;
+  grub_efi_physical_address_t address;
+  grub_efi_boot_services_t *b;
+  grub_efi_uintn_t pages;
+  grub_efi_status_t status;
+  struct overlay *curover;
+
+  curover = (struct overlay *) grub_malloc (sizeof (struct overlay));
+  if (! curover)
+    return 0;
+
+  b = grub_efi_system_table->boot_services;
+  address = start & (~0x3ffULL);
+  pages = (end - address  + 0x3ff) >> 12;
+  status = efi_call_2 (b->free_pages, address, pages);
+  if (status != GRUB_EFI_SUCCESS && status != GRUB_EFI_NOT_FOUND)
+    {
+      grub_free (curover);
+      return 0;
+    }
+  status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ADDRESS,
+		       make_efi_memtype (type), pages, &address);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      grub_free (curover);
+      return 0;
+    }
+  curover->next = overlays;
+  curover->handle = curhandle++;
+  curover->address = address;
+  curover->pages = pages;
+  overlays = curover;
+
+  return curover->handle;
+}
+
+grub_err_t
+grub_mmap_unregister (int handle)
+{
+  struct overlay *curover, *prevover;
+  grub_efi_boot_services_t *b;
+  grub_efi_status_t status;
+
+  b = grub_efi_system_table->boot_services;
+
+
+  for (curover = overlays, prevover = 0; curover;
+       prevover = curover, curover = curover->next)
+    {
+      if (curover->handle == handle)
+	{
+	  status = efi_call_2 (b->free_pages, curover->address, curover->pages);
+	  if (prevover != 0)
+	    prevover->next = curover->next;
+	  else
+	    overlays = curover->next;
+	  grub_free (curover);
+	  return GRUB_ERR_NONE;
+	}
+    }
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "handle %d not found", handle);
+}
+
+/* Result is always page-aligned. */
+void *
+grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)),
+			       grub_uint64_t size,
+			       int *handle, int type,
+			       int flags __attribute__ ((unused)))
+{
+  grub_efi_physical_address_t address;
+  grub_efi_boot_services_t *b;
+  grub_efi_uintn_t pages;
+  grub_efi_status_t status;
+  struct overlay *curover;
+  grub_efi_allocate_type_t atype;
+
+  curover = (struct overlay *) grub_malloc (sizeof (struct overlay));
+  if (! curover)
+    return 0;
+
+  b = grub_efi_system_table->boot_services;
+
+  address = 0xffffffff;
+
+#if GRUB_TARGET_SIZEOF_VOID_P < 8
+  /* Limit the memory access to less than 4GB for 32-bit platforms.  */
+  atype = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
+#else
+  atype = GRUB_EFI_ALLOCATE_ANY_PAGES;
+#endif
+
+  pages = (size + 0x3ff) >> 12;
+  status = efi_call_4 (b->allocate_pages, atype,
+		       make_efi_memtype (type), pages, &address);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      grub_free (curover);
+      return 0;
+    }
+
+  if (address == 0)
+    {
+      /* Uggh, the address 0 was allocated... This is too annoying,
+	 so reallocate another one.  */
+      address = 0xffffffff;
+      status = efi_call_4 (b->allocate_pages, atype,
+			   make_efi_memtype (type), pages, &address);
+      grub_efi_free_pages (0, pages);
+      if (status != GRUB_EFI_SUCCESS)
+	return 0;
+    }
+
+  curover->next = overlays;
+  curover->handle = curhandle++;
+  curover->address = address;
+  curover->pages = pages;
+  overlays = curover;
+  *handle = curover->handle;
+
+  return UINT_TO_PTR (curover->address);
+}
+
+void
+grub_mmap_free_and_unregister (int handle)
+{
+  grub_mmap_unregister (handle);
+}
diff --git a/mmap/i386/mmap.c b/mmap/i386/mmap.c
new file mode 100644
index 0000000..f6e1612
--- /dev/null
+++ b/mmap/i386/mmap.c
@@ -0,0 +1,98 @@
+/* Mmap management. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+
+void *
+grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size,
+			       int *handle, int type, int flags)
+{
+  grub_uint64_t highestlow = 0;
+
+  auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
+				       grub_uint32_t);
+  int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t rangesize,
+				  grub_uint32_t memtype)
+  {
+    grub_uint64_t end = start + rangesize;
+    if (memtype != GRUB_MACHINE_MEMORY_AVAILABLE)
+      return 0;
+    if (end > 0x100000)
+      end = 0x100000;
+    if (end > start + size
+	&& highestlow < ((end - size) - ((end - size) & (align - 1))))
+      highestlow = (end - size)  - ((end - size) & (align - 1));
+    return 0;
+  }
+
+  void *ret;
+  if (flags & GRUB_MMAP_MALLOC_LOW)
+    {
+      /* FIXME: use low-memory mm allocation once it's available. */
+      grub_mmap_iterate (find_hook);
+      ret = UINT_TO_PTR (highestlow);
+    }
+  else
+    ret = grub_memalign (align, size);
+
+  if (! ret)
+    {
+      *handle = 0;
+      return 0;
+    }
+
+  *handle = grub_mmap_register (PTR_TO_UINT64 (ret), size, type);
+  if (! *handle)
+    {
+      grub_free (ret);
+      return 0;
+    }
+
+  return ret;
+}
+
+void
+grub_mmap_free_and_unregister (int handle)
+{
+  struct grub_mmap_region *cur;
+  grub_uint64_t addr;
+
+  for (cur = grub_mmap_overlays; cur; cur = cur->next)
+    if (cur->handle == handle)
+      break;
+
+  if (! cur)
+    return;
+
+  addr = cur->start;
+
+  grub_mmap_unregister (handle);
+
+  if (addr >= 0x100000)
+    grub_free (UINT_TO_PTR (addr));
+}
+
+#endif
diff --git a/mmap/i386/pc/mmap.c b/mmap/i386/pc/mmap.c
new file mode 100644
index 0000000..0e2dfe6
--- /dev/null
+++ b/mmap/i386/pc/mmap.c
@@ -0,0 +1,216 @@
+/* Mmap management. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/loader.h>
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+static void *hooktarget = 0;
+
+extern grub_uint8_t grub_machine_mmaphook_start;
+extern grub_uint8_t grub_machine_mmaphook_end;
+extern grub_uint8_t grub_machine_mmaphook_int12;
+extern grub_uint8_t grub_machine_mmaphook_int15;
+
+static grub_uint16_t grub_machine_mmaphook_int12offset = 0;
+static grub_uint16_t grub_machine_mmaphook_int12segment = 0;
+extern grub_uint16_t grub_machine_mmaphook_int15offset;
+extern grub_uint16_t grub_machine_mmaphook_int15segment;
+
+extern grub_uint16_t grub_machine_mmaphook_mmap_num;
+extern grub_uint16_t grub_machine_mmaphook_kblow;
+extern grub_uint16_t grub_machine_mmaphook_kbin16mb;
+extern grub_uint16_t grub_machine_mmaphook_64kbin4gb;
+
+struct grub_e820_mmap_entry
+{
+  grub_uint64_t addr;
+  grub_uint64_t len;
+  grub_uint32_t type;
+} __attribute__((packed));
+
+
+static grub_err_t
+preboot (int noreturn __attribute__ ((unused)))
+{
+  struct grub_e820_mmap_entry *hookmmap, *hookmmapcur;
+  auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
+				       grub_uint32_t);
+  int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size,
+				  grub_uint32_t type)
+  {
+    grub_dprintf ("mmap", "mmap chunk %llx-%llx:%x\n", addr, addr + size, type);
+    hookmmapcur->addr = addr;
+    hookmmapcur->len = size;
+    hookmmapcur->type = type;
+    hookmmapcur++;
+    return 0;
+  }
+
+  if (! hooktarget)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		       "no space is allocated for memory hook");
+
+  grub_dprintf ("mmap", "installing preboot handlers\n");
+
+  hookmmapcur = hookmmap = (struct grub_e820_mmap_entry *)
+    ((grub_uint8_t *) hooktarget + (&grub_machine_mmaphook_end
+				    - &grub_machine_mmaphook_start));
+
+  grub_mmap_iterate (fill_hook);
+  grub_machine_mmaphook_mmap_num = hookmmapcur - hookmmap;
+
+  grub_machine_mmaphook_kblow = grub_mmap_get_lower () >> 10;
+  grub_machine_mmaphook_kbin16mb
+    = min (grub_mmap_get_upper (),0x3f00000ULL) >> 10;
+  grub_machine_mmaphook_64kbin4gb
+    = min (grub_mmap_get_post64 (), 0xfc000000ULL) >> 16;
+
+  /* Correct BDA. */
+  *((grub_uint16_t *) 0x413) = grub_mmap_get_lower () >> 10;
+
+  /* Save old interrupt handlers. */
+  grub_machine_mmaphook_int12offset = *((grub_uint16_t *) 0x48);
+  grub_machine_mmaphook_int12segment = *((grub_uint16_t *) 0x4a);
+  grub_machine_mmaphook_int15offset = *((grub_uint16_t *) 0x54);
+  grub_machine_mmaphook_int15segment = *((grub_uint16_t *) 0x56);
+
+  grub_dprintf ("mmap", "hooktarget = %p\n", hooktarget);
+
+  /* Install the interrupt handlers. */
+  grub_memcpy (hooktarget, &grub_machine_mmaphook_start,
+	       &grub_machine_mmaphook_end - &grub_machine_mmaphook_start);
+
+  *((grub_uint16_t *) 0x4a) = PTR_TO_UINT32 (hooktarget) >> 4;
+  *((grub_uint16_t *) 0x56) = PTR_TO_UINT32 (hooktarget) >> 4;
+  *((grub_uint16_t *) 0x48) = &grub_machine_mmaphook_int12
+    - &grub_machine_mmaphook_start;
+  *((grub_uint16_t *) 0x54) = &grub_machine_mmaphook_int15
+    - &grub_machine_mmaphook_start;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+preboot_rest (void)
+{
+  /* Restore old interrupt handlers. */
+  *((grub_uint16_t *) 0x48) = grub_machine_mmaphook_int12offset;
+  *((grub_uint16_t *) 0x4a) = grub_machine_mmaphook_int12segment;
+  *((grub_uint16_t *) 0x54) = grub_machine_mmaphook_int15offset;
+  *((grub_uint16_t *) 0x56) = grub_machine_mmaphook_int15segment;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+malloc_hook (void)
+{
+  static int reentry = 0;
+  static int mmapregion = 0;
+  static int slots_available = 0;
+  int hooksize;
+  int regcount = 0;
+  auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t,
+					grub_uint32_t);
+  int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
+				   grub_uint64_t size __attribute__ ((unused)),
+				   grub_uint32_t type __attribute__ ((unused)))
+  {
+    regcount++;
+    return 0;
+  }
+
+  if (reentry)
+    return GRUB_ERR_NONE;
+
+  grub_dprintf ("mmap", "registering\n");
+
+  grub_mmap_iterate (count_hook);
+
+  /* Mapping hook itself may introduce up to 2 additional regions. */
+  regcount += 2;
+
+  if (regcount <= slots_available)
+    return GRUB_ERR_NONE;
+
+  if (mmapregion)
+    {
+      grub_mmap_free_and_unregister (mmapregion);
+      mmapregion = 0;
+      hooktarget = 0;
+    }
+
+  hooksize = &grub_machine_mmaphook_end - &grub_machine_mmaphook_start
+    + regcount * sizeof (struct grub_e820_mmap_entry);
+  /* Allocate an integer number of KiB. */
+  hooksize = ((hooksize - 1) | 0x3ff) + 1;
+  slots_available = (hooksize - (&grub_machine_mmaphook_end
+				 - &grub_machine_mmaphook_start))
+    / sizeof (struct grub_e820_mmap_entry);
+
+  reentry = 1;
+  hooktarget
+    = grub_mmap_malign_and_register (16, hooksize, &mmapregion,
+				     GRUB_MACHINE_MEMORY_RESERVED,
+				     GRUB_MMAP_MALLOC_LOW);
+  reentry = 0;
+
+  if (! hooktarget)
+    {
+      slots_available = 0;
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "No space for mmap hook");
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
+			    grub_uint64_t size __attribute__ ((unused)),
+			    int type __attribute__ ((unused)),
+			    int handle  __attribute__ ((unused)))
+{
+  grub_err_t err;
+  static void *preb_handle = 0;
+
+  err = malloc_hook ();
+  if (err)
+    return err;
+
+  if (! preb_handle)
+    {
+      grub_dprintf ("mmap", "adding preboot\n");
+      preb_handle
+	= grub_loader_register_preboot_hook (preboot, preboot_rest,
+					     GRUB_LOADER_PREBOOT_HOOK_PRIO_MEMORY);
+      if (! preb_handle)
+	return grub_errno;
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_machine_mmap_unregister (int handle __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
diff --git a/mmap/i386/pc/mmap_helper.S b/mmap/i386/pc/mmap_helper.S
new file mode 100644
index 0000000..c6d12fd
--- /dev/null
+++ b/mmap/i386/pc/mmap_helper.S
@@ -0,0 +1,154 @@
+/* Mmap management. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+#define DS(x) ((x) - segstart)
+
+segstart:
+VARIABLE(grub_machine_mmaphook_start)
+	.code16
+VARIABLE(grub_machine_mmaphook_int12)
+	push %ds
+	push %cs
+	pop %ds
+#ifdef APPLE_CC
+	grub_machine_mmaphook_kblow_rel = DS (EXT_C (grub_machine_mmaphook_kblow))
+	movw (grub_machine_mmaphook_kblow_rel), %ax
+#else
+	movw DS (EXT_C (grub_machine_mmaphook_kblow)), %ax
+#endif
+	pop %ds
+	iret
+
+VARIABLE(grub_machine_mmaphook_int15)
+	pushf
+	cmpw $0xe801, %ax
+	jz e801
+	cmpw $0xe820, %ax
+	jz e820
+	cmpb $0x88, %ah
+	jz h88
+	popf
+	/* ljmp */
+	.byte	0xea
+VARIABLE (grub_machine_mmaphook_int15offset)
+	.word	0
+VARIABLE (grub_machine_mmaphook_int15segment)
+	.word	0
+
+e801:
+	popf
+	push %ds
+	push %cs
+	pop %ds
+#ifdef APPLE_CC
+	grub_machine_mmaphook_kbin16mb_rel = DS (EXT_C (grub_machine_mmaphook_kbin16mb))
+	grub_machine_mmaphook_64kbin4gb_rel = DS (EXT_C (grub_machine_mmaphook_64kbin4gb))
+	movw (grub_machine_mmaphook_kbin16mb_rel), %ax
+	movw (grub_machine_mmaphook_64kbin4gb_rel), %bx
+#else
+	movw DS (EXT_C (grub_machine_mmaphook_kbin16mb)), %ax
+	movw DS (EXT_C (grub_machine_mmaphook_64kbin4gb)), %bx
+#endif
+	movw %ax, %cx
+	movw %bx, %dx
+	pop %ds
+	clc
+	iret
+
+h88:
+	popf
+	push %ds
+	push %cs
+	pop %ds
+#ifdef APPLE_CC
+	movw (grub_machine_mmaphook_kbin16mb_rel), %ax
+#else
+	movw DS (EXT_C (grub_machine_mmaphook_kbin16mb)), %ax
+#endif
+	pop %ds
+	clc
+	iret
+
+e820:
+#ifdef APPLE_CC
+	mmaphook_mmap_rel = DS(mmaphook_mmap)
+	mmaphook_mmap_num_rel = DS(EXT_C(grub_machine_mmaphook_mmap_num))
+#endif
+	popf
+	push %ds
+	push %cs
+	pop %ds
+	cmpw $20, %cx
+	jb errexit
+#ifdef APPLE_CC
+	cmpw (mmaphook_mmap_num_rel), %bx
+#else
+	cmpw DS (EXT_C (grub_machine_mmaphook_mmap_num)), %bx
+#endif
+	jae errexit
+	cmp $0x534d4150, %edx
+	jne errexit
+	push %si
+	push %di
+	movw $20, %cx
+#ifdef APPLE_CC
+	movl $(mmaphook_mmap_rel), %esi
+#else
+	movw $(DS(mmaphook_mmap)), %si
+#endif
+	mov %bx, %ax
+	imul $20, %ax
+	add %ax, %si
+	rep movsb
+	pop %di
+	pop %si
+	movl $20, %ecx
+	inc %bx
+#ifdef APPLE_CC
+	cmpw (mmaphook_mmap_num_rel), %bx
+#else
+	cmpw DS(EXT_C(grub_machine_mmaphook_mmap_num)), %bx
+#endif
+	jb noclean
+	xor %bx, %bx
+noclean:
+	mov $0x534d4150, %eax
+	pop %ds
+	clc
+	iret
+errexit:
+	mov $0x534d4150, %eax
+	pop %ds
+	stc
+	xor %bx, %bx
+	iret
+
+VARIABLE(grub_machine_mmaphook_mmap_num)
+	.word 0
+VARIABLE(grub_machine_mmaphook_kblow)
+	.word 0
+VARIABLE (grub_machine_mmaphook_kbin16mb)
+	.word 0
+VARIABLE (grub_machine_mmaphook_64kbin4gb)
+	.word 0
+mmaphook_mmap:
+	/* Memory map is placed just after the interrupt handlers. */
+VARIABLE(grub_machine_mmaphook_end)
diff --git a/mmap/i386/uppermem.c b/mmap/i386/uppermem.c
new file mode 100644
index 0000000..cd1a452
--- /dev/null
+++ b/mmap/i386/uppermem.c
@@ -0,0 +1,85 @@
+/* Compute amount of lower and upper memory till the first hole. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/memory.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+grub_uint64_t
+grub_mmap_get_lower (void)
+{
+  grub_uint64_t lower = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+			     grub_uint32_t type)
+    {
+      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+	return 0;
+      if (addr == 0)
+	lower = size;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+  if (lower > 0x100000)
+    lower =  0x100000;
+  return lower;
+}
+
+grub_uint64_t
+grub_mmap_get_upper (void)
+{
+  grub_uint64_t upper = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+			     grub_uint32_t type)
+    {
+      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+	return 0;
+      if (addr <= 0x100000 && addr + size > 0x100000)
+	upper = addr + size - 0x100000;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+  return upper;
+}
+
+/* Count the continuous bytes after 64 MiB. */
+grub_uint64_t
+grub_mmap_get_post64 (void)
+{
+  grub_uint64_t post64 = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+			     grub_uint32_t type)
+    {
+      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+	return 0;
+      if (addr <= 0x4000000 && addr + size > 0x4000000)
+	post64 = addr + size - 0x4000000;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+  return post64;
+}
diff --git a/mmap/mmap.c b/mmap/mmap.c
new file mode 100644
index 0000000..7598cf5
--- /dev/null
+++ b/mmap/mmap.c
@@ -0,0 +1,425 @@
+/* Mmap management. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/command.h>
+#include <grub/dl.h>
+
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+
+struct grub_mmap_region *grub_mmap_overlays = 0;
+static int curhandle = 1;
+
+#endif
+
+grub_err_t
+grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+						 grub_uint64_t, grub_uint32_t))
+{
+
+  /* This function resolves overlapping regions and sorts the memory map.
+     It uses scanline (sweeping) algorithm.
+  */
+  /* If same page is used by multiple types it's resolved
+     according to priority:
+     1 - free memory
+     2 - memory usable by firmware-aware code
+     3 - unusable memory
+     4 - a range deliberately empty
+  */
+  int priority[GRUB_MACHINE_MEMORY_MAX_TYPE + 2] =
+    {
+#ifdef GRUB_MACHINE_MEMORY_AVAILABLE
+      [GRUB_MACHINE_MEMORY_AVAILABLE] = 1,
+#endif
+#ifdef GRUB_MACHINE_MEMORY_RESERVED
+      [GRUB_MACHINE_MEMORY_RESERVED] = 3,
+#endif
+#ifdef GRUB_MACHINE_MEMORY_ACPI
+      [GRUB_MACHINE_MEMORY_ACPI] = 2,
+#endif
+#ifdef GRUB_MACHINE_MEMORY_CODE
+      [GRUB_MACHINE_MEMORY_CODE] = 3,
+#endif
+#ifdef GRUB_MACHINE_MEMORY_NVS
+      [GRUB_MACHINE_MEMORY_NVS] = 3,
+#endif
+      [GRUB_MACHINE_MEMORY_HOLE] = 4,
+    };
+
+  int i, k, done;
+
+  /* Scanline events. */
+  struct grub_mmap_scan
+  {
+    /* At which memory address. */
+    grub_uint64_t pos;
+    /* 0 = region starts, 1 = region ends. */
+    int type;
+    /* Which type of memory region? */
+    int memtype;
+  };
+  struct grub_mmap_scan *scanline_events;
+  struct grub_mmap_scan t;
+
+  /* Previous scanline event. */
+  grub_uint64_t lastaddr;
+  int lasttype;
+  /* Current scanline event. */
+  int curtype;
+  /* How many regions of given type overlap at current location? */
+  int present[GRUB_MACHINE_MEMORY_MAX_TYPE + 2];
+  /* Number of mmap chunks. */
+  int mmap_num;
+
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+  struct grub_mmap_region *cur;
+#endif
+
+  auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t,
+					grub_uint32_t);
+  int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
+				   grub_uint64_t size __attribute__ ((unused)),
+				   grub_uint32_t type __attribute__ ((unused)))
+  {
+    mmap_num++;
+    return 0;
+  }
+
+  auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
+					grub_uint32_t);
+  int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
+				  grub_uint64_t size,
+				  grub_uint32_t type)
+  {
+    scanline_events[i].pos = addr;
+    scanline_events[i].type = 0;
+    if (type <= GRUB_MACHINE_MEMORY_MAX_TYPE && priority[type])
+      scanline_events[i].memtype = type;
+    else
+      {
+	grub_dprintf ("mmap", "Unknown memory type %d. Assuming unusable\n",
+		      type);
+	scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED;
+      }
+    i++;
+
+    scanline_events[i].pos = addr + size;
+    scanline_events[i].type = 1;
+    scanline_events[i].memtype = scanline_events[i - 1].memtype;
+    i++;
+
+    return 0;
+  }
+
+  mmap_num = 0;
+
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+  for (cur = grub_mmap_overlays; cur; cur = cur->next)
+    mmap_num++;
+#endif
+
+  grub_machine_mmap_iterate (count_hook);
+
+  /* Initialize variables. */
+  grub_memset (present, 0, sizeof (present));
+  scanline_events = (struct grub_mmap_scan *)
+    grub_malloc (sizeof (struct grub_mmap_scan) * 2 * mmap_num);
+
+  if (! scanline_events)
+    {
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+			 "couldn't allocate space for new memory map");
+    }
+
+  i = 0;
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+  /* Register scanline events. */
+  for (cur = grub_mmap_overlays; cur; cur = cur->next)
+    {
+      scanline_events[i].pos = cur->start;
+      scanline_events[i].type = 0;
+      if (cur->type == GRUB_MACHINE_MEMORY_HOLE
+	  || (cur->type >= 0 && cur->type <= GRUB_MACHINE_MEMORY_MAX_TYPE
+	      && priority[cur->type]))
+	scanline_events[i].memtype = cur->type;
+      else
+	scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED;
+      i++;
+
+      scanline_events[i].pos = cur->end;
+      scanline_events[i].type = 1;
+      scanline_events[i].memtype = scanline_events[i - 1].memtype;
+      i++;
+    }
+#endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */
+
+  grub_machine_mmap_iterate (fill_hook);
+
+  /* Primitive bubble sort. It has complexity O(n^2) but since we're
+     unlikely to have more than 100 chunks it's probably one of the
+     fastest for one purpose. */
+  done = 1;
+  while (done)
+    {
+      done = 0;
+      for (i = 0; i < 2 * mmap_num - 1; i++)
+	if (scanline_events[i + 1].pos < scanline_events[i].pos
+	    || (scanline_events[i + 1].pos == scanline_events[i].pos
+		&& scanline_events[i + 1].type == 0
+		&& scanline_events[i].type == 1))
+	  {
+	    t = scanline_events[i + 1];
+	    scanline_events[i + 1] = scanline_events[i];
+	    scanline_events[i] = t;
+	    done = 1;
+	  }
+    }
+
+  lastaddr = scanline_events[0].pos;
+  lasttype = scanline_events[0].memtype;
+  for (i = 0; i < 2 * mmap_num; i++)
+    {
+      /* Process event. */
+      if (scanline_events[i].type)
+	present[scanline_events[i].memtype]--;
+      else
+	present[scanline_events[i].memtype]++;
+
+      /* Determine current region type. */
+      curtype = -1;
+      for (k = 0; k <= GRUB_MACHINE_MEMORY_MAX_TYPE + 1; k++)
+	if (present[k] && (curtype == -1 || priority[k] > priority[curtype]))
+	  curtype = k;
+
+      /* Announce region to the hook if necessary. */
+      if ((curtype == -1 || curtype != lasttype)
+	  && lastaddr != scanline_events[i].pos
+	  && lasttype != -1
+	  && lasttype != GRUB_MACHINE_MEMORY_HOLE
+	  && hook (lastaddr, scanline_events[i].pos - lastaddr, lasttype))
+	{
+	  grub_free (scanline_events);
+	  return GRUB_ERR_NONE;
+	}
+
+      /* Update last values if necessary. */
+      if (curtype == -1 || curtype != lasttype)
+	{
+	  lasttype = curtype;
+	  lastaddr = scanline_events[i].pos;
+	}
+    }
+
+  grub_free (scanline_events);
+  return GRUB_ERR_NONE;
+}
+
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+int
+grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type)
+{
+  struct grub_mmap_region *cur;
+
+  grub_dprintf ("mmap", "registering\n");
+
+  cur = (struct grub_mmap_region *)
+    grub_malloc (sizeof (struct grub_mmap_region));
+  if (! cur)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		  "couldn't allocate memory map overlay");
+      return 0;
+    }
+
+  cur->next = grub_mmap_overlays;
+  cur->start = start;
+  cur->end = start + size;
+  cur->type = type;
+  cur->handle = curhandle++;
+  grub_mmap_overlays = cur;
+
+  if (grub_machine_mmap_register (start, size, type, curhandle))
+    {
+      grub_mmap_overlays = cur->next;
+      grub_free (cur);
+      return 0;
+    }
+
+  return cur->handle;
+}
+
+grub_err_t
+grub_mmap_unregister (int handle)
+{
+  struct grub_mmap_region *cur, *prev;
+
+  for (cur = grub_mmap_overlays, prev = 0; cur; prev= cur, cur = cur->next)
+    if (handle == cur->handle)
+      {
+	grub_err_t err;
+	if ((err = grub_machine_mmap_unregister (handle)))
+	  return err;
+
+	if (prev)
+	  prev->next = cur->next;
+	else
+	  grub_mmap_overlays = cur->next;
+	grub_free (cur);
+	return GRUB_ERR_NONE;
+      }
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "mmap overlay not found");
+}
+
+#endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */
+
+#define CHUNK_SIZE	0x400
+
+static inline grub_uint64_t
+fill_mask (grub_uint64_t addr, grub_uint64_t mask, grub_uint64_t iterator)
+{
+  int i, j;
+  grub_uint64_t ret = (addr & mask);
+
+  /* Find first fixed bit. */
+  for (i = 0; i < 64; i++)
+    if ((mask & (1ULL << i)) != 0)
+      break;
+  j = 0;
+  for (; i < 64; i++)
+    if ((mask & (1ULL << i)) == 0)
+      {
+	if ((iterator & (1ULL << j)) != 0)
+	  ret |= 1ULL << i;
+	j++;
+      }
+  return ret;
+}
+
+static grub_err_t
+grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)),
+		 int argc, char **args)
+{
+  char * str;
+  grub_uint64_t badaddr, badmask;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr,
+			     grub_uint64_t size,
+			     grub_uint32_t type __attribute__ ((unused)))
+  {
+    grub_uint64_t iterator, low, high, cur;
+    int tail, var;
+    int i;
+    grub_dprintf ("badram", "hook %llx+%llx\n", (unsigned long long) addr,
+		  (unsigned long long) size);
+
+    /* How many trailing zeros? */
+    for (tail = 0; ! (badmask & (1ULL << tail)); tail++);
+
+    /* How many zeros in mask? */
+    var = 0;
+    for (i = 0; i < 64; i++)
+      if (! (badmask & (1ULL << i)))
+	var++;
+
+    if (fill_mask (badaddr, badmask, 0) >= addr)
+      iterator = 0;
+    else
+      {
+	low = 0;
+	high = ~0ULL;
+	/* Find starting value. Keep low and high such that
+	   fill_mask (low) < addr and fill_mask (high) >= addr;
+	*/
+	while (high - low > 1)
+	  {
+	    cur = (low + high) / 2;
+	    if (fill_mask (badaddr, badmask, cur) >= addr)
+	      high = cur;
+	    else
+	      low = cur;
+	  }
+	iterator = high;
+      }
+
+    for (; iterator < (1ULL << (var - tail))
+	   && (cur = fill_mask (badaddr, badmask, iterator)) < addr + size;
+	 iterator++)
+      {
+	grub_dprintf ("badram", "%llx (size %llx) is a badram range\n",
+		      (unsigned long long) cur, (1ULL << tail));
+	grub_mmap_register (cur, (1ULL << tail), GRUB_MACHINE_MEMORY_HOLE);
+      }
+    return 0;
+  }
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "badram string required");
+
+  grub_dprintf ("badram", "executing badram\n");
+
+  str = args[0];
+
+  while (1)
+    {
+      /* Parse address and mask.  */
+      badaddr = grub_strtoull (str, &str, 16);
+      if (*str == ',')
+	str++;
+      badmask = grub_strtoull (str, &str, 16);
+      if (*str == ',')
+	str++;
+
+      if (grub_errno == GRUB_ERR_BAD_NUMBER)
+	{
+	  grub_errno = 0;
+	  return GRUB_ERR_NONE;
+	}
+
+      /* When part of a page is tainted, we discard the whole of it.  There's
+	 no point in providing sub-page chunks.  */
+      badmask &= ~(CHUNK_SIZE - 1);
+
+      grub_dprintf ("badram", "badram %llx:%llx\n",
+		    (unsigned long long) badaddr, (unsigned long long) badmask);
+
+      grub_mmap_iterate (hook);
+    }
+}
+
+static grub_command_t cmd;
+
+
+GRUB_MOD_INIT(mmap)
+{
+  cmd = grub_register_command ("badram", grub_cmd_badram,
+			       "badram ADDR1,MASK1[,ADDR2,MASK2[,...]]",
+			       "declare memory regions as badram");
+}
+
+GRUB_MOD_FINI(mmap)
+{
+  grub_unregister_command (cmd);
+}
+
diff --git a/normal/auth.c b/normal/auth.c
new file mode 100644
index 0000000..9029ba1
--- /dev/null
+++ b/normal/auth.c
@@ -0,0 +1,256 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/auth.h>
+#include <grub/list.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/normal.h>
+
+struct grub_auth_user
+{
+  struct grub_auth_user *next;
+  char *name;
+  grub_auth_callback_t callback;
+  void *arg;
+  int authenticated;
+};
+
+struct grub_auth_user *users = NULL;
+
+int
+grub_auth_strcmp (const char *user_input, const char *template)
+{
+  int ok = 1;
+  const char *ptr1, *ptr2;
+  for (ptr1 = user_input, ptr2 = template; *ptr1; ptr1++)
+    if (*ptr1 == (ptr2 ? *ptr2 : ptr1[1]) && ok && ptr2 != NULL)
+      ptr2++;
+    else
+      ok = 0;
+
+  return !ok;
+}
+
+static int
+grub_iswordseparator (int c)
+{
+  return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
+}
+
+int
+grub_auth_strword (const char *haystack, const char *needle)
+{
+  const char *n_pos = needle;
+  int found = 0;
+
+  while (grub_iswordseparator (*haystack))
+    haystack++;
+
+  while (*haystack)
+    {
+      int ok = 1;
+      /* Crawl both the needle and the haystack word we're on.  */
+      while(*haystack && !grub_iswordseparator (*haystack))
+        {
+	  if (*haystack == *n_pos && ok)
+	    n_pos++;
+	  else
+	    ok = 0;
+
+          haystack++;
+        }
+
+      if (ok)
+	found = 1;
+    }
+
+  return found;
+}
+
+grub_err_t
+grub_auth_register_authentication (const char *user,
+				   grub_auth_callback_t callback,
+				   void *arg)
+{
+  struct grub_auth_user *cur;
+
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+  if (!cur)
+    cur = grub_zalloc (sizeof (*cur));
+  if (!cur)
+    return grub_errno;
+  cur->callback = callback;
+  cur->arg = arg;
+  if (! cur->name)
+    {
+      cur->name = grub_strdup (user);
+      if (!cur->name)
+	{
+	  grub_free (cur);
+	  return grub_errno;
+	}
+      grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_auth_unregister_authentication (const char *user)
+{
+  struct grub_auth_user *cur;
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+  if (!cur)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
+  if (!cur->authenticated)
+    {
+      grub_free (cur->name);
+      grub_list_remove (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+      grub_free (cur);
+    }
+  else
+    {
+      cur->callback = NULL;
+      cur->arg = NULL;
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_auth_authenticate (const char *user)
+{
+  struct grub_auth_user *cur;
+
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+  if (!cur)
+    cur = grub_zalloc (sizeof (*cur));
+  if (!cur)
+    return grub_errno;
+
+  cur->authenticated = 1;
+
+  if (! cur->name)
+    {
+      cur->name = grub_strdup (user);
+      if (!cur->name)
+	{
+	  grub_free (cur);
+	  return grub_errno;
+	}
+      grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_auth_deauthenticate (const char *user)
+{
+  struct grub_auth_user *cur;
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+  if (!cur)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
+  if (!cur->callback)
+    {
+      grub_free (cur->name);
+      grub_list_remove (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+      grub_free (cur);
+    }
+  else
+    cur->authenticated = 0;
+  return GRUB_ERR_NONE;
+}
+
+static int
+is_authenticated (const char *userlist)
+{
+  const char *superusers;
+
+  auto int hook (grub_list_t item);
+  int hook (grub_list_t item)
+  {
+    const char *name;
+    if (!((struct grub_auth_user *) item)->authenticated)
+      return 0;
+    name = ((struct grub_auth_user *) item)->name;
+
+    return (userlist && grub_auth_strword (userlist, name))
+      || grub_auth_strword (superusers, name);
+  }
+
+  superusers = grub_env_get ("superusers");
+
+  if (!superusers)
+    return 1;
+
+  return grub_list_iterate (GRUB_AS_LIST (users), hook);
+}
+
+grub_err_t
+grub_auth_check_authentication (const char *userlist)
+{
+  char login[1024];
+  struct grub_auth_user *cur = NULL;
+  grub_err_t err;
+
+  auto int hook (grub_list_t item);
+  int hook (grub_list_t item)
+  {
+    if (grub_auth_strcmp (login, ((struct grub_auth_user *) item)->name) == 0)
+      cur = (struct grub_auth_user *) item;
+    return 0;
+  }
+
+  auto int hook_any (grub_list_t item);
+  int hook_any (grub_list_t item)
+  {
+    if (((struct grub_auth_user *) item)->callback)
+      cur = (struct grub_auth_user *) item;
+    return 0;
+  }
+
+  grub_memset (login, 0, sizeof (login));
+
+  if (is_authenticated (userlist))
+    return GRUB_ERR_NONE;
+
+  if (!grub_cmdline_get ("Enter username: ", login, sizeof (login) - 1,
+			 0, 0, 0))
+    return GRUB_ACCESS_DENIED;
+
+  grub_list_iterate (GRUB_AS_LIST (users), hook);
+
+  if (!cur || ! cur->callback)
+    {
+      grub_list_iterate (GRUB_AS_LIST (users), hook_any);
+
+      /* No users present at all.  */
+      if (!cur)
+	return GRUB_ACCESS_DENIED;
+
+      /* Display any of available authentication schemes.  */
+      err = cur->callback (login, 0);
+
+      return GRUB_ACCESS_DENIED;
+    }
+  err = cur->callback (login, cur->arg);
+  if (is_authenticated (userlist))
+    return GRUB_ERR_NONE;
+  return GRUB_ACCESS_DENIED;
+}
diff --git a/normal/autofs.c b/normal/autofs.c
new file mode 100644
index 0000000..39f2f9d
--- /dev/null
+++ b/normal/autofs.c
@@ -0,0 +1,134 @@
+/* autofs.c - support auto-loading from fs.lst */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/fs.h>
+#include <grub/normal.h>
+
+/* This is used to store the names of filesystem modules for auto-loading.  */
+struct grub_fs_module_list
+{
+  char *name;
+  struct grub_fs_module_list *next;
+};
+typedef struct grub_fs_module_list *grub_fs_module_list_t;
+
+static grub_fs_module_list_t fs_module_list = 0;
+
+/* The auto-loading hook for filesystems.  */
+static int
+autoload_fs_module (void)
+{
+  grub_fs_module_list_t p;
+
+  while ((p = fs_module_list) != 0)
+    {
+      if (! grub_dl_get (p->name) && grub_dl_load (p->name))
+	return 1;
+
+      fs_module_list = p->next;
+      grub_free (p->name);
+      grub_free (p);
+    }
+
+  return 0;
+}
+
+/* Read the file fs.lst for auto-loading.  */
+void
+read_fs_list (void)
+{
+  const char *prefix;
+  static int first_time = 1;
+
+  /* Make sure that this function does not get executed twice.  */
+  if (! first_time)
+    return;
+  first_time = 0;
+
+  prefix = grub_env_get ("prefix");
+  if (prefix)
+    {
+      char *filename;
+
+      filename = grub_malloc (grub_strlen (prefix) + sizeof ("/fs.lst"));
+      if (filename)
+	{
+	  grub_file_t file;
+
+	  grub_sprintf (filename, "%s/fs.lst", prefix);
+	  file = grub_file_open (filename);
+	  if (file)
+	    {
+	      while (1)
+		{
+		  char *buf;
+		  char *p;
+		  char *q;
+		  grub_fs_module_list_t fs_mod;
+
+		  buf = grub_file_getline (file);
+		  if (! buf)
+		    break;
+
+		  p = buf;
+		  q = buf + grub_strlen (buf) - 1;
+
+		  /* Ignore space.  */
+		  while (grub_isspace (*p))
+		    p++;
+
+		  while (p < q && grub_isspace (*q))
+		    *q-- = '\0';
+
+		  /* If the line is empty, skip it.  */
+		  if (p >= q)
+		    continue;
+
+		  fs_mod = grub_malloc (sizeof (*fs_mod));
+		  if (! fs_mod)
+		    continue;
+
+		  fs_mod->name = grub_strdup (p);
+		  if (! fs_mod->name)
+		    {
+		      grub_free (fs_mod);
+		      continue;
+		    }
+
+		  fs_mod->next = fs_module_list;
+		  fs_module_list = fs_mod;
+		}
+
+	      grub_file_close (file);
+	    }
+
+	  grub_free (filename);
+	}
+    }
+
+  /* Ignore errors.  */
+  grub_errno = GRUB_ERR_NONE;
+
+  /* Set the hook.  */
+  grub_fs_autoload_hook = autoload_fs_module;
+}
diff --git a/normal/cmdline.c b/normal/cmdline.c
new file mode 100644
index 0000000..7a5b6ec
--- /dev/null
+++ b/normal/cmdline.c
@@ -0,0 +1,484 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/env.h>
+
+static char *kill_buf;
+
+static int hist_size;
+static char **hist_lines = 0;
+static int hist_pos = 0;
+static int hist_end = 0;
+static int hist_used = 0;
+
+grub_err_t
+grub_set_history (int newsize)
+{
+  char **old_hist_lines = hist_lines;
+  hist_lines = grub_malloc (sizeof (char *) * newsize);
+
+  /* Copy the old lines into the new buffer.  */
+  if (old_hist_lines)
+    {
+      /* Remove the lines that don't fit in the new buffer.  */
+      if (newsize < hist_used)
+	{
+	  int i;
+	  int delsize = hist_used - newsize;
+	  hist_used = newsize;
+
+	  for (i = 1; i <= delsize; i++)
+	    {
+	      int pos = hist_end - i;
+	      if (pos < 0)
+		pos += hist_size;
+	      grub_free (old_hist_lines[pos]);
+	    }
+
+	  hist_end -= delsize;
+	  if (hist_end < 0)
+	    hist_end += hist_size;
+	}
+
+      if (hist_pos < hist_end)
+	grub_memmove (hist_lines, old_hist_lines + hist_pos,
+		      (hist_end - hist_pos) * sizeof (char *));
+      else if (hist_used)
+	{
+	  /* Copy the older part.  */
+	  grub_memmove (hist_lines, old_hist_lines + hist_pos,
+ 			(hist_size - hist_pos) * sizeof (char *));
+
+	  /* Copy the newer part. */
+	  grub_memmove (hist_lines + hist_size - hist_pos, old_hist_lines,
+			hist_end * sizeof (char *));
+	}
+    }
+
+  grub_free (old_hist_lines);
+
+  hist_size = newsize;
+  hist_pos = 0;
+  hist_end = hist_used;
+  return 0;
+}
+
+/* Get the entry POS from the history where `0' is the newest
+   entry.  */
+static char *
+grub_history_get (int pos)
+{
+  pos = (hist_pos + pos) % hist_size;
+  return hist_lines[pos];
+}
+
+
+/* Insert a new history line S on the top of the history.  */
+static void
+grub_history_add (char *s)
+{
+  /* Remove the oldest entry in the history to make room for a new
+     entry.  */
+  if (hist_used + 1 > hist_size)
+    {
+      hist_end--;
+      if (hist_end < 0)
+	hist_end = hist_size + hist_end;
+
+      grub_free (hist_lines[hist_end]);
+    }
+  else
+    hist_used++;
+
+  /* Move to the next position.  */
+  hist_pos--;
+  if (hist_pos < 0)
+    hist_pos = hist_size + hist_pos;
+
+  /* Insert into history.  */
+  hist_lines[hist_pos] = grub_strdup (s);
+}
+
+/* Replace the history entry on position POS with the string S.  */
+static void
+grub_history_replace (int pos, char *s)
+{
+  pos = (hist_pos + pos) % hist_size;
+  grub_free (hist_lines[pos]);
+  hist_lines[pos] = grub_strdup (s);
+}
+
+/* A completion hook to print items.  */
+static void
+print_completion (const char *item, grub_completion_type_t type, int count)
+{
+  if (count == 0)
+    {
+      /* If this is the first time, print a label.  */
+      const char *what;
+
+      switch (type)
+	{
+	case GRUB_COMPLETION_TYPE_COMMAND:
+	  what = "commands";
+	  break;
+	case GRUB_COMPLETION_TYPE_DEVICE:
+	  what = "devices";
+	  break;
+	case GRUB_COMPLETION_TYPE_FILE:
+	  what = "files";
+	  break;
+	case GRUB_COMPLETION_TYPE_PARTITION:
+	  what = "partitions";
+	  break;
+	case GRUB_COMPLETION_TYPE_ARGUMENT:
+	  what = "arguments";
+	  break;
+	default:
+	  what = "things";
+	  break;
+	}
+
+      grub_printf ("\nPossible %s are:\n", what);
+    }
+
+  if (type == GRUB_COMPLETION_TYPE_PARTITION)
+    {
+      grub_normal_print_device_info (item);
+      grub_errno = GRUB_ERR_NONE;
+    }
+  else
+    grub_printf (" %s", item);
+}
+
+/* Get a command-line. If ECHO_CHAR is not zero, echo it instead of input
+   characters. If READLINE is non-zero, readline-like key bindings are
+   available. If ESC is pushed, return zero, otherwise return non-zero.  */
+/* FIXME: The dumb interface is not supported yet.  */
+int
+grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
+		  int echo_char, int readline, int history)
+{
+  unsigned xpos, ypos, ystart;
+  grub_size_t lpos, llen;
+  grub_size_t plen;
+  char buf[max_len];
+  int key;
+  int histpos = 0;
+  auto void cl_insert (const char *str);
+  auto void cl_delete (unsigned len);
+  auto void cl_print (int pos, int c);
+  auto void cl_set_pos (void);
+
+  void cl_set_pos (void)
+    {
+      xpos = (plen + lpos) % 79;
+      ypos = ystart + (plen + lpos) / 79;
+      grub_gotoxy (xpos, ypos);
+
+      grub_refresh ();
+    }
+
+  void cl_print (int pos, int c)
+    {
+      char *p;
+
+      for (p = buf + pos; *p; p++)
+	{
+	  if (xpos++ > 78)
+	    {
+	      grub_putchar ('\n');
+
+	      xpos = 1;
+	      if (ypos == (unsigned) (grub_getxy () & 0xFF))
+		ystart--;
+	      else
+		ypos++;
+	    }
+
+	  if (c)
+	    grub_putchar (c);
+	  else
+	    grub_putchar (*p);
+	}
+    }
+
+  void cl_insert (const char *str)
+    {
+      grub_size_t len = grub_strlen (str);
+
+      if (len + llen < max_len)
+	{
+	  grub_memmove (buf + lpos + len, buf + lpos, llen - lpos + 1);
+	  grub_memmove (buf + lpos, str, len);
+
+	  llen += len;
+	  lpos += len;
+	  cl_print (lpos - len, echo_char);
+	  cl_set_pos ();
+	}
+
+      grub_refresh ();
+    }
+
+  void cl_delete (unsigned len)
+    {
+      if (lpos + len <= llen)
+	{
+	  grub_size_t saved_lpos = lpos;
+
+	  lpos = llen - len;
+	  cl_set_pos ();
+	  cl_print (lpos, ' ');
+	  lpos = saved_lpos;
+	  cl_set_pos ();
+
+	  grub_memmove (buf + lpos, buf + lpos + len, llen - lpos + 1);
+	  llen -= len;
+	  cl_print (lpos, echo_char);
+	  cl_set_pos ();
+	}
+
+      grub_refresh ();
+    }
+
+  plen = grub_strlen (prompt);
+  lpos = llen = 0;
+  buf[0] = '\0';
+
+  if ((grub_getxy () >> 8) != 0)
+    grub_putchar ('\n');
+
+  grub_printf ("%s", prompt);
+
+  xpos = plen;
+  ystart = ypos = (grub_getxy () & 0xFF);
+
+  cl_insert (cmdline);
+
+  if (history && hist_used == 0)
+    grub_history_add (buf);
+
+  while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r')
+    {
+      if (readline)
+	{
+	  switch (key)
+	    {
+	    case 1:	/* Ctrl-a */
+	      lpos = 0;
+	      cl_set_pos ();
+	      break;
+
+	    case 2:	/* Ctrl-b */
+	      if (lpos > 0)
+		{
+		  lpos--;
+		  cl_set_pos ();
+		}
+	      break;
+
+	    case 5:	/* Ctrl-e */
+	      lpos = llen;
+	      cl_set_pos ();
+	      break;
+
+	    case 6:	/* Ctrl-f */
+	      if (lpos < llen)
+		{
+		  lpos++;
+		  cl_set_pos ();
+		}
+	      break;
+
+	    case 9:	/* Ctrl-i or TAB */
+	      {
+		char *insert;
+		int restore;
+
+		/* Backup the next character and make it 0 so it will
+		   be easy to use string functions.  */
+		char backup = buf[lpos];
+		buf[lpos] = '\0';
+
+
+		insert = grub_normal_do_completion (buf, &restore,
+						    print_completion);
+		/* Restore the original string.  */
+		buf[lpos] = backup;
+
+		if (restore)
+		  {
+		    /* Restore the prompt.  */
+		    grub_printf ("\n%s%s", prompt, buf);
+		    xpos = plen;
+		    ystart = ypos = (grub_getxy () & 0xFF);
+		  }
+
+		if (insert)
+		  {
+		    cl_insert (insert);
+		    grub_free (insert);
+		  }
+	      }
+	      break;
+
+	    case 11:	/* Ctrl-k */
+	      if (lpos < llen)
+		{
+		  if (kill_buf)
+		    grub_free (kill_buf);
+
+		  kill_buf = grub_strdup (buf + lpos);
+		  grub_errno = GRUB_ERR_NONE;
+
+		  cl_delete (llen - lpos);
+		}
+	      break;
+
+	    case 14:	/* Ctrl-n */
+	      {
+		char *hist;
+
+		lpos = 0;
+
+		if (histpos > 0)
+		  {
+		    grub_history_replace (histpos, buf);
+		    histpos--;
+		  }
+
+		cl_delete (llen);
+		hist = grub_history_get (histpos);
+		cl_insert (hist);
+
+		break;
+	      }
+	    case 16:	/* Ctrl-p */
+	      {
+		char *hist;
+
+		lpos = 0;
+
+		if (histpos < hist_used - 1)
+		  {
+		    grub_history_replace (histpos, buf);
+		    histpos++;
+		  }
+
+		cl_delete (llen);
+		hist = grub_history_get (histpos);
+
+		cl_insert (hist);
+	      }
+	      break;
+
+	    case 21:	/* Ctrl-u */
+	      if (lpos > 0)
+		{
+		  grub_size_t n = lpos;
+
+		  if (kill_buf)
+		    grub_free (kill_buf);
+
+		  kill_buf = grub_malloc (n + 1);
+		  grub_errno = GRUB_ERR_NONE;
+		  if (kill_buf)
+		    {
+		      grub_memcpy (kill_buf, buf, n);
+		      kill_buf[n] = '\0';
+		    }
+
+		  lpos = 0;
+		  cl_set_pos ();
+		  cl_delete (n);
+		}
+	      break;
+
+	    case 25:	/* Ctrl-y */
+	      if (kill_buf)
+		cl_insert (kill_buf);
+	      break;
+	    }
+	}
+
+      switch (key)
+	{
+	case '\e':
+	  return 0;
+
+	case '\b':
+	  if (lpos > 0)
+	    {
+	      lpos--;
+	      cl_set_pos ();
+	    }
+          else
+            break;
+	  /* fall through */
+
+	case 4:	/* Ctrl-d */
+	  if (lpos < llen)
+	    cl_delete (1);
+	  break;
+
+	default:
+	  if (grub_isprint (key))
+	    {
+	      char str[2];
+
+	      str[0] = key;
+	      str[1] = '\0';
+	      cl_insert (str);
+	    }
+	  break;
+	}
+    }
+
+  grub_putchar ('\n');
+  grub_refresh ();
+
+  /* If ECHO_CHAR is NUL, remove leading spaces.  */
+  lpos = 0;
+  if (! echo_char)
+    while (buf[lpos] == ' ')
+      lpos++;
+
+  if (history)
+    {
+      histpos = 0;
+      if (grub_strlen (buf) > 0)
+	{
+	  grub_history_replace (histpos, buf);
+	  grub_history_add ("");
+	}
+    }
+
+  grub_memcpy (cmdline, buf + lpos, llen - lpos + 1);
+
+  return 1;
+}
diff --git a/normal/color.c b/normal/color.c
new file mode 100644
index 0000000..340e43a
--- /dev/null
+++ b/normal/color.c
@@ -0,0 +1,148 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/normal.h>
+#include <grub/term.h>
+
+/* Borrowed from GRUB Legacy */
+static char *color_list[16] =
+{
+  "black",
+  "blue",
+  "green",
+  "cyan",
+  "red",
+  "magenta",
+  "brown",
+  "light-gray",
+  "dark-gray",
+  "light-blue",
+  "light-green",
+  "light-cyan",
+  "light-red",
+  "light-magenta",
+  "yellow",
+  "white"
+};
+
+static int
+parse_color_name (grub_uint8_t *ret, char *name)
+{
+  grub_uint8_t i;
+  for (i = 0; i < sizeof (color_list) / sizeof (*color_list); i++)
+    if (! grub_strcmp (name, color_list[i]))
+      {
+        *ret = i;
+        return 0;
+      }
+  return -1;
+}
+
+void
+grub_parse_color_name_pair (grub_uint8_t *ret, const char *name)
+{
+  grub_uint8_t fg, bg;
+  char *fg_name, *bg_name;
+
+  /* nothing specified by user */
+  if (name == NULL)
+    return;
+
+  fg_name = grub_strdup (name);
+  if (fg_name == NULL)
+    {
+      /* "out of memory" message was printed by grub_strdup() */
+      grub_wait_after_message ();
+      return;
+    }
+
+  bg_name = grub_strchr (fg_name, '/');
+  if (bg_name == NULL)
+    {
+      grub_printf ("Warning: syntax error (missing slash) in `%s'\n", fg_name);
+      grub_wait_after_message ();
+      goto free_and_return;
+    }
+
+  *(bg_name++) = '\0';
+
+  if (parse_color_name (&fg, fg_name) == -1)
+    {
+      grub_printf ("Warning: invalid foreground color `%s'\n", fg_name);
+      grub_wait_after_message ();
+      goto free_and_return;
+    }
+  if (parse_color_name (&bg, bg_name) == -1)
+    {
+      grub_printf ("Warning: invalid background color `%s'\n", bg_name);
+      grub_wait_after_message ();
+      goto free_and_return;
+    }
+
+  *ret = (bg << 4) | fg;
+
+free_and_return:
+  grub_free (fg_name);
+}
+
+/* Replace default `normal' colors with the ones specified by user (if any).  */
+char *
+grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)),
+			     const char *val)
+{
+  grub_uint8_t color_normal, color_highlight;
+
+  /* Use old settings in case grub_parse_color_name_pair() has no effect.  */
+  grub_getcolor (&color_normal, &color_highlight);
+
+  grub_parse_color_name_pair (&color_normal, val);
+
+  /* Reloads terminal `normal' and `highlight' colors.  */
+  grub_setcolor (color_normal, color_highlight);
+
+  /* Propagates `normal' color to terminal current color.  */
+  grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+
+  return grub_strdup (val);
+}
+
+/* Replace default `highlight' colors with the ones specified by user (if any).  */
+char *
+grub_env_write_color_highlight (struct grub_env_var *var __attribute__ ((unused)),
+				const char *val)
+{
+  grub_uint8_t color_normal, color_highlight;
+
+  /* Use old settings in case grub_parse_color_name_pair() has no effect.  */
+  grub_getcolor (&color_normal, &color_highlight);
+
+  grub_parse_color_name_pair (&color_highlight, val);
+
+  /* Reloads terminal `normal' and `highlight' colors.  */
+  grub_setcolor (color_normal, color_highlight);
+
+  /* Propagates `normal' color to terminal current color.
+     Note: Using GRUB_TERM_COLOR_NORMAL here rather than
+     GRUB_TERM_COLOR_HIGHLIGHT is intentional.  We don't want to switch
+     to highlight state just because color was reloaded.  */
+  grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+
+  return grub_strdup (val);
+}
diff --git a/normal/completion.c b/normal/completion.c
new file mode 100644
index 0000000..4b38e33
--- /dev/null
+++ b/normal/completion.c
@@ -0,0 +1,499 @@
+/* completion.c - complete a command, a disk, a partition or a file */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/parser.h>
+#include <grub/extcmd.h>
+
+/* The current word.  */
+static char *current_word;
+
+/* The matched string.  */
+static char *match;
+
+/* The count of candidates.  */
+static int num_found;
+
+/* The string to be appended.  */
+static const char *suffix;
+
+/* The callback function to print items.  */
+static void (*print_func) (const char *, grub_completion_type_t, int);
+
+/* The state the command line is in.  */
+static grub_parser_state_t cmdline_state;
+
+
+/* Add a string to the list of possible completions. COMPLETION is the
+   string that should be added. EXTRA will be appended if COMPLETION
+   matches uniquely. The type TYPE specifies what kind of data is added.  */
+static int
+add_completion (const char *completion, const char *extra,
+		grub_completion_type_t type)
+{
+  if (grub_strncmp (current_word, completion, grub_strlen (current_word)) == 0)
+    {
+      num_found++;
+
+      switch (num_found)
+	{
+	case 1:
+	  match = grub_strdup (completion);
+	  if (! match)
+	    return 1;
+	  suffix = extra;
+	  break;
+
+	case 2:
+	  if (print_func)
+	    print_func (match, type, 0);
+
+	  /* Fall through.  */
+
+	default:
+	  {
+	    char *s = match;
+	    const char *t = completion;
+
+	    if (print_func)
+	      print_func (completion, type, num_found - 1);
+
+	    /* Detect the matched portion.  */
+	    while (*s && *t && *s == *t)
+	      {
+		s++;
+		t++;
+	      }
+
+	    *s = '\0';
+	  }
+	  break;
+	}
+    }
+
+  return 0;
+}
+
+static int
+iterate_partition (grub_disk_t disk, const grub_partition_t p)
+{
+  const char *disk_name = disk->name;
+  char *partition_name = grub_partition_get_name (p);
+  char *name;
+  int ret;
+
+  if (! partition_name)
+    return 1;
+
+  name = grub_malloc (grub_strlen (disk_name) + 1
+		      + grub_strlen (partition_name) + 1);
+  if (! name)
+    {
+      grub_free (partition_name);
+      return 1;
+    }
+
+  grub_sprintf (name, "%s,%s", disk_name, partition_name);
+  grub_free (partition_name);
+
+  ret = add_completion (name, ")", GRUB_COMPLETION_TYPE_PARTITION);
+  grub_free (name);
+  return ret;
+}
+
+static int
+iterate_dir (const char *filename, const struct grub_dirhook_info *info)
+{
+  if (! info->dir)
+    {
+      const char *prefix;
+      if (cmdline_state == GRUB_PARSER_STATE_DQUOTE)
+	prefix = "\" ";
+      else if (cmdline_state == GRUB_PARSER_STATE_QUOTE)
+	prefix = "\' ";
+      else
+	prefix = " ";
+
+      if (add_completion (filename, prefix, GRUB_COMPLETION_TYPE_FILE))
+	return 1;
+    }
+  else if (grub_strcmp (filename, ".") && grub_strcmp (filename, ".."))
+    {
+      char fname[grub_strlen (filename) + 2];
+
+      grub_sprintf (fname, "%s/", filename);
+      if (add_completion (fname, "", GRUB_COMPLETION_TYPE_FILE))
+	return 1;
+    }
+
+  return 0;
+}
+
+static int
+iterate_dev (const char *devname)
+{
+  grub_device_t dev;
+
+  /* Complete the partition part.  */
+  dev = grub_device_open (devname);
+
+  if (dev)
+    {
+      if (dev->disk && dev->disk->has_partitions)
+	{
+	  if (add_completion (devname, ",", GRUB_COMPLETION_TYPE_DEVICE))
+	    return 1;
+	}
+      else
+	{
+	  if (add_completion (devname, ")", GRUB_COMPLETION_TYPE_DEVICE))
+	    return 1;
+	}
+    }
+
+  grub_errno = GRUB_ERR_NONE;
+  return 0;
+}
+
+static int
+iterate_command (grub_command_t cmd)
+{
+  if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE)
+    {
+      if (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)
+	{
+	  if (add_completion (cmd->name, " ", GRUB_COMPLETION_TYPE_COMMAND))
+	    return 1;
+	}
+    }
+
+  return 0;
+}
+
+/* Complete a device.  */
+static int
+complete_device (void)
+{
+  /* Check if this is a device or a partition.  */
+  char *p = grub_strchr (++current_word, ',');
+  grub_device_t dev;
+
+  if (! p)
+    {
+      /* Complete the disk part.  */
+      if (grub_disk_dev_iterate (iterate_dev))
+	return 1;
+    }
+  else
+    {
+      /* Complete the partition part.  */
+      *p = '\0';
+      dev = grub_device_open (current_word);
+      *p = ',';
+      grub_errno = GRUB_ERR_NONE;
+
+      if (dev)
+	{
+	  if (dev->disk && dev->disk->has_partitions)
+	    {
+	      if (grub_partition_iterate (dev->disk, iterate_partition))
+		{
+		  grub_device_close (dev);
+		  return 1;
+		}
+	    }
+
+	  grub_device_close (dev);
+	}
+      else
+	return 1;
+    }
+
+  return 0;
+}
+
+/* Complete a file.  */
+static int
+complete_file (void)
+{
+  char *device;
+  char *dir;
+  char *last_dir;
+  grub_fs_t fs;
+  grub_device_t dev;
+  int ret = 0;
+
+  device = grub_file_get_device_name (current_word);
+  if (grub_errno != GRUB_ERR_NONE)
+    return 1;
+
+  dev = grub_device_open (device);
+  if (! dev)
+    {
+      ret = 1;
+      goto fail;
+    }
+
+  fs = grub_fs_probe (dev);
+  if (! fs)
+    {
+      ret = 1;
+      goto fail;
+    }
+
+  dir = grub_strchr (current_word, '/');
+  last_dir = grub_strrchr (current_word, '/');
+  if (dir)
+    {
+      char *dirfile;
+
+      current_word = last_dir + 1;
+
+      dir = grub_strdup (dir);
+      if (! dir)
+	{
+	  ret = 1;
+	  goto fail;
+	}
+
+      /* Cut away the filename part.  */
+      dirfile = grub_strrchr (dir, '/');
+      dirfile[1] = '\0';
+
+      /* Iterate the directory.  */
+      (fs->dir) (dev, dir, iterate_dir);
+
+      grub_free (dir);
+
+      if (grub_errno)
+	{
+	  ret = 1;
+	  goto fail;
+	}
+    }
+  else
+    {
+      current_word += grub_strlen (current_word);
+      match = grub_strdup ("/");
+      if (! match)
+	{
+	  ret = 1;
+	  goto fail;
+	}
+
+      suffix = "";
+      num_found = 1;
+    }
+
+ fail:
+  if (dev)
+    grub_device_close (dev);
+  grub_free (device);
+  return ret;
+}
+
+/* Complete an argument.  */
+static int
+complete_arguments (char *command)
+{
+  grub_command_t cmd;
+  grub_extcmd_t ext;
+  const struct grub_arg_option *option;
+  char shortarg[] = "- ";
+
+  cmd = grub_command_find (command);
+
+  if (!cmd || !(cmd->flags & GRUB_COMMAND_FLAG_EXTCMD))
+    return 0;
+
+  ext = cmd->data;
+  if (!ext->options)
+    return 0;
+
+  if (add_completion ("-u", " ", GRUB_COMPLETION_TYPE_ARGUMENT))
+    return 1;
+
+  /* Add the short arguments.  */
+  for (option = ext->options; option->doc; option++)
+    {
+      if (! option->shortarg)
+	continue;
+
+      shortarg[1] = option->shortarg;
+      if (add_completion (shortarg, " ", GRUB_COMPLETION_TYPE_ARGUMENT))
+	return 1;
+
+    }
+
+  /* First add the built-in arguments.  */
+  if (add_completion ("--help", " ", GRUB_COMPLETION_TYPE_ARGUMENT))
+    return 1;
+  if (add_completion ("--usage", " ", GRUB_COMPLETION_TYPE_ARGUMENT))
+    return 1;
+
+  /* Add the long arguments.  */
+  for (option = ext->options; option->doc; option++)
+    {
+      char *longarg;
+      if (!option->longarg)
+	continue;
+
+      longarg = grub_malloc (grub_strlen (option->longarg));
+      grub_sprintf (longarg, "--%s", option->longarg);
+
+      if (add_completion (longarg, " ", GRUB_COMPLETION_TYPE_ARGUMENT))
+	{
+	  grub_free (longarg);
+	  return 1;
+	}
+      grub_free (longarg);
+    }
+
+  return 0;
+}
+
+
+static grub_parser_state_t
+get_state (const char *cmdline)
+{
+  grub_parser_state_t state = GRUB_PARSER_STATE_TEXT;
+  char use;
+
+  while (*cmdline)
+    state = grub_parser_cmdline_state (state, *(cmdline++), &use);
+  return state;
+}
+
+
+/* Try to complete the string in BUF. Return the characters that
+   should be added to the string.  This command outputs the possible
+   completions by calling HOOK, in that case set RESTORE to 1 so the
+   caller can restore the prompt.  */
+char *
+grub_normal_do_completion (char *buf, int *restore,
+			   void (*hook) (const char *, grub_completion_type_t, int))
+{
+  int argc;
+  char **argv;
+
+  /* Initialize variables.  */
+  match = 0;
+  num_found = 0;
+  suffix = "";
+  print_func = hook;
+
+  *restore = 1;
+
+  if (grub_parser_split_cmdline (buf, 0, &argc, &argv))
+    return 0;
+
+  current_word = argv[argc];
+
+  /* Determine the state the command line is in, depending on the
+     state, it can be determined how to complete.  */
+  cmdline_state = get_state (buf);
+
+  if (argc == 0)
+    {
+      /* Complete a command.  */
+      if (grub_command_iterate (iterate_command))
+	goto fail;
+    }
+  else if (*current_word == '-')
+    {
+      if (complete_arguments (buf))
+	goto fail;
+    }
+  else if (*current_word == '(' && ! grub_strchr (current_word, ')'))
+    {
+      /* Complete a device.  */
+      if (complete_device ())
+	    goto fail;
+    }
+  else
+    {
+      /* Complete a file.  */
+      if (complete_file ())
+	goto fail;
+    }
+
+  /* If more than one match is found those matches will be printed and
+     the prompt should be restored.  */
+  if (num_found > 1)
+    *restore = 1;
+  else
+    *restore = 0;
+
+  /* Return the part that matches.  */
+  if (match)
+    {
+      char *ret;
+      char *escstr;
+      char *newstr;
+      int current_len;
+      int match_len;
+      int spaces = 0;
+
+      current_len = grub_strlen (current_word);
+      match_len = grub_strlen (match);
+
+      /* Count the number of spaces that have to be escaped.  XXX:
+	 More than just spaces have to be escaped.  */
+      for (escstr = match + current_len; *escstr; escstr++)
+	if (*escstr == ' ')
+	  spaces++;
+
+      ret = grub_malloc (match_len - current_len + grub_strlen (suffix) + spaces + 1);
+      newstr = ret;
+      for (escstr = match + current_len; *escstr; escstr++)
+	{
+	  if (*escstr == ' ' && cmdline_state != GRUB_PARSER_STATE_QUOTE
+	      && cmdline_state != GRUB_PARSER_STATE_QUOTE)
+	    *(newstr++) = '\\';
+	  *(newstr++) = *escstr;
+	}
+      *newstr = '\0';
+
+      if (num_found == 1)
+	grub_strcat (ret, suffix);
+
+      if (*ret == '\0')
+	{
+	  grub_free (ret);
+          goto fail;
+	}
+
+      grub_free (argv[0]);
+      grub_free (match);
+      return ret;
+    }
+
+ fail:
+  grub_free (argv[0]);
+  grub_free (match);
+  grub_errno = GRUB_ERR_NONE;
+
+  return 0;
+}
diff --git a/normal/datetime.c b/normal/datetime.c
new file mode 100644
index 0000000..44791e1
--- /dev/null
+++ b/normal/datetime.c
@@ -0,0 +1,100 @@
+/* datetime.c - Module for common datetime function.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/datetime.h>
+
+static char *grub_weekday_names[] =
+{
+  "Sunday",
+  "Monday",
+  "Tuesday",
+  "Wednesday",
+  "Thursday",
+  "Friday",
+  "Saturday",
+};
+
+int
+grub_get_weekday (struct grub_datetime *datetime)
+{
+  int a, y, m;
+
+  a = (14 - datetime->month) / 12;
+  y = datetime->year - a;
+  m = datetime->month + 12 * a - 2;
+
+  return (datetime->day + y + y / 4 - y / 100 + y / 400 + (31 * m / 12)) % 7;
+}
+
+char *
+grub_get_weekday_name (struct grub_datetime *datetime)
+{
+  return grub_weekday_names[grub_get_weekday (datetime)];
+}
+
+#define SECPERMIN 60
+#define SECPERHOUR (60*SECPERMIN)
+#define SECPERDAY (24*SECPERHOUR)
+#define SECPERYEAR (365*SECPERDAY)
+#define SECPER4YEARS (4*SECPERYEAR+SECPERDAY)
+
+
+void
+grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime)
+{
+  int i;
+  int div;
+  grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+  /* In the period of validity of unixtime all years divisible by 4
+     are bissextile*/
+  /* Convenience: let's have 3 consecutive non-bissextile years
+     at the beginning of the epoch. So count from 1973 instead of 1970 */
+  nix -= 3*SECPERYEAR + SECPERDAY;
+  /* Transform C divisions and modulos to mathematical ones */
+  div = nix / SECPER4YEARS;
+  if (nix < 0)
+    div--;
+  datetime->year = 1973 + 4 * div;
+  nix -= div * SECPER4YEARS;
+
+  /* On 31st December of bissextile years 365 days from the beginning
+     of the year elapsed but year isn't finished yet */
+  if (nix / SECPERYEAR == 4)
+    {
+      datetime->year += 3;
+      nix -= 3*SECPERYEAR;
+    }
+  else
+    {
+      datetime->year += nix / SECPERYEAR;
+      nix %= SECPERYEAR;
+    }
+  for (i = 0; i < 12
+	 && nix >= ((grub_int32_t) (i==1 && datetime->year % 4 == 0
+				    ? 29 : months[i]))*SECPERDAY; i++)
+    nix -= ((grub_int32_t) (i==1 && datetime->year % 4 == 0
+			    ? 29 : months[i]))*SECPERDAY;
+  datetime->month = i + 1;
+  datetime->day = 1 + (nix / SECPERDAY);
+  nix %= SECPERDAY;
+  datetime->hour = (nix / SECPERHOUR);
+  nix %= SECPERHOUR;
+  datetime->minute = nix / SECPERMIN;
+  datetime->second = nix % SECPERMIN;
+}
diff --git a/normal/dyncmd.c b/normal/dyncmd.c
new file mode 100644
index 0000000..154da61
--- /dev/null
+++ b/normal/dyncmd.c
@@ -0,0 +1,158 @@
+/* dyncmd.c - support dynamic command */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/normal.h>
+
+static grub_err_t
+grub_dyncmd_dispatcher (struct grub_command *cmd,
+			int argc, char **args)
+{
+  char *modname = cmd->data;
+  grub_dl_t mod;
+  grub_err_t ret;
+
+  mod = grub_dl_load (modname);
+  if (mod)
+    {
+      char *name;
+
+      grub_free (modname);
+      grub_dl_ref (mod);
+
+      name = (char *) cmd->name;
+      grub_unregister_command (cmd);
+
+      cmd = grub_command_find (name);
+      if (cmd)
+	ret = (cmd->func) (cmd, argc, args);
+      else
+	ret = grub_errno;
+
+      grub_free (name);
+    }
+  else
+    ret = grub_errno;
+
+  return ret;
+}
+
+/* Read the file command.lst for auto-loading.  */
+void
+read_command_list (void)
+{
+  const char *prefix;
+  static int first_time = 1;
+
+  /* Make sure that this function does not get executed twice.  */
+  if (! first_time)
+    return;
+  first_time = 0;
+
+  prefix = grub_env_get ("prefix");
+  if (prefix)
+    {
+      char *filename;
+
+      filename = grub_malloc (grub_strlen (prefix) + sizeof ("/command.lst"));
+      if (filename)
+	{
+	  grub_file_t file;
+
+	  grub_sprintf (filename, "%s/command.lst", prefix);
+	  file = grub_file_open (filename);
+	  if (file)
+	    {
+	      char *buf = 0;
+	      for (;; grub_free(buf))
+		{
+		  char *p, *name, *modname;
+		  grub_command_t cmd;
+		  int prio = 0;
+
+		  buf = grub_file_getline (file);
+
+		  if (! buf)
+		    break;
+
+		  name = buf;
+		  if (*name == '*')
+		    {
+		      name++;
+		      prio++;
+		    }
+
+		  if (! grub_isgraph (name[0]))
+		    continue;
+
+		  p = grub_strchr (name, ':');
+		  if (! p)
+		    continue;
+
+		  *p = '\0';
+		  while (*++p == ' ')
+		    ;
+
+		  if (! grub_isgraph (*p))
+		    continue;
+
+		  if (grub_dl_get (p))
+		    continue;
+
+		  name = grub_strdup (name);
+		  if (! name)
+		    continue;
+
+		  modname = grub_strdup (p);
+		  if (! modname)
+		    {
+		      grub_free (name);
+		      continue;
+		    }
+
+		  cmd = grub_register_command_prio (name,
+						    grub_dyncmd_dispatcher,
+						    0, "not loaded", prio);
+		  if (! cmd)
+		    {
+		      grub_free (name);
+		      grub_free (modname);
+		      continue;
+		    }
+		  cmd->flags |= GRUB_COMMAND_FLAG_DYNCMD;
+		  cmd->data = modname;
+
+		  /* Update the active flag.  */
+		  grub_command_find (name);
+		}
+
+	      grub_file_close (file);
+	    }
+
+	  grub_free (filename);
+	}
+    }
+
+  /* Ignore errors.  */
+  grub_errno = GRUB_ERR_NONE;
+}
diff --git a/normal/handler.c b/normal/handler.c
new file mode 100644
index 0000000..fe31478
--- /dev/null
+++ b/normal/handler.c
@@ -0,0 +1,232 @@
+/* handler.c - support handler loading */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/handler.h>
+#include <grub/normal.h>
+
+struct grub_handler_list
+{
+  struct grub_handler_list *next;
+  char *name;
+  grub_command_t cmd;
+};
+
+static grub_list_t handler_list;
+
+static grub_err_t
+grub_handler_cmd (struct grub_command *cmd,
+		  int argc __attribute__ ((unused)),
+		  char **args __attribute__ ((unused)))
+{
+  char *p;
+  grub_handler_class_t class;
+  grub_handler_t handler;
+
+  p = grub_strchr (cmd->name, '.');
+  if (! p)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid command name");
+
+  if (cmd->data)
+    {
+      if (! grub_dl_get (cmd->data))
+	{
+	  grub_dl_t mod;
+
+	  mod = grub_dl_load (cmd->data);
+	  if (mod)
+	    grub_dl_ref (mod);
+	  else
+	    return grub_errno;
+	}
+      grub_free (cmd->data);
+      cmd->data = 0;
+    }
+
+  *p = 0;
+  class = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_handler_class_list),
+				cmd->name);
+  *p = '.';
+
+  if (! class)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
+
+
+  handler = grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list),
+				  p + 1);
+  if (! handler)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
+
+  grub_handler_set_current (class, handler);
+
+  return 0;
+}
+
+static void
+insert_handler (char *name, char *module)
+{
+  struct grub_handler_list *item;
+  char *data;
+
+  if (grub_command_find (name))
+    return;
+
+  item = grub_malloc (sizeof (*item));
+  if (! item)
+    return;
+
+  item->name = grub_strdup (name);
+  if (! item->name)
+    {
+      grub_free (item);
+      return;
+    }
+
+  if (module)
+    {
+      data = grub_strdup (module);
+      if (! data)
+	{
+	  grub_free (item->name);
+	  grub_free (item);
+	  return;
+	}
+    }
+  else
+    data = 0;
+
+  item->cmd = grub_register_command (item->name, grub_handler_cmd, 0,
+				     "Set active handler");
+  if (! item->cmd)
+    {
+      grub_free (data);
+      grub_free (item->name);
+      grub_free (item);
+      return;
+    }
+
+  item->cmd->data = data;
+  grub_list_push (&handler_list, GRUB_AS_LIST (item));
+}
+
+/* Read the file handler.lst for auto-loading.  */
+void
+read_handler_list (void)
+{
+  const char *prefix;
+  static int first_time = 1;
+  const char *class_name;
+
+  auto int iterate_handler (grub_handler_t handler);
+  int iterate_handler (grub_handler_t handler)
+    {
+      char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2];
+
+      grub_strcpy (name, class_name);
+      grub_strcat (name, ".");
+      grub_strcat (name, handler->name);
+
+      insert_handler (name, 0);
+
+      return 0;
+    }
+
+  auto int iterate_class (grub_handler_class_t class);
+  int iterate_class (grub_handler_class_t class)
+    {
+      class_name = class->name;
+      grub_list_iterate (GRUB_AS_LIST (class->handler_list),
+			 (grub_list_hook_t) iterate_handler);
+
+      return 0;
+    }
+
+  /* Make sure that this function does not get executed twice.  */
+  if (! first_time)
+    return;
+  first_time = 0;
+
+  prefix = grub_env_get ("prefix");
+  if (prefix)
+    {
+      char *filename;
+
+      filename = grub_malloc (grub_strlen (prefix) + sizeof ("/handler.lst"));
+      if (filename)
+	{
+	  grub_file_t file;
+
+	  grub_sprintf (filename, "%s/handler.lst", prefix);
+	  file = grub_file_open (filename);
+	  if (file)
+	    {
+	      char *buf = 0;
+	      for (;; grub_free(buf))
+		{
+		  char *p;
+
+		  buf = grub_file_getline (file);
+
+		  if (! buf)
+		    break;
+
+		  if (! grub_isgraph (buf[0]))
+		    continue;
+
+		  p = grub_strchr (buf, ':');
+		  if (! p)
+		    continue;
+
+		  *p = '\0';
+		  while (*++p == ' ')
+		    ;
+
+		  insert_handler (buf, p);
+		}
+	      grub_file_close (file);
+	    }
+	  grub_free (filename);
+	}
+    }
+
+  grub_list_iterate (GRUB_AS_LIST (grub_handler_class_list),
+		     (grub_list_hook_t) iterate_class);
+
+  /* Ignore errors.  */
+  grub_errno = GRUB_ERR_NONE;
+}
+
+void
+free_handler_list (void)
+{
+  struct grub_handler_list *item;
+
+  while ((item = grub_list_pop (&handler_list)) != 0)
+    {
+      grub_free (item->cmd->data);
+      grub_unregister_command (item->cmd);
+      grub_free (item->name);
+      grub_free (item);
+    }
+}
diff --git a/normal/main.c b/normal/main.c
new file mode 100644
index 0000000..748eef8
--- /dev/null
+++ b/normal/main.c
@@ -0,0 +1,596 @@
+/* main.c - the normal mode main routine */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/term.h>
+#include <grub/env.h>
+#include <grub/parser.h>
+#include <grub/reader.h>
+#include <grub/menu_viewer.h>
+#include <grub/auth.h>
+
+#define GRUB_DEFAULT_HISTORY_SIZE	50
+
+/* Read a line from the file FILE.  */
+char *
+grub_file_getline (grub_file_t file)
+{
+  char c;
+  int pos = 0;
+  int literal = 0;
+  char *cmdline;
+  int max_len = 64;
+
+  /* Initially locate some space.  */
+  cmdline = grub_malloc (max_len);
+  if (! cmdline)
+    return 0;
+
+  while (1)
+    {
+      if (grub_file_read (file, &c, 1) != 1)
+	break;
+
+      /* Skip all carriage returns.  */
+      if (c == '\r')
+	continue;
+
+      /* Replace tabs with spaces.  */
+      if (c == '\t')
+	c = ' ';
+
+      /* The previous is a backslash, then...  */
+      if (literal)
+	{
+	  /* If it is a newline, replace it with a space and continue.  */
+	  if (c == '\n')
+	    {
+	      c = ' ';
+
+	      /* Go back to overwrite the backslash.  */
+	      if (pos > 0)
+		pos--;
+	    }
+
+	  literal = 0;
+	}
+
+      if (c == '\\')
+	literal = 1;
+
+      if (pos == 0)
+	{
+	  if (! grub_isspace (c))
+	    cmdline[pos++] = c;
+	}
+      else
+	{
+	  if (pos >= max_len)
+	    {
+	      char *old_cmdline = cmdline;
+	      max_len = max_len * 2;
+	      cmdline = grub_realloc (cmdline, max_len);
+	      if (! cmdline)
+		{
+		  grub_free (old_cmdline);
+		  return 0;
+		}
+	    }
+
+	  if (c == '\n')
+	    break;
+
+	  cmdline[pos++] = c;
+	}
+    }
+
+  cmdline[pos] = '\0';
+
+  /* If the buffer is empty, don't return anything at all.  */
+  if (pos == 0)
+    {
+      grub_free (cmdline);
+      cmdline = 0;
+    }
+
+  return cmdline;
+}
+
+static void
+free_menu (grub_menu_t menu)
+{
+  grub_menu_entry_t entry = menu->entry_list;
+
+  while (entry)
+    {
+      grub_menu_entry_t next_entry = entry->next;
+
+      grub_free ((void *) entry->title);
+      grub_free ((void *) entry->sourcecode);
+      entry = next_entry;
+    }
+
+  grub_free (menu);
+  grub_env_unset_data_slot ("menu");
+}
+
+static void
+free_menu_entry_classes (struct grub_menu_entry_class *head)
+{
+  /* Free all the classes.  */
+  while (head)
+    {
+      struct grub_menu_entry_class *next;
+
+      grub_free (head->name);
+      next = head->next;
+      grub_free (head);
+      head = next;
+    }
+}
+
+/* Add a menu entry to the current menu context (as given by the environment
+   variable data slot `menu').  As the configuration file is read, the script
+   parser calls this when a menu entry is to be created.  */
+grub_err_t
+grub_normal_add_menu_entry (int argc, const char **args,
+			    const char *sourcecode)
+{
+  const char *menutitle = 0;
+  const char *menusourcecode;
+  grub_menu_t menu;
+  grub_menu_entry_t *last;
+  int failed = 0;
+  int i;
+  struct grub_menu_entry_class *classes_head;  /* Dummy head node for list.  */
+  struct grub_menu_entry_class *classes_tail;
+  char *users = NULL;
+
+  /* Allocate dummy head node for class list.  */
+  classes_head = grub_zalloc (sizeof (struct grub_menu_entry_class));
+  if (! classes_head)
+    return grub_errno;
+  classes_tail = classes_head;
+
+  menu = grub_env_get_data_slot ("menu");
+  if (! menu)
+    return grub_error (GRUB_ERR_MENU, "no menu context");
+
+  last = &menu->entry_list;
+
+  menusourcecode = grub_strdup (sourcecode);
+  if (! menusourcecode)
+    return grub_errno;
+
+  /* Parse menu arguments.  */
+  for (i = 0; i < argc; i++)
+    {
+      /* Capture arguments.  */
+      if (grub_strncmp ("--", args[i], 2) == 0)
+	{
+	  const char *arg = &args[i][2];
+
+	  /* Handle menu class.  */
+	  if (grub_strcmp(arg, "class") == 0)
+	    {
+	      char *class_name;
+	      struct grub_menu_entry_class *new_class;
+
+	      i++;
+	      class_name = grub_strdup (args[i]);
+	      if (! class_name)
+		{
+		  failed = 1;
+		  break;
+		}
+
+	      /* Create a new class and add it at the tail of the list.  */
+	      new_class = grub_zalloc (sizeof (struct grub_menu_entry_class));
+	      if (! new_class)
+		{
+		  grub_free (class_name);
+		  failed = 1;
+		  break;
+		}
+	      /* Fill in the new class node.  */
+	      new_class->name = class_name;
+	      /* Link the tail to it, and make it the new tail.  */
+	      classes_tail->next = new_class;
+	      classes_tail = new_class;
+	      continue;
+	    }
+	  else if (grub_strcmp(arg, "users") == 0)
+	    {
+	      i++;
+	      users = grub_strdup (args[i]);
+	      if (! users)
+		{
+		  failed = 1;
+		  break;
+		}
+
+	      continue;
+	    }
+	  else
+	    {
+	      /* Handle invalid argument.  */
+	      failed = 1;
+	      grub_error (GRUB_ERR_MENU,
+			  "invalid argument for menuentry: %s", args[i]);
+	      break;
+	    }
+	}
+
+      /* Capture title.  */
+      if (! menutitle)
+	{
+	  menutitle = grub_strdup (args[i]);
+	}
+      else
+	{
+	  failed = 1;
+	  grub_error (GRUB_ERR_MENU,
+		      "too many titles for menuentry: %s", args[i]);
+	  break;
+	}
+    }
+
+  /* Validate arguments.  */
+  if ((! failed) && (! menutitle))
+    {
+      grub_error (GRUB_ERR_MENU, "menuentry is missing title");
+      failed = 1;
+    }
+
+  /* If argument parsing failed, free any allocated resources.  */
+  if (failed)
+    {
+      free_menu_entry_classes (classes_head);
+      grub_free ((void *) menutitle);
+      grub_free ((void *) menusourcecode);
+
+      /* Here we assume that grub_error has been used to specify failure details.  */
+      return grub_errno;
+    }
+
+  /* Add the menu entry at the end of the list.  */
+  while (*last)
+    last = &(*last)->next;
+
+  *last = grub_zalloc (sizeof (**last));
+  if (! *last)
+    {
+      free_menu_entry_classes (classes_head);
+      grub_free ((void *) menutitle);
+      grub_free ((void *) menusourcecode);
+      return grub_errno;
+    }
+
+  (*last)->title = menutitle;
+  (*last)->classes = classes_head;
+  if (users)
+    (*last)->restricted = 1;
+  (*last)->users = users;
+  (*last)->sourcecode = menusourcecode;
+
+  menu->size++;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_menu_t
+read_config_file (const char *config)
+{
+  grub_file_t file;
+  grub_parser_t old_parser = 0;
+
+  auto grub_err_t getline (char **line, int cont);
+  grub_err_t getline (char **line, int cont __attribute__ ((unused)))
+    {
+      while (1)
+	{
+	  char *buf;
+
+	  *line = buf = grub_file_getline (file);
+	  if (! buf)
+	    return grub_errno;
+
+	  if (buf[0] == '#')
+	    {
+	      if (buf[1] == '!')
+		{
+		  grub_parser_t parser;
+		  grub_named_list_t list;
+
+		  buf += 2;
+		  while (grub_isspace (*buf))
+		    buf++;
+
+		  if (! old_parser)
+		    old_parser = grub_parser_get_current ();
+
+		  list = GRUB_AS_NAMED_LIST (grub_parser_class.handler_list);
+		  parser = grub_named_list_find (list, buf);
+		  if (parser)
+		    grub_parser_set_current (parser);
+		  else
+		    {
+		      char cmd_name[8 + grub_strlen (buf)];
+
+		      /* Perhaps it's not loaded yet, try the autoload
+			 command.  */
+		      grub_strcpy (cmd_name, "parser.");
+		      grub_strcat (cmd_name, buf);
+		      grub_command_execute (cmd_name, 0, 0);
+		    }
+		}
+	      grub_free (*line);
+	    }
+	  else
+	    break;
+	}
+
+      return GRUB_ERR_NONE;
+    }
+
+  grub_menu_t newmenu;
+
+  newmenu = grub_env_get_data_slot ("menu");
+  if (! newmenu)
+    {
+      newmenu = grub_zalloc (sizeof (*newmenu));
+      if (! newmenu)
+	return 0;
+
+      grub_env_set_data_slot ("menu", newmenu);
+    }
+
+  /* Try to open the config file.  */
+  file = grub_file_open (config);
+  if (! file)
+    return 0;
+
+  grub_reader_loop (getline);
+  grub_file_close (file);
+
+  if (old_parser)
+    grub_parser_set_current (old_parser);
+
+  return newmenu;
+}
+
+/* Initialize the screen.  */
+void
+grub_normal_init_page (void)
+{
+  grub_uint8_t width, margin;
+
+#define TITLE ("GNU GRUB  version " PACKAGE_VERSION)
+
+  width = grub_getwh () >> 8;
+  margin = (width - (sizeof(TITLE) + 7)) / 2;
+
+  grub_cls ();
+  grub_putchar ('\n');
+
+  while (margin--)
+    grub_putchar (' ');
+
+  grub_printf ("%s\n\n", TITLE);
+
+#undef TITLE
+}
+
+static int reader_nested;
+
+/* Read the config file CONFIG and execute the menu interface or
+   the command line interface if BATCH is false.  */
+void
+grub_normal_execute (const char *config, int nested, int batch)
+{
+  grub_menu_t menu = 0;
+
+  read_command_list ();
+  read_fs_list ();
+  read_handler_list ();
+  grub_command_execute ("parser.sh", 0, 0);
+
+  reader_nested = nested;
+
+  if (config)
+    {
+      menu = read_config_file (config);
+
+      /* Ignore any error.  */
+      grub_errno = GRUB_ERR_NONE;
+    }
+
+  if (! batch)
+    {
+      if (menu && menu->size)
+	{
+	  grub_menu_viewer_show_menu (menu, nested);
+	  if (nested)
+	    free_menu (menu);
+	}
+    }
+}
+
+/* This starts the normal mode.  */
+void
+grub_enter_normal_mode (const char *config)
+{
+  grub_normal_execute (config, 0, 0);
+}
+
+/* Enter normal mode from rescue mode.  */
+static grub_err_t
+grub_cmd_normal (struct grub_command *cmd,
+		 int argc, char *argv[])
+{
+  grub_unregister_command (cmd);
+
+  if (argc == 0)
+    {
+      /* Guess the config filename. It is necessary to make CONFIG static,
+	 so that it won't get broken by longjmp.  */
+      static char *config;
+      const char *prefix;
+
+      prefix = grub_env_get ("prefix");
+      if (prefix)
+	{
+	  config = grub_malloc (grub_strlen (prefix) + sizeof ("/grub.cfg"));
+	  if (! config)
+	    goto quit;
+
+	  grub_sprintf (config, "%s/grub.cfg", prefix);
+	  grub_enter_normal_mode (config);
+	  grub_free (config);
+	}
+      else
+	grub_enter_normal_mode (0);
+    }
+  else
+    grub_enter_normal_mode (argv[0]);
+
+quit:
+  return 0;
+}
+
+void
+grub_cmdline_run (int nested)
+{
+  grub_reader_t reader;
+  grub_err_t err = GRUB_ERR_NONE;
+
+  err = grub_auth_check_authentication (NULL);
+
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  reader = grub_reader_get_current ();
+
+  reader_nested = nested;
+  if (reader->init)
+    reader->init ();
+  grub_reader_loop (0);
+}
+
+static grub_err_t
+grub_normal_reader_init (void)
+{
+  grub_normal_init_page ();
+  grub_setcursor (1);
+
+  grub_printf ("\
+ [ Minimal BASH-like line editing is supported. For the first word, TAB\n\
+   lists possible command completions. Anywhere else TAB lists possible\n\
+   device/file completions.%s ]\n\n",
+	       reader_nested ? " ESC at any time exits." : "");
+
+  return 0;
+}
+
+static char cmdline[GRUB_MAX_CMDLINE];
+
+static grub_err_t
+grub_normal_read_line (char **line, int cont)
+{
+  grub_parser_t parser = grub_parser_get_current ();
+  char prompt[8 + grub_strlen (parser->name)];
+
+  grub_sprintf (prompt, "%s:%s> ", parser->name, (cont) ? "" : "grub");
+
+  while (1)
+    {
+      cmdline[0] = 0;
+      if (grub_cmdline_get (prompt, cmdline, sizeof (cmdline), 0, 1, 1))
+	break;
+
+      if ((reader_nested) || (cont))
+	{
+	  *line = 0;
+	  return grub_errno;
+	}
+    }
+
+  *line = grub_strdup (cmdline);
+  return 0;
+}
+
+static struct grub_reader grub_normal_reader =
+  {
+    .name = "normal",
+    .init = grub_normal_reader_init,
+    .read_line = grub_normal_read_line
+  };
+
+static char *
+grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)),
+		      const char *val)
+{
+  grub_set_more ((*val == '1'));
+  return grub_strdup (val);
+}
+
+GRUB_MOD_INIT(normal)
+{
+  /* Normal mode shouldn't be unloaded.  */
+  if (mod)
+    grub_dl_ref (mod);
+
+  grub_menu_viewer_register (&grub_normal_text_menu_viewer);
+
+  grub_set_history (GRUB_DEFAULT_HISTORY_SIZE);
+
+  grub_reader_register ("normal", &grub_normal_reader);
+  grub_reader_set_current (&grub_normal_reader);
+  grub_register_variable_hook ("pager", 0, grub_env_write_pager);
+
+  /* Register a command "normal" for the rescue mode.  */
+  grub_register_command_prio ("normal", grub_cmd_normal,
+			      0, "Enter normal mode", 0);
+
+  /* Reload terminal colors when these variables are written to.  */
+  grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal);
+  grub_register_variable_hook ("color_highlight", NULL, grub_env_write_color_highlight);
+
+  /* Preserve hooks after context changes.  */
+  grub_env_export ("color_normal");
+  grub_env_export ("color_highlight");
+}
+
+GRUB_MOD_FINI(normal)
+{
+  grub_set_history (0);
+  grub_reader_unregister (&grub_normal_reader);
+  grub_register_variable_hook ("pager", 0, 0);
+  grub_fs_autoload_hook = 0;
+  free_handler_list ();
+}
diff --git a/normal/menu.c b/normal/menu.c
new file mode 100644
index 0000000..8ee7d1c
--- /dev/null
+++ b/normal/menu.c
@@ -0,0 +1,180 @@
+/* menu.c - General supporting functionality for menus.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/misc.h>
+#include <grub/loader.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/env.h>
+#include <grub/menu_viewer.h>
+#include <grub/command.h>
+#include <grub/parser.h>
+#include <grub/auth.h>
+
+/* Get a menu entry by its index in the entry list.  */
+grub_menu_entry_t
+grub_menu_get_entry (grub_menu_t menu, int no)
+{
+  grub_menu_entry_t e;
+
+  for (e = menu->entry_list; e && no > 0; e = e->next, no--)
+    ;
+
+  return e;
+}
+
+/* Return the current timeout. If the variable "timeout" is not set or
+   invalid, return -1.  */
+int
+grub_menu_get_timeout (void)
+{
+  char *val;
+  int timeout;
+
+  val = grub_env_get ("timeout");
+  if (! val)
+    return -1;
+
+  grub_error_push ();
+
+  timeout = (int) grub_strtoul (val, 0, 0);
+
+  /* If the value is invalid, unset the variable.  */
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_env_unset ("timeout");
+      grub_errno = GRUB_ERR_NONE;
+      timeout = -1;
+    }
+
+  grub_error_pop ();
+
+  return timeout;
+}
+
+/* Set current timeout in the variable "timeout".  */
+void
+grub_menu_set_timeout (int timeout)
+{
+  /* Ignore TIMEOUT if it is zero, because it will be unset really soon.  */
+  if (timeout > 0)
+    {
+      char buf[16];
+
+      grub_sprintf (buf, "%d", timeout);
+      grub_env_set ("timeout", buf);
+    }
+}
+
+/* Get the first entry number from the value of the environment variable NAME,
+   which is a space-separated list of non-negative integers.  The entry number
+   which is returned is stripped from the value of NAME.  If no entry number
+   can be found, -1 is returned.  */
+static int
+get_and_remove_first_entry_number (const char *name)
+{
+  char *val;
+  char *tail;
+  int entry;
+
+  val = grub_env_get (name);
+  if (! val)
+    return -1;
+
+  grub_error_push ();
+
+  entry = (int) grub_strtoul (val, &tail, 0);
+
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      /* Skip whitespace to find the next digit.  */
+      while (*tail && grub_isspace (*tail))
+	tail++;
+      grub_env_set (name, tail);
+    }
+  else
+    {
+      grub_env_unset (name);
+      grub_errno = GRUB_ERR_NONE;
+      entry = -1;
+    }
+
+  grub_error_pop ();
+
+  return entry;
+}
+
+/* Run a menu entry.  */
+void
+grub_menu_execute_entry(grub_menu_entry_t entry)
+{
+  grub_err_t err = GRUB_ERR_NONE;
+
+  if (entry->restricted)
+    err = grub_auth_check_authentication (entry->users);
+
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  grub_parser_execute ((char *) entry->sourcecode);
+
+  if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
+    /* Implicit execution of boot, only if something is loaded.  */
+    grub_command_execute ("boot", 0, 0);
+}
+
+/* Execute ENTRY from the menu MENU, falling back to entries specified
+   in the environment variable "fallback" if it fails.  CALLBACK is a
+   pointer to a struct of function pointers which are used to allow the
+   caller provide feedback to the user.  */
+void
+grub_menu_execute_with_fallback (grub_menu_t menu,
+				 grub_menu_entry_t entry,
+				 grub_menu_execute_callback_t callback,
+				 void *callback_data)
+{
+  int fallback_entry;
+
+  callback->notify_booting (entry, callback_data);
+
+  grub_menu_execute_entry (entry);
+
+  /* Deal with fallback entries.  */
+  while ((fallback_entry = get_and_remove_first_entry_number ("fallback"))
+	 >= 0)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+
+      entry = grub_menu_get_entry (menu, fallback_entry);
+      callback->notify_fallback (entry, callback_data);
+      grub_menu_execute_entry (entry);
+      /* If the function call to execute the entry returns at all, then this is
+	 taken to indicate a boot failure.  For menu entries that do something
+	 other than actually boot an operating system, this could assume
+	 incorrectly that something failed.  */
+    }
+
+  callback->notify_failure (callback_data);
+}
diff --git a/normal/menu_entry.c b/normal/menu_entry.c
new file mode 100644
index 0000000..75a6377
--- /dev/null
+++ b/normal/menu_entry.c
@@ -0,0 +1,1181 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/loader.h>
+#include <grub/command.h>
+#include <grub/parser.h>
+#include <grub/auth.h>
+
+enum update_mode
+  {
+    NO_LINE,
+    SINGLE_LINE,
+    ALL_LINES
+  };
+
+struct line
+{
+  /* The line buffer.  */
+  char *buf;
+  /* The length of the line.  */
+  int len;
+  /* The maximum length of the line.  */
+  int max_len;
+};
+
+struct screen
+{
+  /* The array of lines.  */
+  struct line *lines;
+  /* The number of lines.  */
+  int num_lines;
+  /* The current column.  */
+  int column;
+  /* The real column.  */
+  int real_column;
+  /* The current line.  */
+  int line;
+  /* The X coordinate.  */
+  int x;
+  /* The Y coordinate.  */
+  int y;
+  /* The kill buffer.  */
+  char *killed_text;
+  /* The flag of a completion window.  */
+  int completion_shown;
+};
+
+/* Used for storing completion items temporarily.  */
+static struct line completion_buffer;
+
+/* Initialize a line.  */
+static int
+init_line (struct line *linep)
+{
+  linep->len = 0;
+  linep->max_len = 80; /* XXX */
+  linep->buf = grub_malloc (linep->max_len);
+  if (! linep->buf)
+    return 0;
+
+  return 1;
+}
+
+/* Allocate extra space if necessary.  */
+static int
+ensure_space (struct line *linep, int extra)
+{
+  if (linep->max_len < linep->len + extra)
+    {
+      linep->max_len = linep->len + extra + 80; /* XXX */
+      linep->buf = grub_realloc (linep->buf, linep->max_len + 1);
+      if (! linep->buf)
+	return 0;
+    }
+
+  return 1;
+}
+
+/* Return the number of lines occupied by this line on the screen.  */
+static int
+get_logical_num_lines (struct line *linep)
+{
+  return (linep->len / GRUB_TERM_ENTRY_WIDTH) + 1;
+}
+
+/* Print a line.  */
+static void
+print_line (struct line *linep, int offset, int start, int y)
+{
+  int i;
+  char *p;
+
+  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + start + 1,
+	       y + GRUB_TERM_FIRST_ENTRY_Y);
+
+  for (p = linep->buf + offset + start, i = start;
+       i < GRUB_TERM_ENTRY_WIDTH && offset + i < linep->len;
+       p++, i++)
+    grub_putchar (*p);
+
+  for (; i < GRUB_TERM_ENTRY_WIDTH; i++)
+    grub_putchar (' ');
+
+  if (linep->len >= offset + GRUB_TERM_ENTRY_WIDTH)
+    grub_putchar ('\\');
+  else
+    grub_putchar (' ');
+}
+
+/* Print an empty line.  */
+static void
+print_empty_line (int y)
+{
+  int i;
+
+  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
+	       y + GRUB_TERM_FIRST_ENTRY_Y);
+
+  for (i = 0; i < GRUB_TERM_ENTRY_WIDTH + 1; i++)
+    grub_putchar (' ');
+}
+
+/* Print an up arrow.  */
+static void
+print_up (int flag)
+{
+  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
+	       GRUB_TERM_FIRST_ENTRY_Y);
+
+  if (flag)
+    grub_putcode (GRUB_TERM_DISP_UP);
+  else
+    grub_putchar (' ');
+}
+
+/* Print a down arrow.  */
+static void
+print_down (int flag)
+{
+  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
+	       GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES);
+
+  if (flag)
+    grub_putcode (GRUB_TERM_DISP_DOWN);
+  else
+    grub_putchar (' ');
+}
+
+/* Draw the lines of the screen SCREEN.  */
+static void
+update_screen (struct screen *screen, int region_start, int region_column,
+	       int up, int down, enum update_mode mode)
+{
+  int up_flag = 0;
+  int down_flag = 0;
+  int y;
+  int i;
+  struct line *linep;
+
+  /* Check if scrolling is necessary.  */
+  if (screen->y < 0 || screen->y >= GRUB_TERM_NUM_ENTRIES)
+    {
+      if (screen->y < 0)
+	screen->y = 0;
+      else
+	screen->y = GRUB_TERM_NUM_ENTRIES - 1;
+
+      region_start = 0;
+      region_column = 0;
+      up = 1;
+      down = 1;
+      mode = ALL_LINES;
+    }
+
+  if (mode != NO_LINE)
+    {
+      /* Draw lines. This code is tricky, because this must calculate logical
+	 positions.  */
+      y = screen->y - screen->column / GRUB_TERM_ENTRY_WIDTH;
+      i = screen->line;
+      linep = screen->lines + i;
+      while (y > 0)
+	{
+	   i--;
+	   linep--;
+	   y -= get_logical_num_lines (linep);
+	}
+
+      if (y < 0 || i > 0)
+	up_flag = 1;
+
+      do
+	{
+	  int column;
+
+	  for (column = 0;
+	       column <= linep->len && y < GRUB_TERM_NUM_ENTRIES;
+	       column += GRUB_TERM_ENTRY_WIDTH, y++)
+	    {
+	      if (y < 0)
+		continue;
+
+	      if (i == region_start)
+		{
+		  if (region_column >= column
+		      && region_column < column + GRUB_TERM_ENTRY_WIDTH)
+		    print_line (linep, column, region_column - column, y);
+		  else if (region_column < column)
+		    print_line (linep, column, 0, y);
+		}
+	      else if (i > region_start && mode == ALL_LINES)
+		print_line (linep, column, 0, y);
+	    }
+
+	  if (y == GRUB_TERM_NUM_ENTRIES)
+	    {
+	      if (column <= linep->len || i + 1 < screen->num_lines)
+		down_flag = 1;
+	    }
+
+	  linep++;
+	  i++;
+
+	  if (mode == ALL_LINES && i == screen->num_lines)
+	    for (; y < GRUB_TERM_NUM_ENTRIES; y++)
+	      print_empty_line (y);
+
+	}
+      while (y < GRUB_TERM_NUM_ENTRIES);
+
+      /* Draw up and down arrows.  */
+      if (up)
+	print_up (up_flag);
+      if (down)
+	print_down (down_flag);
+    }
+
+  /* Place the cursor.  */
+  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1 + screen->x,
+	       GRUB_TERM_FIRST_ENTRY_Y + screen->y);
+
+  grub_refresh ();
+}
+
+/* Insert the string S into the screen SCREEN. This updates the cursor
+   position and redraw the screen. Return zero if fails.  */
+static int
+insert_string (struct screen *screen, char *s, int update)
+{
+  int region_start = screen->num_lines;
+  int region_column = 0;
+  int down = 0;
+  enum update_mode mode = NO_LINE;
+
+  while (*s)
+    {
+      if (*s == '\n')
+	{
+	  /* LF is special because it creates a new line.  */
+	  struct line *current_linep;
+	  struct line *next_linep;
+	  int size;
+
+	  /* Make a new line.  */
+	  screen->num_lines++;
+	  screen->lines = grub_realloc (screen->lines,
+					screen->num_lines
+					* sizeof (struct line));
+	  if (! screen->lines)
+	    return 0;
+
+	  /* Scroll down. */
+	  grub_memmove (screen->lines + screen->line + 2,
+			screen->lines + screen->line + 1,
+			((screen->num_lines - screen->line - 2)
+			 * sizeof (struct line)));
+
+	  if (! init_line (screen->lines + screen->line + 1))
+	    return 0;
+
+	  /* Fold the line.  */
+	  current_linep = screen->lines + screen->line;
+	  next_linep = current_linep + 1;
+	  size = current_linep->len - screen->column;
+
+	  if (! ensure_space (next_linep, size))
+	    return 0;
+
+	  grub_memmove (next_linep->buf,
+			current_linep->buf + screen->column,
+			size);
+	  current_linep->len = screen->column;
+	  next_linep->len = size;
+
+	  /* Update a dirty region.  */
+	  if (region_start > screen->line)
+	    {
+	      region_start = screen->line;
+	      region_column = screen->column;
+	    }
+
+	  mode = ALL_LINES;
+	  down = 1; /* XXX not optimal.  */
+
+	  /* Move the cursor.  */
+	  screen->column = screen->real_column = 0;
+	  screen->line++;
+	  screen->x = 0;
+	  screen->y++;
+
+	  s++;
+	}
+      else
+	{
+	  /* All but LF.  */
+	  char *p;
+	  struct line *current_linep;
+	  int size;
+	  int orig_num, new_num;
+
+	  /* Find a string delimited by LF.  */
+	  p = grub_strchr (s, '\n');
+	  if (! p)
+	    p = s + grub_strlen (s);
+
+	  /* Insert the string.  */
+	  current_linep = screen->lines + screen->line;
+	  size = p - s;
+	  if (! ensure_space (current_linep, size))
+	    return 0;
+
+	  grub_memmove (current_linep->buf + screen->column + size,
+			current_linep->buf + screen->column,
+			current_linep->len - screen->column);
+	  grub_memmove (current_linep->buf + screen->column,
+			s,
+			size);
+	  orig_num = get_logical_num_lines (current_linep);
+	  current_linep->len += size;
+	  new_num = get_logical_num_lines (current_linep);
+
+	  /* Update the dirty region.  */
+	  if (region_start > screen->line)
+	    {
+	      region_start = screen->line;
+	      region_column = screen->column;
+	    }
+
+	  if (orig_num != new_num)
+	    {
+	      mode = ALL_LINES;
+	      down = 1; /* XXX not optimal.  */
+	    }
+	  else if (mode != ALL_LINES)
+	    mode = SINGLE_LINE;
+
+	  /* Move the cursor.  */
+	  screen->column += size;
+	  screen->real_column = screen->column;
+	  screen->x += size;
+	  screen->y += screen->x / GRUB_TERM_ENTRY_WIDTH;
+	  screen->x %= GRUB_TERM_ENTRY_WIDTH;
+
+	  s = p;
+	}
+    }
+
+  if (update)
+    update_screen (screen, region_start, region_column, 0, down, mode);
+
+  return 1;
+}
+
+/* Release the resource allocated for SCREEN.  */
+static void
+destroy_screen (struct screen *screen)
+{
+  int i;
+
+  if (screen->lines)
+    for (i = 0; i < screen->num_lines; i++)
+      {
+	struct line *linep = screen->lines + i;
+
+	if (linep)
+	  grub_free (linep->buf);
+      }
+
+  grub_free (screen->killed_text);
+  grub_free (screen->lines);
+  grub_free (screen);
+}
+
+/* Make a new screen.  */
+static struct screen *
+make_screen (grub_menu_entry_t entry)
+{
+  struct screen *screen;
+
+  /* Initialize the screen.  */
+  screen = grub_zalloc (sizeof (*screen));
+  if (! screen)
+    return 0;
+
+  screen->num_lines = 1;
+  screen->lines = grub_malloc (sizeof (struct line));
+  if (! screen->lines)
+    goto fail;
+
+  /* Initialize the first line which must be always present.  */
+  if (! init_line (screen->lines))
+    goto fail;
+
+  insert_string (screen, (char *) entry->sourcecode, 0);
+
+  /* Reset the cursor position.  */
+  screen->column = 0;
+  screen->real_column = 0;
+  screen->line = 0;
+  screen->x = 0;
+  screen->y = 0;
+
+  return screen;
+
+ fail:
+  destroy_screen (screen);
+  return 0;
+}
+
+static int
+forward_char (struct screen *screen, int update)
+{
+  struct line *linep;
+
+  linep = screen->lines + screen->line;
+  if (screen->column < linep->len)
+    {
+      screen->column++;
+      screen->x++;
+      if (screen->x == GRUB_TERM_ENTRY_WIDTH)
+	{
+	  screen->x = 0;
+	  screen->y++;
+	}
+    }
+  else if (screen->num_lines > screen->line + 1)
+    {
+      screen->column = 0;
+      screen->line++;
+      screen->x = 0;
+      screen->y++;
+    }
+
+  screen->real_column = screen->column;
+
+  if (update)
+    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+  return 1;
+}
+
+static int
+backward_char (struct screen *screen, int update)
+{
+  if (screen->column > 0)
+    {
+      screen->column--;
+      screen->x--;
+      if (screen->x == -1)
+	{
+	  screen->x = GRUB_TERM_ENTRY_WIDTH - 1;
+	  screen->y--;
+	}
+    }
+  else if (screen->line > 0)
+    {
+      struct line *linep;
+
+      screen->line--;
+      linep = screen->lines + screen->line;
+      screen->column = linep->len;
+      screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
+      screen->y--;
+    }
+
+  screen->real_column = screen->column;
+
+  if (update)
+    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+
+  return 1;
+}
+
+static int
+previous_line (struct screen *screen, int update)
+{
+  if (screen->line > 0)
+    {
+      struct line *linep;
+      int dy;
+
+      /* How many physical lines from the current position
+	 to the first physical line?  */
+      dy = screen->column / GRUB_TERM_ENTRY_WIDTH;
+
+      screen->line--;
+
+      linep = screen->lines + screen->line;
+      if (linep->len < screen->real_column)
+	screen->column = linep->len;
+      else
+	screen->column = screen->real_column;
+
+      /* How many physical lines from the current position
+	 to the last physical line?  */
+      dy += (linep->len / GRUB_TERM_ENTRY_WIDTH
+	     - screen->column / GRUB_TERM_ENTRY_WIDTH);
+
+      screen->y -= dy + 1;
+      screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
+    }
+  else
+    {
+      screen->y -= screen->column / GRUB_TERM_ENTRY_WIDTH;
+      screen->column = 0;
+      screen->x = 0;
+    }
+
+  if (update)
+    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+
+  return 1;
+}
+
+static int
+next_line (struct screen *screen, int update)
+{
+  if (screen->line < screen->num_lines - 1)
+    {
+      struct line *linep;
+      int dy;
+
+      /* How many physical lines from the current position
+	 to the last physical line?  */
+      linep = screen->lines + screen->line;
+      dy = (linep->len / GRUB_TERM_ENTRY_WIDTH
+	    - screen->column / GRUB_TERM_ENTRY_WIDTH);
+
+      screen->line++;
+
+      linep++;
+      if (linep->len < screen->real_column)
+	screen->column = linep->len;
+      else
+	screen->column = screen->real_column;
+
+      /* How many physical lines from the current position
+	 to the first physical line?  */
+      dy += screen->column / GRUB_TERM_ENTRY_WIDTH;
+
+      screen->y += dy + 1;
+      screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
+    }
+  else
+    {
+      struct line *linep;
+
+      linep = screen->lines + screen->line;
+      screen->y += (linep->len / GRUB_TERM_ENTRY_WIDTH
+		    - screen->column / GRUB_TERM_ENTRY_WIDTH);
+      screen->column = linep->len;
+      screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
+    }
+
+  if (update)
+    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+
+  return 1;
+}
+
+static int
+beginning_of_line (struct screen *screen, int update)
+{
+  screen->y -= screen->column / GRUB_TERM_ENTRY_WIDTH;
+  screen->column = screen->real_column = 0;
+  screen->x = 0;
+
+  if (update)
+    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+
+  return 1;
+}
+
+static int
+end_of_line (struct screen *screen, int update)
+{
+  struct line *linep;
+
+  linep = screen->lines + screen->line;
+  screen->y += (linep->len / GRUB_TERM_ENTRY_WIDTH
+		- screen->column / GRUB_TERM_ENTRY_WIDTH);
+  screen->column = screen->real_column = linep->len;
+  screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
+
+  if (update)
+    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+
+  return 1;
+}
+
+static int
+delete_char (struct screen *screen, int update)
+{
+  struct line *linep;
+  enum update_mode mode = NO_LINE;
+  int start = screen->num_lines;
+  int column = 0;
+  int down = 0;
+
+  linep = screen->lines + screen->line;
+  if (linep->len > screen->column)
+    {
+      int orig_num, new_num;
+
+      orig_num = get_logical_num_lines (linep);
+
+      grub_memmove (linep->buf + screen->column,
+		    linep->buf + screen->column + 1,
+		    linep->len - screen->column - 1);
+      linep->len--;
+
+      new_num = get_logical_num_lines (linep);
+
+      if (orig_num != new_num)
+	mode = ALL_LINES;
+      else
+	mode = SINGLE_LINE;
+
+      start = screen->line;
+      column = screen->column;
+    }
+  else if (screen->num_lines > screen->line + 1)
+    {
+      struct line *next_linep;
+
+      next_linep = linep + 1;
+      if (! ensure_space (linep, next_linep->len))
+	return 0;
+
+      grub_memmove (linep->buf + linep->len, next_linep->buf, next_linep->len);
+      linep->len += next_linep->len;
+
+      grub_free (next_linep->buf);
+      grub_memmove (next_linep,
+		    next_linep + 1,
+		    (screen->num_lines - screen->line - 2)
+		    * sizeof (struct line));
+      screen->num_lines--;
+
+      mode = ALL_LINES;
+      start = screen->line;
+      column = screen->column;
+      down = 1;
+    }
+
+  screen->real_column = screen->column;
+
+  if (update)
+    update_screen (screen, start, column, 0, down, mode);
+
+  return 1;
+}
+
+static int
+backward_delete_char (struct screen *screen, int update)
+{
+  int saved_column;
+  int saved_line;
+
+  saved_column = screen->column;
+  saved_line = screen->line;
+
+  if (! backward_char (screen, 0))
+    return 0;
+
+  if (saved_column != screen->column || saved_line != screen->line)
+    if (! delete_char (screen, update))
+      return 0;
+
+  return 1;
+}
+
+static int
+kill_line (struct screen *screen, int continuous, int update)
+{
+  struct line *linep;
+  char *p;
+  int size;
+  int offset;
+
+  p = screen->killed_text;
+  if (! continuous && p)
+    p[0] = '\0';
+
+  linep = screen->lines + screen->line;
+  size = linep->len - screen->column;
+
+  if (p)
+    offset = grub_strlen (p);
+  else
+    offset = 0;
+
+  if (size > 0)
+    {
+      enum update_mode mode = SINGLE_LINE;
+      int down = 0;
+      int orig_num, new_num;
+
+      p = grub_realloc (p, offset + size + 1);
+      if (! p)
+	return 0;
+
+      grub_memmove (p + offset, linep->buf + screen->column, size);
+      p[offset + size - 1] = '\0';
+
+      screen->killed_text = p;
+
+      orig_num = get_logical_num_lines (linep);
+      linep->len = screen->column;
+      new_num = get_logical_num_lines (linep);
+
+      if (orig_num != new_num)
+	{
+	  mode = ALL_LINES;
+	  down = 1;
+	}
+
+      if (update)
+	update_screen (screen, screen->line, screen->column, 0, down, mode);
+    }
+  else if (screen->line + 1 < screen->num_lines)
+    {
+      p = grub_realloc (p, offset + 1 + 1);
+      if (! p)
+	return 0;
+
+      p[offset] = '\n';
+      p[offset + 1] = '\0';
+
+      screen->killed_text = p;
+
+      return delete_char (screen, update);
+    }
+
+  return 1;
+}
+
+static int
+yank (struct screen *screen, int update)
+{
+  if (screen->killed_text)
+    return insert_string (screen, screen->killed_text, update);
+
+  return 1;
+}
+
+static int
+open_line (struct screen *screen, int update)
+{
+  int saved_y = screen->y;
+
+  if (! insert_string (screen, "\n", 0))
+    return 0;
+
+  if (! backward_char (screen, 0))
+    return 0;
+
+  screen->y = saved_y;
+
+  if (update)
+    update_screen (screen, screen->line, screen->column, 0, 1, ALL_LINES);
+
+  return 1;
+}
+
+/* A completion hook to print items.  */
+static void
+store_completion (const char *item, grub_completion_type_t type, int count)
+{
+  char *p;
+
+  if (count == 0)
+    {
+      /* If this is the first time, print a label.  */
+      const char *what;
+
+      switch (type)
+	{
+	case GRUB_COMPLETION_TYPE_COMMAND:
+	  what = "commands";
+	  break;
+	case GRUB_COMPLETION_TYPE_DEVICE:
+	  what = "devices";
+	  break;
+	case GRUB_COMPLETION_TYPE_FILE:
+	  what = "files";
+	  break;
+	case GRUB_COMPLETION_TYPE_PARTITION:
+	  what = "partitions";
+	  break;
+	case GRUB_COMPLETION_TYPE_ARGUMENT:
+	  what = "arguments";
+	  break;
+	default:
+	  what = "things";
+	  break;
+	}
+
+      grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
+      grub_printf ("   Possible %s are:\n    ", what);
+    }
+
+  /* Make sure that the completion buffer has enough room.  */
+  if (completion_buffer.max_len < (completion_buffer.len
+				   + (int) grub_strlen (item) + 1 + 1))
+    {
+      grub_size_t new_len;
+
+      new_len = completion_buffer.len + grub_strlen (item) + 80;
+      p = grub_realloc (completion_buffer.buf, new_len);
+      if (! p)
+	{
+	  /* Possibly not fatal.  */
+	  grub_errno = GRUB_ERR_NONE;
+	  return;
+	}
+      p[completion_buffer.len] = 0;
+      completion_buffer.buf = p;
+      completion_buffer.max_len = new_len;
+    }
+
+  p = completion_buffer.buf + completion_buffer.len;
+  if (completion_buffer.len != 0)
+    {
+      *p++ = ' ';
+      completion_buffer.len++;
+    }
+  grub_strcpy (p, item);
+  completion_buffer.len += grub_strlen (item);
+}
+
+static int
+complete (struct screen *screen, int continuous, int update)
+{
+  grub_uint16_t pos;
+  char saved_char;
+  struct line *linep;
+  int restore;
+  char *insert;
+  static int count = -1;
+
+  if (continuous)
+    count++;
+  else
+    count = 0;
+
+  pos = grub_getxy ();
+  grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
+
+  completion_buffer.buf = 0;
+  completion_buffer.len = 0;
+  completion_buffer.max_len = 0;
+
+  linep = screen->lines + screen->line;
+  saved_char = linep->buf[screen->column];
+  linep->buf[screen->column] = '\0';
+
+  insert = grub_normal_do_completion (linep->buf, &restore, store_completion);
+
+  linep->buf[screen->column] = saved_char;
+
+  if (restore)
+    {
+      char *p = completion_buffer.buf;
+
+      screen->completion_shown = 1;
+
+      if (p)
+	{
+	  int num_sections = ((completion_buffer.len + GRUB_TERM_WIDTH - 8 - 1)
+			      / (GRUB_TERM_WIDTH - 8));
+	  char *endp;
+
+	  p += (count % num_sections) * (GRUB_TERM_WIDTH - 8);
+	  endp = p + (GRUB_TERM_WIDTH - 8);
+
+	  if (p != completion_buffer.buf)
+	    grub_putcode (GRUB_TERM_DISP_LEFT);
+	  else
+	    grub_putchar (' ');
+
+	  while (*p && p < endp)
+	    grub_putchar (*p++);
+
+	  if (*p)
+	    grub_putcode (GRUB_TERM_DISP_RIGHT);
+	}
+    }
+
+  grub_gotoxy (pos >> 8, pos & 0xFF);
+
+  if (insert)
+    {
+      insert_string (screen, insert, update);
+      count = -1;
+      grub_free (insert);
+    }
+  else if (update)
+    grub_refresh ();
+
+  grub_free (completion_buffer.buf);
+  return 1;
+}
+
+/* Clear displayed completions.  */
+static void
+clear_completions (void)
+{
+  grub_uint16_t pos;
+  int i, j;
+
+  pos = grub_getxy ();
+  grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
+
+  for (i = 0; i < 2; i++)
+    {
+      for (j = 0; j < GRUB_TERM_WIDTH - 1; j++)
+	grub_putchar (' ');
+      grub_putchar ('\n');
+    }
+
+  grub_gotoxy (pos >> 8, pos & 0xFF);
+  grub_refresh ();
+}
+
+/* Execute the command list in the screen SCREEN.  */
+static int
+run (struct screen *screen)
+{
+  int currline = 0;
+  char *nextline;
+
+  auto grub_err_t editor_getline (char **line, int cont);
+  grub_err_t editor_getline (char **line, int cont __attribute__ ((unused)))
+    {
+      struct line *linep = screen->lines + currline;
+      char *p;
+
+      if (currline > screen->num_lines)
+	{
+	  *line = 0;
+	  return 0;
+	}
+
+      /* Trim down space characters.  */
+      for (p = linep->buf + linep->len - 1;
+	   p >= linep->buf && grub_isspace (*p);
+	   p--)
+	;
+      *++p = '\0';
+
+      linep->len = p - linep->buf;
+      for (p = linep->buf; grub_isspace (*p); p++)
+	;
+      *line = grub_strdup (p);
+      currline++;
+      return 0;
+    }
+
+  grub_cls ();
+  grub_printf ("  Booting a command list\n\n");
+
+
+  /* Execute the script, line for line.  */
+  while (currline < screen->num_lines)
+    {
+      editor_getline (&nextline, 0);
+      if (grub_parser_get_current ()->parse_line (nextline, editor_getline))
+	break;
+    }
+
+  if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
+    /* Implicit execution of boot, only if something is loaded.  */
+    grub_command_execute ("boot", 0, 0);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      grub_wait_after_message ();
+    }
+
+  return 1;
+}
+
+/* Edit a menu entry with an Emacs-like interface.  */
+void
+grub_menu_entry_run (grub_menu_entry_t entry)
+{
+  struct screen *screen;
+  int prev_c;
+  grub_err_t err = GRUB_ERR_NONE;
+
+  err = grub_auth_check_authentication (NULL);
+
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  screen = make_screen (entry);
+  if (! screen)
+    return;
+
+ refresh:
+  /* Draw the screen.  */
+  grub_menu_init_page (0, 1);
+  update_screen (screen, 0, 0, 1, 1, ALL_LINES);
+  grub_setcursor (1);
+  prev_c = '\0';
+
+  while (1)
+    {
+      int c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
+
+      if (screen->completion_shown)
+	{
+	  clear_completions ();
+	  screen->completion_shown = 0;
+	}
+
+      switch (c)
+	{
+	case 16: /* C-p */
+	  if (! previous_line (screen, 1))
+	    goto fail;
+	  break;
+
+	case 14: /* C-n */
+	  if (! next_line (screen, 1))
+	    goto fail;
+	  break;
+
+	case 6: /* C-f */
+	  if (! forward_char (screen, 1))
+	    goto fail;
+	  break;
+
+	case 2: /* C-b */
+	  if (! backward_char (screen, 1))
+	    goto fail;
+	  break;
+
+	case 1: /* C-a */
+	  if (! beginning_of_line (screen, 1))
+	    goto fail;
+	  break;
+
+	case 5: /* C-e */
+	  if (! end_of_line (screen, 1))
+	    goto fail;
+	  break;
+
+	case '\t': /* C-i */
+	  if (! complete (screen, prev_c == c, 1))
+	    goto fail;
+	  break;
+
+	case 4: /* C-d */
+	  if (! delete_char (screen, 1))
+	    goto fail;
+	  break;
+
+	case 8: /* C-h */
+	  if (! backward_delete_char (screen, 1))
+	    goto fail;
+	  break;
+
+	case 11: /* C-k */
+	  if (! kill_line (screen, prev_c == c, 1))
+	    goto fail;
+	  break;
+
+	case 21: /* C-u */
+	  /* FIXME: What behavior is good for this key?  */
+	  break;
+
+	case 25: /* C-y */
+	  if (! yank (screen, 1))
+	    goto fail;
+	  break;
+
+	case 12: /* C-l */
+	  /* FIXME: centering.  */
+	  goto refresh;
+
+	case 15: /* C-o */
+	  if (! open_line (screen, 1))
+	    goto fail;
+	  break;
+
+	case '\n':
+	case '\r':
+	  if (! insert_string (screen, "\n", 1))
+	    goto fail;
+	  break;
+
+	case '\e':
+	  destroy_screen (screen);
+	  return;
+
+	case 3: /* C-c */
+	  grub_cmdline_run (1);
+	  goto refresh;
+
+	case 24: /* C-x */
+	  if (! run (screen))
+	    goto fail;
+	  goto refresh;
+
+	case 18: /* C-r */
+	case 19: /* C-s */
+	case 20: /* C-t */
+	  /* FIXME */
+	  break;
+
+	default:
+	  if (grub_isprint (c))
+	    {
+	      char buf[2];
+
+	      buf[0] = c;
+	      buf[1] = '\0';
+	      if (! insert_string (screen, buf, 1))
+		goto fail;
+	    }
+	  break;
+	}
+
+      prev_c = c;
+    }
+
+ fail:
+  destroy_screen (screen);
+
+  grub_cls ();
+  grub_print_error ();
+  grub_errno = GRUB_ERR_NONE;
+  grub_printf ("\nPress any key to continue...");
+  (void) grub_getkey ();
+}
diff --git a/normal/menu_text.c b/normal/menu_text.c
new file mode 100644
index 0000000..e0d96c4
--- /dev/null
+++ b/normal/menu_text.c
@@ -0,0 +1,600 @@
+/* menu_text.c - Basic text menu implementation.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/loader.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/env.h>
+#include <grub/menu_viewer.h>
+
+/* Time to delay after displaying an error message about a default/fallback
+   entry failing to boot.  */
+#define DEFAULT_ENTRY_ERROR_DELAY_MS  2500
+
+static grub_uint8_t grub_color_menu_normal;
+static grub_uint8_t grub_color_menu_highlight;
+
+/* Wait until the user pushes any key so that the user
+   can see what happened.  */
+void
+grub_wait_after_message (void)
+{
+  grub_printf ("\nPress any key to continue...");
+  (void) grub_getkey ();
+  grub_putchar ('\n');
+}
+
+static void
+draw_border (void)
+{
+  unsigned i;
+
+  grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+
+  grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y);
+  grub_putcode (GRUB_TERM_DISP_UL);
+  for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++)
+    grub_putcode (GRUB_TERM_DISP_HLINE);
+  grub_putcode (GRUB_TERM_DISP_UR);
+
+  for (i = 0; i < (unsigned) GRUB_TERM_NUM_ENTRIES; i++)
+    {
+      grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1);
+      grub_putcode (GRUB_TERM_DISP_VLINE);
+      grub_gotoxy (GRUB_TERM_MARGIN + GRUB_TERM_BORDER_WIDTH - 1,
+		   GRUB_TERM_TOP_BORDER_Y + i + 1);
+      grub_putcode (GRUB_TERM_DISP_VLINE);
+    }
+
+  grub_gotoxy (GRUB_TERM_MARGIN,
+	       GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + 1);
+  grub_putcode (GRUB_TERM_DISP_LL);
+  for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++)
+    grub_putcode (GRUB_TERM_DISP_HLINE);
+  grub_putcode (GRUB_TERM_DISP_LR);
+
+  grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+
+  grub_gotoxy (GRUB_TERM_MARGIN,
+	       (GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES
+		+ GRUB_TERM_MARGIN + 1));
+}
+
+static void
+print_message (int nested, int edit)
+{
+  grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+
+  if (edit)
+    {
+      grub_printf ("\n\
+      Minimum Emacs-like screen editing is supported. TAB lists\n\
+      completions. Press Ctrl-x to boot, Ctrl-c for a command-line\n\
+      or ESC to return menu.");
+    }
+  else
+    {
+      grub_printf ("\n\
+      Use the %C and %C keys to select which entry is highlighted.\n",
+		   (grub_uint32_t) GRUB_TERM_DISP_UP, (grub_uint32_t) GRUB_TERM_DISP_DOWN);
+      grub_printf ("\
+      Press enter to boot the selected OS, \'e\' to edit the\n\
+      commands before booting or \'c\' for a command-line.");
+      if (nested)
+	grub_printf ("\n\
+      ESC to return previous menu.");
+    }
+}
+
+static void
+print_entry (int y, int highlight, grub_menu_entry_t entry)
+{
+  int x;
+  const char *title;
+  grub_size_t title_len;
+  grub_ssize_t len;
+  grub_uint32_t *unicode_title;
+  grub_ssize_t i;
+  grub_uint8_t old_color_normal, old_color_highlight;
+
+  title = entry ? entry->title : "";
+  title_len = grub_strlen (title);
+  unicode_title = grub_malloc (title_len * sizeof (*unicode_title));
+  if (! unicode_title)
+    /* XXX How to show this error?  */
+    return;
+
+  len = grub_utf8_to_ucs4 (unicode_title, title_len,
+                           (grub_uint8_t *) title, -1, 0);
+  if (len < 0)
+    {
+      /* It is an invalid sequence.  */
+      grub_free (unicode_title);
+      return;
+    }
+
+  grub_getcolor (&old_color_normal, &old_color_highlight);
+  grub_setcolor (grub_color_menu_normal, grub_color_menu_highlight);
+  grub_setcolorstate (highlight
+		      ? GRUB_TERM_COLOR_HIGHLIGHT
+		      : GRUB_TERM_COLOR_NORMAL);
+
+  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y);
+
+  for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, i = 0;
+       x < GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH - GRUB_TERM_MARGIN;
+       i++)
+    {
+      if (i < len
+	  && x <= (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH
+		   - GRUB_TERM_MARGIN - 1))
+	{
+	  grub_ssize_t width;
+
+	  width = grub_getcharwidth (unicode_title[i]);
+
+	  if (x + width > (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH
+			   - GRUB_TERM_MARGIN - 1))
+	    grub_putcode (GRUB_TERM_DISP_RIGHT);
+	  else
+	    grub_putcode (unicode_title[i]);
+
+	  x += width;
+	}
+      else
+	{
+	  grub_putchar (' ');
+	  x++;
+	}
+    }
+  grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+  grub_putchar (' ');
+
+  grub_gotoxy (GRUB_TERM_CURSOR_X, y);
+
+  grub_setcolor (old_color_normal, old_color_highlight);
+  grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+  grub_free (unicode_title);
+}
+
+static void
+print_entries (grub_menu_t menu, int first, int offset)
+{
+  grub_menu_entry_t e;
+  int i;
+
+  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
+	       GRUB_TERM_FIRST_ENTRY_Y);
+
+  if (first)
+    grub_putcode (GRUB_TERM_DISP_UP);
+  else
+    grub_putchar (' ');
+
+  e = grub_menu_get_entry (menu, first);
+
+  for (i = 0; i < GRUB_TERM_NUM_ENTRIES; i++)
+    {
+      print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, offset == i, e);
+      if (e)
+	e = e->next;
+    }
+
+  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
+	       GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES);
+
+  if (e)
+    grub_putcode (GRUB_TERM_DISP_DOWN);
+  else
+    grub_putchar (' ');
+
+  grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
+}
+
+/* Initialize the screen.  If NESTED is non-zero, assume that this menu
+   is run from another menu or a command-line. If EDIT is non-zero, show
+   a message for the menu entry editor.  */
+void
+grub_menu_init_page (int nested, int edit)
+{
+  grub_uint8_t old_color_normal, old_color_highlight;
+
+  grub_getcolor (&old_color_normal, &old_color_highlight);
+
+  /* By default, use the same colors for the menu.  */
+  grub_color_menu_normal = old_color_normal;
+  grub_color_menu_highlight = old_color_highlight;
+
+  /* Then give user a chance to replace them.  */
+  grub_parse_color_name_pair (&grub_color_menu_normal, grub_env_get ("menu_color_normal"));
+  grub_parse_color_name_pair (&grub_color_menu_highlight, grub_env_get ("menu_color_highlight"));
+
+  grub_normal_init_page ();
+  grub_setcolor (grub_color_menu_normal, grub_color_menu_highlight);
+  draw_border ();
+  grub_setcolor (old_color_normal, old_color_highlight);
+  print_message (nested, edit);
+}
+
+/* Get the entry number from the variable NAME.  */
+static int
+get_entry_number (const char *name)
+{
+  char *val;
+  int entry;
+
+  val = grub_env_get (name);
+  if (! val)
+    return -1;
+
+  grub_error_push ();
+
+  entry = (int) grub_strtoul (val, 0, 0);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_errno = GRUB_ERR_NONE;
+      entry = -1;
+    }
+
+  grub_error_pop ();
+
+  return entry;
+}
+
+static void
+print_timeout (int timeout, int offset, int second_stage)
+{
+  /* NOTE: Do not remove the trailing space characters.
+     They are required to clear the line.  */
+  char *msg = "   The highlighted entry will be booted automatically in %ds.    ";
+  char *msg_end = grub_strchr (msg, '%');
+
+  grub_gotoxy (second_stage ? (msg_end - msg) : 0, GRUB_TERM_HEIGHT - 3);
+  grub_printf (second_stage ? msg_end : msg, timeout);
+  grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
+  grub_refresh ();
+};
+
+/* Show the menu and handle menu entry selection.  Returns the menu entry
+   index that should be executed or -1 if no entry should be executed (e.g.,
+   Esc pressed to exit a sub-menu or switching menu viewers).
+   If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu
+   entry to be executed is a result of an automatic default selection because
+   of the timeout.  */
+static int
+run_menu (grub_menu_t menu, int nested, int *auto_boot)
+{
+  int first, offset;
+  grub_uint64_t saved_time;
+  int default_entry;
+  int timeout;
+
+  first = 0;
+
+  default_entry = get_entry_number ("default");
+
+  /* If DEFAULT_ENTRY is not within the menu entries, fall back to
+     the first entry.  */
+  if (default_entry < 0 || default_entry >= menu->size)
+    default_entry = 0;
+
+  /* If timeout is 0, drawing is pointless (and ugly).  */
+  if (grub_menu_get_timeout () == 0)
+    {
+      *auto_boot = 1;
+      return default_entry;
+    }
+
+  offset = default_entry;
+  if (offset > GRUB_TERM_NUM_ENTRIES - 1)
+    {
+      first = offset - (GRUB_TERM_NUM_ENTRIES - 1);
+      offset = GRUB_TERM_NUM_ENTRIES - 1;
+    }
+
+  /* Initialize the time.  */
+  saved_time = grub_get_time_ms ();
+
+ refresh:
+  grub_setcursor (0);
+  grub_menu_init_page (nested, 0);
+  print_entries (menu, first, offset);
+  grub_refresh ();
+
+  timeout = grub_menu_get_timeout ();
+
+  if (timeout > 0)
+    print_timeout (timeout, offset, 0);
+
+  while (1)
+    {
+      int c;
+      timeout = grub_menu_get_timeout ();
+
+      if (timeout > 0)
+	{
+	  grub_uint64_t current_time;
+
+	  current_time = grub_get_time_ms ();
+	  if (current_time - saved_time >= 1000)
+	    {
+	      timeout--;
+	      grub_menu_set_timeout (timeout);
+	      saved_time = current_time;
+	      print_timeout (timeout, offset, 1);
+	    }
+	}
+
+      if (timeout == 0)
+	{
+	  grub_env_unset ("timeout");
+          *auto_boot = 1;
+	  return default_entry;
+	}
+
+      if (grub_checkkey () >= 0 || timeout < 0)
+	{
+	  c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
+
+	  if (timeout >= 0)
+	    {
+	      grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
+              grub_printf ("\
+                                                                        ");
+	      grub_env_unset ("timeout");
+	      grub_env_unset ("fallback");
+	      grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
+	    }
+
+	  switch (c)
+	    {
+	    case GRUB_TERM_HOME:
+	      first = 0;
+	      offset = 0;
+	      print_entries (menu, first, offset);
+	      break;
+
+	    case GRUB_TERM_END:
+	      offset = menu->size - 1;
+	      if (offset > GRUB_TERM_NUM_ENTRIES - 1)
+		{
+		  first = offset - (GRUB_TERM_NUM_ENTRIES - 1);
+		  offset = GRUB_TERM_NUM_ENTRIES - 1;
+		}
+		print_entries (menu, first, offset);
+	      break;
+
+	    case GRUB_TERM_UP:
+	    case '^':
+	      if (offset > 0)
+		{
+		  print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0,
+			       grub_menu_get_entry (menu, first + offset));
+		  offset--;
+		  print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1,
+			       grub_menu_get_entry (menu, first + offset));
+		}
+	      else if (first > 0)
+		{
+		  first--;
+		  print_entries (menu, first, offset);
+		}
+	      break;
+
+	    case GRUB_TERM_DOWN:
+	    case 'v':
+	      if (menu->size > first + offset + 1)
+		{
+		  if (offset < GRUB_TERM_NUM_ENTRIES - 1)
+		    {
+		      print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0,
+				   grub_menu_get_entry (menu, first + offset));
+		      offset++;
+		      print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1,
+				   grub_menu_get_entry (menu, first + offset));
+		    }
+		  else
+		    {
+		      first++;
+		      print_entries (menu, first, offset);
+		    }
+		}
+	      break;
+
+	    case GRUB_TERM_PPAGE:
+	      if (first == 0)
+		{
+		  offset = 0;
+		}
+	      else
+		{
+		  first -= GRUB_TERM_NUM_ENTRIES;
+
+		  if (first < 0)
+		    {
+		      offset += first;
+		      first = 0;
+		    }
+		}
+	      print_entries (menu, first, offset);
+	      break;
+
+	    case GRUB_TERM_NPAGE:
+	      if (offset == 0)
+		{
+		  offset += GRUB_TERM_NUM_ENTRIES - 1;
+		  if (first + offset >= menu->size)
+		    {
+		      offset = menu->size - first - 1;
+		    }
+		}
+	      else
+		{
+		  first += GRUB_TERM_NUM_ENTRIES;
+
+		  if (first + offset >= menu->size)
+		    {
+		      first -= GRUB_TERM_NUM_ENTRIES;
+		      offset += GRUB_TERM_NUM_ENTRIES;
+
+		      if (offset > menu->size - 1 ||
+			  offset > GRUB_TERM_NUM_ENTRIES - 1)
+			{
+			  offset = menu->size - first - 1;
+			}
+		      if (offset > GRUB_TERM_NUM_ENTRIES)
+			{
+			  first += offset - GRUB_TERM_NUM_ENTRIES + 1;
+			  offset = GRUB_TERM_NUM_ENTRIES - 1;
+			}
+		    }
+		}
+	      print_entries (menu, first, offset);
+	      break;
+
+	    case '\n':
+	    case '\r':
+	    case 6:
+	      grub_setcursor (1);
+              *auto_boot = 0;
+	      return first + offset;
+
+	    case '\e':
+	      if (nested)
+		{
+		  grub_setcursor (1);
+		  return -1;
+		}
+	      break;
+
+	    case 'c':
+	      grub_cmdline_run (1);
+	      goto refresh;
+
+	    case 'e':
+		{
+		  grub_menu_entry_t e = grub_menu_get_entry (menu, first + offset);
+		  if (e)
+		    grub_menu_entry_run (e);
+		}
+	      goto refresh;
+
+	    default:
+	      break;
+	    }
+
+	  grub_refresh ();
+	}
+    }
+
+  /* Never reach here.  */
+  return -1;
+}
+
+/* Callback invoked immediately before a menu entry is executed.  */
+static void
+notify_booting (grub_menu_entry_t entry,
+		void *userdata __attribute__((unused)))
+{
+  grub_printf ("  Booting \'%s\'\n\n", entry->title);
+}
+
+/* Callback invoked when a default menu entry executed because of a timeout
+   has failed and an attempt will be made to execute the next fallback
+   entry, ENTRY.  */
+static void
+notify_fallback (grub_menu_entry_t entry,
+		 void *userdata __attribute__((unused)))
+{
+  grub_printf ("\n  Falling back to \'%s\'\n\n", entry->title);
+  grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS);
+}
+
+/* Callback invoked when a menu entry has failed and there is no remaining
+   fallback entry to attempt.  */
+static void
+notify_execution_failure (void *userdata __attribute__((unused)))
+{
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+    }
+  grub_printf ("\n  Failed to boot default entries.\n");
+  grub_wait_after_message ();
+}
+
+/* Callbacks used by the text menu to provide user feedback when menu entries
+   are executed.  */
+static struct grub_menu_execute_callback execution_callback =
+{
+  .notify_booting = notify_booting,
+  .notify_fallback = notify_fallback,
+  .notify_failure = notify_execution_failure
+};
+
+static grub_err_t
+show_text_menu (grub_menu_t menu, int nested)
+{
+  while (1)
+    {
+      int boot_entry;
+      grub_menu_entry_t e;
+      int auto_boot;
+
+      boot_entry = run_menu (menu, nested, &auto_boot);
+      if (boot_entry < 0)
+	break;
+
+      e = grub_menu_get_entry (menu, boot_entry);
+      if (! e)
+	continue; /* Menu is empty.  */
+
+      grub_cls ();
+      grub_setcursor (1);
+
+      if (auto_boot)
+        {
+          grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
+        }
+      else
+        {
+          grub_errno = GRUB_ERR_NONE;
+          grub_menu_execute_entry (e);
+          if (grub_errno != GRUB_ERR_NONE)
+            {
+              grub_print_error ();
+              grub_errno = GRUB_ERR_NONE;
+              grub_wait_after_message ();
+            }
+        }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+struct grub_menu_viewer grub_normal_text_menu_viewer =
+{
+  .name = "text",
+  .show_menu = show_text_menu
+};
diff --git a/normal/menu_viewer.c b/normal/menu_viewer.c
new file mode 100644
index 0000000..1bd271a
--- /dev/null
+++ b/normal/menu_viewer.c
@@ -0,0 +1,81 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/menu_viewer.h>
+#include <grub/menu.h>
+#include <grub/auth.h>
+
+/* The list of menu viewers.  */
+static grub_menu_viewer_t menu_viewer_list;
+
+void
+grub_menu_viewer_register (grub_menu_viewer_t viewer)
+{
+  viewer->next = menu_viewer_list;
+  menu_viewer_list = viewer;
+}
+
+static grub_menu_viewer_t get_current_menu_viewer (void)
+{
+  const char *selected_name = grub_env_get ("menuviewer");
+
+  /* If none selected, pick the last registered one. */
+  if (selected_name == 0)
+    return menu_viewer_list;
+
+  grub_menu_viewer_t cur;
+  for (cur = menu_viewer_list; cur; cur = cur->next)
+    {
+      if (grub_strcmp (cur->name, selected_name) == 0)
+        return cur;
+    }
+
+  /* Fall back to the first entry (or null).  */
+  return menu_viewer_list;
+}
+
+grub_err_t
+grub_menu_viewer_show_menu (grub_menu_t menu, int nested)
+{
+  grub_menu_viewer_t cur = get_current_menu_viewer ();
+  grub_err_t err1, err2;
+  if (!cur)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "No menu viewer available.");
+
+  while (1)
+    {
+      err1 = cur->show_menu (menu, nested);
+      grub_print_error ();
+
+      err2 = grub_auth_check_authentication (NULL);
+      if (err2)
+	{
+	  grub_print_error ();
+	  grub_errno = GRUB_ERR_NONE;
+	  continue;
+	}
+
+      break;
+    }
+
+  return err1;
+}
+
diff --git a/normal/misc.c b/normal/misc.c
new file mode 100644
index 0000000..0a1a2f0
--- /dev/null
+++ b/normal/misc.c
@@ -0,0 +1,107 @@
+/* misc.c - miscellaneous functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/disk.h>
+#include <grub/fs.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/datetime.h>
+
+/* Print the information on the device NAME.  */
+grub_err_t
+grub_normal_print_device_info (const char *name)
+{
+  grub_device_t dev;
+  char *p;
+
+  p = grub_strchr (name, ',');
+  if (p)
+    grub_printf ("\tPartition %s: ", name);
+  else
+    grub_printf ("Device %s: ", name);
+
+  dev = grub_device_open (name);
+  if (! dev)
+    grub_printf ("Filesystem cannot be accessed");
+  else if (dev->disk)
+    {
+      grub_fs_t fs;
+
+      fs = grub_fs_probe (dev);
+      /* Ignore all errors.  */
+      grub_errno = 0;
+
+      if (fs)
+	{
+	  grub_printf ("Filesystem type %s", fs->name);
+	  if (fs->label)
+	    {
+	      char *label;
+	      (fs->label) (dev, &label);
+	      if (grub_errno == GRUB_ERR_NONE)
+		{
+		  if (label && grub_strlen (label))
+		    grub_printf (", Label %s", label);
+		  grub_free (label);
+		}
+	      grub_errno = GRUB_ERR_NONE;
+	    }
+	  if (fs->mtime)
+	    {
+	      grub_int32_t tm;
+	      struct grub_datetime datetime;
+	      (fs->mtime) (dev, &tm);
+	      if (grub_errno == GRUB_ERR_NONE)
+		{
+		  grub_unixtime2datetime (tm, &datetime);
+		  grub_printf (", Last modification time %d-%02d-%02d "
+			       "%02d:%02d:%02d %s",
+			       datetime.year, datetime.month, datetime.day,
+			       datetime.hour, datetime.minute, datetime.second,
+			       grub_get_weekday_name (&datetime));
+
+		}
+	      grub_errno = GRUB_ERR_NONE;
+	    }
+	  if (fs->uuid)
+	    {
+	      char *uuid;
+	      (fs->uuid) (dev, &uuid);
+	      if (grub_errno == GRUB_ERR_NONE)
+		{
+		  if (uuid && grub_strlen (uuid))
+		    grub_printf (", UUID %s", uuid);
+		  grub_free (uuid);
+		}
+	      grub_errno = GRUB_ERR_NONE;
+	    }
+	}
+      else if (! dev->disk->has_partitions || dev->disk->partition)
+	grub_printf ("Unknown filesystem");
+      else
+	grub_printf ("Partition table");
+
+      grub_device_close (dev);
+    }
+
+  grub_printf ("\n");
+  return grub_errno;
+}
diff --git a/partmap/acorn.c b/partmap/acorn.c
new file mode 100644
index 0000000..e005975
--- /dev/null
+++ b/partmap/acorn.c
@@ -0,0 +1,206 @@
+/* acorn.c - Read Linux/ADFS partition tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/acorn_filecore.h>
+
+#define LINUX_NATIVE_MAGIC grub_cpu_to_le32 (0xdeafa1de)
+#define LINUX_SWAP_MAGIC   grub_cpu_to_le32 (0xdeafab1e)
+#define LINUX_MAP_ENTRIES  (512 / 12)
+
+#define NONADFS_PARTITION_TYPE_LINUX 9
+#define NONADFS_PARTITION_TYPE_MASK 15
+
+struct grub_acorn_boot_block
+{
+  grub_uint8_t misc[0x1C0];
+  struct grub_filecore_disc_record disc_record;
+  grub_uint8_t flags;
+  grub_uint16_t start_cylinder;
+  grub_uint8_t checksum;
+} __attribute__ ((packed, aligned));
+
+struct linux_part
+{
+  grub_uint32_t magic;
+  grub_uint32_t start;
+  grub_uint32_t size;
+};
+
+static struct grub_partition_map grub_acorn_partition_map;
+
+static grub_err_t
+acorn_partition_map_find (grub_disk_t disk, struct linux_part *m,
+			  grub_disk_addr_t *sector)
+{
+  struct grub_acorn_boot_block boot;
+  grub_err_t err;
+  unsigned int checksum = 0;
+  unsigned int heads;
+  unsigned int sectors_per_cylinder;
+  int i;
+
+  err = grub_disk_read (disk, 0xC00 / GRUB_DISK_SECTOR_SIZE, 0,
+			sizeof (struct grub_acorn_boot_block),
+			&boot);
+  if (err)
+    return err;
+
+  if ((boot.flags & NONADFS_PARTITION_TYPE_MASK) != NONADFS_PARTITION_TYPE_LINUX)
+    goto fail;
+
+  for (i = 0; i != 0x1ff; ++i)
+    checksum = (checksum & 0xff) + (checksum >> 8) + boot.misc[i];
+
+  if ((grub_uint8_t) checksum != boot.checksum)
+    goto fail;
+
+  heads = (boot.disc_record.heads
+		    + ((boot.disc_record.lowsector >> 6) & 1));
+  sectors_per_cylinder = boot.disc_record.secspertrack * heads;
+  *sector = grub_le_to_cpu16 (boot.start_cylinder) * sectors_per_cylinder;
+
+  return grub_disk_read (disk, *sector, 0,
+			 sizeof (struct linux_part) * LINUX_MAP_ENTRIES,
+			 m);
+
+fail:
+  return grub_error (GRUB_ERR_BAD_PART_TABLE,
+		     "Linux/ADFS partition map not found.");
+
+}
+
+
+static grub_err_t
+acorn_partition_map_iterate (grub_disk_t disk,
+			     int (*hook) (grub_disk_t disk,
+					  const grub_partition_t partition))
+{
+  struct grub_partition part;
+  struct grub_disk raw;
+  struct linux_part map[LINUX_MAP_ENTRIES];
+  int i;
+  grub_disk_addr_t sector;
+  grub_err_t err;
+
+  /* Enforce raw disk access.  */
+  raw = *disk;
+  raw.partition = 0;
+
+  err = acorn_partition_map_find (&raw, map, &sector);
+  if (err)
+    return err;
+
+  part.partmap = &grub_acorn_partition_map;
+
+  for (i = 0; i != LINUX_MAP_ENTRIES; ++i)
+    {
+      if (map[i].magic != LINUX_NATIVE_MAGIC
+	  && map[i].magic != LINUX_SWAP_MAGIC)
+	return GRUB_ERR_NONE;
+
+      part.start = sector + map[i].start;
+      part.len = map[i].size;
+      part.offset = 6;
+      part.index = i;
+
+      if (hook (disk, &part))
+	return grub_errno;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_partition_t
+acorn_partition_map_probe (grub_disk_t disk, const char *str)
+{
+  struct linux_part map[LINUX_MAP_ENTRIES];
+  struct grub_disk raw = *disk;
+  unsigned long partnum = grub_strtoul (str, 0, 10) - 1;
+  grub_disk_addr_t sector;
+  grub_err_t err;
+  grub_partition_t p;
+
+  /* Enforce raw disk access.  */
+  raw.partition = 0;
+
+  /* Get the partition number.  */
+  if (partnum > LINUX_MAP_ENTRIES)
+    goto fail;
+
+  err = acorn_partition_map_find (&raw, map, &sector);
+  if (err)
+    return 0;
+
+  if (map[partnum].magic != LINUX_NATIVE_MAGIC
+      && map[partnum].magic != LINUX_SWAP_MAGIC)
+    goto fail;
+
+  p = grub_malloc (sizeof (struct grub_partition));
+  if (! p)
+    return 0;
+
+  p->start = sector + map[partnum].start;
+  p->len = map[partnum].size;
+  p->offset = 6;
+  p->index = partnum;
+  return p;
+
+fail:
+  grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
+  return 0;
+}
+
+
+static char *
+acorn_partition_map_get_name (const grub_partition_t p)
+{
+  char *name;
+
+  name = grub_malloc (13);
+  if (! name)
+    return 0;
+
+  grub_sprintf (name, "%d", p->index + 1);
+  return name;
+}
+
+
+/* Partition map type.  */
+static struct grub_partition_map grub_acorn_partition_map =
+{
+  .name = "part_acorn",
+  .iterate = acorn_partition_map_iterate,
+  .probe = acorn_partition_map_probe,
+  .get_name = acorn_partition_map_get_name
+};
+
+GRUB_MOD_INIT(acorn_partition_map)
+{
+  grub_partition_map_register (&grub_acorn_partition_map);
+}
+
+GRUB_MOD_FINI(acorn_partition_map)
+{
+  grub_partition_map_unregister (&grub_acorn_partition_map);
+}
diff --git a/partmap/amiga.c b/partmap/amiga.c
new file mode 100644
index 0000000..dce9f4f
--- /dev/null
+++ b/partmap/amiga.c
@@ -0,0 +1,215 @@
+/* amiga.c - Read amiga partition tables (RDB).  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/dl.h>
+
+struct grub_amiga_rdsk
+{
+  /* "RDSK".  */
+  grub_uint8_t magic[4];
+  grub_uint32_t size;
+  grub_int32_t checksum;
+  grub_uint32_t scsihost;
+  grub_uint32_t blksz;
+  grub_uint32_t flags;
+  grub_uint32_t badblcklst;
+  grub_uint32_t partitionlst;
+  grub_uint32_t fslst;
+
+  /* The other information is not important for us.  */
+} __attribute__ ((packed));
+
+struct grub_amiga_partition
+{
+  /* "PART".  */
+  grub_uint8_t magic[4];
+  grub_int32_t size;
+  grub_int32_t checksum;
+  grub_uint32_t scsihost;
+  grub_uint32_t next;
+  grub_uint32_t flags;
+  grub_uint32_t unused1[2];
+  grub_uint32_t devflags;
+  grub_uint8_t namelen;
+  grub_uint8_t name[31];
+  grub_uint32_t unused2[15];
+
+  grub_uint32_t unused3[3];
+  grub_uint32_t heads;
+  grub_uint32_t unused4;
+  grub_uint32_t block_per_track;
+  grub_uint32_t unused5[3];
+  grub_uint32_t lowcyl;
+  grub_uint32_t highcyl;
+
+  grub_uint32_t firstcyl;
+} __attribute__ ((packed));
+
+static struct grub_partition_map grub_amiga_partition_map;
+
+
+
+static grub_err_t
+amiga_partition_map_iterate (grub_disk_t disk,
+			     int (*hook) (grub_disk_t disk,
+					  const grub_partition_t partition))
+{
+  struct grub_partition part;
+  struct grub_amiga_rdsk rdsk;
+  struct grub_disk raw;
+  int partno = 0;
+  int next = -1;
+  unsigned pos;
+
+  /* Enforce raw disk access.  */
+  raw = *disk;
+  raw.partition = 0;
+
+  /* The RDSK block is one of the first 15 blocks.  */
+  for (pos = 0; pos < 15; pos++)
+    {
+      /* Read the RDSK block which is a descriptor for the entire disk.  */
+      if (grub_disk_read (&raw, pos, 0, sizeof (rdsk), &rdsk))
+	return grub_errno;
+
+      if (grub_strcmp ((char *) rdsk.magic, "RDSK") == 0)
+	{
+	  /* Found the first PART block.  */
+	  next = grub_be_to_cpu32 (rdsk.partitionlst);
+	  break;
+	}
+    }
+
+  if (next == -1)
+    return grub_error (GRUB_ERR_BAD_PART_TABLE,
+		       "Amiga partition map not found.");
+
+  /* The end of the partition list is marked using "-1".  */
+  while (next != -1)
+    {
+      struct grub_amiga_partition apart;
+
+      /* Read the RDSK block which is a descriptor for the entire disk.  */
+      if (grub_disk_read (&raw, next, 0, sizeof (apart), &apart))
+	return grub_errno;
+
+      /* Calculate the first block and the size of the partition.  */
+      part.start = (grub_be_to_cpu32 (apart.lowcyl)
+		    * grub_be_to_cpu32 (apart.heads)
+		    * grub_be_to_cpu32 (apart.block_per_track));
+      part.len = ((grub_be_to_cpu32 (apart.highcyl)
+		   - grub_be_to_cpu32 (apart.lowcyl) + 1)
+		  * grub_be_to_cpu32 (apart.heads)
+		  * grub_be_to_cpu32 (apart.block_per_track));
+
+      part.offset = (grub_off_t) next * 512;
+      part.index = partno;
+      part.partmap = &grub_amiga_partition_map;
+
+      if (hook (disk, &part))
+	return grub_errno;
+
+      next = grub_be_to_cpu32 (apart.next);
+      partno++;
+    }
+
+  return 0;
+}
+
+
+static grub_partition_t
+amiga_partition_map_probe (grub_disk_t disk, const char *str)
+{
+  grub_partition_t p = 0;
+  int partnum = 0;
+  char *s = (char *) str;
+
+  auto int find_func (grub_disk_t d, const grub_partition_t partition);
+
+  int find_func (grub_disk_t d __attribute__ ((unused)),
+		 const grub_partition_t partition)
+    {
+      if (partnum == partition->index)
+	{
+	  p = (grub_partition_t) grub_malloc (sizeof (*p));
+	  if (! p)
+	    return 1;
+
+	  grub_memcpy (p, partition, sizeof (*p));
+	  return 1;
+	}
+
+      return 0;
+    }
+
+  /* Get the partition number.  */
+  partnum = grub_strtoul (s, 0, 10) - 1;
+  if (grub_errno)
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
+      return 0;
+    }
+
+  if (amiga_partition_map_iterate (disk, find_func))
+    goto fail;
+
+  return p;
+
+ fail:
+  grub_free (p);
+  return 0;
+}
+
+
+static char *
+amiga_partition_map_get_name (const grub_partition_t p)
+{
+  char *name;
+
+  name = grub_malloc (13);
+  if (! name)
+    return 0;
+
+  grub_sprintf (name, "%d", p->index + 1);
+  return name;
+}
+
+
+/* Partition map type.  */
+static struct grub_partition_map grub_amiga_partition_map =
+  {
+    .name = "part_amiga",
+    .iterate = amiga_partition_map_iterate,
+    .probe = amiga_partition_map_probe,
+    .get_name = amiga_partition_map_get_name
+  };
+
+GRUB_MOD_INIT(amiga_partition_map)
+{
+  grub_partition_map_register (&grub_amiga_partition_map);
+}
+
+GRUB_MOD_FINI(amiga_partition_map)
+{
+  grub_partition_map_unregister (&grub_amiga_partition_map);
+}
diff --git a/partmap/apple.c b/partmap/apple.c
new file mode 100644
index 0000000..4dea55a
--- /dev/null
+++ b/partmap/apple.c
@@ -0,0 +1,259 @@
+/* apple.c - Read macintosh partition tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+
+#define GRUB_APPLE_HEADER_MAGIC	0x4552
+#define GRUB_APPLE_PART_MAGIC	0x504D
+
+struct grub_apple_header
+{
+  /* The magic number to identify the partition map, it should have
+     the value `0x4552'.  */
+  grub_uint16_t magic;
+  grub_uint16_t blocksize;
+};
+
+struct grub_apple_part
+{
+  /* The magic number to identify this as a partition, it should have
+     the value `0x504D'.  */
+  grub_uint16_t magic;
+
+  /* Reserved.  */
+  grub_uint16_t reserved;
+
+  /* The size of the partition map in blocks.  */
+  grub_uint32_t partmap_size;
+
+  /* The first physical block of the partition.  */
+  grub_uint32_t first_phys_block;
+
+  /* The amount of blocks.  */
+  grub_uint32_t blockcnt;
+
+  /* The partition name.  */
+  char partname[32];
+
+  /* The partition type.  */
+  char parttype[32];
+
+  /* The first datablock of the partition.  */
+  grub_uint32_t datablocks_first;
+
+  /* The amount datablocks.  */
+  grub_uint32_t datablocks_count;
+
+  /* The status of the partition. (???)  */
+  grub_uint32_t status;
+
+  /* The first block on which the bootcode can be found.  */
+  grub_uint32_t bootcode_pos;
+
+  /* The size of the bootcode in bytes.  */
+  grub_uint32_t bootcode_size;
+
+  /* The load address of the bootcode.  */
+  grub_uint32_t bootcode_loadaddr;
+
+  /* Reserved.  */
+  grub_uint32_t reserved2;
+
+  /* The entry point of the bootcode.  */
+  grub_uint32_t bootcode_entrypoint;
+
+  /* Reserved.  */
+  grub_uint32_t reserved3;
+
+  /* A checksum of the bootcode.  */
+  grub_uint32_t bootcode_checksum;
+
+  /* The processor type.  */
+  char processor[16];
+
+  /* Padding.  */
+  grub_uint16_t pad[187];
+};
+
+static struct grub_partition_map grub_apple_partition_map;
+
+
+static grub_err_t
+apple_partition_map_iterate (grub_disk_t disk,
+			     int (*hook) (grub_disk_t disk,
+					  const grub_partition_t partition))
+{
+  struct grub_partition part;
+  struct grub_apple_header aheader;
+  struct grub_apple_part apart;
+  struct grub_disk raw;
+  int partno = 0, partnum = 0;
+  unsigned pos;
+
+  /* Enforce raw disk access.  */
+  raw = *disk;
+  raw.partition = 0;
+
+  part.partmap = &grub_apple_partition_map;
+
+  if (grub_disk_read (&raw, 0, 0, sizeof (aheader), &aheader))
+    return grub_errno;
+
+  if (grub_be_to_cpu16 (aheader.magic) != GRUB_APPLE_HEADER_MAGIC)
+    {
+      grub_dprintf ("partition",
+		    "bad magic (found 0x%x; wanted 0x%x\n",
+		    grub_be_to_cpu16 (aheader.magic),
+		    GRUB_APPLE_HEADER_MAGIC);
+      goto fail;
+    }
+
+  pos = grub_be_to_cpu16 (aheader.blocksize);
+
+  do
+    {
+      if (grub_disk_read (&raw, pos / GRUB_DISK_SECTOR_SIZE,
+			  pos % GRUB_DISK_SECTOR_SIZE,
+			  sizeof (struct grub_apple_part),  &apart))
+	return grub_errno;
+
+      if (grub_be_to_cpu16 (apart.magic) != GRUB_APPLE_PART_MAGIC)
+	{
+	  grub_dprintf ("partition",
+			"partition %d: bad magic (found 0x%x; wanted 0x%x\n",
+			partno, grub_be_to_cpu16 (apart.magic),
+			GRUB_APPLE_PART_MAGIC);
+	  break;
+	}
+
+      if (partnum == 0)
+	partnum = grub_be_to_cpu32 (apart.partmap_size);
+
+      part.start = ((grub_disk_addr_t) grub_be_to_cpu32 (apart.first_phys_block)
+		    * grub_be_to_cpu16 (aheader.blocksize))
+	/ GRUB_DISK_SECTOR_SIZE;
+      part.len = ((grub_disk_addr_t) grub_be_to_cpu32 (apart.blockcnt)
+		  * grub_be_to_cpu16 (aheader.blocksize))
+	/ GRUB_DISK_SECTOR_SIZE;
+      part.offset = pos;
+      part.index = partno;
+
+      grub_dprintf ("partition",
+		    "partition %d: name %s, type %s, start 0x%x, len 0x%x\n",
+		    partno, apart.partname, apart.parttype,
+		    grub_be_to_cpu32 (apart.first_phys_block),
+		    grub_be_to_cpu32 (apart.blockcnt));
+
+      if (hook (disk, &part))
+	return grub_errno;
+
+      pos += grub_be_to_cpu16 (aheader.blocksize);
+      partno++;
+    }
+  while (partno < partnum);
+
+  if (partno != 0)
+    return 0;
+
+ fail:
+  return grub_error (GRUB_ERR_BAD_PART_TABLE,
+		     "Apple partition map not found.");
+}
+
+
+static grub_partition_t
+apple_partition_map_probe (grub_disk_t disk, const char *str)
+{
+  grub_partition_t p = 0;
+  int partnum = 0;
+  char *s = (char *) str;
+
+  auto int find_func (grub_disk_t d, const grub_partition_t partition);
+
+  int find_func (grub_disk_t d __attribute__ ((unused)),
+		 const grub_partition_t partition)
+    {
+      if (partnum == partition->index)
+	{
+	  p = (grub_partition_t) grub_malloc (sizeof (*p));
+	  if (! p)
+	    return 1;
+
+	  grub_memcpy (p, partition, sizeof (*p));
+	  return 1;
+	}
+
+      return 0;
+    }
+
+  /* Get the partition number.  */
+  partnum = grub_strtoul (s, 0, 10) - 1;
+  if (grub_errno)
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
+      return 0;
+    }
+
+  if (apple_partition_map_iterate (disk, find_func))
+    goto fail;
+
+  return p;
+
+ fail:
+  grub_free (p);
+  return 0;
+}
+
+
+static char *
+apple_partition_map_get_name (const grub_partition_t p)
+{
+  char *name;
+
+  name = grub_malloc (13);
+  if (! name)
+    return 0;
+
+  grub_sprintf (name, "%d", p->index + 1);
+  return name;
+}
+
+
+/* Partition map type.  */
+static struct grub_partition_map grub_apple_partition_map =
+  {
+    .name = "part_apple",
+    .iterate = apple_partition_map_iterate,
+    .probe = apple_partition_map_probe,
+    .get_name = apple_partition_map_get_name
+  };
+
+GRUB_MOD_INIT(apple_partition_map)
+{
+  grub_partition_map_register (&grub_apple_partition_map);
+}
+
+GRUB_MOD_FINI(apple_partition_map)
+{
+  grub_partition_map_unregister (&grub_apple_partition_map);
+}
+
diff --git a/partmap/gpt.c b/partmap/gpt.c
new file mode 100644
index 0000000..4a49574
--- /dev/null
+++ b/partmap/gpt.c
@@ -0,0 +1,193 @@
+/* gpt.c - Read GUID Partition Tables (GPT).  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/dl.h>
+#include <grub/msdos_partition.h>
+#include <grub/gpt_partition.h>
+
+static grub_uint8_t grub_gpt_magic[8] =
+  {
+    0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54
+  };
+
+static const grub_gpt_part_type_t grub_gpt_partition_type_empty = GRUB_GPT_PARTITION_TYPE_EMPTY;
+
+static struct grub_partition_map grub_gpt_partition_map;
+
+
+
+static grub_err_t
+gpt_partition_map_iterate (grub_disk_t disk,
+			   int (*hook) (grub_disk_t disk,
+					const grub_partition_t partition))
+{
+  struct grub_partition part;
+  struct grub_gpt_header gpt;
+  struct grub_gpt_partentry entry;
+  struct grub_disk raw;
+  struct grub_msdos_partition_mbr mbr;
+  grub_uint64_t entries;
+  unsigned int i;
+  int last_offset = 0;
+
+  /* Enforce raw disk access.  */
+  raw = *disk;
+  raw.partition = 0;
+
+  /* Read the protective MBR.  */
+  if (grub_disk_read (&raw, 0, 0, sizeof (mbr), &mbr))
+    return grub_errno;
+
+  /* Check if it is valid.  */
+  if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
+    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
+
+  /* Make sure the MBR is a protective MBR and not a normal MBR.  */
+  if (mbr.entries[0].type != GRUB_PC_PARTITION_TYPE_GPT_DISK)
+    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found");
+
+  /* Read the GPT header.  */
+  if (grub_disk_read (&raw, 1, 0, sizeof (gpt), &gpt))
+    return grub_errno;
+
+  if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)))
+    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no valid GPT header");
+
+  grub_dprintf ("gpt", "Read a valid GPT header\n");
+
+  entries = grub_le_to_cpu64 (gpt.partitions);
+  for (i = 0; i < grub_le_to_cpu32 (gpt.maxpart); i++)
+    {
+      if (grub_disk_read (&raw, entries, last_offset,
+			  sizeof (entry), &entry))
+	return grub_errno;
+
+      if (grub_memcmp (&grub_gpt_partition_type_empty, &entry.type,
+		       sizeof (grub_gpt_partition_type_empty)))
+	{
+	  /* Calculate the first block and the size of the partition.  */
+	  part.start = grub_le_to_cpu64 (entry.start);
+	  part.len = (grub_le_to_cpu64 (entry.end)
+		      - grub_le_to_cpu64 (entry.start) + 1);
+	  part.offset = entries;
+	  part.index = i;
+	  part.partmap = &grub_gpt_partition_map;
+	  part.data = &entry;
+
+	  grub_dprintf ("gpt", "GPT entry %d: start=%lld, length=%lld\n", i,
+			(unsigned long long) part.start,
+			(unsigned long long) part.len);
+
+	  if (hook (disk, &part))
+	    return 1;
+	}
+
+      last_offset += grub_le_to_cpu32 (gpt.partentry_size);
+      if (last_offset == GRUB_DISK_SECTOR_SIZE)
+	{
+	  last_offset = 0;
+	  entries++;
+	}
+    }
+
+  return 0;
+}
+
+
+static grub_partition_t
+gpt_partition_map_probe (grub_disk_t disk, const char *str)
+{
+  grub_partition_t p = 0;
+  int partnum = 0;
+  char *s = (char *) str;
+
+  auto int find_func (grub_disk_t d, const grub_partition_t partition);
+
+  int find_func (grub_disk_t d __attribute__ ((unused)),
+		 const grub_partition_t partition)
+    {
+      if (partnum == partition->index)
+	{
+	  p = (grub_partition_t) grub_malloc (sizeof (*p));
+	  if (! p)
+	    return 1;
+
+	  grub_memcpy (p, partition, sizeof (*p));
+	  return 1;
+	}
+
+      return 0;
+    }
+
+  /* Get the partition number.  */
+  partnum = grub_strtoul (s, 0, 10) - 1;
+  if (grub_errno)
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
+      return 0;
+    }
+
+  gpt_partition_map_iterate (disk, find_func);
+  if (grub_errno)
+    goto fail;
+
+  return p;
+
+ fail:
+  grub_free (p);
+  return 0;
+}
+
+
+static char *
+gpt_partition_map_get_name (const grub_partition_t p)
+{
+  char *name;
+
+  name = grub_malloc (13);
+  if (! name)
+    return 0;
+
+  grub_sprintf (name, "%d", p->index + 1);
+  return name;
+}
+
+
+/* Partition map type.  */
+static struct grub_partition_map grub_gpt_partition_map =
+  {
+    .name = "part_gpt",
+    .iterate = gpt_partition_map_iterate,
+    .probe = gpt_partition_map_probe,
+    .get_name = gpt_partition_map_get_name
+  };
+
+GRUB_MOD_INIT(gpt_partition_map)
+{
+  grub_partition_map_register (&grub_gpt_partition_map);
+}
+
+GRUB_MOD_FINI(gpt_partition_map)
+{
+  grub_partition_map_unregister (&grub_gpt_partition_map);
+}
diff --git a/partmap/msdos.c b/partmap/msdos.c
new file mode 100644
index 0000000..6ba7fb9
--- /dev/null
+++ b/partmap/msdos.c
@@ -0,0 +1,338 @@
+/* pc.c - Read PC style partition tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/partition.h>
+#include <grub/msdos_partition.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/dl.h>
+
+static struct grub_partition_map grub_msdos_partition_map;
+
+
+/* Parse the partition representation in STR and return a partition.  */
+static grub_partition_t
+grub_partition_parse (const char *str)
+{
+  grub_partition_t p;
+  struct grub_msdos_partition *pcdata;
+
+  char *s = (char *) str;
+
+  p = (grub_partition_t) grub_malloc (sizeof (*p));
+  if (! p)
+    return 0;
+
+  pcdata = (struct grub_msdos_partition *) grub_malloc (sizeof (*pcdata));
+  if (! pcdata)
+    goto fail;
+
+  p->data = pcdata;
+  p->partmap = &grub_msdos_partition_map;
+
+  /* Initialize some of the fields with invalid values.  */
+  pcdata->bsd_part = pcdata->dos_type = pcdata->bsd_type = p->index = -1;
+
+  /* Get the DOS partition number. The number is counted from one for
+     the user interface, and from zero internally.  */
+  pcdata->dos_part = grub_strtoul (s, &s, 0) - 1;
+
+  if (grub_errno)
+    {
+      /* Not found. Maybe only a BSD label is specified.  */
+      pcdata->dos_part = -1;
+      grub_errno = GRUB_ERR_NONE;
+    }
+  else if (*s == ',')
+    s++;
+
+  if (*s)
+    {
+      if (*s >= 'a' && *s <= 'h')
+	{
+	  pcdata->bsd_part = *s - 'a';
+	  s++;
+	}
+
+      if (*s)
+	goto fail;
+    }
+
+  if (pcdata->dos_part == -1 && pcdata->bsd_part == -1)
+    goto fail;
+
+  return p;
+
+ fail:
+  grub_free (p);
+  grub_free (pcdata);
+  grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
+  return 0;
+}
+
+static grub_err_t
+pc_partition_map_iterate (grub_disk_t disk,
+			  int (*hook) (grub_disk_t disk,
+				       const grub_partition_t partition))
+{
+  struct grub_partition p;
+  struct grub_msdos_partition pcdata;
+  struct grub_msdos_partition_mbr mbr;
+  struct grub_msdos_partition_disk_label label;
+  struct grub_disk raw;
+  int labeln = 0;
+  grub_disk_addr_t lastaddr;
+
+  /* Enforce raw disk access.  */
+  raw = *disk;
+  raw.partition = 0;
+
+  p.offset = 0;
+  pcdata.ext_offset = 0;
+  pcdata.dos_part = -1;
+  p.data = &pcdata;
+  p.partmap = &grub_msdos_partition_map;
+
+  /* Any value different than `p.offset' will satisfy the check during
+     first loop.  */
+  lastaddr = !p.offset;
+
+  while (1)
+    {
+      int i;
+      struct grub_msdos_partition_entry *e;
+
+      /* Read the MBR.  */
+      if (grub_disk_read (&raw, p.offset, 0, sizeof (mbr), &mbr))
+	goto finish;
+
+      /* This is our loop-detection algorithm. It works the following way:
+	 It saves last position which was a power of two. Then it compares the
+	 saved value with a current one. This way it's guaranteed that the loop
+	 will be broken by at most third walk.
+       */
+      if (labeln && lastaddr == p.offset)
+	return grub_error (GRUB_ERR_BAD_PART_TABLE, "loop detected");
+
+      labeln++;
+      if ((labeln & (labeln - 1)) == 0)
+	lastaddr = p.offset;
+
+      /* Check if it is valid.  */
+      if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
+	return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
+
+      for (i = 0; i < 4; i++)
+	if (mbr.entries[i].flag & 0x7f)
+	  return grub_error (GRUB_ERR_BAD_PART_TABLE, "bad boot flag");
+
+      /* Analyze DOS partitions.  */
+      for (p.index = 0; p.index < 4; p.index++)
+	{
+	  e = mbr.entries + p.index;
+
+	  p.start = p.offset + grub_le_to_cpu32 (e->start);
+	  p.len = grub_le_to_cpu32 (e->length);
+	  pcdata.bsd_part = -1;
+	  pcdata.dos_type = e->type;
+	  pcdata.bsd_type = -1;
+
+	  grub_dprintf ("partition",
+			"partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",
+			p.index, e->flag, pcdata.dos_type,
+			(unsigned long long) p.start,
+			(unsigned long long) p.len);
+
+	  /* If this is a GPT partition, this MBR is just a dummy.  */
+	  if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && p.index == 0)
+	    return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr");
+
+	  /* If this partition is a normal one, call the hook.  */
+	  if (! grub_msdos_partition_is_empty (e->type)
+	      && ! grub_msdos_partition_is_extended (e->type))
+	    {
+	      pcdata.dos_part++;
+
+	      if (hook (disk, &p))
+		return 1;
+
+	      /* Check if this is a BSD partition.  */
+	      if (grub_msdos_partition_is_bsd (e->type))
+		{
+		  /* Check if the BSD label is within the DOS partition.  */
+		  if (p.len <= GRUB_PC_PARTITION_BSD_LABEL_SECTOR)
+		    {
+		      grub_dprintf ("partition", "no space for disk label\n");
+		      continue;
+		    }
+		  /* Read the BSD label.  */
+		  if (grub_disk_read (&raw,
+				      (p.start
+				       + GRUB_PC_PARTITION_BSD_LABEL_SECTOR),
+				      0,
+				      sizeof (label),
+				      &label))
+		    goto finish;
+
+		  /* Check if it is valid.  */
+		  if (label.magic
+		      != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
+		    {
+		      grub_dprintf ("partition",
+				    "invalid disk label magic 0x%x on partition %d\n",
+				    label.magic, p.index);
+		      continue;
+		    }
+		  for (pcdata.bsd_part = 0;
+		       pcdata.bsd_part < grub_cpu_to_le16 (label.num_partitions);
+		       pcdata.bsd_part++)
+		    {
+		      struct grub_msdos_partition_bsd_entry *be
+			= label.entries + pcdata.bsd_part;
+
+		      p.start = grub_le_to_cpu32 (be->offset);
+		      p.len = grub_le_to_cpu32 (be->size);
+		      pcdata.bsd_type = be->fs_type;
+
+		      if (be->fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED)
+			if (hook (disk, &p))
+			  return 1;
+		    }
+		}
+	    }
+	  else if (pcdata.dos_part < 4)
+	    /* If this partition is a logical one, shouldn't increase the
+	       partition number.  */
+	    pcdata.dos_part++;
+	}
+
+      /* Find an extended partition.  */
+      for (i = 0; i < 4; i++)
+	{
+	  e = mbr.entries + i;
+
+	  if (grub_msdos_partition_is_extended (e->type))
+	    {
+	      p.offset = pcdata.ext_offset + grub_le_to_cpu32 (e->start);
+	      if (! pcdata.ext_offset)
+		pcdata.ext_offset = p.offset;
+
+	      break;
+	    }
+	}
+
+      /* If no extended partition, the end.  */
+      if (i == 4)
+	break;
+    }
+
+ finish:
+  return grub_errno;
+}
+
+
+static grub_partition_t
+pc_partition_map_probe (grub_disk_t disk, const char *str)
+{
+  grub_partition_t p;
+  struct grub_msdos_partition *pcdata;
+
+  auto int find_func (grub_disk_t d, const grub_partition_t partition);
+
+  int find_func (grub_disk_t d __attribute__ ((unused)),
+		 const grub_partition_t partition)
+    {
+      struct grub_msdos_partition *partdata = partition->data;
+
+      if ((pcdata->dos_part == partdata->dos_part || pcdata->dos_part == -1)
+	  && pcdata->bsd_part == partdata->bsd_part)
+	{
+	  grub_memcpy (p, partition, sizeof (*p));
+	  p->data = pcdata;
+	  grub_memcpy (pcdata, partdata, sizeof (*pcdata));
+	  return 1;
+	}
+
+      return 0;
+    }
+
+  p = grub_partition_parse (str);
+  if (! p)
+    return 0;
+
+  pcdata = p->data;
+  pc_partition_map_iterate (disk, find_func);
+  if (grub_errno)
+    goto fail;
+
+  if (p->index < 0)
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "no such partition");
+      goto fail;
+    }
+
+  return p;
+
+ fail:
+  grub_free (p);
+  grub_free (pcdata);
+  return 0;
+}
+
+
+static char *
+pc_partition_map_get_name (const grub_partition_t p)
+{
+  char *name;
+  struct grub_msdos_partition *pcdata = p->data;
+
+  name = grub_malloc (13);
+  if (! name)
+    return 0;
+
+  if (pcdata->bsd_part < 0)
+    grub_sprintf (name, "%d", pcdata->dos_part + 1);
+  else if (pcdata->dos_part < 0)
+    grub_sprintf (name, "%c", pcdata->bsd_part + 'a');
+  else
+    grub_sprintf (name, "%d,%c", pcdata->dos_part + 1, pcdata->bsd_part + 'a');
+
+  return name;
+}
+
+
+/* Partition map type.  */
+static struct grub_partition_map grub_msdos_partition_map =
+  {
+    .name = "part_msdos",
+    .iterate = pc_partition_map_iterate,
+    .probe = pc_partition_map_probe,
+    .get_name = pc_partition_map_get_name
+  };
+
+GRUB_MOD_INIT(pc_partition_map)
+{
+  grub_partition_map_register (&grub_msdos_partition_map);
+}
+
+GRUB_MOD_FINI(pc_partition_map)
+{
+  grub_partition_map_unregister (&grub_msdos_partition_map);
+}
diff --git a/partmap/sun.c b/partmap/sun.c
new file mode 100644
index 0000000..e816ec1
--- /dev/null
+++ b/partmap/sun.c
@@ -0,0 +1,214 @@
+/* sun.c - Read SUN style partition tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/partition.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/dl.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/err.h>
+
+#define GRUB_PARTMAP_SUN_MAGIC 0xDABE
+#define GRUB_PARTMAP_SUN_MAX_PARTS 8
+#define GRUB_PARTMAP_SUN_WHOLE_DISK_ID 0x05
+
+struct grub_sun_partition_info
+{
+  grub_uint8_t spare1;
+  grub_uint8_t id;
+  grub_uint8_t spare2;
+  grub_uint8_t flags;
+} __attribute__ ((packed));
+
+struct grub_sun_partition_descriptor
+{
+  grub_uint32_t start_cylinder;
+  grub_uint32_t num_sectors;
+} __attribute__ ((packed));
+
+struct grub_sun_block
+{
+  grub_uint8_t  info[128];      /* Informative text string.  */
+  grub_uint8_t  spare0[14];
+  struct grub_sun_partition_info infos[8];
+  grub_uint8_t  spare1[246];    /* Boot information etc.  */
+  grub_uint16_t  rspeed;        /* Disk rotational speed.  */
+  grub_uint16_t  pcylcount;     /* Physical cylinder count.  */
+  grub_uint16_t  sparecyl;      /* extra sects per cylinder.  */
+  grub_uint8_t  spare2[4];      /* More magic...  */
+  grub_uint16_t  ilfact;        /* Interleave factor.  */
+  grub_uint16_t  ncyl;          /* Data cylinder count.  */
+  grub_uint16_t  nacyl;         /* Alt. cylinder count.  */
+  grub_uint16_t  ntrks;         /* Tracks per cylinder.  */
+  grub_uint16_t  nsect;         /* Sectors per track.  */
+  grub_uint8_t  spare3[4];      /* Even more magic...  */
+  struct grub_sun_partition_descriptor partitions[8];
+  grub_uint16_t  magic;         /* Magic number.  */
+  grub_uint16_t  csum;          /* Label xor'd checksum.  */
+} __attribute__ ((packed));
+
+static struct grub_partition_map grub_sun_partition_map;
+
+/* Verify checksum (true=ok).  */
+static int
+grub_sun_is_valid (struct grub_sun_block *label)
+{
+  grub_uint16_t *pos;
+  grub_uint16_t sum = 0;
+
+  for (pos = (grub_uint16_t *) label;
+       pos < (grub_uint16_t *) (label + 1);
+       pos++)
+    sum ^= *pos;
+
+  return ! sum;
+}
+
+static grub_err_t
+sun_partition_map_iterate (grub_disk_t disk,
+                           int (*hook) (grub_disk_t disk,
+					const grub_partition_t partition))
+{
+  grub_partition_t p;
+  struct grub_disk raw;
+  struct grub_sun_block block;
+  int partnum;
+
+  raw = *disk;
+  raw.partition = 0;
+
+  p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition));
+  if (! p)
+    return grub_errno;
+
+  p->partmap = &grub_sun_partition_map;
+  if (grub_disk_read (&raw, 0, 0, sizeof (struct grub_sun_block),
+		      &block) == GRUB_ERR_NONE)
+    {
+      if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic))
+	grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun partition table");
+
+      if (! grub_sun_is_valid (&block))
+	grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
+
+      /* Maybe another error value would be better, because partition
+	 table _is_ recognized but invalid.  */
+      for (partnum = 0; partnum < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++)
+	{
+	  struct grub_sun_partition_descriptor *desc;
+
+	  if (block.infos[partnum].id == 0
+	      || block.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID)
+	    continue;
+
+	  desc = &block.partitions[partnum];
+	  p->start = ((grub_uint64_t) grub_be_to_cpu32 (desc->start_cylinder)
+		      * grub_be_to_cpu16 (block.ntrks)
+		      * grub_be_to_cpu16 (block.nsect));
+	  p->len = grub_be_to_cpu32 (desc->num_sectors);
+	  p->index = partnum;
+	  if (p->len)
+	    {
+	      if (hook (disk, p))
+		partnum = GRUB_PARTMAP_SUN_MAX_PARTS;
+	    }
+	}
+    }
+
+  grub_free (p);
+
+  return grub_errno;
+}
+
+static grub_partition_t
+sun_partition_map_probe (grub_disk_t disk, const char *str)
+{
+  grub_partition_t p = 0;
+  int partnum = 0;
+  char *s = (char *) str;
+
+  auto int find_func (grub_disk_t d, const grub_partition_t partition);
+
+  int find_func (grub_disk_t d __attribute__ ((unused)),
+		 const grub_partition_t partition)
+    {
+      if (partnum == partition->index)
+        {
+          p = (grub_partition_t) grub_malloc (sizeof (*p));
+          if (p)
+            grub_memcpy (p, partition, sizeof (*p));
+
+          return 1;
+        }
+
+      return 0;
+    }
+
+  grub_errno = GRUB_ERR_NONE;
+  partnum = grub_strtoul (s, 0, 10) - 1;
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      if (sun_partition_map_iterate (disk, find_func))
+        {
+          grub_free (p);
+          p = 0;
+        }
+    }
+  else
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
+      p = 0;
+    }
+
+  return p;
+}
+
+static char *
+sun_partition_map_get_name (const grub_partition_t p)
+{
+  char *name;
+
+  name = grub_malloc (13);
+  if (name)
+    grub_sprintf (name, "%d", p->index + 1);
+
+  return name;
+}
+
+/* Partition map type.  */
+static struct grub_partition_map grub_sun_partition_map =
+  {
+    .name = "part_sun",
+    .iterate = sun_partition_map_iterate,
+    .probe = sun_partition_map_probe,
+    .get_name = sun_partition_map_get_name
+  };
+
+GRUB_MOD_INIT(sun_partition_map)
+{
+  grub_partition_map_register (&grub_sun_partition_map);
+}
+
+GRUB_MOD_FINI(sun_partition_map)
+{
+  grub_partition_map_unregister (&grub_sun_partition_map);
+}
+
diff --git a/parttool/msdospart.c b/parttool/msdospart.c
new file mode 100644
index 0000000..dbb25bc
--- /dev/null
+++ b/parttool/msdospart.c
@@ -0,0 +1,155 @@
+/* pcpart.c - manipulate fdisk partitions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  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 <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/msdos_partition.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/parttool.h>
+
+static int activate_table_handle = -1;
+static int type_table_handle = -1;
+
+static struct grub_parttool_argdesc grub_pcpart_bootargs[] =
+{
+  {"boot", "Make partition active", GRUB_PARTTOOL_ARG_BOOL},
+  {0, 0, 0}
+};
+
+static grub_err_t grub_pcpart_boot (const grub_device_t dev,
+				    const struct grub_parttool_args *args)
+{
+  int i, index;
+  grub_partition_t part;
+  struct grub_msdos_partition_mbr mbr;
+
+  if (dev->disk->partition->offset)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a primary partition");
+
+  index = dev->disk->partition->index;
+  part = dev->disk->partition;
+  dev->disk->partition = 0;
+
+  /* Read the MBR.  */
+  if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), &mbr))
+    {
+      dev->disk->partition = part;
+      return grub_errno;
+    }
+
+  if (args[0].set && args[0].bool)
+    {
+      for (i = 0; i < 4; i++)
+	mbr.entries[i].flag = 0x0;
+      mbr.entries[index].flag = 0x80;
+      grub_printf ("Partition %d is active now. \n", index);
+    }
+  else
+    {
+      mbr.entries[index].flag = 0x0;
+      grub_printf ("Cleared active flag on %d. \n", index);
+    }
+
+   /* Write the MBR.  */
+  grub_disk_write (dev->disk, 0, 0, sizeof (mbr), &mbr);
+
+  dev->disk->partition = part;
+
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_parttool_argdesc grub_pcpart_typeargs[] =
+{
+  {"type", "Change partition type", GRUB_PARTTOOL_ARG_VAL},
+  {"hidden", "Make partition hidden", GRUB_PARTTOOL_ARG_BOOL},
+  {0, 0, 0}
+};
+
+static grub_err_t grub_pcpart_type (const grub_device_t dev,
+				    const struct grub_parttool_args *args)
+{
+  int index;
+  grub_uint8_t type;
+  grub_partition_t part;
+  struct grub_msdos_partition_mbr mbr;
+
+  index = dev->disk->partition->index;
+  part = dev->disk->partition;
+  dev->disk->partition = 0;
+
+  /* Read the parttable.  */
+  if (grub_disk_read (dev->disk, part->offset, 0,
+		      sizeof (mbr), &mbr))
+    {
+      dev->disk->partition = part;
+      return grub_errno;
+    }
+
+  if (args[0].set)
+    type = grub_strtoul (args[0].str, 0, 0);
+  else
+    type = mbr.entries[index].type;
+
+  if (args[1].set)
+    {
+      if (args[1].bool)
+	type |= GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
+      else
+	type &= ~GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
+    }
+
+  if (grub_msdos_partition_is_empty (type)
+      || grub_msdos_partition_is_extended (type))
+    {
+      dev->disk->partition = part;
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid type");
+    }
+
+  mbr.entries[index].type = type;
+  grub_printf ("Setting partition type to 0x%x\n", type);
+
+   /* Write the parttable.  */
+  grub_disk_write (dev->disk, part->offset, 0,
+		   sizeof (mbr), &mbr);
+
+  dev->disk->partition = part;
+
+  return GRUB_ERR_NONE;
+}
+
+GRUB_MOD_INIT (pcpart)
+{
+  activate_table_handle = grub_parttool_register ("part_msdos",
+						  grub_pcpart_boot,
+						  grub_pcpart_bootargs);
+  type_table_handle = grub_parttool_register ("part_msdos",
+					      grub_pcpart_type,
+					      grub_pcpart_typeargs);
+
+}
+GRUB_MOD_FINI(pcpart)
+{
+  grub_parttool_unregister (activate_table_handle);
+  grub_parttool_unregister (type_table_handle);
+}
diff --git a/script/sh/execute.c b/script/sh/execute.c
new file mode 100644
index 0000000..e9064ad
--- /dev/null
+++ b/script/sh/execute.c
@@ -0,0 +1,254 @@
+/* execute.c -- Execute a GRUB script.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/script_sh.h>
+#include <grub/command.h>
+#include <grub/menu.h>
+#include <grub/lib/arg.h>
+#include <grub/normal.h>
+
+static grub_err_t
+grub_script_execute_cmd (struct grub_script_cmd *cmd)
+{
+  if (cmd == 0)
+    return 0;
+
+  return cmd->exec (cmd);
+}
+
+/* Parse ARG and return the textual representation.  Add strings are
+   concatenated and all values of the variables are filled in.  */
+char *
+grub_script_execute_argument_to_string (struct grub_script_arg *arg)
+{
+  int size = 0;
+  char *val;
+  char *chararg;
+  struct grub_script_arg *argi;
+
+  /* First determine the size of the argument.  */
+  for (argi = arg; argi; argi = argi->next)
+    {
+      if (argi->type == 1)
+	{
+	  val = grub_env_get (argi->str);
+	  if (val)
+	    size += grub_strlen (val);
+	}
+      else
+	size += grub_strlen (argi->str);
+    }
+
+  /* Create the argument.  */
+  chararg = grub_malloc (size + 1);
+  if (! chararg)
+    return 0;
+
+  *chararg = '\0';
+  /* First determine the size of the argument.  */
+  for (argi = arg; argi; argi = argi->next)
+    {
+      if (argi->type == 1)
+	{
+	  val = grub_env_get (argi->str);
+	  if (val)
+	    grub_strcat (chararg, val);
+	}
+      else
+	grub_strcat (chararg, argi->str);
+    }
+
+  return chararg;
+}
+
+/* Execute a single command line.  */
+grub_err_t
+grub_script_execute_cmdline (struct grub_script_cmd *cmd)
+{
+  struct grub_script_cmdline *cmdline = (struct grub_script_cmdline *) cmd;
+  struct grub_script_arglist *arglist;
+  char **args = 0;
+  int i = 0;
+  grub_command_t grubcmd;
+  grub_err_t ret = 0;
+  int argcount = 0;
+  grub_script_function_t func = 0;
+  char errnobuf[6];
+  char *cmdname;
+
+  /* Lookup the command.  */
+  cmdname = grub_script_execute_argument_to_string (cmdline->arglist->arg);
+  grubcmd = grub_command_find (cmdname);
+  if (! grubcmd)
+    {
+      /* Ignore errors.  */
+      grub_errno = GRUB_ERR_NONE;
+
+      /* It's not a GRUB command, try all functions.  */
+      func = grub_script_function_find (cmdname);
+      if (! func)
+	{
+	  /* As a last resort, try if it is an assignment.  */
+	  char *assign = grub_strdup (cmdname);
+	  char *eq = grub_strchr (assign, '=');
+
+	  if (eq)
+	    {
+	      /* Create two strings and set the variable.  */
+	      *eq = '\0';
+	      eq++;
+	      grub_env_set (assign, eq);
+
+	      /* This was set because the command was not found.  */
+	      grub_errno = GRUB_ERR_NONE;
+	    }
+	  grub_free (assign);
+
+	  grub_sprintf (errnobuf, "%d", grub_errno);
+	  grub_env_set ("?", errnobuf);
+
+	  return 0;
+	}
+    }
+  grub_free (cmdname);
+
+  if (cmdline->arglist->next)
+    {
+      argcount = cmdline->arglist->argcount - 1;
+
+      /* Create argv from the arguments.  */
+      args = grub_malloc (sizeof (char *) * argcount);
+      for (arglist = cmdline->arglist->next; arglist; arglist = arglist->next)
+	{
+	  char *str;
+	  str = grub_script_execute_argument_to_string (arglist->arg);
+	  args[i++] = str;
+	}
+    }
+
+  /* Execute the GRUB command or function.  */
+  if (grubcmd)
+    ret = (grubcmd->func) (grubcmd, argcount, args);
+  else
+    ret = grub_script_function_call (func, argcount, args);
+
+  /* Free arguments.  */
+  for (i = 0; i < argcount; i++)
+    grub_free (args[i]);
+  grub_free (args);
+
+  grub_sprintf (errnobuf, "%d", ret);
+  grub_env_set ("?", errnobuf);
+
+  return ret;
+}
+
+/* Execute a block of one or more commands.  */
+grub_err_t
+grub_script_execute_cmdblock (struct grub_script_cmd *cmd)
+{
+  struct grub_script_cmdblock *cmdblock = (struct grub_script_cmdblock *) cmd;
+
+  /* Loop over every command and execute it.  */
+  for (cmd = cmdblock->cmdlist; cmd; cmd = cmd->next)
+    grub_script_execute_cmd (cmd);
+
+  return 0;
+}
+
+/* Execute an if statement.  */
+grub_err_t
+grub_script_execute_cmdif (struct grub_script_cmd *cmd)
+{
+  struct grub_script_cmdif *cmdif = (struct grub_script_cmdif *) cmd;
+  char *result;
+
+  /* Check if the commands results in a true or a false.  The value is
+     read from the env variable `?'.  */
+  grub_script_execute_cmd (cmdif->exec_to_evaluate);
+  result = grub_env_get ("?");
+
+  grub_errno = GRUB_ERR_NONE;
+
+  /* Execute the `if' or the `else' part depending on the value of
+     `?'.  */
+  if (result && ! grub_strcmp (result, "0"))
+    return grub_script_execute_cmd (cmdif->exec_on_true);
+  else
+    return grub_script_execute_cmd (cmdif->exec_on_false);
+}
+
+/* Execute the menu entry generate statement.  */
+grub_err_t
+grub_script_execute_menuentry (struct grub_script_cmd *cmd)
+{
+  struct grub_script_cmd_menuentry *cmd_menuentry;
+  struct grub_script_arglist *arglist;
+  char **args = 0;
+  int argcount = 0;
+  int i = 0;
+
+  cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd;
+
+  if (cmd_menuentry->arglist)
+    {
+      argcount = cmd_menuentry->arglist->argcount;
+
+      /* Create argv from the arguments.  */
+      args = grub_malloc (sizeof (char *) * argcount);
+
+      if (! args)
+	{
+	  return grub_errno;
+	}
+
+      for (arglist = cmd_menuentry->arglist; arglist; arglist = arglist->next)
+	{
+	  char *str;
+	  str = grub_script_execute_argument_to_string (arglist->arg);
+	  args[i++] = str;
+	}
+    }
+
+  grub_normal_add_menu_entry (argcount, (const char **) args,
+			      cmd_menuentry->sourcecode);
+
+  /* Free arguments.  */
+  for (i = 0; i < argcount; i++)
+    grub_free (args[i]);
+  grub_free (args);
+
+  return grub_errno;
+}
+
+
+
+/* Execute any GRUB pre-parsed command or script.  */
+grub_err_t
+grub_script_execute (struct grub_script *script)
+{
+  if (script == 0)
+    return 0;
+
+  return grub_script_execute_cmd (script->cmd);
+}
+
diff --git a/script/sh/function.c b/script/sh/function.c
new file mode 100644
index 0000000..a3950a8
--- /dev/null
+++ b/script/sh/function.c
@@ -0,0 +1,126 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/script_sh.h>
+#include <grub/parser.h>
+#include <grub/mm.h>
+
+static grub_script_function_t grub_script_function_list;
+
+grub_script_function_t
+grub_script_function_create (struct grub_script_arg *functionname_arg,
+			     struct grub_script *cmd)
+{
+  grub_script_function_t func;
+  grub_script_function_t *p;
+
+  func = (grub_script_function_t) grub_malloc (sizeof (*func));
+  if (! func)
+    return 0;
+
+  func->name = grub_script_execute_argument_to_string (functionname_arg);
+  if (! func->name)
+    {
+      grub_free (func);
+      return 0;
+    }
+
+  func->func = cmd;
+
+  /* Keep the list sorted for simplicity.  */
+  p = &grub_script_function_list;
+  while (*p)
+    {
+      if (grub_strcmp ((*p)->name, func->name) >= 0)
+	break;
+
+      p = &((*p)->next);
+    }
+
+  /* If the function already exists, overwrite the old function.  */
+  if (*p && grub_strcmp ((*p)->name, func->name) == 0)
+    {
+      grub_script_function_t q;
+
+      q = *p;
+      grub_script_free (q->func);
+      q->func = cmd;
+      grub_free (func);
+      func = q;
+    }
+  else
+    {
+      func->next = *p;
+      *p = func;
+    }
+
+  return func;
+}
+
+void
+grub_script_function_remove (const char *name)
+{
+  grub_script_function_t *p, q;
+
+  for (p = &grub_script_function_list, q = *p; q; p = &(q->next), q = q->next)
+    if (grub_strcmp (name, q->name) == 0)
+      {
+        *p = q->next;
+	grub_free (q->name);
+	grub_script_free (q->func);
+        grub_free (q);
+        break;
+      }
+}
+
+grub_script_function_t
+grub_script_function_find (char *functionname)
+{
+  grub_script_function_t func;
+
+  for (func = grub_script_function_list; func; func = func->next)
+    if (grub_strcmp (functionname, func->name) == 0)
+      break;
+
+  if (! func)
+    grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%.20s'", functionname);
+
+  return func;
+}
+
+int
+grub_script_function_iterate (int (*iterate) (grub_script_function_t))
+{
+  grub_script_function_t func;
+
+  for (func = grub_script_function_list; func; func = func->next)
+    if (iterate (func))
+      return 1;
+
+  return 0;
+}
+
+int
+grub_script_function_call (grub_script_function_t func,
+			   int argc __attribute__((unused)),
+			   char **args __attribute__((unused)))
+{
+  /* XXX: Arguments are not supported yet.  */
+  return grub_script_execute (func->func);
+}
diff --git a/script/sh/lexer.c b/script/sh/lexer.c
new file mode 100644
index 0000000..a30e3c0
--- /dev/null
+++ b/script/sh/lexer.c
@@ -0,0 +1,433 @@
+/* lexer.c - The scripting lexer.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/parser.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/script_sh.h>
+
+#include "grub_script.tab.h"
+
+static int
+check_varstate (grub_parser_state_t state)
+{
+  return (state == GRUB_PARSER_STATE_VARNAME
+	  || state == GRUB_PARSER_STATE_VAR
+	  || state == GRUB_PARSER_STATE_QVAR
+	  || state == GRUB_PARSER_STATE_VARNAME2
+	  || state == GRUB_PARSER_STATE_QVARNAME
+	  || state == GRUB_PARSER_STATE_QVARNAME2);
+}
+
+static int
+check_textstate (grub_parser_state_t state)
+{
+  return (state == GRUB_PARSER_STATE_TEXT
+	  || state == GRUB_PARSER_STATE_ESC
+	  || state == GRUB_PARSER_STATE_QUOTE
+	  || state == GRUB_PARSER_STATE_DQUOTE);
+}
+
+struct grub_lexer_param *
+grub_script_lexer_init (char *script, grub_reader_getline_t getline)
+{
+  struct grub_lexer_param *param;
+
+  param = grub_zalloc (sizeof (*param));
+  if (! param)
+    return 0;
+
+  param->state = GRUB_PARSER_STATE_TEXT;
+  param->getline = getline;
+  param->script = script;
+
+  return param;
+}
+
+void
+grub_script_lexer_ref (struct grub_lexer_param *state)
+{
+  state->refs++;
+}
+
+void
+grub_script_lexer_deref (struct grub_lexer_param *state)
+{
+  state->refs--;
+}
+
+/* Start recording all characters passing through the lexer.  */
+void
+grub_script_lexer_record_start (struct grub_lexer_param *state)
+{
+  state->record = 1;
+  state->recordlen = 100;
+  state->recording = grub_malloc (state->recordlen);
+  state->recordpos = 0;
+}
+
+char *
+grub_script_lexer_record_stop (struct grub_lexer_param *state)
+{
+  state->record = 0;
+
+  /* Delete the last character, it is a `}'.  */
+  if (state->recordpos > 0)
+    {
+      if (state->recording[--state->recordpos] != '}')
+	{
+	  grub_printf ("Internal error while parsing menu entry");
+	  for (;;); /* XXX */
+	}
+      state->recording[state->recordpos] = '\0';
+    }
+
+  return state->recording;
+}
+
+/* When recording is enabled, record the character C as the next item
+   in the character stream.  */
+static void
+recordchar (struct grub_lexer_param *state, char c)
+{
+  if (state->recordpos == state->recordlen)
+    {
+      char *old = state->recording;
+      state->recordlen += 100;
+      state->recording = grub_realloc (state->recording, state->recordlen);
+      if (! state->recording)
+	{
+	  grub_free (old);
+	  state->record = 0;
+	}
+    }
+  state->recording[state->recordpos++] = c;
+}
+
+/* Fetch the next character for the lexer.  */
+static void
+nextchar (struct grub_lexer_param *state)
+{
+  if (state->record)
+    recordchar (state, *state->script);
+  state->script++;
+}
+
+int
+grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate)
+{
+  grub_parser_state_t newstate;
+  char use;
+  struct grub_lexer_param *state = parsestate->lexerstate;
+  int firstrun = 1;
+
+  yylval->arg = 0;
+
+  if (state->tokenonhold)
+    {
+      int token = state->tokenonhold;
+      state->tokenonhold = 0;
+      return token;
+    }
+
+  for (;! state->done; firstrun = 0)
+    {
+      if (! state->script || ! *state->script)
+	{
+	  /* Check if more tokens are requested by the parser.  */
+	  if (((state->refs && ! parsestate->err)
+	       || state->state == GRUB_PARSER_STATE_ESC
+	       || state->state == GRUB_PARSER_STATE_QUOTE
+	       || state->state == GRUB_PARSER_STATE_DQUOTE)
+	      && state->getline)
+	    {
+	      int doexit = 0;
+	      if (state->state != GRUB_PARSER_STATE_ESC
+		  && state->state != GRUB_PARSER_STATE_QUOTE
+		  && state->state != GRUB_PARSER_STATE_DQUOTE
+		  && ! state->was_newline)
+		{
+		  state->was_newline = 1;
+		  state->tokenonhold = '\n';
+		  break;
+		}
+	      while (! state->script || ! *state->script)
+		{
+		  grub_free (state->newscript);
+		  state->newscript = 0;
+		  state->getline (&state->newscript, 1);
+		  state->script = state->newscript;
+		  if (! state->script)
+		    {
+		      doexit = 1;
+		      break;
+		    }
+		}
+	      if (doexit)
+		break;
+	      grub_dprintf ("scripting", "token=`\\n'\n");
+	      recordchar (state, '\n');
+	      if (state->state == GRUB_PARSER_STATE_VARNAME)
+		state->state = GRUB_PARSER_STATE_TEXT;
+	      if (state->state == GRUB_PARSER_STATE_QVARNAME)
+		state->state = GRUB_PARSER_STATE_DQUOTE;
+	      if (state->state == GRUB_PARSER_STATE_DQUOTE
+		  || state->state == GRUB_PARSER_STATE_QUOTE)
+		yylval->arg = grub_script_arg_add (parsestate, yylval->arg,
+						   GRUB_SCRIPT_ARG_TYPE_STR,
+						   "\n");
+	    }
+	  else
+	    {
+	      grub_free (state->newscript);
+	      state->newscript = 0;
+	      state->done = 1;
+	      grub_dprintf ("scripting", "token=`\\n'\n");
+	      state->tokenonhold = '\n';
+	      break;
+	    }
+	}
+      state->was_newline = 0;
+
+      newstate = grub_parser_cmdline_state (state->state, *state->script, &use);
+
+      /* Check if it is a text.  */
+      if (check_textstate (newstate))
+	{
+	  char *buffer = NULL;
+	  int bufpos = 0;
+	  /* Buffer is initially large enough to hold most commands
+	     but extends automatically when needed.  */
+	  int bufsize = 128;
+
+	  buffer = grub_malloc (bufsize);
+
+	  /* In case the string is not quoted, this can be a one char
+	     length symbol.  */
+	  if (newstate == GRUB_PARSER_STATE_TEXT)
+	    {
+	      int doexit = 0;
+	      switch (*state->script)
+		{
+		case ' ':
+		  while (*state->script)
+		    {
+		      newstate = grub_parser_cmdline_state (state->state,
+							    *state->script, &use);
+		      if (! (state->state == GRUB_PARSER_STATE_TEXT
+			     && *state->script == ' '))
+			{
+			  grub_dprintf ("scripting", "token=` '\n");
+			  if (! firstrun)
+			    doexit = 1;
+			  break;
+			}
+		      state->state = newstate;
+		      nextchar (state);
+		    }
+		  grub_dprintf ("scripting", "token=` '\n");
+		  if (! firstrun)
+		    doexit = 1;
+		  break;
+		case '{':
+		case '}':
+		case ';':
+		case '\n':
+		  {
+		    char c;
+		    grub_dprintf ("scripting", "token=`%c'\n", *state->script);
+		    c = *state->script;
+		    nextchar (state);
+		    state->tokenonhold = c;
+		    doexit = 1;
+		    break;
+		  }
+		}
+	      if (doexit)
+		{
+		  grub_free (buffer);
+		  break;
+		}
+	    }
+
+	  /* Read one token, possible quoted.  */
+	  while (*state->script)
+	    {
+	      newstate = grub_parser_cmdline_state (state->state,
+						    *state->script, &use);
+
+	      /* Check if a variable name starts.  */
+	      if (check_varstate (newstate))
+		break;
+
+	      /* If the string is not quoted or escaped, stop processing
+		 when a special token was found.  It will be recognized
+		 next time when this function is called.  */
+	      if (newstate == GRUB_PARSER_STATE_TEXT
+		  && state->state != GRUB_PARSER_STATE_ESC
+		  && state->state != GRUB_PARSER_STATE_QUOTE
+		  && state->state != GRUB_PARSER_STATE_DQUOTE)
+		{
+		  int breakout = 0;
+
+		  switch (use)
+		    {
+		    case ' ':
+		    case '{':
+		    case '}':
+		    case ';':
+		    case '\n':
+		      breakout = 1;
+		    }
+		  if (breakout)
+		    break;
+		}
+
+	      if (use)
+		{
+		  if (bufsize <= bufpos + 1)
+		    {
+		      bufsize <<= 1;
+		      buffer = grub_realloc (buffer, bufsize);
+		    }
+		  buffer[bufpos++] = use;
+		}
+
+	      state->state = newstate;
+	      nextchar (state);
+	    }
+
+	  /* A string of text was read in.  */
+	  if (bufsize <= bufpos + 1)
+	    {
+	      bufsize <<= 1;
+	      buffer = grub_realloc (buffer, bufsize);
+	    }
+
+	  buffer[bufpos++] = 0;
+
+	  grub_dprintf ("scripting", "token=`%s'\n", buffer);
+	  yylval->arg = grub_script_arg_add (parsestate, yylval->arg,
+					     GRUB_SCRIPT_ARG_TYPE_STR, buffer);
+
+	  grub_free (buffer);
+	}
+      else if (newstate == GRUB_PARSER_STATE_VAR
+	       || newstate == GRUB_PARSER_STATE_QVAR)
+	{
+	  char *buffer = NULL;
+	  int bufpos = 0;
+	  /* Buffer is initially large enough to hold most commands
+	     but extends automatically when needed.  */
+	  int bufsize = 128;
+
+	  buffer = grub_malloc (bufsize);
+
+	  /* This is a variable, read the variable name.  */
+	  while (*state->script)
+	    {
+	      newstate = grub_parser_cmdline_state (state->state,
+						    *state->script, &use);
+
+	      /* Check if this character is not part of the variable name
+		 anymore.  */
+	      if (! (check_varstate (newstate)))
+		{
+		  if (state->state == GRUB_PARSER_STATE_VARNAME2
+		  || state->state == GRUB_PARSER_STATE_QVARNAME2)
+		    nextchar (state);
+		  state->state = newstate;
+		  break;
+		}
+
+	      if (use)
+		{
+		  if (bufsize <= bufpos + 1)
+		    {
+		      bufsize <<= 1;
+		      buffer = grub_realloc (buffer, bufsize);
+		    }
+		  buffer[bufpos++] = use;
+		}
+
+	      nextchar (state);
+	      state->state = newstate;
+	    }
+
+	  if (bufsize <= bufpos + 1)
+	    {
+	      bufsize <<= 1;
+	      buffer = grub_realloc (buffer, bufsize);
+	    }
+
+	  buffer[bufpos++] = 0;
+
+	  state->state = newstate;
+	  yylval->arg = grub_script_arg_add (parsestate, yylval->arg,
+					     GRUB_SCRIPT_ARG_TYPE_VAR, buffer);
+	  grub_dprintf ("scripting", "vartoken=`%s'\n", buffer);
+
+	  grub_free (buffer);
+	}
+      else
+	{
+	  /* There is either text or a variable name.  In the case you
+	 arrive here there is a serious problem with the lexer.  */
+	  grub_error (GRUB_ERR_BAD_ARGUMENT, "Internal error\n");
+	  return 0;
+	}
+    }
+
+  if (yylval->arg == 0)
+    {
+      int token = state->tokenonhold;
+      state->tokenonhold = 0;
+      return token;
+    }
+
+  if (yylval->arg->next == 0 && yylval->arg->type == GRUB_SCRIPT_ARG_TYPE_STR)
+    {
+      /* Detect some special tokens.  */
+      if (! grub_strcmp (yylval->arg->str, "while"))
+	return GRUB_PARSER_TOKEN_WHILE;
+      else if (! grub_strcmp (yylval->arg->str, "if"))
+	return GRUB_PARSER_TOKEN_IF;
+      else if (! grub_strcmp (yylval->arg->str, "function"))
+	return GRUB_PARSER_TOKEN_FUNCTION;
+      else if (! grub_strcmp (yylval->arg->str, "menuentry"))
+	return GRUB_PARSER_TOKEN_MENUENTRY;
+      else if (! grub_strcmp (yylval->arg->str, "@"))
+	return GRUB_PARSER_TOKEN_MENUENTRY;
+      else if (! grub_strcmp (yylval->arg->str, "else"))
+	return GRUB_PARSER_TOKEN_ELSE;
+      else if (! grub_strcmp (yylval->arg->str, "then"))
+	return GRUB_PARSER_TOKEN_THEN;
+      else if (! grub_strcmp (yylval->arg->str, "fi"))
+	return GRUB_PARSER_TOKEN_FI;
+    }
+
+  return GRUB_PARSER_TOKEN_ARG;
+}
+
+void
+grub_script_yyerror (struct grub_parser_param *lex __attribute__ ((unused)),
+		     char const *err)
+{
+  grub_printf ("%s\n", err);
+}
diff --git a/script/sh/main.c b/script/sh/main.c
new file mode 100644
index 0000000..4eefafa
--- /dev/null
+++ b/script/sh/main.c
@@ -0,0 +1,57 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/parser.h>
+#include <grub/script_sh.h>
+
+static grub_err_t
+grub_normal_parse_line (char *line, grub_reader_getline_t getline)
+{
+  struct grub_script *parsed_script;
+
+  /* Parse the script.  */
+  parsed_script = grub_script_parse (line, getline);
+
+  if (parsed_script)
+    {
+      /* Execute the command(s).  */
+      grub_script_execute (parsed_script);
+
+      /* The parsed script was executed, throw it away.  */
+      grub_script_free (parsed_script);
+    }
+
+  return grub_errno;
+}
+
+static struct grub_parser grub_sh_parser =
+  {
+    .name = "sh",
+    .parse_line = grub_normal_parse_line
+  };
+
+GRUB_MOD_INIT(sh)
+{
+  grub_parser_register ("sh", &grub_sh_parser);
+}
+
+GRUB_MOD_FINI(sh)
+{
+  grub_parser_unregister (&grub_sh_parser);
+}
diff --git a/script/sh/parser.y b/script/sh/parser.y
new file mode 100644
index 0000000..094a885
--- /dev/null
+++ b/script/sh/parser.y
@@ -0,0 +1,197 @@
+/* parser.y - The scripting parser.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+%{
+#include <grub/script_sh.h>
+#include <grub/mm.h>
+
+#define YYFREE		grub_free
+#define YYMALLOC	grub_malloc
+#define YYLTYPE_IS_TRIVIAL      0
+#define YYENABLE_NLS	0
+
+%}
+
+%union {
+  struct grub_script_cmd *cmd;
+  struct grub_script_arglist *arglist;
+  struct grub_script_arg *arg;
+  char *string;
+}
+
+%token GRUB_PARSER_TOKEN_IF		"if"
+%token GRUB_PARSER_TOKEN_WHILE		"while"
+%token GRUB_PARSER_TOKEN_FUNCTION	"function"
+%token GRUB_PARSER_TOKEN_MENUENTRY	"menuentry"
+%token GRUB_PARSER_TOKEN_ELSE		"else"
+%token GRUB_PARSER_TOKEN_THEN		"then"
+%token GRUB_PARSER_TOKEN_FI		"fi"
+%token GRUB_PARSER_TOKEN_ARG
+%type <cmd> script_init script grubcmd command commands commandblock menuentry if
+%type <arglist> arguments;
+%type <arg> GRUB_PARSER_TOKEN_ARG;
+
+%pure-parser
+%lex-param { struct grub_parser_param *state };
+%parse-param { struct grub_parser_param *state };
+
+%%
+/* It should be possible to do this in a clean way...  */
+script_init:	{ state->err = 0; } script
+		  {
+		    state->parsed = $2;
+		  }
+;
+
+script:		{ $$ = 0; }
+                | '\n' { $$ = 0; }
+                | commands { $$ = $1; }
+		| function '\n' { $$ = 0; }
+		| menuentry '\n' { $$ = $1; }
+		| error
+		  {
+		    $$ = 0;
+		    yyerror (state, "Incorrect command");
+		    state->err = 1;
+		    yyerrok;
+		  }
+;
+
+delimiter:	'\n'
+		| ';'
+		| delimiter '\n'
+;
+
+newlines:	/* Empty */
+		| newlines '\n'
+;
+
+
+
+arguments:	GRUB_PARSER_TOKEN_ARG
+		  {
+		    $$ = grub_script_add_arglist (state, 0, $1);
+		  }
+		| arguments GRUB_PARSER_TOKEN_ARG
+		  {
+		    $$ = grub_script_add_arglist (state, $1, $2);
+		  }
+;
+
+grubcmd:	arguments
+		  {
+		    $$ = grub_script_create_cmdline (state, $1);
+		  }
+;
+
+/* A single command.  */
+command:	grubcmd delimiter { $$ = $1; }
+		| if delimiter 	{ $$ = $1; }
+		| commandblock delimiter { $$ = $1; }
+;
+
+/* A block of commands.  */
+commands:	command
+		  {
+		    $$ = grub_script_add_cmd (state, 0, $1);
+		  }
+		| command commands
+		  {
+		    struct grub_script_cmdblock *cmd;
+		    cmd = (struct grub_script_cmdblock *) $2;
+		    $$ = grub_script_add_cmd (state, cmd, $1);
+		  }
+;
+
+/* A function.  Carefully save the memory that is allocated.  Don't
+   change any stuff because it might seem like a fun thing to do!
+   Special care was take to make sure the mid-rule actions are
+   executed on the right moment.  So the `commands' rule should be
+   recognized after executing the `grub_script_mem_record; and before
+   `grub_script_mem_record_stop'.  */
+function:	"function" GRUB_PARSER_TOKEN_ARG
+		  {
+		    grub_script_lexer_ref (state->lexerstate);
+		  } newlines '{'
+		  {
+		    /* The first part of the function was recognized.
+		       Now start recording the memory usage to store
+		       this function.  */
+		    state->func_mem = grub_script_mem_record (state);
+		  } newlines commands '}'
+		  {
+		    struct grub_script *script;
+
+		    /* All the memory usage for parsing this function
+		       was recorded.  */
+		    state->func_mem = grub_script_mem_record_stop (state,
+								   state->func_mem);
+		    script = grub_script_create ($8, state->func_mem);
+		    if (script)
+		      grub_script_function_create ($2, script);
+		    grub_script_lexer_deref (state->lexerstate);
+		  }
+;
+
+/* Carefully designed, together with `menuentry' so everything happens
+   just in the expected order.  */
+commandblock:	'{'
+		  {
+		    grub_script_lexer_ref (state->lexerstate);
+		  }
+                newlines commands '}'
+                  {
+		    grub_script_lexer_deref (state->lexerstate);
+		    $$ = $4;
+		  }
+;
+
+/* A menu entry.  Carefully save the memory that is allocated.  */
+menuentry:	"menuentry"
+		  {
+		    grub_script_lexer_ref (state->lexerstate);
+		  } arguments newlines '{'
+		  {
+		    grub_script_lexer_record_start (state->lexerstate);
+		  } newlines commands '}'
+		  {
+		    char *menu_entry;
+		    menu_entry = grub_script_lexer_record_stop (state->lexerstate);
+		    grub_script_lexer_deref (state->lexerstate);
+		    $$ = grub_script_create_cmdmenu (state, $3, menu_entry, 0);
+		  }
+;
+
+/* The first part of the if statement.  It's used to switch the lexer
+   to a state in which it demands more tokens.  */
+if_statement:	"if" { grub_script_lexer_ref (state->lexerstate); }
+;
+
+/* The if statement.  */
+if:		 if_statement commands "then" newlines commands "fi"
+		  {
+		    $$ = grub_script_create_cmdif (state, $2, $5, 0);
+		    grub_script_lexer_deref (state->lexerstate);
+		  }
+		 | if_statement commands "then" newlines commands "else" newlines commands  "fi"
+		  {
+		    $$ = grub_script_create_cmdif (state, $2, $5, $8);
+		    grub_script_lexer_deref (state->lexerstate);
+		  }
+;
diff --git a/script/sh/script.c b/script/sh/script.c
new file mode 100644
index 0000000..c04a449
--- /dev/null
+++ b/script/sh/script.c
@@ -0,0 +1,345 @@
+/* script.c -- Functions to create an in memory description of the script. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/script_sh.h>
+#include <grub/parser.h>
+#include <grub/mm.h>
+
+/* It is not possible to deallocate the memory when a syntax error was
+   found.  Because of that it is required to keep track of all memory
+   allocations.  The memory is freed in case of an error, or
+   assigned to the parsed script when parsing was successful.  */
+
+/* XXX */
+
+/* In case of the normal malloc, some additional bytes are allocated
+   for this datastructure.  All reserved memory is stored in a linked
+   list so it can be easily freed.  The original memory can be found
+   from &mem.  */
+struct grub_script_mem
+{
+  struct grub_script_mem *next;
+  char mem;
+};
+
+/* Return malloc'ed memory and keep track of the allocation.  */
+void *
+grub_script_malloc (struct grub_parser_param *state, grub_size_t size)
+{
+  struct grub_script_mem *mem;
+  mem = (struct grub_script_mem *) grub_malloc (size + sizeof (*mem)
+						- sizeof (char));
+
+  grub_dprintf ("scripting", "malloc %p\n", mem);
+  mem->next = state->memused;
+  state->memused = mem;
+  return (void *) &mem->mem;
+}
+
+/* Free all memory described by MEM.  */
+static void
+grub_script_mem_free (struct grub_script_mem *mem)
+{
+  struct grub_script_mem *memfree;
+
+  while (mem)
+    {
+      memfree = mem->next;
+      grub_dprintf ("scripting", "free %p\n", mem);
+      grub_free (mem);
+      mem = memfree;
+    }
+}
+
+/* Start recording memory usage.  Returns the memory that should be
+   restored when calling stop.  */
+struct grub_script_mem *
+grub_script_mem_record (struct grub_parser_param *state)
+{
+  struct grub_script_mem *mem = state->memused;
+  state->memused = 0;
+
+  return mem;
+}
+
+/* Stop recording memory usage.  Restore previous recordings using
+   RESTORE.  Return the recorded memory.  */
+struct grub_script_mem *
+grub_script_mem_record_stop (struct grub_parser_param *state,
+			     struct grub_script_mem *restore)
+{
+  struct grub_script_mem *mem = state->memused;
+  state->memused = restore;
+  return mem;
+}
+
+/* Free the memory reserved for CMD and all of it's children.  */
+void
+grub_script_free (struct grub_script *script)
+{
+  if (! script)
+    return;
+  grub_script_mem_free (script->mem);
+  grub_free (script);
+}
+
+
+
+/* Extend the argument arg with a variable or string of text.  If ARG
+   is zero a new list is created.  */
+struct grub_script_arg *
+grub_script_arg_add (struct grub_parser_param *state, struct grub_script_arg *arg,
+		     grub_script_arg_type_t type, char *str)
+{
+  struct grub_script_arg *argpart;
+  struct grub_script_arg *ll;
+  int len;
+
+  argpart = (struct grub_script_arg *) grub_script_malloc (state, sizeof (*arg));
+  argpart->type = type;
+  len = grub_strlen (str) + 1;
+  argpart->str = grub_script_malloc (state, len);
+  grub_memcpy (argpart->str, str, len);
+  argpart->next = 0;
+
+  if (! arg)
+    return argpart;
+
+  for (ll = arg; ll->next; ll = ll->next);
+  ll->next = argpart;
+
+  return arg;
+}
+
+/* Add the argument ARG to the end of the argument list LIST.  If LIST
+   is zero, a new list will be created.  */
+struct grub_script_arglist *
+grub_script_add_arglist (struct grub_parser_param *state,
+			 struct grub_script_arglist *list, struct grub_script_arg *arg)
+{
+  struct grub_script_arglist *link;
+  struct grub_script_arglist *ll;
+
+  grub_dprintf ("scripting", "arglist\n");
+
+  link = (struct grub_script_arglist *) grub_script_malloc (state, sizeof (*link));
+  link->next = 0;
+  link->arg = arg;
+  link->argcount = 0;
+
+  if (! list)
+    {
+      link->argcount++;
+      return link;
+    }
+
+  list->argcount++;
+
+  /* Look up the last link in the chain.  */
+  for (ll = list; ll->next; ll = ll->next);
+  ll->next = link;
+
+  return list;
+}
+
+/* Create a command that describes a single command line.  CMDLINE
+   contains the name of the command that should be executed.  ARGLIST
+   holds all arguments for this command.  */
+struct grub_script_cmd *
+grub_script_create_cmdline (struct grub_parser_param *state,
+			    struct grub_script_arglist *arglist)
+{
+  struct grub_script_cmdline *cmd;
+
+  grub_dprintf ("scripting", "cmdline\n");
+
+  cmd = grub_script_malloc (state, sizeof (*cmd));
+  cmd->cmd.exec = grub_script_execute_cmdline;
+  cmd->cmd.next = 0;
+  cmd->arglist = arglist;
+
+  return (struct grub_script_cmd *) cmd;
+}
+
+/* Create a command that functions as an if statement.  If BOOL is
+   evaluated to true (the value is returned in envvar '?'), the
+   interpreter will run the command TRUE, otherwise the interpreter
+   runs the command FALSE.  */
+struct grub_script_cmd *
+grub_script_create_cmdif (struct grub_parser_param *state,
+			  struct grub_script_cmd *exec_to_evaluate,
+			  struct grub_script_cmd *exec_on_true,
+			  struct grub_script_cmd *exec_on_false)
+{
+  struct grub_script_cmdif *cmd;
+
+  grub_dprintf ("scripting", "cmdif\n");
+
+  cmd = grub_script_malloc (state, sizeof (*cmd));
+  cmd->cmd.exec = grub_script_execute_cmdif;
+  cmd->cmd.next = 0;
+  cmd->exec_to_evaluate = exec_to_evaluate;
+  cmd->exec_on_true = exec_on_true;
+  cmd->exec_on_false = exec_on_false;
+
+  return (struct grub_script_cmd *) cmd;
+}
+
+/* Create a command that adds a menu entry to the menu.  Title is an
+   argument that is parsed to generate a string that can be used as
+   the title.  The sourcecode for this entry is passed in SOURCECODE.
+   The options for this entry are passed in OPTIONS.  */
+struct grub_script_cmd *
+grub_script_create_cmdmenu (struct grub_parser_param *state,
+			    struct grub_script_arglist *arglist,
+			    char *sourcecode,
+			    int options)
+{
+  struct grub_script_cmd_menuentry *cmd;
+  int i;
+
+  /* Skip leading newlines to make the sourcecode better readable when
+     using the editor.  */
+  while (*sourcecode == '\n')
+    sourcecode++;
+
+  /* Having trailing returns can some some annoying conflicts, remove
+     them.  XXX: Can the parser be improved to handle this?  */
+  for (i = grub_strlen (sourcecode) - 1; i > 0; i--)
+    {
+      if (sourcecode[i] != '\n')
+	break;
+      sourcecode[i] = '\0';
+    }
+
+  cmd = grub_script_malloc (state, sizeof (*cmd));
+  cmd->cmd.exec = grub_script_execute_menuentry;
+  cmd->cmd.next = 0;
+  /* XXX: Check if this memory is properly freed.  */
+  cmd->sourcecode = sourcecode;
+  cmd->arglist = arglist;
+  cmd->options = options;
+
+  return (struct grub_script_cmd *) cmd;
+}
+
+/* Create a block of commands.  CMD contains the command that should
+   be added at the end of CMDBLOCK's list.  If CMDBLOCK is zero, a new
+   cmdblock will be created.  */
+struct grub_script_cmd *
+grub_script_add_cmd (struct grub_parser_param *state,
+		     struct grub_script_cmdblock *cmdblock,
+		     struct grub_script_cmd *cmd)
+{
+  grub_dprintf ("scripting", "cmdblock\n");
+
+  if (! cmd)
+    return (struct grub_script_cmd *) cmdblock;
+
+  if (! cmdblock)
+    {
+      cmdblock = (struct grub_script_cmdblock *) grub_script_malloc (state,
+								     sizeof (*cmdblock));
+      cmdblock->cmd.exec = grub_script_execute_cmdblock;
+      cmdblock->cmd.next = 0;
+      cmdblock->cmdlist = cmd;
+      cmd->next = 0;
+    }
+  else
+    {
+      cmd->next = cmdblock->cmdlist;
+      cmdblock->cmdlist = cmd;
+    }
+
+  return (struct grub_script_cmd *) cmdblock;
+}
+
+
+
+struct grub_script *
+grub_script_create (struct grub_script_cmd *cmd, struct grub_script_mem *mem)
+{
+  struct grub_script *parsed;
+
+  parsed = grub_malloc (sizeof (*parsed));
+  if (! parsed)
+    {
+      grub_script_mem_free (mem);
+      grub_free (cmd);
+
+      return 0;
+    }
+
+  parsed->mem = mem;
+  parsed->cmd = cmd;
+
+  return parsed;
+}
+
+/* Parse the script passed in SCRIPT and return the parsed
+   datastructure that is ready to be interpreted.  */
+struct grub_script *
+grub_script_parse (char *script, grub_reader_getline_t getline)
+{
+  struct grub_script *parsed;
+  struct grub_script_mem *membackup;
+  struct grub_lexer_param *lexstate;
+  struct grub_parser_param *parsestate;
+
+  parsed = grub_malloc (sizeof (*parsed));
+  if (! parsed)
+    return 0;
+
+  parsestate = grub_zalloc (sizeof (*parsestate));
+  if (! parsestate)
+    return 0;
+
+  /* Initialize the lexer.  */
+  lexstate = grub_script_lexer_init (script, getline);
+  if (! lexstate)
+    {
+      grub_free (parsed);
+      grub_free (parsestate);
+      return 0;
+    }
+
+  parsestate->lexerstate = lexstate;
+
+  membackup = grub_script_mem_record (parsestate);
+
+  /* Parse the script.  */
+  if (grub_script_yyparse (parsestate) || parsestate->err)
+    {
+      struct grub_script_mem *memfree;
+      memfree = grub_script_mem_record_stop (parsestate, membackup);
+      grub_script_mem_free (memfree);
+      grub_free (lexstate);
+      grub_free (parsestate);
+      return 0;
+    }
+
+  parsed->mem = grub_script_mem_record_stop (parsestate, membackup);
+  parsed->cmd = parsestate->parsed;
+
+  grub_free (lexstate);
+  grub_free (parsestate);
+
+  return parsed;
+}
diff --git a/stamp-h.in b/stamp-h.in
new file mode 100644
index 0000000..9788f70
--- /dev/null
+++ b/stamp-h.in
@@ -0,0 +1 @@
+timestamp
diff --git a/term/efi/console.c b/term/efi/console.c
new file mode 100644
index 0000000..f384508
--- /dev/null
+++ b/term/efi/console.c
@@ -0,0 +1,378 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/api.h>
+#include <grub/efi/console.h>
+
+static grub_uint8_t
+grub_console_standard_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW,
+						  GRUB_EFI_BACKGROUND_BLACK);
+static grub_uint8_t
+grub_console_normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY,
+						GRUB_EFI_BACKGROUND_BLACK);
+static grub_uint8_t
+grub_console_highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK,
+						   GRUB_EFI_BACKGROUND_LIGHTGRAY);
+
+static int read_key = -1;
+
+static grub_uint32_t
+map_char (grub_uint32_t c)
+{
+  if (c > 0x7f)
+    {
+      /* Map some unicode characters to the EFI character.  */
+      switch (c)
+	{
+	case 0x2190:	/* left arrow */
+	  c = 0x25c4;
+	  break;
+	case 0x2191:	/* up arrow */
+	  c = 0x25b2;
+	  break;
+	case 0x2192:	/* right arrow */
+	  c = 0x25ba;
+	  break;
+	case 0x2193:	/* down arrow */
+	  c = 0x25bc;
+	  break;
+	case 0x2501:	/* horizontal line */
+	  c = 0x2500;
+	  break;
+	case 0x2503:	/* vertical line */
+	  c = 0x2502;
+	  break;
+	case 0x250F:	/* upper-left corner */
+	  c = 0x250c;
+	  break;
+	case 0x2513:	/* upper-right corner */
+	  c = 0x2510;
+	  break;
+	case 0x2517:	/* lower-left corner */
+	  c = 0x2514;
+	  break;
+	case 0x251B:	/* lower-right corner */
+	  c = 0x2518;
+	  break;
+
+	default:
+	  c = '?';
+	  break;
+	}
+    }
+
+  return c;
+}
+
+static void
+grub_console_putchar (grub_uint32_t c)
+{
+  grub_efi_char16_t str[2];
+  grub_efi_simple_text_output_interface_t *o;
+
+  o = grub_efi_system_table->con_out;
+
+  /* For now, do not try to use a surrogate pair.  */
+  if (c > 0xffff)
+    c = '?';
+
+  str[0] = (grub_efi_char16_t)  map_char (c & 0xffff);
+  str[1] = 0;
+
+  /* Should this test be cached?  */
+  if (c > 0x7f && efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS)
+    return;
+
+  efi_call_2 (o->output_string, o, str);
+}
+
+static grub_ssize_t
+grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
+{
+  /* For now, every printable character has the width 1.  */
+  return 1;
+}
+
+static int
+grub_console_checkkey (void)
+{
+  grub_efi_simple_input_interface_t *i;
+  grub_efi_input_key_t key;
+  grub_efi_status_t status;
+
+  if (read_key >= 0)
+    return 1;
+
+  i = grub_efi_system_table->con_in;
+  status = efi_call_2 (i->read_key_stroke, i, &key);
+#if 0
+  switch (status)
+    {
+    case GRUB_EFI_SUCCESS:
+      {
+	grub_uint16_t xy;
+
+	xy = grub_getxy ();
+	grub_gotoxy (0, 0);
+	grub_printf ("scan_code=%x,unicode_char=%x  ",
+		     (unsigned) key.scan_code,
+		     (unsigned) key.unicode_char);
+	grub_gotoxy (xy >> 8, xy & 0xff);
+      }
+      break;
+
+    case GRUB_EFI_NOT_READY:
+      //grub_printf ("not ready   ");
+      break;
+
+    default:
+      //grub_printf ("device error   ");
+      break;
+    }
+#endif
+
+  if (status == GRUB_EFI_SUCCESS)
+    {
+      switch (key.scan_code)
+	{
+	case 0x00:
+	  read_key = key.unicode_char;
+	  break;
+	case 0x01:
+	  read_key = 16;
+	  break;
+	case 0x02:
+	  read_key = 14;
+	  break;
+	case 0x03:
+	  read_key = 6;
+	  break;
+	case 0x04:
+	  read_key = 2;
+	  break;
+	case 0x05:
+	  read_key = 1;
+	  break;
+	case 0x06:
+	  read_key = 5;
+	  break;
+	case 0x07:
+	  break;
+	case 0x08:
+	  read_key = 4;
+	  break;
+	case 0x09:
+	  break;
+	case 0x0a:
+	  break;
+	case 0x0b:
+	  read_key = 24;
+	  break;
+	case 0x0c:
+	  read_key = 1;
+	  break;
+	case 0x0d:
+	  read_key = 5;
+	  break;
+	case 0x17:
+	  read_key = '\e';
+	  break;
+	default:
+	  break;
+	}
+    }
+
+  return read_key;
+}
+
+static int
+grub_console_getkey (void)
+{
+  grub_efi_simple_input_interface_t *i;
+  grub_efi_boot_services_t *b;
+  grub_efi_uintn_t index;
+  grub_efi_status_t status;
+  int key;
+
+  if (read_key >= 0)
+    {
+      key = read_key;
+      read_key = -1;
+      return key;
+    }
+
+  i = grub_efi_system_table->con_in;
+  b = grub_efi_system_table->boot_services;
+
+  do
+    {
+      status = efi_call_3 (b->wait_for_event, 1, &(i->wait_for_key), &index);
+      if (status != GRUB_EFI_SUCCESS)
+        return -1;
+
+      grub_console_checkkey ();
+    }
+  while (read_key < 0);
+
+  key = read_key;
+  read_key = -1;
+  return key;
+}
+
+static grub_uint16_t
+grub_console_getwh (void)
+{
+  grub_efi_simple_text_output_interface_t *o;
+  grub_efi_uintn_t columns, rows;
+
+  o = grub_efi_system_table->con_out;
+  if (efi_call_4 (o->query_mode, o, o->mode->mode, &columns, &rows) != GRUB_EFI_SUCCESS)
+    {
+      /* Why does this fail?  */
+      columns = 80;
+      rows = 25;
+    }
+
+  return ((columns << 8) | rows);
+}
+
+static grub_uint16_t
+grub_console_getxy (void)
+{
+  grub_efi_simple_text_output_interface_t *o;
+
+  o = grub_efi_system_table->con_out;
+  return ((o->mode->cursor_column << 8) | o->mode->cursor_row);
+}
+
+static void
+grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  grub_efi_simple_text_output_interface_t *o;
+
+  o = grub_efi_system_table->con_out;
+  efi_call_3 (o->set_cursor_position, o, x, y);
+}
+
+static void
+grub_console_cls (void)
+{
+  grub_efi_simple_text_output_interface_t *o;
+  grub_efi_int32_t orig_attr;
+
+  o = grub_efi_system_table->con_out;
+  orig_attr = o->mode->attribute;
+  efi_call_2 (o->set_attributes, o, GRUB_EFI_BACKGROUND_BLACK);
+  efi_call_1 (o->clear_screen, o);
+  efi_call_2 (o->set_attributes, o, orig_attr);
+}
+
+static void
+grub_console_setcolorstate (grub_term_color_state state)
+{
+  grub_efi_simple_text_output_interface_t *o;
+
+  o = grub_efi_system_table->con_out;
+
+  switch (state) {
+    case GRUB_TERM_COLOR_STANDARD:
+      efi_call_2 (o->set_attributes, o, grub_console_standard_color);
+      break;
+    case GRUB_TERM_COLOR_NORMAL:
+      efi_call_2 (o->set_attributes, o, grub_console_normal_color);
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      efi_call_2 (o->set_attributes, o, grub_console_highlight_color);
+      break;
+    default:
+      break;
+  }
+}
+
+static void
+grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
+{
+  grub_console_normal_color = normal_color;
+  grub_console_highlight_color = highlight_color;
+}
+
+static void
+grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
+{
+  *normal_color = grub_console_normal_color;
+  *highlight_color = grub_console_highlight_color;
+}
+
+static void
+grub_console_setcursor (int on)
+{
+  grub_efi_simple_text_output_interface_t *o;
+
+  o = grub_efi_system_table->con_out;
+  efi_call_2 (o->enable_cursor, o, on);
+}
+
+static struct grub_term_input grub_console_term_input =
+  {
+    .name = "console",
+    .checkkey = grub_console_checkkey,
+    .getkey = grub_console_getkey,
+  };
+
+static struct grub_term_output grub_console_term_output =
+  {
+    .name = "console",
+    .putchar = grub_console_putchar,
+    .getcharwidth = grub_console_getcharwidth,
+    .getwh = grub_console_getwh,
+    .getxy = grub_console_getxy,
+    .gotoxy = grub_console_gotoxy,
+    .cls = grub_console_cls,
+    .setcolorstate = grub_console_setcolorstate,
+    .setcolor = grub_console_setcolor,
+    .getcolor = grub_console_getcolor,
+    .setcursor = grub_console_setcursor,
+    .flags = 0,
+  };
+
+void
+grub_console_init (void)
+{
+  /* FIXME: it is necessary to consider the case where no console control
+     is present but the default is already in text mode.  */
+  if (! grub_efi_set_text_mode (1))
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode");
+      return;
+    }
+
+  grub_term_register_input ("console", &grub_console_term_input);
+  grub_term_register_output ("console", &grub_console_term_output);
+}
+
+void
+grub_console_fini (void)
+{
+  grub_term_unregister_input (&grub_console_term_input);
+  grub_term_unregister_output (&grub_console_term_output);
+}
diff --git a/term/gfxterm.c b/term/gfxterm.c
new file mode 100644
index 0000000..f161499
--- /dev/null
+++ b/term/gfxterm.c
@@ -0,0 +1,966 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/font.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/video.h>
+#include <grub/bitmap.h>
+#include <grub/command.h>
+
+#define DEFAULT_VIDEO_MODE "1024x768,800x600,640x480"
+#define DEFAULT_BORDER_WIDTH	10
+
+#define DEFAULT_STANDARD_COLOR  0x07
+#define DEFAULT_NORMAL_COLOR    0x07
+#define DEFAULT_HIGHLIGHT_COLOR 0x70
+
+struct grub_dirty_region
+{
+  int top_left_x;
+  int top_left_y;
+  int bottom_right_x;
+  int bottom_right_y;
+};
+
+struct grub_colored_char
+{
+  /* An Unicode codepoint.  */
+  grub_uint32_t code;
+
+  /* Color values.  */
+  grub_video_color_t fg_color;
+  grub_video_color_t bg_color;
+
+  /* The width of this character minus one.  */
+  unsigned char width;
+
+  /* The column index of this character.  */
+  unsigned char index;
+};
+
+struct grub_virtual_screen
+{
+  /* Dimensions of the virtual screen in pixels.  */
+  unsigned int width;
+  unsigned int height;
+
+  /* Offset in the display in pixels.  */
+  unsigned int offset_x;
+  unsigned int offset_y;
+
+  /* TTY Character sizes in pixes.  */
+  unsigned int normal_char_width;
+  unsigned int normal_char_height;
+
+  /* Virtual screen TTY size in characters.  */
+  unsigned int columns;
+  unsigned int rows;
+
+  /* Current cursor location in characters.  */
+  unsigned int cursor_x;
+  unsigned int cursor_y;
+
+  /* Current cursor state. */
+  int cursor_state;
+
+  /* Font settings. */
+  grub_font_t font;
+
+  /* Terminal color settings.  */
+  grub_uint8_t standard_color_setting;
+  grub_uint8_t normal_color_setting;
+  grub_uint8_t highlight_color_setting;
+  grub_uint8_t term_color;
+
+  /* Color settings.  */
+  grub_video_color_t fg_color;
+  grub_video_color_t bg_color;
+
+  /* Text buffer for virtual screen.  Contains (columns * rows) number
+     of entries.  */
+  struct grub_colored_char *text_buffer;
+};
+
+static struct grub_virtual_screen virtual_screen;
+
+static struct grub_video_mode_info mode_info;
+
+static struct grub_video_render_target *text_layer;
+
+static unsigned int bitmap_width;
+static unsigned int bitmap_height;
+static struct grub_video_bitmap *bitmap;
+
+static struct grub_dirty_region dirty_region;
+
+static void dirty_region_reset (void);
+
+static int dirty_region_is_empty (void);
+
+static void dirty_region_add (int x, int y,
+                              unsigned int width, unsigned int height);
+
+static unsigned int calculate_normal_character_width (grub_font_t font);
+
+static unsigned char calculate_character_width (struct grub_font_glyph *glyph);
+
+static void
+set_term_color (grub_uint8_t term_color)
+{
+  struct grub_video_render_target *old_target;
+
+  /* Save previous target and switch to text layer.  */
+  grub_video_get_active_render_target (&old_target);
+  grub_video_set_active_render_target (text_layer);
+
+  /* Map terminal color to text layer compatible video colors.  */
+  virtual_screen.fg_color = grub_video_map_color(term_color & 0x0f);
+
+  /* Special case: use black as transparent color.  */
+  if (((term_color >> 4) & 0x0f) == 0)
+    {
+      virtual_screen.bg_color = grub_video_map_rgba(0, 0, 0, 0);
+    }
+  else
+    {
+      virtual_screen.bg_color = grub_video_map_color((term_color >> 4) & 0x0f);
+    }
+
+  /* Restore previous target.  */
+  grub_video_set_active_render_target (old_target);
+}
+
+static void
+clear_char (struct grub_colored_char *c)
+{
+  c->code = ' ';
+  c->fg_color = virtual_screen.fg_color;
+  c->bg_color = virtual_screen.bg_color;
+  c->width = 0;
+  c->index = 0;
+}
+
+static void
+grub_virtual_screen_free (void)
+{
+  /* If virtual screen has been allocated, free it.  */
+  if (virtual_screen.text_buffer != 0)
+    grub_free (virtual_screen.text_buffer);
+
+  /* Reset virtual screen data.  */
+  grub_memset (&virtual_screen, 0, sizeof (virtual_screen));
+
+  /* Free render targets.  */
+  grub_video_delete_render_target (text_layer);
+  text_layer = 0;
+}
+
+static grub_err_t
+grub_virtual_screen_setup (unsigned int x, unsigned int y,
+                           unsigned int width, unsigned int height,
+                           const char *font_name)
+{
+  unsigned int i;
+
+  /* Free old virtual screen.  */
+  grub_virtual_screen_free ();
+
+  /* Initialize with default data.  */
+  virtual_screen.font = grub_font_get (font_name);
+  if (!virtual_screen.font)
+    return grub_error (GRUB_ERR_BAD_FONT,
+                       "No font loaded.");
+  virtual_screen.width = width;
+  virtual_screen.height = height;
+  virtual_screen.offset_x = x;
+  virtual_screen.offset_y = y;
+  virtual_screen.normal_char_width =
+    calculate_normal_character_width (virtual_screen.font);
+  virtual_screen.normal_char_height =
+    grub_font_get_max_char_height (virtual_screen.font);
+  virtual_screen.cursor_x = 0;
+  virtual_screen.cursor_y = 0;
+  virtual_screen.cursor_state = 1;
+
+  /* Calculate size of text buffer.  */
+  virtual_screen.columns = virtual_screen.width / virtual_screen.normal_char_width;
+  virtual_screen.rows = virtual_screen.height / virtual_screen.normal_char_height;
+
+  /* Allocate memory for text buffer.  */
+  virtual_screen.text_buffer =
+    (struct grub_colored_char *) grub_malloc (virtual_screen.columns
+                                              * virtual_screen.rows
+                                              * sizeof (*virtual_screen.text_buffer));
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Create new render target for text layer.  */
+  grub_video_create_render_target (&text_layer,
+                                   virtual_screen.width,
+                                   virtual_screen.height,
+                                   GRUB_VIDEO_MODE_TYPE_RGB
+                                   | GRUB_VIDEO_MODE_TYPE_ALPHA);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* As we want to have colors compatible with rendering target,
+     we can only have those after mode is initialized.  */
+  grub_video_set_active_render_target (text_layer);
+
+  virtual_screen.standard_color_setting = DEFAULT_STANDARD_COLOR;
+  virtual_screen.normal_color_setting = DEFAULT_NORMAL_COLOR;
+  virtual_screen.highlight_color_setting = DEFAULT_HIGHLIGHT_COLOR;
+
+  virtual_screen.term_color = virtual_screen.normal_color_setting;
+
+  set_term_color (virtual_screen.term_color);
+
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+  /* Clear out text buffer. */
+  for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
+    clear_char (&(virtual_screen.text_buffer[i]));
+
+  return grub_errno;
+}
+
+static int NESTED_FUNC_ATTR video_hook (grub_video_adapter_t p __attribute__ ((unused)),
+					struct grub_video_mode_info *info)
+{
+  return ! (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT);
+}
+
+static grub_err_t
+grub_gfxterm_init (void)
+{
+  char *font_name;
+  char *modevar;
+  char *tmp;
+  grub_video_color_t color;
+  int width;
+  int height;
+  grub_err_t err;
+
+  /* Select the font to use. */
+  font_name = grub_env_get ("gfxterm_font");
+  if (! font_name)
+    font_name = "";   /* Allow fallback to any font. */
+
+  /* Parse gfxmode environment variable if set.  */
+  modevar = grub_env_get ("gfxmode");
+  if (! modevar || *modevar == 0)
+    err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook);
+  else
+    {
+      tmp = grub_malloc (grub_strlen (modevar)
+			 + sizeof (DEFAULT_VIDEO_MODE) + 1);
+      grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
+      err = grub_video_set_mode (tmp, video_hook);
+      grub_free (tmp);
+    }
+
+  if (err)
+    return err;
+
+  err = grub_video_get_info (&mode_info);
+  /* Figure out what mode we ended up.  */
+  if (err)
+    return err;
+
+  /* Make sure screen is black.  */
+  color = grub_video_map_rgb (0, 0, 0);
+  grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height);
+  bitmap = 0;
+
+  /* Leave borders for virtual screen.  */
+  width = mode_info.width - (2 * DEFAULT_BORDER_WIDTH);
+  height = mode_info.height - (2 * DEFAULT_BORDER_WIDTH);
+
+  /* Create virtual screen.  */
+  if (grub_virtual_screen_setup (DEFAULT_BORDER_WIDTH, DEFAULT_BORDER_WIDTH,
+                                 width, height, font_name) != GRUB_ERR_NONE)
+    {
+      grub_video_restore ();
+      return grub_errno;
+    }
+
+  /* Mark whole screen as dirty.  */
+  dirty_region_reset ();
+  dirty_region_add (0, 0, mode_info.width, mode_info.height);
+
+  return (grub_errno = GRUB_ERR_NONE);
+}
+
+static grub_err_t
+grub_gfxterm_fini (void)
+{
+  if (bitmap)
+    {
+      grub_video_bitmap_destroy (bitmap);
+      bitmap = 0;
+    }
+
+  grub_virtual_screen_free ();
+
+  grub_video_restore ();
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+redraw_screen_rect (unsigned int x, unsigned int y,
+                    unsigned int width, unsigned int height)
+{
+  grub_video_color_t color;
+
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+
+  if (bitmap)
+    {
+      /* Render bitmap as background.  */
+      grub_video_blit_bitmap (bitmap, GRUB_VIDEO_BLIT_REPLACE, x, y,
+			      x, y,
+                              width, height);
+
+      /* If bitmap is smaller than requested blit area, use background
+         color.  */
+      color = virtual_screen.bg_color;
+
+      /* Fill right side of the bitmap if needed.  */
+      if ((x + width >= bitmap_width) && (y < bitmap_height))
+        {
+          int w = (x + width) - bitmap_width;
+          int h = height;
+          unsigned int tx = x;
+
+          if (y + height >= bitmap_height)
+            {
+              h = bitmap_height - y;
+            }
+
+          if (bitmap_width > tx)
+            {
+              tx = bitmap_width;
+            }
+
+          /* Render background layer.  */
+	  grub_video_fill_rect (color, tx, y, w, h);
+        }
+
+      /* Fill bottom side of the bitmap if needed.  */
+      if (y + height >= bitmap_height)
+        {
+          int h = (y + height) - bitmap_height;
+          unsigned int ty = y;
+
+          if (bitmap_height > ty)
+            {
+              ty = bitmap_height;
+            }
+
+          /* Render background layer.  */
+	  grub_video_fill_rect (color, x, ty, width, h);
+        }
+
+      /* Render text layer as blended.  */
+      grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, x, y,
+                                     x - virtual_screen.offset_x,
+                                     y - virtual_screen.offset_y,
+                                     width, height);
+    }
+  else
+    {
+      /* Render background layer.  */
+      color = virtual_screen.bg_color;
+      grub_video_fill_rect (color, x, y, width, height);
+
+      /* Render text layer as replaced (to get texts background color).  */
+      grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_REPLACE, x, y,
+                                     x - virtual_screen.offset_x,
+                                     y - virtual_screen.offset_y,
+				     width, height);
+    }
+}
+
+static void
+dirty_region_reset (void)
+{
+  dirty_region.top_left_x = -1;
+  dirty_region.top_left_y = -1;
+  dirty_region.bottom_right_x = -1;
+  dirty_region.bottom_right_y = -1;
+}
+
+static int
+dirty_region_is_empty (void)
+{
+  if ((dirty_region.top_left_x == -1)
+      || (dirty_region.top_left_y == -1)
+      || (dirty_region.bottom_right_x == -1)
+      || (dirty_region.bottom_right_y == -1))
+    return 1;
+  return 0;
+}
+
+static void
+dirty_region_add (int x, int y, unsigned int width, unsigned int height)
+{
+  if ((width == 0) || (height == 0))
+    return;
+
+  if (dirty_region_is_empty ())
+    {
+      dirty_region.top_left_x = x;
+      dirty_region.top_left_y = y;
+      dirty_region.bottom_right_x = x + width - 1;
+      dirty_region.bottom_right_y = y + height - 1;
+    }
+  else
+    {
+      if (x < dirty_region.top_left_x)
+        dirty_region.top_left_x = x;
+      if (y < dirty_region.top_left_y)
+        dirty_region.top_left_y = y;
+      if ((x + (int)width - 1) > dirty_region.bottom_right_x)
+        dirty_region.bottom_right_x = x + width - 1;
+      if ((y + (int)height - 1) > dirty_region.bottom_right_y)
+        dirty_region.bottom_right_y = y + height - 1;
+    }
+}
+
+static void
+dirty_region_add_virtualscreen (void)
+{
+  /* Mark virtual screen as dirty.  */
+  dirty_region_add (virtual_screen.offset_x, virtual_screen.offset_y,
+                    virtual_screen.width, virtual_screen.height);
+}
+
+
+static void
+dirty_region_redraw (void)
+{
+  int x;
+  int y;
+  int width;
+  int height;
+
+  if (dirty_region_is_empty ())
+    return;
+
+  x = dirty_region.top_left_x;
+  y = dirty_region.top_left_y;
+
+  width = dirty_region.bottom_right_x - x + 1;
+  height = dirty_region.bottom_right_y - y + 1;
+
+  redraw_screen_rect (x, y, width, height);
+
+  dirty_region_reset ();
+}
+
+static void
+write_char (void)
+{
+  struct grub_colored_char *p;
+  struct grub_font_glyph *glyph;
+  grub_video_color_t color;
+  grub_video_color_t bgcolor;
+  unsigned int x;
+  unsigned int y;
+  int ascent;
+  unsigned int height;
+  unsigned int width;
+
+  /* Find out active character.  */
+  p = (virtual_screen.text_buffer
+       + virtual_screen.cursor_x
+       + (virtual_screen.cursor_y * virtual_screen.columns));
+
+  p -= p->index;
+
+  /* Get glyph for character.  */
+  glyph = grub_font_get_glyph (virtual_screen.font, p->code);
+  ascent = grub_font_get_ascent (virtual_screen.font);
+
+  width = virtual_screen.normal_char_width * calculate_character_width(glyph);
+  height = virtual_screen.normal_char_height;
+
+  color = p->fg_color;
+  bgcolor = p->bg_color;
+
+  x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
+  y = virtual_screen.cursor_y * virtual_screen.normal_char_height;
+
+  /* Render glyph to text layer.  */
+  grub_video_set_active_render_target (text_layer);
+  grub_video_fill_rect (bgcolor, x, y, width, height);
+  grub_font_draw_glyph (glyph, color, x, y + ascent);
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+  /* Mark character to be drawn.  */
+  dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y,
+                    width, height);
+}
+
+static void
+draw_cursor (int show)
+{
+  write_char ();
+
+  if (show)
+    {
+      unsigned int x;
+      unsigned int y;
+      unsigned int width;
+      unsigned int height;
+      grub_video_color_t color;
+
+      /* Determine cursor properties and position on text layer. */
+      x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
+      width = virtual_screen.normal_char_width;
+      color = virtual_screen.fg_color;
+      y = (virtual_screen.cursor_y * virtual_screen.normal_char_height
+           + grub_font_get_ascent (virtual_screen.font));
+      height = 2;
+
+      /* Render cursor to text layer.  */
+      grub_video_set_active_render_target (text_layer);
+      grub_video_fill_rect (color, x, y, width, height);
+      grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+      /* Mark cursor to be redrawn.  */
+      dirty_region_add (virtual_screen.offset_x + x,
+                        virtual_screen.offset_y + y,
+                        width, height);
+    }
+}
+
+static void
+scroll_up (void)
+{
+  unsigned int i;
+  grub_video_color_t color;
+
+  /* If we don't have background bitmap, remove cursor. */
+  if (!bitmap)
+    {
+      /* Remove cursor.  */
+      draw_cursor (0);
+
+      /* Redraw only changed regions.  */
+      dirty_region_redraw ();
+    }
+
+  /* Scroll text buffer with one line to up.  */
+  grub_memmove (virtual_screen.text_buffer,
+                virtual_screen.text_buffer + virtual_screen.columns,
+                sizeof (*virtual_screen.text_buffer)
+                * virtual_screen.columns
+                * (virtual_screen.rows - 1));
+
+  /* Clear last line in text buffer.  */
+  for (i = virtual_screen.columns * (virtual_screen.rows - 1);
+       i < virtual_screen.columns * virtual_screen.rows;
+       i++)
+    clear_char (&(virtual_screen.text_buffer[i]));
+
+  /* Scroll physical screen.  */
+  grub_video_set_active_render_target (text_layer);
+  color = virtual_screen.bg_color;
+  grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+  /* If we have bitmap, re-draw screen, otherwise scroll physical screen too.  */
+  if (bitmap)
+    {
+      /* Mark virtual screen to be redrawn.  */
+      dirty_region_add_virtualscreen ();
+    }
+  else
+    {
+      /* Clear new border area.  */
+      grub_video_fill_rect (color,
+                            virtual_screen.offset_x, virtual_screen.offset_y,
+                            virtual_screen.width, virtual_screen.normal_char_height);
+
+      /* Scroll physical screen.  */
+      grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
+
+      /* Draw cursor if visible.  */
+      if (virtual_screen.cursor_state)
+	draw_cursor (1);
+    }
+}
+
+static void
+grub_gfxterm_putchar (grub_uint32_t c)
+{
+  if (c == '\a')
+    /* FIXME */
+    return;
+
+  /* Erase current cursor, if any.  */
+  if (virtual_screen.cursor_state)
+    draw_cursor (0);
+
+  if (c == '\b' || c == '\n' || c == '\r')
+    {
+      switch (c)
+        {
+        case '\b':
+          if (virtual_screen.cursor_x > 0)
+            virtual_screen.cursor_x--;
+          break;
+
+        case '\n':
+          if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
+            scroll_up ();
+          else
+            virtual_screen.cursor_y++;
+          break;
+
+        case '\r':
+          virtual_screen.cursor_x = 0;
+          break;
+        }
+    }
+  else
+    {
+      struct grub_font_glyph *glyph;
+      struct grub_colored_char *p;
+      unsigned char char_width;
+
+      /* Get properties of the character.  */
+      glyph = grub_font_get_glyph (virtual_screen.font, c);
+
+      /* Calculate actual character width for glyph. This is number of
+         times of normal_font_width.  */
+      char_width = calculate_character_width(glyph);
+
+      /* If we are about to exceed line length, wrap to next line.  */
+      if (virtual_screen.cursor_x + char_width > virtual_screen.columns)
+        grub_putchar ('\n');
+
+      /* Find position on virtual screen, and fill information.  */
+      p = (virtual_screen.text_buffer +
+           virtual_screen.cursor_x +
+           virtual_screen.cursor_y * virtual_screen.columns);
+      p->code = c;
+      p->fg_color = virtual_screen.fg_color;
+      p->bg_color = virtual_screen.bg_color;
+      p->width = char_width - 1;
+      p->index = 0;
+
+      /* If we have large glyph, add fixup info.  */
+      if (char_width > 1)
+        {
+          unsigned i;
+
+          for (i = 1; i < char_width; i++)
+            {
+              p[i].code = ' ';
+              p[i].width = char_width - 1;
+              p[i].index = i;
+            }
+        }
+
+      /* Draw glyph.  */
+      write_char ();
+
+      /* Make sure we scroll screen when needed and wrap line correctly.  */
+      virtual_screen.cursor_x += char_width;
+      if (virtual_screen.cursor_x >= virtual_screen.columns)
+        {
+          virtual_screen.cursor_x = 0;
+
+          if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
+            scroll_up ();
+          else
+            virtual_screen.cursor_y++;
+        }
+    }
+
+  /* Redraw cursor if it should be visible.  */
+  /* Note: This will redraw the character as well, which means that the
+     above call to write_char is redundant when the cursor is showing.  */
+  if (virtual_screen.cursor_state)
+    draw_cursor (1);
+}
+
+/* Use ASCII characters to determine normal character width.  */
+static unsigned int
+calculate_normal_character_width (grub_font_t font)
+{
+  struct grub_font_glyph *glyph;
+  unsigned int width = 0;
+  unsigned int i;
+
+  /* Get properties of every printable ASCII character.  */
+  for (i = 32; i < 127; i++)
+    {
+      glyph = grub_font_get_glyph (font, i);
+
+      /* Skip unknown characters.  Should never happen on normal conditions.  */
+      if (! glyph)
+	continue;
+
+      if (glyph->device_width > width)
+	width = glyph->device_width;
+    }
+
+  return width;
+}
+
+static unsigned char
+calculate_character_width (struct grub_font_glyph *glyph)
+{
+  if (! glyph || glyph->device_width == 0)
+    return 1;
+
+  return (glyph->device_width
+          + (virtual_screen.normal_char_width - 1))
+         / virtual_screen.normal_char_width;
+}
+
+static grub_ssize_t
+grub_gfxterm_getcharwidth (grub_uint32_t c)
+{
+  struct grub_font_glyph *glyph;
+  unsigned char char_width;
+
+  /* Get properties of the character.  */
+  glyph = grub_font_get_glyph (virtual_screen.font, c);
+
+  /* Calculate actual character width for glyph.  */
+  char_width = calculate_character_width (glyph);
+
+  return char_width;
+}
+
+static grub_uint16_t
+grub_virtual_screen_getwh (void)
+{
+  return (virtual_screen.columns << 8) | virtual_screen.rows;
+}
+
+static grub_uint16_t
+grub_virtual_screen_getxy (void)
+{
+  return ((virtual_screen.cursor_x << 8) | virtual_screen.cursor_y);
+}
+
+static void
+grub_gfxterm_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  if (x >= virtual_screen.columns)
+    x = virtual_screen.columns - 1;
+
+  if (y >= virtual_screen.rows)
+    y = virtual_screen.rows - 1;
+
+  /* Erase current cursor, if any.  */
+  if (virtual_screen.cursor_state)
+    draw_cursor (0);
+
+  virtual_screen.cursor_x = x;
+  virtual_screen.cursor_y = y;
+
+  /* Draw cursor if visible.  */
+  if (virtual_screen.cursor_state)
+    draw_cursor (1);
+}
+
+static void
+grub_virtual_screen_cls (void)
+{
+  grub_uint32_t i;
+
+  for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
+    clear_char (&(virtual_screen.text_buffer[i]));
+
+  virtual_screen.cursor_x = virtual_screen.cursor_y = 0;
+}
+
+static void
+grub_gfxterm_cls (void)
+{
+  grub_video_color_t color;
+
+  /* Clear virtual screen.  */
+  grub_virtual_screen_cls ();
+
+  /* Clear text layer.  */
+  grub_video_set_active_render_target (text_layer);
+  color = virtual_screen.bg_color;
+  grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height);
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+  /* Mark virtual screen to be redrawn.  */
+  dirty_region_add_virtualscreen ();
+}
+
+static void
+grub_virtual_screen_setcolorstate (grub_term_color_state state)
+{
+  switch (state)
+    {
+    case GRUB_TERM_COLOR_STANDARD:
+      virtual_screen.term_color = virtual_screen.standard_color_setting;
+      break;
+
+    case GRUB_TERM_COLOR_NORMAL:
+      virtual_screen.term_color = virtual_screen.normal_color_setting;
+      break;
+
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      virtual_screen.term_color = virtual_screen.highlight_color_setting;
+      break;
+
+    default:
+      break;
+    }
+
+  /* Change color to virtual terminal.  */
+  set_term_color (virtual_screen.term_color);
+}
+
+static void
+grub_virtual_screen_setcolor (grub_uint8_t normal_color,
+                              grub_uint8_t highlight_color)
+{
+  virtual_screen.normal_color_setting = normal_color;
+  virtual_screen.highlight_color_setting = highlight_color;
+}
+
+static void
+grub_virtual_screen_getcolor (grub_uint8_t *normal_color,
+                              grub_uint8_t *highlight_color)
+{
+  *normal_color = virtual_screen.normal_color_setting;
+  *highlight_color = virtual_screen.highlight_color_setting;
+}
+
+static void
+grub_gfxterm_setcursor (int on)
+{
+  if (virtual_screen.cursor_state != on)
+    {
+      if (virtual_screen.cursor_state)
+	draw_cursor (0);
+      else
+	draw_cursor (1);
+
+      virtual_screen.cursor_state = on;
+    }
+}
+
+static void
+grub_gfxterm_refresh (void)
+{
+  /* Redraw only changed regions.  */
+  dirty_region_redraw ();
+}
+
+static grub_err_t
+grub_gfxterm_background_image_cmd (grub_command_t cmd __attribute__ ((unused)),
+                                   int argc,
+                                   char **args)
+{
+  /* Check that we have video adapter active.  */
+  if (grub_video_get_info(NULL) != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Destroy existing background bitmap if loaded.  */
+  if (bitmap)
+    {
+      grub_video_bitmap_destroy (bitmap);
+      bitmap = 0;
+
+      /* Mark whole screen as dirty.  */
+      dirty_region_reset ();
+      dirty_region_add (0, 0, mode_info.width, mode_info.height);
+    }
+
+  /* If filename was provided, try to load that.  */
+  if (argc >= 1)
+    {
+    /* Try to load new one.  */
+    grub_video_bitmap_load (&bitmap, args[0]);
+    if (grub_errno != GRUB_ERR_NONE)
+      return grub_errno;
+
+    /* If bitmap was loaded correctly, display it.  */
+    if (bitmap)
+      {
+        /* Determine bitmap dimensions.  */
+        bitmap_width = grub_video_bitmap_get_width (bitmap);
+        bitmap_height = grub_video_bitmap_get_width (bitmap);
+
+        /* Mark whole screen as dirty.  */
+        dirty_region_reset ();
+        dirty_region_add (0, 0, mode_info.width, mode_info.height);
+      }
+    }
+
+  /* All was ok.  */
+  grub_errno = GRUB_ERR_NONE;
+  return grub_errno;
+}
+
+static struct grub_term_output grub_video_term =
+  {
+    .name = "gfxterm",
+    .init = grub_gfxterm_init,
+    .fini = grub_gfxterm_fini,
+    .putchar = grub_gfxterm_putchar,
+    .getcharwidth = grub_gfxterm_getcharwidth,
+    .getwh = grub_virtual_screen_getwh,
+    .getxy = grub_virtual_screen_getxy,
+    .gotoxy = grub_gfxterm_gotoxy,
+    .cls = grub_gfxterm_cls,
+    .setcolorstate = grub_virtual_screen_setcolorstate,
+    .setcolor = grub_virtual_screen_setcolor,
+    .getcolor = grub_virtual_screen_getcolor,
+    .setcursor = grub_gfxterm_setcursor,
+    .refresh = grub_gfxterm_refresh,
+    .flags = 0,
+    .next = 0
+  };
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(term_gfxterm)
+{
+  grub_term_register_output ("gfxterm", &grub_video_term);
+  cmd = grub_register_command ("background_image",
+			       grub_gfxterm_background_image_cmd,
+			       0, "Load background image for active terminal");
+}
+
+GRUB_MOD_FINI(term_gfxterm)
+{
+  grub_unregister_command (cmd);
+  grub_term_unregister_output (&grub_video_term);
+}
diff --git a/term/i386/pc/at_keyboard.c b/term/i386/pc/at_keyboard.c
new file mode 100644
index 0000000..cf30e72
--- /dev/null
+++ b/term/i386/pc/at_keyboard.c
@@ -0,0 +1,242 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/i386/pc/console.h>
+#include <grub/i386/at_keyboard.h>
+#include <grub/i386/io.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+
+static short at_keyboard_status = 0;
+
+#define KEYBOARD_STATUS_SHIFT_L		(1 << 0)
+#define KEYBOARD_STATUS_SHIFT_R		(1 << 1)
+#define KEYBOARD_STATUS_ALT_L		(1 << 2)
+#define KEYBOARD_STATUS_ALT_R		(1 << 3)
+#define KEYBOARD_STATUS_CTRL_L		(1 << 4)
+#define KEYBOARD_STATUS_CTRL_R		(1 << 5)
+#define KEYBOARD_STATUS_CAPS_LOCK	(1 << 6)
+
+static char keyboard_map[128] =
+{
+  '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6',
+  '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB,
+  'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
+  'o', 'p', '[', ']', '\n', '\0', 'a', 's',
+  'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
+  '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v',
+  'b', 'n', 'm', ',', '.', '/', '\0', '*',
+  '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0',
+  '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_HOME,
+  GRUB_TERM_UP, GRUB_TERM_NPAGE, '-', GRUB_TERM_LEFT, '\0', GRUB_TERM_RIGHT, '+', GRUB_TERM_END,
+  GRUB_TERM_DOWN, GRUB_TERM_PPAGE, '\0', GRUB_TERM_DC, '\0', '\0', '\0', '\0',
+  '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+  '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT,
+  OLPC_RIGHT
+};
+
+static char keyboard_map_shift[128] =
+{
+  '\0', '\0', '!', '@', '#', '$', '%', '^',
+  '&', '*', '(', ')', '_', '+', '\0', '\0',
+  'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
+  'O', 'P', '{', '}', '\n', '\0', 'A', 'S',
+  'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
+  '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V',
+  'B', 'N', 'M', '<', '>', '?'
+};
+
+static grub_uint8_t grub_keyboard_controller_orig;
+
+static void
+grub_keyboard_controller_write (grub_uint8_t c)
+{
+  while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS)));
+  grub_outb (KEYBOARD_COMMAND_WRITE, KEYBOARD_REG_STATUS);
+  grub_outb (c, KEYBOARD_REG_DATA);
+}
+
+static grub_uint8_t
+grub_keyboard_controller_read (void)
+{
+  while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS)));
+  grub_outb (KEYBOARD_COMMAND_READ, KEYBOARD_REG_STATUS);
+  return grub_inb (KEYBOARD_REG_DATA);
+}
+
+/* FIXME: This should become an interrupt service routine.  For now
+   it's just used to catch events from control keys.  */
+static void
+grub_keyboard_isr (char key)
+{
+  char is_make = KEYBOARD_ISMAKE (key);
+  key = KEYBOARD_SCANCODE (key);
+  if (is_make)
+    switch (key)
+      {
+	case SHIFT_L:
+	  at_keyboard_status |= KEYBOARD_STATUS_SHIFT_L;
+	  break;
+	case SHIFT_R:
+	  at_keyboard_status |= KEYBOARD_STATUS_SHIFT_R;
+	  break;
+	case CTRL:
+	  at_keyboard_status |= KEYBOARD_STATUS_CTRL_L;
+	  break;
+	case ALT:
+	  at_keyboard_status |= KEYBOARD_STATUS_ALT_L;
+	  break;
+	default:
+	  /* Skip grub_dprintf.  */
+	  return;
+      }
+  else
+    switch (key)
+      {
+	case SHIFT_L:
+	  at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_L;
+	  break;
+	case SHIFT_R:
+	  at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_R;
+	  break;
+	case CTRL:
+	  at_keyboard_status &= ~KEYBOARD_STATUS_CTRL_L;
+	  break;
+	case ALT:
+	  at_keyboard_status &= ~KEYBOARD_STATUS_ALT_L;
+	  break;
+	default:
+	  /* Skip grub_dprintf.  */
+	  return;
+      }
+#ifdef DEBUG_AT_KEYBOARD
+  grub_dprintf ("atkeyb", "Control key 0x%0x was %s\n", key, is_make ? "pressed" : "unpressed");
+#endif
+}
+
+/* If there is a raw key pending, return it; otherwise return -1.  */
+static int
+grub_keyboard_getkey (void)
+{
+  grub_uint8_t key;
+  if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS)))
+    return -1;
+  key = grub_inb (KEYBOARD_REG_DATA);
+  /* FIXME */ grub_keyboard_isr (key);
+  if (! KEYBOARD_ISMAKE (key))
+    return -1;
+  return (KEYBOARD_SCANCODE (key));
+}
+
+/* If there is a character pending, return it; otherwise return -1.  */
+static int
+grub_at_keyboard_getkey_noblock (void)
+{
+  int code, key;
+  code = grub_keyboard_getkey ();
+  if (code == -1)
+    return -1;
+#ifdef DEBUG_AT_KEYBOARD
+  grub_dprintf ("atkeyb", "Detected key 0x%x\n", key);
+#endif
+  switch (code)
+    {
+      case CAPS_LOCK:
+	at_keyboard_status ^= KEYBOARD_STATUS_CAPS_LOCK;
+	/* Caps lock sends scan code twice.  Get the second one and discard it.  */
+	while (grub_keyboard_getkey () == -1);
+#ifdef DEBUG_AT_KEYBOARD
+	grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK));
+#endif
+	key = -1;
+	break;
+      default:
+	if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R))
+	  key = keyboard_map[code] - 'a' + 1;
+	else if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L | KEYBOARD_STATUS_SHIFT_R))
+	    && keyboard_map_shift[code])
+	  key = keyboard_map_shift[code];
+	else
+	  key = keyboard_map[code];
+
+	if (key == 0)
+	  grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code);
+
+	if (at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK)
+	  {
+	    if ((key >= 'a') && (key <= 'z'))
+	      key += 'A' - 'a';
+	    else if ((key >= 'A') && (key <= 'Z'))
+	      key += 'a' - 'A';
+	  }
+    }
+  return key;
+}
+
+static int
+grub_at_keyboard_checkkey (void)
+{
+  /* FIXME: this will be triggered by BREAK events.  */
+  return KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS)) ? 1 : -1;
+}
+
+static int
+grub_at_keyboard_getkey (void)
+{
+  int key;
+  do
+    {
+      key = grub_at_keyboard_getkey_noblock ();
+    } while (key == -1);
+  return key;
+}
+
+static grub_err_t
+grub_keyboard_controller_init (void)
+{
+  grub_keyboard_controller_orig = grub_keyboard_controller_read ();
+  grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_keyboard_controller_fini (void)
+{
+  grub_keyboard_controller_write (grub_keyboard_controller_orig);
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_term_input grub_at_keyboard_term =
+  {
+    .name = "at_keyboard",
+    .init = grub_keyboard_controller_init,
+    .fini = grub_keyboard_controller_fini,
+    .checkkey = grub_at_keyboard_checkkey,
+    .getkey = grub_at_keyboard_getkey,
+  };
+
+GRUB_MOD_INIT(at_keyboard)
+{
+  grub_term_register_input ("at_keyboard", &grub_at_keyboard_term);
+}
+
+GRUB_MOD_FINI(at_keyboard)
+{
+  grub_term_unregister_input (&grub_at_keyboard_term);
+}
diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c
new file mode 100644
index 0000000..66475d4
--- /dev/null
+++ b/term/i386/pc/console.c
@@ -0,0 +1,88 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/machine/console.h>
+#include <grub/term.h>
+#include <grub/types.h>
+
+static const struct grub_machine_bios_data_area *bios_data_area =
+  (struct grub_machine_bios_data_area *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
+
+#define KEYBOARD_LEFT_SHIFT	(1 << 0)
+#define KEYBOARD_RIGHT_SHIFT	(1 << 1)
+#define KEYBOARD_CTRL		(1 << 2)
+#define KEYBOARD_ALT		(1 << 3)
+
+static int
+grub_console_getkeystatus (void)
+{
+  grub_uint8_t status = bios_data_area->keyboard_flag_lower;
+  int mods = 0;
+
+  if (status & (KEYBOARD_LEFT_SHIFT | KEYBOARD_RIGHT_SHIFT))
+    mods |= GRUB_TERM_STATUS_SHIFT;
+  if (status & KEYBOARD_CTRL)
+    mods |= GRUB_TERM_STATUS_CTRL;
+  if (status & KEYBOARD_ALT)
+    mods |= GRUB_TERM_STATUS_ALT;
+
+  return mods;
+}
+
+static struct grub_term_input grub_console_term_input =
+  {
+    .name = "console",
+    .checkkey = grub_console_checkkey,
+    .getkey = grub_console_getkey,
+    .getkeystatus = grub_console_getkeystatus,
+  };
+
+static struct grub_term_output grub_console_term_output =
+  {
+    .name = "console",
+    .putchar = grub_console_putchar,
+    .getcharwidth = grub_console_getcharwidth,
+    .getwh = grub_console_getwh,
+    .getxy = grub_console_getxy,
+    .gotoxy = grub_console_gotoxy,
+    .cls = grub_console_cls,
+    .setcolorstate = grub_console_setcolorstate,
+    .setcolor = grub_console_setcolor,
+    .getcolor = grub_console_getcolor,
+    .setcursor = grub_console_setcursor,
+    .flags = 0,
+  };
+
+void
+grub_console_init (void)
+{
+  grub_term_register_output ("console", &grub_console_term_output);
+  grub_term_register_input ("console", &grub_console_term_input);
+}
+
+void
+grub_console_fini (void)
+{
+  /* This is to make sure the console is restored to text mode before
+     we boot.  */
+  grub_term_set_current_output (&grub_console_term_output);
+
+  grub_term_unregister_input (&grub_console_term_input);
+  grub_term_unregister_output (&grub_console_term_output);
+}
diff --git a/term/i386/pc/serial.c b/term/i386/pc/serial.c
new file mode 100644
index 0000000..1d74dbb
--- /dev/null
+++ b/term/i386/pc/serial.c
@@ -0,0 +1,625 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/machine.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/serial.h>
+#include <grub/machine/console.h>
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/terminfo.h>
+#include <grub/cpu/io.h>
+#include <grub/extcmd.h>
+
+#define TEXT_WIDTH	80
+#define TEXT_HEIGHT	25
+
+static unsigned int xpos, ypos;
+static unsigned int keep_track = 1;
+static unsigned int registered = 0;
+
+/* An input buffer.  */
+static char input_buf[8];
+static unsigned int npending = 0;
+
+/* Argument options.  */
+static const struct grub_arg_option options[] =
+{
+  {"unit",   'u', 0, "Set the serial unit",             0, ARG_TYPE_INT},
+  {"port",   'p', 0, "Set the serial port address",     0, ARG_TYPE_STRING},
+  {"speed",  's', 0, "Set the serial port speed",       0, ARG_TYPE_INT},
+  {"word",   'w', 0, "Set the serial port word length", 0, ARG_TYPE_INT},
+  {"parity", 'r', 0, "Set the serial port parity",      0, ARG_TYPE_STRING},
+  {"stop",   't', 0, "Set the serial port stop bits",   0, ARG_TYPE_INT},
+  {0, 0, 0, 0, 0, 0}
+};
+
+/* Serial port settings.  */
+struct serial_port
+{
+  unsigned short port;
+  unsigned short divisor;
+  unsigned short word_len;
+  unsigned int   parity;
+  unsigned short stop_bits;
+};
+
+/* Serial port settings.  */
+static struct serial_port serial_settings;
+
+#ifdef GRUB_MACHINE_PCBIOS
+static const unsigned short *serial_hw_io_addr = (const unsigned short *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
+#define GRUB_SERIAL_PORT_NUM 4
+#else
+static const unsigned short serial_hw_io_addr[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
+#define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr))
+#endif
+
+/* Return the port number for the UNITth serial device.  */
+static inline unsigned short
+serial_hw_get_port (const unsigned int unit)
+{
+  if (unit < GRUB_SERIAL_PORT_NUM)
+    return serial_hw_io_addr[unit];
+  else
+    return 0;
+}
+
+/* Fetch a key.  */
+static int
+serial_hw_fetch (void)
+{
+  if (grub_inb (serial_settings.port + UART_LSR) & UART_DATA_READY)
+    return grub_inb (serial_settings.port + UART_RX);
+
+  return -1;
+}
+
+/* Put a character.  */
+static void
+serial_hw_put (const int c)
+{
+  unsigned int timeout = 100000;
+
+  /* Wait until the transmitter holding register is empty.  */
+  while ((grub_inb (serial_settings.port + UART_LSR) & UART_EMPTY_TRANSMITTER) == 0)
+    {
+      if (--timeout == 0)
+        /* There is something wrong. But what can I do?  */
+        return;
+    }
+
+  grub_outb (c, serial_settings.port + UART_TX);
+}
+
+static void
+serial_translate_key_sequence (void)
+{
+  unsigned int i;
+  static struct
+  {
+    char key;
+    char ascii;
+  }
+  three_code_table[] =
+    {
+      {'A', 16},
+      {'B', 14},
+      {'C', 6},
+      {'D', 2},
+      {'F', 5},
+      {'H', 1},
+      {'4', 4}
+    };
+
+  static struct
+  {
+      short key;
+      char ascii;
+  }
+  four_code_table[] =
+    {
+      {('1' | ('~' << 8)), 1},
+      {('3' | ('~' << 8)), 4},
+      {('5' | ('~' << 8)), 7},
+      {('6' | ('~' << 8)), 3}
+    };
+
+  if (npending < 3)
+    return;
+
+  /* The buffer must start with "ESC [".  */
+  if (input_buf[0] != '\e' || input_buf[1] != '[')
+    return;
+
+  for (i = 0; ARRAY_SIZE (three_code_table); i++)
+    if (three_code_table[i].key == input_buf[2])
+      {
+	input_buf[0] = three_code_table[i].ascii;
+	npending -= 2;
+	grub_memmove (input_buf + 1, input_buf + 3, npending - 1);
+	return;
+      }
+
+  if (npending >= 4)
+    {
+      short key = input_buf[3] | (input_buf[4] << 8);
+
+      for (i = 0; i < ARRAY_SIZE (four_code_table); i++)
+	if (four_code_table[i].key == key)
+	  {
+	    input_buf[0] = four_code_table[i].ascii;
+	    npending -= 3;
+	    grub_memmove (input_buf + 1, input_buf + 4, npending - 1);
+	    return;
+	  }
+    }
+}
+
+static int
+fill_input_buf (const int nowait)
+{
+  int i;
+
+  for (i = 0; i < 10000 && npending < sizeof (input_buf); i++)
+    {
+      int c;
+
+      c = serial_hw_fetch ();
+      if (c >= 0)
+	{
+	  input_buf[npending++] = c;
+
+	  /* Reset the counter to zero, to wait for the same interval.  */
+	  i = 0;
+	}
+
+      if (nowait)
+	break;
+    }
+
+  /* Translate some key sequences.  */
+  serial_translate_key_sequence ();
+
+  return npending;
+}
+
+/* Convert speed to divisor.  */
+static unsigned short
+serial_get_divisor (unsigned int speed)
+{
+  unsigned int i;
+
+  /* The structure for speed vs. divisor.  */
+  struct divisor
+  {
+    unsigned int speed;
+    unsigned short div;
+  };
+
+  /* The table which lists common configurations.  */
+  /* 1843200 / (speed * 16)  */
+  static struct divisor divisor_tab[] =
+    {
+      { 2400,   0x0030 },
+      { 4800,   0x0018 },
+      { 9600,   0x000C },
+      { 19200,  0x0006 },
+      { 38400,  0x0003 },
+      { 57600,  0x0002 },
+      { 115200, 0x0001 }
+    };
+
+  /* Set the baud rate.  */
+  for (i = 0; i < sizeof (divisor_tab) / sizeof (divisor_tab[0]); i++)
+    if (divisor_tab[i].speed == speed)
+      return divisor_tab[i].div;
+  return 0;
+}
+
+/* The serial version of checkkey.  */
+static int
+grub_serial_checkkey (void)
+{
+  if (fill_input_buf (1))
+    return input_buf[0];
+  else
+    return -1;
+}
+
+/* The serial version of getkey.  */
+static int
+grub_serial_getkey (void)
+{
+  int c;
+
+  while (! fill_input_buf (0))
+    ;
+
+  c = input_buf[0];
+  grub_memmove (input_buf, input_buf + 1, --npending);
+
+  return c;
+}
+
+/* Initialize a serial device. PORT is the port number for a serial device.
+   SPEED is a DTE-DTE speed which must be one of these: 2400, 4800, 9600,
+   19200, 38400, 57600 and 115200. WORD_LEN is the word length to be used
+   for the device. Likewise, PARITY is the type of the parity and
+   STOP_BIT_LEN is the length of the stop bit. The possible values for
+   WORD_LEN, PARITY and STOP_BIT_LEN are defined in the header file as
+   macros.  */
+static grub_err_t
+serial_hw_init (void)
+{
+  unsigned char status = 0;
+
+  /* Turn off the interrupt.  */
+  grub_outb (0, serial_settings.port + UART_IER);
+
+  /* Set DLAB.  */
+  grub_outb (UART_DLAB, serial_settings.port + UART_LCR);
+
+  /* Set the baud rate.  */
+  grub_outb (serial_settings.divisor & 0xFF, serial_settings.port + UART_DLL);
+  grub_outb (serial_settings.divisor >> 8, serial_settings.port + UART_DLH);
+
+  /* Set the line status.  */
+  status |= (serial_settings.parity
+	     | serial_settings.word_len
+	     | serial_settings.stop_bits);
+  grub_outb (status, serial_settings.port + UART_LCR);
+
+  /* Enable the FIFO.  */
+  grub_outb (UART_ENABLE_FIFO, serial_settings.port + UART_FCR);
+
+  /* Turn on DTR, RTS, and OUT2.  */
+  grub_outb (UART_ENABLE_MODEM, serial_settings.port + UART_MCR);
+
+  /* Drain the input buffer.  */
+  while (grub_serial_checkkey () != -1)
+    (void) grub_serial_getkey ();
+
+  /*  FIXME: should check if the serial terminal was found.  */
+
+  return GRUB_ERR_NONE;
+}
+
+/* The serial version of putchar.  */
+static void
+grub_serial_putchar (grub_uint32_t c)
+{
+  /* Keep track of the cursor.  */
+  if (keep_track)
+    {
+      /* The serial terminal does not have VGA fonts.  */
+      if (c > 0x7F)
+	{
+	  /* Better than nothing.  */
+	  switch (c)
+	    {
+	    case GRUB_TERM_DISP_LEFT:
+	      c = '<';
+	      break;
+
+	    case GRUB_TERM_DISP_UP:
+	      c = '^';
+	      break;
+
+	    case GRUB_TERM_DISP_RIGHT:
+	      c = '>';
+	      break;
+
+	    case GRUB_TERM_DISP_DOWN:
+	      c = 'v';
+	      break;
+
+	    case GRUB_TERM_DISP_HLINE:
+	      c = '-';
+	      break;
+
+	    case GRUB_TERM_DISP_VLINE:
+	      c = '|';
+	      break;
+
+	    case GRUB_TERM_DISP_UL:
+	    case GRUB_TERM_DISP_UR:
+	    case GRUB_TERM_DISP_LL:
+	    case GRUB_TERM_DISP_LR:
+	      c = '+';
+	      break;
+
+	    default:
+	      c = '?';
+	      break;
+	    }
+	}
+
+      switch (c)
+	{
+	case '\a':
+	  break;
+
+	case '\b':
+	case 127:
+	  if (xpos > 0)
+	    xpos--;
+	  break;
+
+	case '\n':
+	  if (ypos < TEXT_HEIGHT)
+	    ypos++;
+	  break;
+
+	case '\r':
+	  xpos = 0;
+	  break;
+
+	default:
+	  if (xpos >= TEXT_WIDTH)
+	    {
+	      grub_putchar ('\r');
+	      grub_putchar ('\n');
+	    }
+	  xpos++;
+	  break;
+	}
+    }
+
+  serial_hw_put (c);
+}
+
+static grub_ssize_t
+grub_serial_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
+{
+  return 1;
+}
+
+static grub_uint16_t
+grub_serial_getwh (void)
+{
+  return (TEXT_WIDTH << 8) | TEXT_HEIGHT;
+}
+
+static grub_uint16_t
+grub_serial_getxy (void)
+{
+  return ((xpos << 8) | ypos);
+}
+
+static void
+grub_serial_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  if (x > TEXT_WIDTH || y > TEXT_HEIGHT)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", x, y);
+    }
+  else
+    {
+      keep_track = 0;
+      grub_terminfo_gotoxy (x, y);
+      keep_track = 1;
+
+      xpos = x;
+      ypos = y;
+    }
+}
+
+static void
+grub_serial_cls (void)
+{
+  keep_track = 0;
+  grub_terminfo_cls ();
+  keep_track = 1;
+
+  xpos = ypos = 0;
+}
+
+static void
+grub_serial_setcolorstate (const grub_term_color_state state)
+{
+  keep_track = 0;
+  switch (state)
+    {
+    case GRUB_TERM_COLOR_STANDARD:
+    case GRUB_TERM_COLOR_NORMAL:
+      grub_terminfo_reverse_video_off ();
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      grub_terminfo_reverse_video_on ();
+      break;
+    default:
+      break;
+    }
+  keep_track = 1;
+}
+
+static void
+grub_serial_setcursor (const int on)
+{
+  if (on)
+    grub_terminfo_cursor_on ();
+  else
+    grub_terminfo_cursor_off ();
+}
+
+static struct grub_term_input grub_serial_term_input =
+{
+  .name = "serial",
+  .checkkey = grub_serial_checkkey,
+  .getkey = grub_serial_getkey,
+};
+
+static struct grub_term_output grub_serial_term_output =
+{
+  .name = "serial",
+  .putchar = grub_serial_putchar,
+  .getcharwidth = grub_serial_getcharwidth,
+  .getwh = grub_serial_getwh,
+  .getxy = grub_serial_getxy,
+  .gotoxy = grub_serial_gotoxy,
+  .cls = grub_serial_cls,
+  .setcolorstate = grub_serial_setcolorstate,
+  .setcursor = grub_serial_setcursor,
+  .flags = 0,
+};
+
+
+
+static grub_err_t
+grub_cmd_serial (grub_extcmd_t cmd,
+                 int argc __attribute__ ((unused)),
+		 char **args __attribute__ ((unused)))
+{
+  struct grub_arg_list *state = cmd->state;
+  struct serial_port backup_settings = serial_settings;
+  grub_err_t hwiniterr;
+
+  if (state[0].set)
+    {
+      unsigned int unit;
+
+      unit = grub_strtoul (state[0].arg, 0, 0);
+      serial_settings.port = serial_hw_get_port (unit);
+      if (!serial_settings.port)
+	return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad unit number.");
+    }
+
+  if (state[1].set)
+    serial_settings.port = (unsigned short) grub_strtoul (state[1].arg, 0, 0);
+
+  if (state[2].set)
+    {
+      unsigned long speed;
+
+      speed = grub_strtoul (state[2].arg, 0, 0);
+      serial_settings.divisor = serial_get_divisor ((unsigned int) speed);
+      if (serial_settings.divisor == 0)
+	{
+	  serial_settings = backup_settings;
+	  return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad speed");
+	}
+    }
+
+  if (state[3].set)
+    {
+      if (! grub_strcmp (state[3].arg, "5"))
+	serial_settings.word_len = UART_5BITS_WORD;
+      else if (! grub_strcmp (state[3].arg, "6"))
+	serial_settings.word_len = UART_6BITS_WORD;
+      else if (! grub_strcmp (state[3].arg, "7"))
+	serial_settings.word_len = UART_7BITS_WORD;
+      else if (! grub_strcmp (state[3].arg, "8"))
+	serial_settings.word_len = UART_8BITS_WORD;
+      else
+	{
+	  serial_settings = backup_settings;
+	  return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad word length");
+	}
+    }
+
+  if (state[4].set)
+    {
+      if (! grub_strcmp (state[4].arg, "no"))
+	serial_settings.parity = UART_NO_PARITY;
+      else if (! grub_strcmp (state[4].arg, "odd"))
+	serial_settings.parity = UART_ODD_PARITY;
+      else if (! grub_strcmp (state[4].arg, "even"))
+	serial_settings.parity = UART_EVEN_PARITY;
+      else
+	{
+	  serial_settings = backup_settings;
+	  return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad parity");
+	}
+    }
+
+  if (state[5].set)
+    {
+      if (! grub_strcmp (state[5].arg, "1"))
+	serial_settings.stop_bits = UART_1_STOP_BIT;
+      else if (! grub_strcmp (state[5].arg, "2"))
+	serial_settings.stop_bits = UART_2_STOP_BITS;
+      else
+	{
+	  serial_settings = backup_settings;
+	  return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad number of stop bits");
+	}
+    }
+
+  /* Initialize with new settings.  */
+  hwiniterr = serial_hw_init ();
+
+  if (hwiniterr == GRUB_ERR_NONE)
+    {
+      /* Register terminal if not yet registered.  */
+      if (registered == 0)
+	{
+	  grub_term_register_input ("serial", &grub_serial_term_input);
+	  grub_term_register_output ("serial", &grub_serial_term_output);
+	  registered = 1;
+	}
+    }
+  else
+    {
+      /* Initialization with new settings failed.  */
+      if (registered == 1)
+	{
+	  /* If the terminal is registered, attempt to restore previous
+	     settings.  */
+	  serial_settings = backup_settings;
+	  if (serial_hw_init () != GRUB_ERR_NONE)
+	    {
+	      /* If unable to restore settings, unregister terminal.  */
+	      grub_term_unregister_input (&grub_serial_term_input);
+	      grub_term_unregister_output (&grub_serial_term_output);
+	      registered = 0;
+	    }
+	}
+    }
+
+  return hwiniterr;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(serial)
+{
+  cmd = grub_register_extcmd ("serial", grub_cmd_serial,
+			      GRUB_COMMAND_FLAG_BOTH,
+			      "serial [OPTIONS...]",
+			      "Configure serial port.", options);
+
+  /* Set default settings.  */
+  serial_settings.port      = serial_hw_get_port (0);
+  serial_settings.divisor   = serial_get_divisor (9600);
+  serial_settings.word_len  = UART_8BITS_WORD;
+  serial_settings.parity    = UART_NO_PARITY;
+  serial_settings.stop_bits = UART_1_STOP_BIT;
+}
+
+GRUB_MOD_FINI(serial)
+{
+  grub_unregister_extcmd (cmd);
+  if (registered == 1)		/* Unregister terminal only if registered. */
+    {
+      grub_term_unregister_input (&grub_serial_term_input);
+      grub_term_unregister_output (&grub_serial_term_output);
+    }
+}
diff --git a/term/i386/pc/vesafb.c b/term/i386/pc/vesafb.c
new file mode 100644
index 0000000..52694ed
--- /dev/null
+++ b/term/i386/pc/vesafb.c
@@ -0,0 +1,606 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// TODO: Deprecated and broken. Scheduled for removal as there is VBE driver in Video subsystem.
+
+#include <grub/machine/memory.h>
+#include <grub/machine/vga.h>
+#include <grub/machine/vbe.h>
+#include <grub/machine/console.h>
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/font.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+
+#define DEFAULT_CHAR_WIDTH  8
+#define DEFAULT_CHAR_HEIGHT 16
+
+#define DEFAULT_FG_COLOR    0xa
+#define DEFAULT_BG_COLOR    0x0
+
+struct grub_colored_char
+{
+  /* An Unicode codepoint.  */
+  grub_uint32_t code;
+
+  /* Color indexes.  */
+  unsigned char fg_color;
+  unsigned char bg_color;
+
+  /* The width of this character minus one.  */
+  unsigned char width;
+
+  /* The column index of this character.  */
+  unsigned char index;
+};
+
+struct grub_virtual_screen
+{
+  /* Dimensions of the virtual screen.  */
+  grub_uint32_t width;
+  grub_uint32_t height;
+
+  /* Offset in the display.  */
+  grub_uint32_t offset_x;
+  grub_uint32_t offset_y;
+
+  /* TTY Character sizes.  */
+  grub_uint32_t char_width;
+  grub_uint32_t char_height;
+
+  /* Virtual screen TTY size.  */
+  grub_uint32_t columns;
+  grub_uint32_t rows;
+
+  /* Current cursor details.  */
+  grub_uint32_t cursor_x;
+  grub_uint32_t cursor_y;
+  grub_uint8_t cursor_state;
+  grub_uint8_t fg_color;
+  grub_uint8_t bg_color;
+
+  /* Text buffer for virtual screen. Contains (columns * rows) number
+     of entries.  */
+  struct grub_colored_char *text_buffer;
+};
+
+/* Make sure text buffer is not marked as allocated.  */
+static struct grub_virtual_screen virtual_screen =
+  {
+    .text_buffer = 0
+  };
+
+static unsigned char *vga_font = 0;
+static grub_uint32_t old_mode = 0;
+
+static struct grub_vbe_mode_info_block mode_info;
+static grub_uint8_t *framebuffer = 0;
+static grub_uint32_t bytes_per_scan_line = 0;
+
+static void
+grub_virtual_screen_free (void)
+{
+  /* If virtual screen has been allocated, free it.  */
+  if (virtual_screen.text_buffer != 0)
+    grub_free (virtual_screen.text_buffer);
+
+  /* Reset virtual screen data.  */
+  grub_memset (&virtual_screen, 0, sizeof (virtual_screen));
+}
+
+static grub_err_t
+grub_virtual_screen_setup (grub_uint32_t width,
+			   grub_uint32_t height)
+{
+  /* Free old virtual screen.  */
+  grub_virtual_screen_free ();
+
+  /* Initialize with default data.  */
+  virtual_screen.width = width;
+  virtual_screen.height = height;
+  virtual_screen.offset_x = 0;
+  virtual_screen.offset_y = 0;
+  virtual_screen.char_width = DEFAULT_CHAR_WIDTH;
+  virtual_screen.char_height = DEFAULT_CHAR_HEIGHT;
+  virtual_screen.cursor_x = 0;
+  virtual_screen.cursor_y = 0;
+  virtual_screen.cursor_state = 1;
+  virtual_screen.fg_color = DEFAULT_FG_COLOR;
+  virtual_screen.bg_color = DEFAULT_BG_COLOR;
+
+  /* Calculate size of text buffer.  */
+  virtual_screen.columns = virtual_screen.width / virtual_screen.char_width;
+  virtual_screen.rows = virtual_screen.height / virtual_screen.char_height;
+
+  /* Allocate memory for text buffer.  */
+  virtual_screen.text_buffer =
+    (struct grub_colored_char *) grub_malloc (virtual_screen.columns
+					      * virtual_screen.rows
+					      * sizeof (*virtual_screen.text_buffer));
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_vesafb_mod_init (void)
+{
+  grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
+  struct grub_vbe_info_block controller_info;
+  char *modevar;
+
+  /* Use fonts from VGA bios.  */
+  vga_font = grub_vga_get_font ();
+
+  /* Check if we have VESA BIOS installed.  */
+  if (grub_vbe_probe (&controller_info) != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Check existence of vbe_mode environment variable.  */
+  modevar = grub_env_get ("vbe_mode");
+
+  if (modevar != 0)
+    {
+      unsigned long value;
+
+      value = grub_strtoul (modevar, 0, 0);
+      if (grub_errno == GRUB_ERR_NONE)
+	use_mode = value;
+    }
+
+  /* Store initial video mode.  */
+  if (grub_vbe_get_video_mode (&old_mode) != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Setup desired graphics mode.  */
+  if (grub_vbe_set_video_mode (use_mode, &mode_info) != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Determine framebuffer and bytes per scan line.  */
+  framebuffer = (grub_uint8_t *) mode_info.phys_base_addr;
+
+  if (controller_info.version >= 0x300)
+    bytes_per_scan_line = mode_info.lin_bytes_per_scan_line;
+  else
+    bytes_per_scan_line = mode_info.bytes_per_scan_line;
+
+  /* Create virtual screen.  */
+  if (grub_virtual_screen_setup (mode_info.x_resolution,
+				 mode_info.y_resolution) != GRUB_ERR_NONE)
+    {
+      grub_vbe_set_video_mode (old_mode, 0);
+      return grub_errno;
+    }
+
+  /* Make sure frame buffer is black.  */
+  grub_memset (framebuffer,
+	       0,
+	       bytes_per_scan_line * mode_info.y_resolution);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_vesafb_mod_fini (void)
+{
+  grub_virtual_screen_free ();
+
+  grub_vbe_set_video_mode (old_mode, 0);
+
+  return GRUB_ERR_NONE;
+}
+
+static int
+grub_virtual_screen_get_glyph (grub_uint32_t code,
+			       unsigned char bitmap[32],
+			       unsigned *width)
+{
+  if (code > 0x7f)
+    {
+      /* Map some unicode characters to the VGA font, if possible.  */
+      switch (code)
+	{
+	case 0x2190:	/* left arrow */
+	  code = 0x1b;
+	  break;
+	case 0x2191:	/* up arrow */
+	  code = 0x18;
+	  break;
+	case 0x2192:	/* right arrow */
+	  code = 0x1a;
+	  break;
+	case 0x2193:	/* down arrow */
+	  code = 0x19;
+	  break;
+	case 0x2501:	/* horizontal line */
+	  code = 0xc4;
+	  break;
+	case 0x2503:	/* vertical line */
+	  code = 0xb3;
+	  break;
+	case 0x250F:	/* upper-left corner */
+	  code = 0xda;
+	  break;
+	case 0x2513:	/* upper-right corner */
+	  code = 0xbf;
+	  break;
+	case 0x2517:	/* lower-left corner */
+	  code = 0xc0;
+	  break;
+	case 0x251B:	/* lower-right corner */
+	  code = 0xd9;
+	  break;
+
+	default:
+	  return grub_font_get_glyph_any (code, bitmap, width);
+	}
+    }
+
+  /* TODO This is wrong for the new font module.  Should it be fixed?  */
+  if (bitmap)
+    grub_memcpy (bitmap,
+		 vga_font + code * virtual_screen.char_height,
+		 virtual_screen.char_height);
+  *width = 1;
+  return 1;
+}
+
+static void
+grub_virtual_screen_invalidate_char (struct grub_colored_char *p)
+{
+  p->code = 0xFFFF;
+
+  if (p->width)
+    {
+      struct grub_colored_char *q;
+
+      for (q = p + 1; q <= p + p->width; q++)
+	{
+	  q->code = 0xFFFF;
+	  q->width = 0;
+	  q->index = 0;
+	}
+    }
+
+  p->width = 0;
+}
+
+static void
+write_char (void)
+{
+  struct grub_colored_char *p;
+  unsigned char bitmap[32];
+  unsigned width;
+  unsigned y;
+  unsigned offset;
+
+  p = (virtual_screen.text_buffer
+       + virtual_screen.cursor_x
+       + (virtual_screen.cursor_y * virtual_screen.columns));
+
+  p -= p->index;
+
+  if (! grub_virtual_screen_get_glyph (p->code, bitmap, &width))
+    {
+      grub_virtual_screen_invalidate_char (p);
+      width = 0;
+    }
+
+  for (y = 0, offset = 0;
+       y < virtual_screen.char_height;
+       y++, offset++)
+    {
+      unsigned i;
+
+      for (i = 0;
+	   (i < width * virtual_screen.char_width) && (offset < 32);
+	   i++)
+	{
+	  unsigned char color;
+
+	  if (bitmap[offset] & (1 << (8-i)))
+	    {
+	      color = p->fg_color;
+	    }
+	  else
+	    {
+	      color = p->bg_color;
+	    }
+
+          grub_vbe_set_pixel_index(i + (virtual_screen.cursor_x
+                                        * virtual_screen.char_width),
+                                   y + (virtual_screen.cursor_y
+                                        * virtual_screen.char_height),
+                                   color);
+	}
+    }
+}
+
+static void
+write_cursor (void)
+{
+  grub_uint32_t x;
+  grub_uint32_t y;
+
+  for (y = ((virtual_screen.cursor_y + 1) * virtual_screen.char_height) - 3;
+       y < ((virtual_screen.cursor_y + 1) * virtual_screen.char_height) - 1;
+       y++)
+    {
+      for (x = virtual_screen.cursor_x * virtual_screen.char_width;
+	   x < (virtual_screen.cursor_x + 1) * virtual_screen.char_width;
+	   x++)
+	{
+	  grub_vbe_set_pixel_index(x, y, 10);
+	}
+    }
+}
+
+static void
+scroll_up (void)
+{
+  grub_uint32_t i;
+
+  /* Scroll text buffer with one line to up.  */
+  grub_memmove (virtual_screen.text_buffer,
+		virtual_screen.text_buffer + virtual_screen.columns,
+                sizeof (*virtual_screen.text_buffer)
+                * virtual_screen.columns
+                * (virtual_screen.rows - 1));
+
+  /* Clear last line in text buffer.  */
+  for (i = virtual_screen.columns * (virtual_screen.rows - 1);
+       i < virtual_screen.columns * virtual_screen.rows;
+       i++)
+    {
+      virtual_screen.text_buffer[i].code = ' ';
+      virtual_screen.text_buffer[i].fg_color = 0;
+      virtual_screen.text_buffer[i].bg_color = 0;
+      virtual_screen.text_buffer[i].width = 0;
+      virtual_screen.text_buffer[i].index = 0;
+    }
+
+  /* Scroll framebuffer with one line to up.  */
+  grub_memmove (framebuffer,
+                framebuffer
+                + bytes_per_scan_line * virtual_screen.char_height,
+                bytes_per_scan_line
+                * (mode_info.y_resolution - virtual_screen.char_height));
+
+  /* Clear last line in framebuffer.  */
+  grub_memset (framebuffer
+               + (bytes_per_scan_line
+                  * (mode_info.y_resolution - virtual_screen.char_height)),
+               0,
+               bytes_per_scan_line * virtual_screen.char_height);
+}
+
+static void
+grub_vesafb_putchar (grub_uint32_t c)
+{
+  if (c == '\a')
+    /* FIXME */
+    return;
+
+  if (c == '\b' || c == '\n' || c == '\r')
+    {
+      /* Erase current cursor, if any.  */
+      if (virtual_screen.cursor_state)
+	write_char ();
+
+      switch (c)
+	{
+	case '\b':
+	  if (virtual_screen.cursor_x > 0)
+	    virtual_screen.cursor_x--;
+	  break;
+
+	case '\n':
+	  if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
+	    scroll_up ();
+	  else
+	    virtual_screen.cursor_y++;
+	  break;
+
+	case '\r':
+	  virtual_screen.cursor_x = 0;
+	  break;
+	}
+
+      if (virtual_screen.cursor_state)
+	write_cursor ();
+    }
+  else
+    {
+      unsigned width;
+      struct grub_colored_char *p;
+
+      grub_virtual_screen_get_glyph (c, 0, &width);
+
+      if (virtual_screen.cursor_x + width > virtual_screen.columns)
+	grub_putchar ('\n');
+
+      p = (virtual_screen.text_buffer +
+	   virtual_screen.cursor_x +
+	   virtual_screen.cursor_y * virtual_screen.columns);
+      p->code = c;
+      p->fg_color = virtual_screen.fg_color;
+      p->bg_color = virtual_screen.bg_color;
+      p->width = width - 1;
+      p->index = 0;
+
+      if (width > 1)
+	{
+	  unsigned i;
+
+	  for (i = 1; i < width; i++)
+	    {
+	      p[i].code = ' ';
+	      p[i].width = width - 1;
+	      p[i].index = i;
+	    }
+	}
+
+      write_char ();
+
+      virtual_screen.cursor_x += width;
+      if (virtual_screen.cursor_x >= virtual_screen.columns)
+	{
+	  virtual_screen.cursor_x = 0;
+
+	  if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
+	    scroll_up ();
+	  else
+	    virtual_screen.cursor_y++;
+	}
+
+      if (virtual_screen.cursor_state)
+	write_cursor ();
+    }
+}
+
+static grub_ssize_t
+grub_vesafb_getcharwidth (grub_uint32_t c)
+{
+  unsigned width;
+
+  if (! grub_virtual_screen_get_glyph (c, 0, &width))
+    return 0;
+
+  return width;
+}
+
+static grub_uint16_t
+grub_virtual_screen_getwh (void)
+{
+  return (virtual_screen.columns << 8) | virtual_screen.rows;
+}
+
+static grub_uint16_t
+grub_virtual_screen_getxy (void)
+{
+  return ((virtual_screen.cursor_x << 8) | virtual_screen.cursor_y);
+}
+
+static void
+grub_vesafb_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  if (x >= virtual_screen.columns || y >= virtual_screen.rows)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)",
+		  (unsigned) x, (unsigned) y);
+      return;
+    }
+
+  if (virtual_screen.cursor_state)
+    write_char ();
+
+  virtual_screen.cursor_x = x;
+  virtual_screen.cursor_y = y;
+
+  if (virtual_screen.cursor_state)
+    write_cursor ();
+}
+
+static void
+grub_virtual_screen_cls (void)
+{
+  grub_uint32_t i;
+
+  for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
+    {
+      virtual_screen.text_buffer[i].code = ' ';
+      virtual_screen.text_buffer[i].fg_color = 0;
+      virtual_screen.text_buffer[i].bg_color = 0;
+      virtual_screen.text_buffer[i].width = 0;
+      virtual_screen.text_buffer[i].index = 0;
+    }
+
+  virtual_screen.cursor_x = virtual_screen.cursor_y = 0;
+}
+
+static void
+grub_vesafb_cls (void)
+{
+  grub_virtual_screen_cls ();
+
+  grub_memset (framebuffer,
+               0,
+	       mode_info.y_resolution * bytes_per_scan_line);
+}
+
+static void
+grub_virtual_screen_setcolorstate (grub_term_color_state state)
+{
+  switch (state)
+    {
+    case GRUB_TERM_COLOR_STANDARD:
+    case GRUB_TERM_COLOR_NORMAL:
+      virtual_screen.fg_color = DEFAULT_FG_COLOR;
+      virtual_screen.bg_color = DEFAULT_BG_COLOR;
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      virtual_screen.fg_color = DEFAULT_BG_COLOR;
+      virtual_screen.bg_color = DEFAULT_FG_COLOR;
+      break;
+    default:
+      break;
+    }
+}
+
+static void
+grub_vesafb_setcursor (int on)
+{
+  if (virtual_screen.cursor_state != on)
+    {
+      if (virtual_screen.cursor_state)
+	write_char ();
+      else
+	write_cursor ();
+
+      virtual_screen.cursor_state = on;
+    }
+}
+
+static struct grub_term_output grub_vesafb_term =
+  {
+    .name = "vesafb",
+    .init = grub_vesafb_mod_init,
+    .fini = grub_vesafb_mod_fini,
+    .putchar = grub_vesafb_putchar,
+    .getcharwidth = grub_vesafb_getcharwidth,
+    .getwh = grub_virtual_screen_getwh,
+    .getxy = grub_virtual_screen_getxy,
+    .gotoxy = grub_vesafb_gotoxy,
+    .cls = grub_vesafb_cls,
+    .setcolorstate = grub_virtual_screen_setcolorstate,
+    .setcursor = grub_vesafb_setcursor,
+    .flags = 0,
+  };
+
+GRUB_MOD_INIT(vesafb)
+{
+  grub_term_register_output ("vesafb", &grub_vesafb_term);
+}
+
+GRUB_MOD_FINI(vesafb)
+{
+  grub_term_unregister_output (&grub_vesafb_term);
+}
diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c
new file mode 100644
index 0000000..9deb6a6
--- /dev/null
+++ b/term/i386/pc/vga.c
@@ -0,0 +1,513 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// TODO: Deprecated and broken. Needs to be converted to Video Driver!
+
+#include <grub/machine/vga.h>
+#include <grub/machine/console.h>
+#include <grub/cpu/io.h>
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/font.h>
+
+#define DEBUG_VGA	0
+
+#define VGA_WIDTH	640
+#define VGA_HEIGHT	350
+#define CHAR_WIDTH	8
+#define CHAR_HEIGHT	16
+#define TEXT_WIDTH	(VGA_WIDTH / CHAR_WIDTH)
+#define TEXT_HEIGHT	(VGA_HEIGHT / CHAR_HEIGHT)
+#define VGA_MEM		((grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR)
+#define PAGE_OFFSET(x)	((x) * (VGA_WIDTH * VGA_HEIGHT / 8))
+
+#define DEFAULT_FG_COLOR	0xa
+#define DEFAULT_BG_COLOR	0x0
+
+struct colored_char
+{
+  /* An Unicode codepoint.  */
+  grub_uint32_t code;
+
+  /* Color indexes.  */
+  unsigned char fg_color;
+  unsigned char bg_color;
+
+  /* The width of this character minus one.  */
+  unsigned char width;
+
+  /* The column index of this character.  */
+  unsigned char index;
+};
+
+static unsigned char text_mode;
+static unsigned xpos, ypos;
+static int cursor_state;
+static unsigned char fg_color, bg_color;
+static struct colored_char text_buf[TEXT_WIDTH * TEXT_HEIGHT];
+static unsigned char saved_map_mask;
+static int page = 0;
+static grub_font_t font = 0;
+
+#define SEQUENCER_ADDR_PORT	0x3C4
+#define SEQUENCER_DATA_PORT	0x3C5
+#define MAP_MASK_REGISTER	0x02
+
+#define CRTC_ADDR_PORT		0x3D4
+#define CRTC_DATA_PORT		0x3D5
+#define START_ADDR_HIGH_REGISTER 0x0C
+#define START_ADDR_LOW_REGISTER	0x0D
+
+#define GRAPHICS_ADDR_PORT	0x3CE
+#define GRAPHICS_DATA_PORT	0x3CF
+#define READ_MAP_REGISTER	0x04
+
+#define INPUT_STATUS1_REGISTER	0x3DA
+#define INPUT_STATUS1_VERTR_BIT 0x08
+
+static inline void
+wait_vretrace (void)
+{
+  /* Wait until there is a vertical retrace.  */
+  while (! (grub_inb (INPUT_STATUS1_REGISTER) & INPUT_STATUS1_VERTR_BIT));
+}
+
+/* Get Map Mask Register.  */
+static unsigned char
+get_map_mask (void)
+{
+  unsigned char old_addr;
+  unsigned char old_data;
+
+  old_addr = grub_inb (SEQUENCER_ADDR_PORT);
+  grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT);
+
+  old_data = grub_inb (SEQUENCER_DATA_PORT);
+
+  grub_outb (old_addr, SEQUENCER_ADDR_PORT);
+
+  return old_data;
+}
+
+/* Set Map Mask Register.  */
+static void
+set_map_mask (unsigned char mask)
+{
+  unsigned char old_addr;
+
+  old_addr = grub_inb (SEQUENCER_ADDR_PORT);
+  grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT);
+
+  grub_outb (mask, SEQUENCER_DATA_PORT);
+
+  grub_outb (old_addr, SEQUENCER_ADDR_PORT);
+}
+
+/* Set Read Map Register.  */
+static void
+set_read_map (unsigned char map)
+{
+  unsigned char old_addr;
+
+  old_addr = grub_inb (GRAPHICS_ADDR_PORT);
+
+  grub_outb (READ_MAP_REGISTER, GRAPHICS_ADDR_PORT);
+  grub_outb (map, GRAPHICS_DATA_PORT);
+
+  grub_outb (old_addr, GRAPHICS_ADDR_PORT);
+}
+
+/* Set start address.  */
+static void
+set_start_address (unsigned int start)
+{
+  unsigned char old_addr;
+
+  old_addr = grub_inb (CRTC_ADDR_PORT);
+
+  grub_outb (START_ADDR_LOW_REGISTER, CRTC_ADDR_PORT);
+  grub_outb (start & 0xFF, CRTC_DATA_PORT);
+
+  grub_outb (START_ADDR_HIGH_REGISTER, CRTC_ADDR_PORT);
+  grub_outb (start >> 8, CRTC_DATA_PORT);
+
+  grub_outb (old_addr, CRTC_ADDR_PORT);
+}
+
+static grub_err_t
+grub_vga_mod_init (void)
+{
+  text_mode = grub_vga_set_mode (0x10);
+  cursor_state = 1;
+  fg_color = DEFAULT_FG_COLOR;
+  bg_color = DEFAULT_BG_COLOR;
+  saved_map_mask = get_map_mask ();
+  set_map_mask (0x0f);
+  set_start_address (PAGE_OFFSET (page));
+  font = grub_font_get ("");  /* Choose any font, for now. */
+  if (!font)
+    return grub_error (GRUB_ERR_BAD_FONT, "No font loaded.");
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_vga_mod_fini (void)
+{
+  set_map_mask (saved_map_mask);
+  grub_vga_set_mode (text_mode);
+  return GRUB_ERR_NONE;
+}
+
+static int
+check_vga_mem (void *p)
+{
+  return (p >= (void *) (VGA_MEM + PAGE_OFFSET (page))
+	  && p <= (void *) (VGA_MEM + PAGE_OFFSET (page)
+			    + VGA_WIDTH * VGA_HEIGHT / 8));
+}
+
+static void
+write_char (void)
+{
+  struct colored_char *p = text_buf + xpos + ypos * TEXT_WIDTH;
+  struct grub_font_glyph *glyph;
+  unsigned char *mem_base;
+  unsigned plane;
+
+  mem_base = (VGA_MEM + xpos +
+	      ypos * CHAR_HEIGHT * TEXT_WIDTH + PAGE_OFFSET (page)) - p->index;
+  p -= p->index;
+
+  /* Get glyph for character.  */
+  glyph = grub_font_get_glyph (font, p->code);
+
+  for (plane = 0x01; plane <= 0x08; plane <<= 1)
+    {
+      unsigned y;
+      unsigned offset;
+      unsigned char *mem;
+
+      set_map_mask (plane);
+
+      for (y = 0, offset = 0, mem = mem_base;
+	   y < CHAR_HEIGHT;
+	   y++, mem += TEXT_WIDTH)
+	{
+          /* TODO Re-implement glyph drawing for vga module.  */
+#if 0
+	  unsigned i;
+
+          unsigned char_width = 1; /* TODO Figure out wide characters.  */
+	  for (i = 0; i < char_width && offset < 32; i++)
+	    {
+	      unsigned char fg_mask, bg_mask;
+
+	      fg_mask = (p->fg_color & plane) ? glyph->bitmap[offset] : 0;
+	      bg_mask = (p->bg_color & plane) ? ~(glyph->bitmap[offset]) : 0;
+	      offset++;
+
+	      if (check_vga_mem (mem + i))
+		mem[i] = (fg_mask | bg_mask);
+	    }
+#endif /* 0 */
+	}
+    }
+
+  set_map_mask (0x0f);
+}
+
+static void
+write_cursor (void)
+{
+  unsigned char *mem = (VGA_MEM + PAGE_OFFSET (page) + xpos
+			+ (ypos * CHAR_HEIGHT + CHAR_HEIGHT - 3) * TEXT_WIDTH);
+  if (check_vga_mem (mem))
+    *mem = 0xff;
+
+  mem += TEXT_WIDTH;
+  if (check_vga_mem (mem))
+    *mem = 0xff;
+}
+
+static void
+scroll_up (void)
+{
+  unsigned i;
+  unsigned plane;
+
+  /* Do all the work in the other page.  */
+  grub_memmove (text_buf, text_buf + TEXT_WIDTH,
+		sizeof (struct colored_char) * TEXT_WIDTH * (TEXT_HEIGHT - 1));
+
+  for (i = TEXT_WIDTH * (TEXT_HEIGHT - 1); i < TEXT_WIDTH * TEXT_HEIGHT; i++)
+    {
+      text_buf[i].code = ' ';
+      text_buf[i].fg_color = 0;
+      text_buf[i].bg_color = 0;
+      text_buf[i].width = 0;
+      text_buf[i].index = 0;
+    }
+
+  for (plane = 1; plane <= 4; plane++)
+    {
+      set_read_map (plane);
+      set_map_mask (1 << plane);
+      grub_memmove (VGA_MEM + PAGE_OFFSET (1 - page), VGA_MEM
+		    + PAGE_OFFSET (page) + VGA_WIDTH * CHAR_HEIGHT / 8,
+		    VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8);
+    }
+
+  set_map_mask (0x0f);
+  grub_memset (VGA_MEM + PAGE_OFFSET (1 - page)
+	       + VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8, 0,
+	       VGA_WIDTH * CHAR_HEIGHT / 8);
+
+  /* Activate the other page.  */
+  page = 1 - page;
+  wait_vretrace ();
+  set_start_address (PAGE_OFFSET (page));
+}
+
+static void
+grub_vga_putchar (grub_uint32_t c)
+{
+#if DEBUG_VGA
+  static int show = 1;
+#endif
+
+  if (c == '\a')
+    /* FIXME */
+    return;
+
+  if (c == '\b' || c == '\n' || c == '\r')
+    {
+      /* Erase current cursor, if any.  */
+      if (cursor_state)
+	write_char ();
+
+      switch (c)
+	{
+	case '\b':
+	  if (xpos > 0)
+	    xpos--;
+	  break;
+
+	case '\n':
+	  if (ypos >= TEXT_HEIGHT - 1)
+	    scroll_up ();
+	  else
+	    ypos++;
+	  break;
+
+	case '\r':
+	  xpos = 0;
+	  break;
+	}
+
+      if (cursor_state)
+	write_cursor ();
+    }
+  else
+    {
+      struct grub_font_glyph *glyph;
+      struct colored_char *p;
+      unsigned char_width = 1;
+
+      glyph = grub_font_get_glyph(font, c);
+
+      if (xpos + char_width > TEXT_WIDTH)
+	grub_putchar ('\n');
+
+      p = text_buf + xpos + ypos * TEXT_WIDTH;
+      p->code = c;
+      p->fg_color = fg_color;
+      p->bg_color = bg_color;
+      p->width = char_width - 1;
+      p->index = 0;
+
+      if (char_width > 1)
+	{
+	  unsigned i;
+
+	  for (i = 1; i < char_width; i++)
+	    {
+	      p[i].code = ' ';
+	      p[i].width = char_width - 1;
+	      p[i].index = i;
+	    }
+	}
+
+      write_char ();
+
+      xpos += char_width;
+      if (xpos >= TEXT_WIDTH)
+	{
+	  xpos = 0;
+
+	  if (ypos >= TEXT_HEIGHT - 1)
+	    scroll_up ();
+	  else
+	    ypos++;
+	}
+
+      if (cursor_state)
+	write_cursor ();
+    }
+
+#if DEBUG_VGA
+  if (show)
+    {
+      grub_uint16_t pos = grub_getxy ();
+
+      show = 0;
+      grub_gotoxy (0, 0);
+      grub_printf ("[%u:%u]", (unsigned) (pos >> 8), (unsigned) (pos & 0xff));
+      grub_gotoxy (pos >> 8, pos & 0xff);
+      show = 1;
+    }
+#endif
+}
+
+static grub_ssize_t
+grub_vga_getcharwidth (grub_uint32_t c)
+{
+#if 0
+  struct grub_font_glyph glyph;
+
+  glyph = grub_font_get_glyph (c);
+
+  return glyph.char_width;
+#else
+  (void) c;   /* Prevent warning.  */
+  return 1;   /* TODO Fix wide characters?  */
+#endif
+}
+
+static grub_uint16_t
+grub_vga_getwh (void)
+{
+  return (TEXT_WIDTH << 8) | TEXT_HEIGHT;
+}
+
+static grub_uint16_t
+grub_vga_getxy (void)
+{
+  return ((xpos << 8) | ypos);
+}
+
+static void
+grub_vga_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  if (x >= TEXT_WIDTH || y >= TEXT_HEIGHT)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)",
+		  (unsigned) x, (unsigned) y);
+      return;
+    }
+
+  if (cursor_state)
+    write_char ();
+
+  xpos = x;
+  ypos = y;
+
+  if (cursor_state)
+    write_cursor ();
+}
+
+static void
+grub_vga_cls (void)
+{
+  unsigned i;
+
+  wait_vretrace ();
+  for (i = 0; i < TEXT_WIDTH * TEXT_HEIGHT; i++)
+    {
+      text_buf[i].code = ' ';
+      text_buf[i].fg_color = 0;
+      text_buf[i].bg_color = 0;
+      text_buf[i].width = 0;
+      text_buf[i].index = 0;
+    }
+
+  grub_memset (VGA_MEM + PAGE_OFFSET (page), 0, VGA_WIDTH * VGA_HEIGHT / 8);
+
+  xpos = ypos = 0;
+}
+
+static void
+grub_vga_setcolorstate (grub_term_color_state state)
+{
+  switch (state)
+    {
+    case GRUB_TERM_COLOR_STANDARD:
+    case GRUB_TERM_COLOR_NORMAL:
+      fg_color = DEFAULT_FG_COLOR;
+      bg_color = DEFAULT_BG_COLOR;
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      fg_color = DEFAULT_BG_COLOR;
+      bg_color = DEFAULT_FG_COLOR;
+      break;
+    default:
+      break;
+    }
+}
+
+static void
+grub_vga_setcursor (int on)
+{
+  if (cursor_state != on)
+    {
+      if (cursor_state)
+	write_char ();
+      else
+	write_cursor ();
+
+      cursor_state = on;
+    }
+}
+
+static struct grub_term_output grub_vga_term =
+  {
+    .name = "vga",
+    .init = grub_vga_mod_init,
+    .fini = grub_vga_mod_fini,
+    .putchar = grub_vga_putchar,
+    .getcharwidth = grub_vga_getcharwidth,
+    .getwh = grub_vga_getwh,
+    .getxy = grub_vga_getxy,
+    .gotoxy = grub_vga_gotoxy,
+    .cls = grub_vga_cls,
+    .setcolorstate = grub_vga_setcolorstate,
+    .setcursor = grub_vga_setcursor,
+    .flags = 0,
+  };
+
+GRUB_MOD_INIT(vga)
+{
+  grub_term_register_output ("vga", &grub_vga_term);
+}
+
+GRUB_MOD_FINI(vga)
+{
+  grub_term_unregister_output (&grub_vga_term);
+}
diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c
new file mode 100644
index 0000000..170f74d
--- /dev/null
+++ b/term/i386/pc/vga_text.c
@@ -0,0 +1,177 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007, 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/i386/vga_common.h>
+#include <grub/i386/io.h>
+#include <grub/types.h>
+
+#define COLS	80
+#define ROWS	25
+
+static int grub_curr_x, grub_curr_y;
+
+#define VGA_TEXT_SCREEN		0xb8000
+
+#define CRTC_ADDR_PORT		0x3D4
+#define CRTC_DATA_PORT		0x3D5
+
+#define CRTC_CURSOR		0x0a
+#define CRTC_CURSOR_ADDR_HIGH	0x0e
+#define CRTC_CURSOR_ADDR_LOW	0x0f
+
+#define CRTC_CURSOR_DISABLE	(1 << 5)
+
+static void
+screen_write_char (int x, int y, short c)
+{
+  ((short *) VGA_TEXT_SCREEN)[y * COLS + x] = c;
+}
+
+static short
+screen_read_char (int x, int y)
+{
+  return ((short *) VGA_TEXT_SCREEN)[y * COLS + x];
+}
+
+static void
+update_cursor (void)
+{
+  unsigned int pos = grub_curr_y * COLS + grub_curr_x;
+  grub_outb (CRTC_CURSOR_ADDR_HIGH, CRTC_ADDR_PORT);
+  grub_outb (pos >> 8, CRTC_DATA_PORT);
+  grub_outb (CRTC_CURSOR_ADDR_LOW, CRTC_ADDR_PORT);
+  grub_outb (pos & 0xFF, CRTC_DATA_PORT);
+}
+
+static void
+inc_y (void)
+{
+  grub_curr_x = 0;
+  if (grub_curr_y < ROWS - 1)
+    grub_curr_y++;
+  else
+    {
+      int x, y;
+      for (y = 0; y < ROWS; y++)
+        for (x = 0; x < COLS; x++)
+          screen_write_char (x, y, screen_read_char (x, y + 1));
+    }
+}
+
+static void
+inc_x (void)
+{
+  if (grub_curr_x >= COLS - 2)
+    inc_y ();
+  else
+    grub_curr_x++;
+}
+
+void
+grub_console_real_putchar (int c)
+{
+  switch (c)
+    {
+      case '\b':
+	if (grub_curr_x != 0)
+	  screen_write_char (grub_curr_x--, grub_curr_y, ' ');
+	break;
+      case '\n':
+	inc_y ();
+	break;
+      case '\r':
+	grub_curr_x = 0;
+	break;
+      default:
+	screen_write_char (grub_curr_x,
+			   grub_curr_y, c | (grub_console_cur_color << 8));
+	inc_x ();
+    }
+
+  update_cursor ();
+}
+
+static grub_uint16_t
+grub_vga_text_getxy (void)
+{
+  return (grub_curr_x << 8) | grub_curr_y;
+}
+
+static void
+grub_vga_text_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  grub_curr_x = x;
+  grub_curr_y = y;
+  update_cursor ();
+}
+
+static void
+grub_vga_text_cls (void)
+{
+  int i;
+  for (i = 0; i < ROWS * COLS; i++)
+    ((short *) VGA_TEXT_SCREEN)[i] = ' ' | (grub_console_cur_color << 8);
+  grub_vga_text_gotoxy (0, 0);
+}
+
+static void
+grub_vga_text_setcursor (int on)
+{
+  grub_uint8_t old;
+  grub_outb (CRTC_CURSOR, CRTC_ADDR_PORT);
+  old = grub_inb (CRTC_DATA_PORT);
+  if (on)
+    grub_outb (old & ~CRTC_CURSOR_DISABLE, CRTC_DATA_PORT);
+  else
+    grub_outb (old | CRTC_CURSOR_DISABLE, CRTC_DATA_PORT);
+}
+
+static grub_err_t
+grub_vga_text_init_fini (void)
+{
+  grub_vga_text_cls ();
+  return 0;
+}
+
+static struct grub_term_output grub_vga_text_term =
+  {
+    .name = "vga_text",
+    .init = grub_vga_text_init_fini,
+    .fini = grub_vga_text_init_fini,
+    .putchar = grub_console_putchar,
+    .getcharwidth = grub_console_getcharwidth,
+    .getwh = grub_console_getwh,
+    .getxy = grub_vga_text_getxy,
+    .gotoxy = grub_vga_text_gotoxy,
+    .cls = grub_vga_text_cls,
+    .setcolorstate = grub_console_setcolorstate,
+    .setcolor = grub_console_setcolor,
+    .getcolor = grub_console_getcolor,
+    .setcursor = grub_vga_text_setcursor,
+  };
+
+GRUB_MOD_INIT(vga_text)
+{
+  grub_term_register_output ("vga_text", &grub_vga_text_term);
+}
+
+GRUB_MOD_FINI(vga_text)
+{
+  grub_term_unregister_output (&grub_vga_text_term);
+}
diff --git a/term/i386/vga_common.c b/term/i386/vga_common.c
new file mode 100644
index 0000000..131b43a
--- /dev/null
+++ b/term/i386/vga_common.c
@@ -0,0 +1,125 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/i386/vga_common.h>
+#include <grub/term.h>
+#include <grub/types.h>
+
+grub_uint8_t grub_console_cur_color = 0x7;
+static grub_uint8_t grub_console_standard_color = 0x7;
+static grub_uint8_t grub_console_normal_color = 0x7;
+static grub_uint8_t grub_console_highlight_color = 0x70;
+
+static grub_uint32_t
+map_char (grub_uint32_t c)
+{
+  if (c > 0x7f)
+    {
+      /* Map some unicode characters to the VGA font, if possible.  */
+      switch (c)
+	{
+	case 0x2190:	/* left arrow */
+	  c = 0x1b;
+	  break;
+	case 0x2191:	/* up arrow */
+	  c = 0x18;
+	  break;
+	case 0x2192:	/* right arrow */
+	  c = 0x1a;
+	  break;
+	case 0x2193:	/* down arrow */
+	  c = 0x19;
+	  break;
+	case 0x2501:	/* horizontal line */
+	  c = 0xc4;
+	  break;
+	case 0x2503:	/* vertical line */
+	  c = 0xb3;
+	  break;
+	case 0x250F:	/* upper-left corner */
+	  c = 0xda;
+	  break;
+	case 0x2513:	/* upper-right corner */
+	  c = 0xbf;
+	  break;
+	case 0x2517:	/* lower-left corner */
+	  c = 0xc0;
+	  break;
+	case 0x251B:	/* lower-right corner */
+	  c = 0xd9;
+	  break;
+
+	default:
+	  c = '?';
+	  break;
+	}
+    }
+
+  return c;
+}
+
+void
+grub_console_putchar (grub_uint32_t c)
+{
+  grub_console_real_putchar (map_char (c));
+}
+
+grub_ssize_t
+grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
+{
+  /* For now, every printable character has the width 1.  */
+  return 1;
+}
+
+grub_uint16_t
+grub_console_getwh (void)
+{
+  return (80 << 8) | 25;
+}
+
+void
+grub_console_setcolorstate (grub_term_color_state state)
+{
+  switch (state) {
+    case GRUB_TERM_COLOR_STANDARD:
+      grub_console_cur_color = grub_console_standard_color;
+      break;
+    case GRUB_TERM_COLOR_NORMAL:
+      grub_console_cur_color = grub_console_normal_color;
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      grub_console_cur_color = grub_console_highlight_color;
+      break;
+    default:
+      break;
+  }
+}
+
+void
+grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
+{
+  grub_console_normal_color = normal_color;
+  grub_console_highlight_color = highlight_color;
+}
+
+void
+grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
+{
+  *normal_color = grub_console_normal_color;
+  *highlight_color = grub_console_highlight_color;
+}
diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c
new file mode 100644
index 0000000..c61e16e
--- /dev/null
+++ b/term/ieee1275/ofconsole.c
@@ -0,0 +1,432 @@
+/*  ofconsole.c -- Open Firmware console for GRUB.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/machine/console.h>
+#include <grub/ieee1275/ieee1275.h>
+
+static grub_ieee1275_ihandle_t stdout_ihandle;
+static grub_ieee1275_ihandle_t stdin_ihandle;
+
+static grub_uint8_t grub_ofconsole_width;
+static grub_uint8_t grub_ofconsole_height;
+
+static int grub_curr_x;
+static int grub_curr_y;
+
+static int grub_keybuf;
+static int grub_buflen;
+
+struct color
+{
+  int red;
+  int green;
+  int blue;
+};
+
+#define	MAX 0xff
+static struct color colors[8] =
+  {
+    { 0,   0,   0},
+    { MAX, 0,   0},
+    { 0,   MAX, 0},
+    { MAX, MAX, 0},
+    { 0,   0,   MAX},
+    { MAX, 0,   MAX},
+    { 0,   MAX, MAX},
+    { MAX, MAX, MAX}
+  };
+
+static grub_uint8_t grub_ofconsole_normal_color = 0x7;
+static grub_uint8_t grub_ofconsole_highlight_color = 0x70;
+
+/* Write control characters to the console.  */
+static void
+grub_ofconsole_writeesc (const char *str)
+{
+  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
+    return;
+
+  while (*str)
+    {
+      char chr = *(str++);
+      grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
+    }
+
+}
+
+static void
+grub_ofconsole_putchar (grub_uint32_t c)
+{
+  char chr = c;
+  if (c == '\n')
+    {
+      grub_curr_y++;
+      grub_curr_x = 0;
+    }
+  else
+    {
+      grub_curr_x++;
+      if (grub_curr_x > grub_ofconsole_width)
+        {
+          grub_putcode ('\n');
+          grub_curr_x++;
+        }
+    }
+  grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
+}
+
+static grub_ssize_t
+grub_ofconsole_getcharwidth (grub_uint32_t c __attribute__((unused)))
+{
+  return 1;
+}
+
+static void
+grub_ofconsole_setcolorstate (grub_term_color_state state)
+{
+  char setcol[20];
+  int fg;
+  int bg;
+
+  switch (state)
+    {
+    case GRUB_TERM_COLOR_STANDARD:
+    case GRUB_TERM_COLOR_NORMAL:
+      fg = grub_ofconsole_normal_color & 0x0f;
+      bg = grub_ofconsole_normal_color >> 4;
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      fg = grub_ofconsole_highlight_color & 0x0f;
+      bg = grub_ofconsole_highlight_color >> 4;
+      break;
+    default:
+      return;
+    }
+
+  grub_sprintf (setcol, "\e[3%dm\e[4%dm", fg, bg);
+  grub_ofconsole_writeesc (setcol);
+}
+
+static void
+grub_ofconsole_setcolor (grub_uint8_t normal_color,
+			 grub_uint8_t highlight_color)
+{
+  grub_ofconsole_normal_color = normal_color;
+  grub_ofconsole_highlight_color = highlight_color;
+}
+
+static void
+grub_ofconsole_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
+{
+  *normal_color = grub_ofconsole_normal_color;
+  *highlight_color = grub_ofconsole_highlight_color;
+}
+
+static int
+grub_ofconsole_readkey (int *key)
+{
+  char c;
+  grub_ssize_t actual = 0;
+
+  grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
+
+  if (actual > 0 && c == '\e')
+    {
+      grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
+      if (actual <= 0)
+	{
+	  *key = '\e';
+	  return 1;
+	}
+
+      if (c != 91)
+	return 0;
+
+      grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
+      if (actual <= 0)
+	return 0;
+
+      switch (c)
+	{
+	case 65:
+	  /* Up: Ctrl-p.  */
+	  c = 16;
+	  break;
+	case 66:
+	  /* Down: Ctrl-n.  */
+	  c = 14;
+	  break;
+	case 67:
+	  /* Right: Ctrl-f.  */
+	  c = 6;
+	  break;
+	case 68:
+	  /* Left: Ctrl-b.  */
+	  c = 2;
+	  break;
+	}
+    }
+
+  *key = c;
+  return actual > 0;
+}
+
+static int
+grub_ofconsole_checkkey (void)
+{
+  int key;
+  int read;
+
+  if (grub_buflen)
+    return 1;
+
+  read = grub_ofconsole_readkey (&key);
+  if (read)
+    {
+      grub_keybuf = key;
+      grub_buflen = 1;
+      return 1;
+    }
+
+  return -1;
+}
+
+static int
+grub_ofconsole_getkey (void)
+{
+  int key;
+
+  if (grub_buflen)
+    {
+      grub_buflen  =0;
+      return grub_keybuf;
+    }
+
+  while (! grub_ofconsole_readkey (&key));
+
+  return key;
+}
+
+static grub_uint16_t
+grub_ofconsole_getxy (void)
+{
+  return ((grub_curr_x - 1) << 8) | grub_curr_y;
+}
+
+static grub_uint16_t
+grub_ofconsole_getwh (void)
+{
+  grub_ieee1275_ihandle_t options;
+  char *val;
+  grub_ssize_t lval;
+
+  if (grub_ofconsole_width && grub_ofconsole_height)
+    return (grub_ofconsole_width << 8) | grub_ofconsole_height;
+
+  if (! grub_ieee1275_finddevice ("/options", &options)
+      && options != (grub_ieee1275_ihandle_t) -1)
+    {
+      if (! grub_ieee1275_get_property_length (options, "screen-#columns",
+					       &lval) && lval != -1)
+	{
+	  val = grub_malloc (lval);
+	  if (val)
+	    {
+	      if (! grub_ieee1275_get_property (options, "screen-#columns",
+						val, lval, 0))
+		grub_ofconsole_width = (grub_uint8_t) grub_strtoul (val, 0, 10);
+
+	      grub_free (val);
+	    }
+	}
+      if (! grub_ieee1275_get_property_length (options, "screen-#rows",
+					       &lval) && lval != -1)
+	{
+	  val = grub_malloc (lval);
+	  if (val)
+	    {
+	      if (! grub_ieee1275_get_property (options, "screen-#rows",
+						val, lval, 0))
+		grub_ofconsole_height = (grub_uint8_t) grub_strtoul (val, 0, 10);
+
+	      grub_free (val);
+	    }
+	}
+    }
+
+  /* Use a small console by default.  */
+  if (! grub_ofconsole_width)
+    grub_ofconsole_width = 80;
+  if (! grub_ofconsole_height)
+    grub_ofconsole_height = 24;
+
+  return (grub_ofconsole_width << 8) | grub_ofconsole_height;
+}
+
+static void
+grub_ofconsole_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  char s[11]; /* 5 + 3 + 3.  */
+
+  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
+    {
+      grub_curr_x = x;
+      grub_curr_y = y;
+
+      grub_sprintf (s, "\e[%d;%dH", y + 1, x + 1);
+      grub_ofconsole_writeesc (s);
+    }
+  else
+    {
+      if ((y == grub_curr_y) && (x == grub_curr_x - 1))
+        {
+          char chr;
+
+          chr = '\b';
+          grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
+        }
+
+      grub_curr_x = x;
+      grub_curr_y = y;
+    }
+}
+
+static void
+grub_ofconsole_cls (void)
+{
+  /* Clear the screen.  Using serial console, screen(1) only recognizes the
+   * ANSI escape sequence.  Using video console, Apple Open Firmware (version
+   * 3.1.1) only recognizes the literal ^L.  So use both.  */
+  grub_ofconsole_writeesc ("\e[2J");
+  grub_gotoxy (0, 0);
+}
+
+static void
+grub_ofconsole_setcursor (int on)
+{
+  /* Understood by the Open Firmware flavour in OLPC.  */
+  if (on)
+    grub_ieee1275_interpret ("cursor-on", 0);
+  else
+    grub_ieee1275_interpret ("cursor-off", 0);
+}
+
+static void
+grub_ofconsole_refresh (void)
+{
+  /* Do nothing, the current console state is ok.  */
+}
+
+static grub_err_t
+grub_ofconsole_init_input (void)
+{
+  grub_ssize_t actual;
+
+  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdin", &stdin_ihandle,
+					  sizeof stdin_ihandle, &actual)
+      || actual != sizeof stdin_ihandle)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdin");
+
+  return 0;
+}
+
+static grub_err_t
+grub_ofconsole_init_output (void)
+{
+  grub_ssize_t actual;
+  int col;
+
+  /* The latest PowerMacs don't actually initialize the screen for us, so we
+   * use this trick to re-open the output device (but we avoid doing this on
+   * platforms where it's known to be broken). */
+  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT))
+    grub_ieee1275_interpret ("output-device output", 0);
+
+  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdout", &stdout_ihandle,
+					  sizeof stdout_ihandle, &actual)
+      || actual != sizeof stdout_ihandle)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdout");
+
+  /* Initialize colors.  */
+  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS))
+    {
+      for (col = 0; col < 7; col++)
+	grub_ieee1275_set_color (stdout_ihandle, col, colors[col].red,
+				 colors[col].green, colors[col].blue);
+
+    /* Set the right fg and bg colors.  */
+      grub_ofconsole_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_ofconsole_fini (void)
+{
+  return 0;
+}
+
+
+
+static struct grub_term_input grub_ofconsole_term_input =
+  {
+    .name = "ofconsole",
+    .init = grub_ofconsole_init_input,
+    .fini = grub_ofconsole_fini,
+    .checkkey = grub_ofconsole_checkkey,
+    .getkey = grub_ofconsole_getkey,
+  };
+
+static struct grub_term_output grub_ofconsole_term_output =
+  {
+    .name = "ofconsole",
+    .init = grub_ofconsole_init_output,
+    .fini = grub_ofconsole_fini,
+    .putchar = grub_ofconsole_putchar,
+    .getcharwidth = grub_ofconsole_getcharwidth,
+    .getxy = grub_ofconsole_getxy,
+    .getwh = grub_ofconsole_getwh,
+    .gotoxy = grub_ofconsole_gotoxy,
+    .cls = grub_ofconsole_cls,
+    .setcolorstate = grub_ofconsole_setcolorstate,
+    .setcolor = grub_ofconsole_setcolor,
+    .getcolor = grub_ofconsole_getcolor,
+    .setcursor = grub_ofconsole_setcursor,
+    .refresh = grub_ofconsole_refresh,
+    .flags = 0,
+  };
+
+void
+grub_console_init (void)
+{
+  grub_term_register_input ("ofconsole", &grub_ofconsole_term_input);
+  grub_term_register_output ("ofconsole", &grub_ofconsole_term_output);
+}
+
+void
+grub_console_fini (void)
+{
+  grub_term_unregister_input (&grub_ofconsole_term_input);
+  grub_term_unregister_output (&grub_ofconsole_term_output);
+}
diff --git a/term/terminfo.c b/term/terminfo.c
new file mode 100644
index 0000000..80ae9b1
--- /dev/null
+++ b/term/terminfo.c
@@ -0,0 +1,188 @@
+/* terminfo.c - simple terminfo module */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This file contains various functions dealing with different
+ * terminal capabilities. For example, vt52 and vt100.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/term.h>
+#include <grub/terminfo.h>
+#include <grub/tparm.h>
+#include <grub/command.h>
+
+struct terminfo
+{
+  char *name;
+
+  char *gotoxy;
+  char *cls;
+  char *reverse_video_on;
+  char *reverse_video_off;
+  char *cursor_on;
+  char *cursor_off;
+};
+
+static struct terminfo term;
+
+/* Get current terminfo name.  */
+char *
+grub_terminfo_get_current (void)
+{
+  return term.name;
+}
+
+/* Free *PTR and set *PTR to NULL, to prevent double-free.  */
+static void
+grub_terminfo_free (char **ptr)
+{
+  grub_free (*ptr);
+  *ptr = 0;
+}
+
+/* Set current terminfo type.  */
+grub_err_t
+grub_terminfo_set_current (const char *str)
+{
+  /* TODO
+   * Lookup user specified terminfo type. If found, set term variables
+   * as appropriate. Otherwise return an error.
+   *
+   * How should this be done?
+   *  a. A static table included in this module.
+   *     - I do not like this idea.
+   *  b. A table stored in the configuration directory.
+   *     - Users must convert their terminfo settings if we have not already.
+   *  c. Look for terminfo files in the configuration directory.
+   *     - /usr/share/terminfo is 6.3M on my system.
+   *     - /usr/share/terminfo is not on most users boot partition.
+   *     + Copying the terminfo files you want to use to the grub
+   *       configuration directory is easier then (b).
+   *  d. Your idea here.
+   */
+
+  /* Free previously allocated memory.  */
+  grub_terminfo_free (&term.name);
+  grub_terminfo_free (&term.gotoxy);
+  grub_terminfo_free (&term.cls);
+  grub_terminfo_free (&term.reverse_video_on);
+  grub_terminfo_free (&term.reverse_video_off);
+  grub_terminfo_free (&term.cursor_on);
+  grub_terminfo_free (&term.cursor_off);
+
+  if (grub_strcmp ("vt100", str) == 0)
+    {
+      term.name              = grub_strdup ("vt100");
+      term.gotoxy            = grub_strdup ("\e[%i%p1%d;%p2%dH");
+      term.cls               = grub_strdup ("\e[H\e[J");
+      term.reverse_video_on  = grub_strdup ("\e[7m");
+      term.reverse_video_off = grub_strdup ("\e[m");
+      term.cursor_on         = grub_strdup ("\e[?25h");
+      term.cursor_off        = grub_strdup ("\e[?25l");
+      return grub_errno;
+    }
+
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type.");
+}
+
+/* Wrapper for grub_putchar to write strings.  */
+static void
+putstr (const char *str)
+{
+  while (*str)
+    grub_putchar (*str++);
+}
+
+/* Move the cursor to the given position starting with "0".  */
+void
+grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  putstr (grub_terminfo_tparm (term.gotoxy, y, x));
+}
+
+/* Clear the screen.  */
+void
+grub_terminfo_cls (void)
+{
+  putstr (grub_terminfo_tparm (term.cls));
+}
+
+/* Set reverse video mode on.  */
+void
+grub_terminfo_reverse_video_on (void)
+{
+  putstr (grub_terminfo_tparm (term.reverse_video_on));
+}
+
+/* Set reverse video mode off.  */
+void
+grub_terminfo_reverse_video_off (void)
+{
+  putstr (grub_terminfo_tparm (term.reverse_video_off));
+}
+
+/* Show cursor.  */
+void
+grub_terminfo_cursor_on (void)
+{
+  putstr (grub_terminfo_tparm (term.cursor_on));
+}
+
+/* Hide cursor.  */
+void
+grub_terminfo_cursor_off (void)
+{
+  putstr (grub_terminfo_tparm (term.cursor_off));
+}
+
+/* GRUB Command.  */
+
+static grub_err_t
+grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)),
+		   int argc, char **args)
+{
+  if (argc == 0)
+  {
+    grub_printf ("Current terminfo type: %s\n", grub_terminfo_get_current());
+    return GRUB_ERR_NONE;
+  }
+  else if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters.");
+  else
+    return grub_terminfo_set_current (args[0]);
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(terminfo)
+{
+  cmd = grub_register_command ("terminfo", grub_cmd_terminfo,
+			       "terminfo [TERM]", "Set terminfo type.");
+  grub_terminfo_set_current ("vt100");
+}
+
+GRUB_MOD_FINI(terminfo)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/term/tparm.c b/term/tparm.c
new file mode 100644
index 0000000..53f9285
--- /dev/null
+++ b/term/tparm.c
@@ -0,0 +1,758 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1998-2003,2004,2005 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**********************************************************************
+ * This code is a modification of lib_tparm.c found in ncurses-5.2. The
+ * modification are for use in grub by replacing all libc function through
+ * special grub functions. This also meant to delete all dynamic memory
+ * allocation and replace it by a number of fixed buffers.
+ *
+ * Modifications by Tilmann Bubeck <t.bubeck@reinform.de> 2002
+ *
+ * Resync with ncurses-5.4 by Omniflux <omniflux+devel@omniflux.com> 2005
+ **********************************************************************/
+
+/****************************************************************************
+ *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
+ *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
+ *     and: Thomas E. Dickey, 1996 on                                       *
+ ****************************************************************************/
+
+/*
+ *	tparm.c
+ *
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/tparm.h>
+
+/*
+ * Common/troublesome character definitions
+ */
+typedef char grub_bool_t;
+#ifndef FALSE
+# define FALSE (0)
+#endif
+#ifndef TRUE
+# define TRUE (!FALSE)
+#endif
+
+#define NUM_PARM 9
+#define NUM_VARS 26
+#define STACKSIZE 20
+#define MAX_FORMAT_LEN 256
+
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#define isdigit(c) ((c) >= '0' && (c) <= '9')
+#define isUPPER(c) ((c) >= 'A' && (c) <= 'Z')
+#define isLOWER(c) ((c) >= 'a' && (c) <= 'z')
+
+#define UChar(c) ((unsigned char)(c))
+
+//MODULE_ID("$Id: tparm.c 2629 2009-10-12 21:53:15Z robertmh $")
+
+/*
+ *	char *
+ *	tparm(string, ...)
+ *
+ *	Substitute the given parameters into the given string by the following
+ *	rules (taken from terminfo(5)):
+ *
+ *	     Cursor addressing and other strings  requiring  parame-
+ *	ters in the terminal are described by a parameterized string
+ *	capability, with like escapes %x in  it.   For  example,  to
+ *	address  the  cursor, the cup capability is given, using two
+ *	parameters: the row and column to  address  to.   (Rows  and
+ *	columns  are  numbered  from  zero and refer to the physical
+ *	screen visible to the user, not to any  unseen  memory.)  If
+ *	the terminal has memory relative cursor addressing, that can
+ *	be indicated by
+ *
+ *	     The parameter mechanism uses  a  stack  and  special  %
+ *	codes  to manipulate it.  Typically a sequence will push one
+ *	of the parameters onto the stack and then print it  in  some
+ *	format.  Often more complex operations are necessary.
+ *
+ *	     The % encodings have the following meanings:
+ *
+ *	     %%        outputs `%'
+ *	     %c        print pop() like %c in printf()
+ *	     %s        print pop() like %s in printf()
+ *           %[[:]flags][width[.precision]][doxXs]
+ *                     as in printf, flags are [-+#] and space
+ *                     The ':' is used to avoid making %+ or %-
+ *                     patterns (see below).
+ *
+ *	     %p[1-9]   push ith parm
+ *	     %P[a-z]   set dynamic variable [a-z] to pop()
+ *	     %g[a-z]   get dynamic variable [a-z] and push it
+ *	     %P[A-Z]   set static variable [A-Z] to pop()
+ *	     %g[A-Z]   get static variable [A-Z] and push it
+ *	     %l        push strlen(pop)
+ *	     %'c'      push char constant c
+ *	     %{nn}     push integer constant nn
+ *
+ *	     %+ %- %* %/ %m
+ *	               arithmetic (%m is mod): push(pop() op pop())
+ *	     %& %| %^  bit operations: push(pop() op pop())
+ *	     %= %> %<  logical operations: push(pop() op pop())
+ *	     %A %O     logical and & or operations for conditionals
+ *	     %! %~     unary operations push(op pop())
+ *	     %i        add 1 to first two parms (for ANSI terminals)
+ *
+ *	     %? expr %t thenpart %e elsepart %;
+ *	               if-then-else, %e elsepart is optional.
+ *	               else-if's are possible ala Algol 68:
+ *	               %? c1 %t b1 %e c2 %t b2 %e c3 %t b3 %e c4 %t b4 %e b5 %;
+ *
+ *	For those of the above operators which are binary and not commutative,
+ *	the stack works in the usual way, with
+ *			%gx %gy %m
+ *	resulting in x mod y, not the reverse.
+ */
+
+typedef struct {
+    union {
+	int num;
+	char *str;
+    } data;
+    grub_bool_t num_type;
+} stack_frame;
+
+static stack_frame stack[STACKSIZE];
+static int stack_ptr;
+static const char *tparam_base = "";
+
+static char *out_buff;
+static grub_size_t out_size;
+static grub_size_t out_used;
+
+static char *fmt_buff;
+static grub_size_t fmt_size;
+
+static inline void
+get_space(grub_size_t need)
+{
+    need += out_used;
+    if (need > out_size) {
+	out_size = need * 2;
+	out_buff = grub_realloc(out_buff, out_size*sizeof(char));
+	/* FIX ME! handle out_buff == 0.  */
+    }
+}
+
+static inline void
+save_text(const char *fmt, const char *s, int len)
+{
+    grub_size_t s_len = grub_strlen(s);
+    if (len > (int) s_len)
+	s_len = len;
+
+    get_space(s_len + 1);
+
+    (void) grub_sprintf(out_buff + out_used, fmt, s);
+    out_used += grub_strlen(out_buff + out_used);
+}
+
+static inline void
+save_number(const char *fmt, int number, int len)
+{
+    if (len < 30)
+	len = 30;		/* actually log10(MAX_INT)+1 */
+
+    get_space((unsigned) len + 1);
+
+    (void) grub_sprintf(out_buff + out_used, fmt, number);
+    out_used += grub_strlen(out_buff + out_used);
+}
+
+static inline void
+save_char(int c)
+{
+    if (c == 0)
+	c = 0200;
+    get_space(1);
+    out_buff[out_used++] = c;
+}
+
+static inline void
+npush(int x)
+{
+    if (stack_ptr < STACKSIZE) {
+	stack[stack_ptr].num_type = TRUE;
+	stack[stack_ptr].data.num = x;
+	stack_ptr++;
+    }
+}
+
+static inline int
+npop(void)
+{
+    int result = 0;
+    if (stack_ptr > 0) {
+	stack_ptr--;
+	if (stack[stack_ptr].num_type)
+	    result = stack[stack_ptr].data.num;
+    }
+    return result;
+}
+
+static inline void
+spush(char *x)
+{
+    if (stack_ptr < STACKSIZE) {
+	stack[stack_ptr].num_type = FALSE;
+	stack[stack_ptr].data.str = x;
+	stack_ptr++;
+    }
+}
+
+static inline char *
+spop(void)
+{
+    static char dummy[] = "";	/* avoid const-cast */
+    char *result = dummy;
+    if (stack_ptr > 0) {
+	stack_ptr--;
+	if (!stack[stack_ptr].num_type && stack[stack_ptr].data.str != 0)
+	    result = stack[stack_ptr].data.str;
+    }
+    return result;
+}
+
+static inline const char *
+parse_format(const char *s, char *format, int *len)
+{
+    *len = 0;
+    if (format != 0) {
+	grub_bool_t done = FALSE;
+	grub_bool_t allowminus = FALSE;
+	grub_bool_t dot = FALSE;
+	grub_bool_t err = FALSE;
+	char *fmt = format;
+	int my_width = 0;
+	int my_prec = 0;
+	int value = 0;
+
+	*len = 0;
+	*format++ = '%';
+	while (*s != '\0' && !done) {
+	    switch (*s) {
+	    case 'c':		/* FALLTHRU */
+	    case 'd':		/* FALLTHRU */
+	    case 'o':		/* FALLTHRU */
+	    case 'x':		/* FALLTHRU */
+	    case 'X':		/* FALLTHRU */
+	    case 's':
+		*format++ = *s;
+		done = TRUE;
+		break;
+	    case '.':
+		*format++ = *s++;
+		if (dot) {
+		    err = TRUE;
+		} else {	/* value before '.' is the width */
+		    dot = TRUE;
+		    my_width = value;
+		}
+		value = 0;
+		break;
+	    case '#':
+		*format++ = *s++;
+		break;
+	    case ' ':
+		*format++ = *s++;
+		break;
+	    case ':':
+		s++;
+		allowminus = TRUE;
+		break;
+	    case '-':
+		if (allowminus) {
+		    *format++ = *s++;
+		} else {
+		    done = TRUE;
+		}
+		break;
+	    default:
+		if (isdigit(UChar(*s))) {
+		    value = (value * 10) + (*s - '0');
+		    if (value > 10000)
+			err = TRUE;
+		    *format++ = *s++;
+		} else {
+		    done = TRUE;
+		}
+	    }
+	}
+
+	/*
+	 * If we found an error, ignore (and remove) the flags.
+	 */
+	if (err) {
+	    my_width = my_prec = value = 0;
+	    format = fmt;
+	    *format++ = '%';
+	    *format++ = *s;
+	}
+
+	/*
+	 * Any value after '.' is the precision.  If we did not see '.', then
+	 * the value is the width.
+	 */
+	if (dot)
+	    my_prec = value;
+	else
+	    my_width = value;
+
+	*format = '\0';
+	/* return maximum string length in print */
+	*len = (my_width > my_prec) ? my_width : my_prec;
+    }
+    return s;
+}
+
+/*
+ * Analyze the string to see how many parameters we need from the varargs list,
+ * and what their types are.  We will only accept string parameters if they
+ * appear as a %l or %s format following an explicit parameter reference (e.g.,
+ * %p2%s).  All other parameters are numbers.
+ *
+ * 'number' counts coarsely the number of pop's we see in the string, and
+ * 'popcount' shows the highest parameter number in the string.  We would like
+ * to simply use the latter count, but if we are reading termcap strings, there
+ * may be cases that we cannot see the explicit parameter numbers.
+ */
+static inline int
+analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount)
+{
+    grub_size_t len2;
+    int i;
+    int lastpop = -1;
+    int len;
+    int number = 0;
+    const char *cp = string;
+    static char dummy[] = "";
+
+    *popcount = 0;
+
+    if (cp == 0)
+	return 0;
+
+    if ((len2 = grub_strlen(cp)) > fmt_size) {
+	fmt_size = len2 + fmt_size + 2;
+	if ((fmt_buff = grub_realloc(fmt_buff, fmt_size*sizeof(char))) == 0)
+	      return 0;
+    }
+
+    grub_memset(p_is_s, 0, sizeof(p_is_s[0]) * NUM_PARM);
+
+    while ((cp - string) < (int) len2) {
+	if (*cp == '%') {
+	    cp++;
+	    cp = parse_format(cp, fmt_buff, &len);
+	    switch (*cp) {
+	    default:
+		break;
+
+	    case 'd':		/* FALLTHRU */
+	    case 'o':		/* FALLTHRU */
+	    case 'x':		/* FALLTHRU */
+	    case 'X':		/* FALLTHRU */
+	    case 'c':		/* FALLTHRU */
+		if (lastpop <= 0)
+		    number++;
+		lastpop = -1;
+		break;
+
+	    case 'l':
+	    case 's':
+		if (lastpop > 0)
+		    p_is_s[lastpop - 1] = dummy;
+		++number;
+		break;
+
+	    case 'p':
+		cp++;
+		i = (UChar(*cp) - '0');
+		if (i >= 0 && i <= NUM_PARM) {
+		    lastpop = i;
+		    if (lastpop > *popcount)
+			*popcount = lastpop;
+		}
+		break;
+
+	    case 'P':
+		++number;
+		++cp;
+		break;
+
+	    case 'g':
+		cp++;
+		break;
+
+	    case '\'':
+		cp += 2;
+		lastpop = -1;
+		break;
+
+	    case '{':
+		cp++;
+		while (isdigit(UChar(*cp))) {
+		    cp++;
+		}
+		break;
+
+	    case '+':
+	    case '-':
+	    case '*':
+	    case '/':
+	    case 'm':
+	    case 'A':
+	    case 'O':
+	    case '&':
+	    case '|':
+	    case '^':
+	    case '=':
+	    case '<':
+	    case '>':
+		lastpop = -1;
+		number += 2;
+		break;
+
+	    case '!':
+	    case '~':
+		lastpop = -1;
+		++number;
+		break;
+
+	    case 'i':
+		/* will add 1 to first (usually two) parameters */
+		break;
+	    }
+	}
+	if (*cp != '\0')
+	    cp++;
+    }
+
+    if (number > NUM_PARM)
+	number = NUM_PARM;
+    return number;
+}
+
+static inline char *
+tparam_internal(const char *string, va_list ap)
+{
+    char *p_is_s[NUM_PARM];
+    long param[NUM_PARM];
+    int popcount;
+    int number;
+    int len;
+    int level;
+    int x, y;
+    int i;
+    const char *cp = string;
+    grub_size_t len2;
+    static int dynamic_var[NUM_VARS];
+    static int static_vars[NUM_VARS];
+
+    if (cp == 0)
+	return 0;
+
+    out_used = out_size = fmt_size = 0;
+
+    len2 = (int) grub_strlen(cp);
+
+    /*
+     * Find the highest parameter-number referred to in the format string.
+     * Use this value to limit the number of arguments copied from the
+     * variable-length argument list.
+     */
+    number = analyze(cp, p_is_s, &popcount);
+    if (fmt_buff == 0)
+	return 0;
+
+    for (i = 0; i < max(popcount, number); i++) {
+	/*
+	 * A few caps (such as plab_norm) have string-valued parms.
+	 * We'll have to assume that the caller knows the difference, since
+	 * a char* and an int may not be the same size on the stack.
+	 */
+	if (p_is_s[i] != 0) {
+	    p_is_s[i] = va_arg(ap, char *);
+	} else {
+	    param[i] = va_arg(ap, long int);
+	}
+    }
+
+    /*
+     * This is a termcap compatibility hack.  If there are no explicit pop
+     * operations in the string, load the stack in such a way that
+     * successive pops will grab successive parameters.  That will make
+     * the expansion of (for example) \E[%d;%dH work correctly in termcap
+     * style, which means tparam() will expand termcap strings OK.
+     */
+    stack_ptr = 0;
+    if (popcount == 0) {
+	popcount = number;
+	for (i = number - 1; i >= 0; i--)
+	    npush(param[i]);
+    }
+
+    while ((cp - string) < (int) len2) {
+	if (*cp != '%') {
+	    save_char(UChar(*cp));
+	} else {
+	    tparam_base = cp++;
+	    cp = parse_format(cp, fmt_buff, &len);
+	    switch (*cp) {
+	    default:
+		break;
+	    case '%':
+		save_char('%');
+		break;
+
+	    case 'd':		/* FALLTHRU */
+	    case 'o':		/* FALLTHRU */
+	    case 'x':		/* FALLTHRU */
+	    case 'X':		/* FALLTHRU */
+		save_number(fmt_buff, npop(), len);
+		break;
+
+	    case 'c':		/* FALLTHRU */
+		save_char(npop());
+		break;
+
+	    case 'l':
+		save_number("%d", (int) grub_strlen(spop()), 0);
+		break;
+
+	    case 's':
+		save_text(fmt_buff, spop(), len);
+		break;
+
+	    case 'p':
+		cp++;
+		i = (UChar(*cp) - '1');
+		if (i >= 0 && i < NUM_PARM) {
+		    if (p_is_s[i])
+			spush(p_is_s[i]);
+		    else
+			npush(param[i]);
+		}
+		break;
+
+	    case 'P':
+		cp++;
+		if (isUPPER(*cp)) {
+		    i = (UChar(*cp) - 'A');
+		    static_vars[i] = npop();
+		} else if (isLOWER(*cp)) {
+		    i = (UChar(*cp) - 'a');
+		    dynamic_var[i] = npop();
+		}
+		break;
+
+	    case 'g':
+		cp++;
+		if (isUPPER(*cp)) {
+		    i = (UChar(*cp) - 'A');
+		    npush(static_vars[i]);
+		} else if (isLOWER(*cp)) {
+		    i = (UChar(*cp) - 'a');
+		    npush(dynamic_var[i]);
+		}
+		break;
+
+	    case '\'':
+		cp++;
+		npush(UChar(*cp));
+		cp++;
+		break;
+
+	    case '{':
+		number = 0;
+		cp++;
+		while (isdigit(UChar(*cp))) {
+		    number = (number * 10) + (UChar(*cp) - '0');
+		    cp++;
+		}
+		npush(number);
+		break;
+
+	    case '+':
+		npush(npop() + npop());
+		break;
+
+	    case '-':
+		y = npop();
+		x = npop();
+		npush(x - y);
+		break;
+
+	    case '*':
+		npush(npop() * npop());
+		break;
+
+	    case '/':
+		y = npop();
+		x = npop();
+		npush(y ? (x / y) : 0);
+		break;
+
+	    case 'm':
+		y = npop();
+		x = npop();
+		npush(y ? (x % y) : 0);
+		break;
+
+	    case 'A':
+		npush(npop() && npop());
+		break;
+
+	    case 'O':
+		npush(npop() || npop());
+		break;
+
+	    case '&':
+		npush(npop() & npop());
+		break;
+
+	    case '|':
+		npush(npop() | npop());
+		break;
+
+	    case '^':
+		npush(npop() ^ npop());
+		break;
+
+	    case '=':
+		y = npop();
+		x = npop();
+		npush(x == y);
+		break;
+
+	    case '<':
+		y = npop();
+		x = npop();
+		npush(x < y);
+		break;
+
+	    case '>':
+		y = npop();
+		x = npop();
+		npush(x > y);
+		break;
+
+	    case '!':
+		npush(!npop());
+		break;
+
+	    case '~':
+		npush(~npop());
+		break;
+
+	    case 'i':
+		if (p_is_s[0] == 0)
+		    param[0]++;
+		if (p_is_s[1] == 0)
+		    param[1]++;
+		break;
+
+	    case '?':
+		break;
+
+	    case 't':
+		x = npop();
+		if (!x) {
+		    /* scan forward for %e or %; at level zero */
+		    cp++;
+		    level = 0;
+		    while (*cp) {
+			if (*cp == '%') {
+			    cp++;
+			    if (*cp == '?')
+				level++;
+			    else if (*cp == ';') {
+				if (level > 0)
+				    level--;
+				else
+				    break;
+			    } else if (*cp == 'e' && level == 0)
+				break;
+			}
+
+			if (*cp)
+			    cp++;
+		    }
+		}
+		break;
+
+	    case 'e':
+		/* scan forward for a %; at level zero */
+		cp++;
+		level = 0;
+		while (*cp) {
+		    if (*cp == '%') {
+			cp++;
+			if (*cp == '?')
+			    level++;
+			else if (*cp == ';') {
+			    if (level > 0)
+				level--;
+			    else
+				break;
+			}
+		    }
+
+		    if (*cp)
+			cp++;
+		}
+		break;
+
+	    case ';':
+		break;
+
+	    }			/* endswitch (*cp) */
+	}			/* endelse (*cp == '%') */
+
+	if (*cp == '\0')
+	    break;
+
+	cp++;
+    }				/* endwhile (*cp) */
+
+    get_space(1);
+    out_buff[out_used] = '\0';
+
+    return (out_buff);
+}
+
+char *
+grub_terminfo_tparm (const char *string, ...)
+{
+    va_list ap;
+    char *result;
+
+    va_start (ap, string);
+    result = tparam_internal (string, ap);
+    va_end (ap);
+    return result;
+}
diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c
new file mode 100644
index 0000000..76b9bc3
--- /dev/null
+++ b/term/usb_keyboard.c
@@ -0,0 +1,330 @@
+/* Support for the HID Boot Protocol.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/machine/machine.h>
+#include <grub/machine/console.h>
+#include <grub/time.h>
+#include <grub/cpu/io.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/usb.h>
+#include <grub/dl.h>
+#include <grub/time.h>
+
+
+static char keyboard_map[128] =
+  {
+    '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd',
+    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+    'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+    'u', 'v', 'w', 'x', 'y', 'z', '1', '2',
+    '3', '4', '5', '6', '7', '8', '9', '0',
+    '\n', GRUB_TERM_ESC, GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, ' ', '-', '=', '[',
+    ']', '\\', '#', ';', '\'', '`', ',', '.',
+    '/', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', GRUB_TERM_HOME, GRUB_TERM_PPAGE, GRUB_TERM_DC, GRUB_TERM_END, GRUB_TERM_NPAGE, GRUB_TERM_RIGHT,
+    GRUB_TERM_LEFT, GRUB_TERM_DOWN, GRUB_TERM_UP
+  };
+
+static char keyboard_map_shift[128] =
+  {
+    '\0', '\0', '\0', '\0', 'A', 'B', 'C', 'D',
+    'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+    'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+    'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@',
+    '#', '$', '%', '^', '&', '*', '(', ')',
+    '\n', '\0', '\0', '\0', ' ', '_', '+', '{',
+    '}', '|', '#', ':', '"', '`', '<', '>',
+    '?'
+  };
+
+static grub_usb_device_t usbdev;
+
+/* Valid values for bmRequestType.  See HID definition version 1.11 section
+   7.2.  */
+#define USB_HID_HOST_TO_DEVICE	0x21
+#define USB_HID_DEVICE_TO_HOST	0xA1
+
+/* Valid values for bRequest.  See HID definition version 1.11 section 7.2. */
+#define USB_HID_GET_REPORT	0x01
+#define USB_HID_GET_IDLE	0x02
+#define USB_HID_GET_PROTOCOL	0x03
+#define USB_HID_SET_REPORT	0x09
+#define USB_HID_SET_IDLE	0x0A
+#define USB_HID_SET_PROTOCOL	0x0B
+
+static void
+grub_usb_hid (void)
+{
+  struct grub_usb_desc_device *descdev;
+
+  auto int usb_iterate (grub_usb_device_t dev);
+  int usb_iterate (grub_usb_device_t dev)
+    {
+      descdev = &dev->descdev;
+
+      grub_dprintf ("usb_keyboard", "%x %x %x\n",
+		   descdev->class, descdev->subclass, descdev->protocol);
+
+#if 0
+      if (descdev->class != 0x09
+	  || descdev->subclass == 0x01
+	  || descdev->protocol != 0x02)
+	return 0;
+#endif
+
+      if (descdev->class != 0 || descdev->subclass != 0 || descdev->protocol != 0)
+	return 0;
+
+      grub_printf ("HID found!\n");
+
+      usbdev = dev;
+
+      return 1;
+    }
+  grub_usb_iterate (usb_iterate);
+
+  /* Place the device in boot mode.  */
+  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_PROTOCOL,
+			0, 0, 0, 0);
+
+  /* Reports every time an event occurs and not more often than that.  */
+  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
+			0<<8, 0, 0, 0);
+}
+
+static grub_err_t
+grub_usb_keyboard_getreport (grub_usb_device_t dev, grub_uint8_t *report)
+{
+  return grub_usb_control_msg (dev, USB_HID_DEVICE_TO_HOST, USB_HID_GET_REPORT,
+			       0, 0, 8, (char *) report);
+}
+
+
+
+static int
+grub_usb_keyboard_checkkey (void)
+{
+  grub_uint8_t data[8];
+  int key;
+  grub_err_t err;
+  grub_uint64_t currtime;
+  int timeout = 50;
+
+  data[2] = 0;
+  currtime = grub_get_time_ms ();
+  do
+    {
+      /* Get_Report.  */
+      err = grub_usb_keyboard_getreport (usbdev, data);
+
+      /* Implement a timeout.  */
+      if (grub_get_time_ms () > currtime + timeout)
+	break;
+    }
+  while (err || !data[2]);
+
+  if (err || !data[2])
+    return -1;
+
+  grub_dprintf ("usb_keyboard",
+		"report: 0x%02x 0x%02x 0x%02x 0x%02x"
+		" 0x%02x 0x%02x 0x%02x 0x%02x\n",
+		data[0], data[1], data[2], data[3],
+		data[4], data[5], data[6], data[7]);
+
+  /* Check if the Control or Shift key was pressed.  */
+  if (data[0] & 0x01 || data[0] & 0x10)
+    key = keyboard_map[data[2]] - 'a' + 1;
+  else if (data[0] & 0x02 || data[0] & 0x20)
+    key = keyboard_map_shift[data[2]];
+  else
+    key = keyboard_map[data[2]];
+
+  if (key == 0)
+    grub_printf ("Unknown key 0x%x detected\n", data[2]);
+
+#if 0
+  /* Wait until the key is released.  */
+  while (!err && data[2])
+    {
+      err = grub_usb_control_msg (usbdev, USB_HID_DEVICE_TO_HOST,
+				  USB_HID_GET_REPORT, 0, 0,
+				  sizeof (data), (char *) data);
+      grub_dprintf ("usb_keyboard",
+		    "report2: 0x%02x 0x%02x 0x%02x 0x%02x"
+		    " 0x%02x 0x%02x 0x%02x 0x%02x\n",
+		    data[0], data[1], data[2], data[3],
+		    data[4], data[5], data[6], data[7]);
+    }
+#endif
+
+  grub_errno = GRUB_ERR_NONE;
+
+  return key;
+}
+
+typedef enum
+{
+  GRUB_HIDBOOT_REPEAT_NONE,
+  GRUB_HIDBOOT_REPEAT_FIRST,
+  GRUB_HIDBOOT_REPEAT
+} grub_usb_keyboard_repeat_t;
+
+static int
+grub_usb_keyboard_getkey (void)
+{
+  int key;
+  grub_err_t err;
+  grub_uint8_t data[8];
+  grub_uint64_t currtime;
+  int timeout;
+  static grub_usb_keyboard_repeat_t repeat = GRUB_HIDBOOT_REPEAT_NONE;
+
+ again:
+
+  do
+    {
+      key = grub_usb_keyboard_checkkey ();
+    } while (key == -1);
+
+  data[2] = !0; /* Or whatever.  */
+  err = 0;
+
+  switch (repeat)
+    {
+    case GRUB_HIDBOOT_REPEAT_FIRST:
+      timeout = 500;
+      break;
+    case GRUB_HIDBOOT_REPEAT:
+      timeout = 50;
+      break;
+    default:
+      timeout = 100;
+      break;
+    }
+
+  /* Wait until the key is released.  */
+  currtime = grub_get_time_ms ();
+  while (!err && data[2])
+    {
+      /* Implement a timeout.  */
+      if (grub_get_time_ms () > currtime + timeout)
+	{
+	  if (repeat == 0)
+	    repeat = 1;
+	  else
+	    repeat = 2;
+
+	  grub_errno = GRUB_ERR_NONE;
+	  return key;
+	}
+
+      err = grub_usb_keyboard_getreport (usbdev, data);
+    }
+
+  if (repeat)
+    {
+      repeat = 0;
+      goto again;
+    }
+
+  repeat = 0;
+
+  grub_errno = GRUB_ERR_NONE;
+
+  return key;
+}
+
+static int
+grub_usb_keyboard_getkeystatus (void)
+{
+  grub_uint8_t data[8];
+  int mods = 0;
+  grub_err_t err;
+  grub_uint64_t currtime;
+  int timeout = 50;
+
+  /* Set idle time to the minimum offered by the spec (4 milliseconds) so
+     that we can find out the current state.  */
+  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
+			0<<8, 0, 0, 0);
+
+  currtime = grub_get_time_ms ();
+  do
+    {
+      /* Get_Report.  */
+      err = grub_usb_keyboard_getreport (usbdev, data);
+
+      /* Implement a timeout.  */
+      if (grub_get_time_ms () > currtime + timeout)
+	break;
+    }
+  while (err || !data[0]);
+
+  /* Go back to reporting every time an event occurs and not more often than
+     that.  */
+  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
+			0<<8, 0, 0, 0);
+
+  /* We allowed a while for modifiers to show up in the report, but it is
+     not an error if they never did.  */
+  if (err)
+    return -1;
+
+  grub_dprintf ("usb_keyboard",
+		"report: 0x%02x 0x%02x 0x%02x 0x%02x"
+		" 0x%02x 0x%02x 0x%02x 0x%02x\n",
+		data[0], data[1], data[2], data[3],
+		data[4], data[5], data[6], data[7]);
+
+  /* Check Shift, Control, and Alt status.  */
+  if (data[0] & 0x02 || data[0] & 0x20)
+    mods |= GRUB_TERM_STATUS_SHIFT;
+  if (data[0] & 0x01 || data[0] & 0x10)
+    mods |= GRUB_TERM_STATUS_CTRL;
+  if (data[0] & 0x04 || data[0] & 0x40)
+    mods |= GRUB_TERM_STATUS_ALT;
+
+  grub_errno = GRUB_ERR_NONE;
+
+  return mods;
+}
+
+static struct grub_term_input grub_usb_keyboard_term =
+  {
+    .name = "usb_keyboard",
+    .checkkey = grub_usb_keyboard_checkkey,
+    .getkey = grub_usb_keyboard_getkey,
+    .getkeystatus = grub_usb_keyboard_getkeystatus,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(usb_keyboard)
+{
+  grub_usb_hid ();
+  grub_term_register_input ("usb_keyboard", &grub_usb_keyboard_term);
+}
+
+GRUB_MOD_FINI(usb_keyboard)
+{
+  grub_term_unregister_input (&grub_usb_keyboard_term);
+}
diff --git a/util/console.c b/util/console.c
new file mode 100644
index 0000000..9d8bb1a
--- /dev/null
+++ b/util/console.c
@@ -0,0 +1,387 @@
+/*  console.c -- Ncurses console for GRUB.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
+
+/* For compatibility.  */
+#ifndef A_NORMAL
+# define A_NORMAL	0
+#endif /* ! A_NORMAL */
+#ifndef A_STANDOUT
+# define A_STANDOUT	0
+#endif /* ! A_STANDOUT */
+
+#include <grub/util/console.h>
+#include <grub/term.h>
+#include <grub/types.h>
+
+static int grub_console_attr = A_NORMAL;
+
+grub_uint8_t grub_console_cur_color = 7;
+
+static grub_uint8_t grub_console_standard_color = 0x7;
+static grub_uint8_t grub_console_normal_color = 0x7;
+static grub_uint8_t grub_console_highlight_color = 0x70;
+
+#define NUM_COLORS	8
+
+static grub_uint8_t color_map[NUM_COLORS] =
+{
+  COLOR_BLACK,
+  COLOR_BLUE,
+  COLOR_GREEN,
+  COLOR_CYAN,
+  COLOR_RED,
+  COLOR_MAGENTA,
+  COLOR_YELLOW,
+  COLOR_WHITE
+};
+
+static int use_color;
+
+static void
+grub_ncurses_putchar (grub_uint32_t c)
+{
+  /* Better than nothing.  */
+  switch (c)
+    {
+    case GRUB_TERM_DISP_LEFT:
+      c = '<';
+      break;
+
+    case GRUB_TERM_DISP_UP:
+      c = '^';
+      break;
+
+    case GRUB_TERM_DISP_RIGHT:
+      c = '>';
+      break;
+
+    case GRUB_TERM_DISP_DOWN:
+      c = 'v';
+      break;
+
+    case GRUB_TERM_DISP_HLINE:
+      c = '-';
+      break;
+
+    case GRUB_TERM_DISP_VLINE:
+      c = '|';
+      break;
+
+    case GRUB_TERM_DISP_UL:
+    case GRUB_TERM_DISP_UR:
+    case GRUB_TERM_DISP_LL:
+    case GRUB_TERM_DISP_LR:
+      c = '+';
+      break;
+
+    default:
+      /* ncurses does not support Unicode.  */
+      if (c > 0x7f)
+	c = '?';
+      break;
+    }
+
+  addch (c | grub_console_attr);
+}
+
+static grub_ssize_t
+grub_ncurses_getcharwidth (grub_uint32_t code __attribute__ ((unused)))
+{
+  return 1;
+}
+
+static void
+grub_ncurses_setcolorstate (grub_term_color_state state)
+{
+  switch (state)
+    {
+    case GRUB_TERM_COLOR_STANDARD:
+      grub_console_cur_color = grub_console_standard_color;
+      grub_console_attr = A_NORMAL;
+      break;
+    case GRUB_TERM_COLOR_NORMAL:
+      grub_console_cur_color = grub_console_normal_color;
+      grub_console_attr = A_NORMAL;
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      grub_console_cur_color = grub_console_highlight_color;
+      grub_console_attr = A_STANDOUT;
+      break;
+    default:
+      break;
+    }
+
+  if (use_color)
+    {
+      grub_uint8_t fg, bg;
+
+      fg = (grub_console_cur_color & 7);
+      bg = (grub_console_cur_color >> 4) & 7;
+
+      grub_console_attr = (grub_console_cur_color & 8) ? A_BOLD : A_NORMAL;
+      color_set ((bg << 3) + fg, 0);
+    }
+}
+
+/* XXX: This function is never called.  */
+static void
+grub_ncurses_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
+{
+  grub_console_normal_color = normal_color;
+  grub_console_highlight_color = highlight_color;
+}
+
+static void
+grub_ncurses_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
+{
+  *normal_color = grub_console_normal_color;
+  *highlight_color = grub_console_highlight_color;
+}
+
+static int saved_char = ERR;
+
+static int
+grub_ncurses_checkkey (void)
+{
+  int c;
+
+  /* Check for SAVED_CHAR. This should not be true, because this
+     means checkkey is called twice continuously.  */
+  if (saved_char != ERR)
+    return saved_char;
+
+  wtimeout (stdscr, 100);
+  c = getch ();
+  /* If C is not ERR, then put it back in the input queue.  */
+  if (c != ERR)
+    {
+      saved_char = c;
+      return c;
+    }
+
+  return -1;
+}
+
+static int
+grub_ncurses_getkey (void)
+{
+  int c;
+
+  /* If checkkey has already got a character, then return it.  */
+  if (saved_char != ERR)
+    {
+      c = saved_char;
+      saved_char = ERR;
+    }
+  else
+    {
+      wtimeout (stdscr, -1);
+      c = getch ();
+    }
+
+  switch (c)
+    {
+    case KEY_LEFT:
+      c = 2;
+      break;
+
+    case KEY_RIGHT:
+      c = 6;
+      break;
+
+    case KEY_UP:
+      c = 16;
+      break;
+
+    case KEY_DOWN:
+      c = 14;
+      break;
+
+    case KEY_IC:
+      c = 24;
+      break;
+
+    case KEY_DC:
+      c = 4;
+      break;
+
+    case KEY_BACKSPACE:
+      /* XXX: For some reason ncurses on xterm does not return
+	 KEY_BACKSPACE.  */
+    case 127:
+      c = 8;
+      break;
+
+    case KEY_HOME:
+      c = 1;
+      break;
+
+    case KEY_END:
+      c = 5;
+      break;
+
+    case KEY_NPAGE:
+      c = 3;
+      break;
+
+    case KEY_PPAGE:
+      c = 7;
+      break;
+    }
+
+  return c;
+}
+
+static grub_uint16_t
+grub_ncurses_getxy (void)
+{
+  int x;
+  int y;
+
+  getyx (stdscr, y, x);
+
+  return (x << 8) | y;
+}
+
+static grub_uint16_t
+grub_ncurses_getwh (void)
+{
+  int x;
+  int y;
+
+  getmaxyx (stdscr, y, x);
+
+  return (x << 8) | y;
+}
+
+static void
+grub_ncurses_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  move (y, x);
+}
+
+static void
+grub_ncurses_cls (void)
+{
+  clear ();
+  refresh ();
+}
+
+static void
+grub_ncurses_setcursor (int on)
+{
+  curs_set (on ? 1 : 0);
+}
+
+static void
+grub_ncurses_refresh (void)
+{
+  refresh ();
+}
+
+static grub_err_t
+grub_ncurses_init (void)
+{
+  initscr ();
+  raw ();
+  noecho ();
+  scrollok (stdscr, TRUE);
+
+  nonl ();
+  intrflush (stdscr, FALSE);
+  keypad (stdscr, TRUE);
+
+  if (has_colors ())
+    {
+      start_color ();
+
+      if ((COLORS >= NUM_COLORS) && (COLOR_PAIRS >= NUM_COLORS * NUM_COLORS))
+        {
+          int i, j, n;
+
+          n = 0;
+          for (i = 0; i < NUM_COLORS; i++)
+            for (j = 0; j < NUM_COLORS; j++)
+              init_pair(n++, color_map[j], color_map[i]);
+
+          use_color = 1;
+        }
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_ncurses_fini (void)
+{
+  endwin ();
+  return 0;
+}
+
+
+static struct grub_term_input grub_ncurses_term_input =
+  {
+    .name = "console",
+    .checkkey = grub_ncurses_checkkey,
+    .getkey = grub_ncurses_getkey,
+  };
+
+static struct grub_term_output grub_ncurses_term_output =
+  {
+    .name = "console",
+    .init = grub_ncurses_init,
+    .fini = grub_ncurses_fini,
+    .putchar = grub_ncurses_putchar,
+    .getcharwidth = grub_ncurses_getcharwidth,
+    .getxy = grub_ncurses_getxy,
+    .getwh = grub_ncurses_getwh,
+    .gotoxy = grub_ncurses_gotoxy,
+    .cls = grub_ncurses_cls,
+    .setcolorstate = grub_ncurses_setcolorstate,
+    .setcolor = grub_ncurses_setcolor,
+    .getcolor = grub_ncurses_getcolor,
+    .setcursor = grub_ncurses_setcursor,
+    .refresh = grub_ncurses_refresh,
+    .flags = 0,
+  };
+
+void
+grub_console_init (void)
+{
+  grub_term_register_output ("console", &grub_ncurses_term_output);
+  grub_term_register_input ("console", &grub_ncurses_term_input);
+  grub_term_set_current_output (&grub_ncurses_term_output);
+  grub_term_set_current_input (&grub_ncurses_term_input);
+}
+
+void
+grub_console_fini (void)
+{
+  grub_ncurses_fini ();
+}
diff --git a/util/deviceiter.c b/util/deviceiter.c
new file mode 100644
index 0000000..b0a9e13
--- /dev/null
+++ b/util/deviceiter.c
@@ -0,0 +1,648 @@
+/* deviceiter.c - iterate over system devices */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+
+#include <grub/util/misc.h>
+#include <grub/util/deviceiter.h>
+
+#ifdef __linux__
+# if !defined(__GLIBC__) || \
+        ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
+/* Maybe libc doesn't have large file support.  */
+#  include <linux/unistd.h>     /* _llseek */
+# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
+# include <sys/ioctl.h>		/* ioctl */
+# ifndef HDIO_GETGEO
+#  define HDIO_GETGEO	0x0301	/* get device geometry */
+/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is
+   defined.  */
+struct hd_geometry
+{
+  unsigned char heads;
+  unsigned char sectors;
+  unsigned short cylinders;
+  unsigned long start;
+};
+# endif /* ! HDIO_GETGEO */
+# ifndef FLOPPY_MAJOR
+#  define FLOPPY_MAJOR	2	/* the major number for floppy */
+# endif /* ! FLOPPY_MAJOR */
+# ifndef MAJOR
+#  define MAJOR(dev)	\
+  ({ \
+     unsigned long long __dev = (dev); \
+     (unsigned) ((__dev >> 8) & 0xfff) \
+                 | ((unsigned int) (__dev >> 32) & ~0xfff); \
+  })
+# endif /* ! MAJOR */
+# ifndef CDROM_GET_CAPABILITY
+#  define CDROM_GET_CAPABILITY	0x5331	/* get capabilities */
+# endif /* ! CDROM_GET_CAPABILITY */
+# ifndef BLKGETSIZE
+#  define BLKGETSIZE	_IO(0x12,96)	/* return device size */
+# endif /* ! BLKGETSIZE */
+#endif /* __linux__ */
+
+/* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with
+   kFreeBSD-based non-FreeBSD systems (e.g. GNU/kFreeBSD) */
+#if defined(__FreeBSD__) && ! defined(__FreeBSD_kernel__)
+# define __FreeBSD_kernel__
+#endif
+#ifdef __FreeBSD_kernel__
+  /* Obtain version of kFreeBSD headers */
+# include <osreldate.h>
+# ifndef __FreeBSD_kernel_version
+#  define __FreeBSD_kernel_version __FreeBSD_version
+# endif
+
+  /* Runtime detection of kernel */
+# include <sys/utsname.h>
+int
+get_kfreebsd_version (void)
+{
+  struct utsname uts;
+  int major;
+  int minor;
+  int v[2];
+
+  uname (&uts);
+  sscanf (uts.release, "%d.%d", &major, &minor);
+
+  if (major >= 9)
+    major = 9;
+  if (major >= 5)
+    {
+      v[0] = minor/10; v[1] = minor%10;
+    }
+  else
+    {
+      v[0] = minor%10; v[1] = minor/10;
+    }
+  return major*100000+v[0]*10000+v[1]*1000;
+}
+#endif /* __FreeBSD_kernel__ */
+
+#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# include <sys/ioctl.h>		/* ioctl */
+# include <sys/disklabel.h>
+# include <sys/cdio.h>		/* CDIOCCLRDEBUG */
+# if defined(__FreeBSD_kernel__)
+#  include <sys/param.h>
+#  if __FreeBSD_kernel_version >= 500040
+#   include <sys/disk.h>
+#  endif
+# endif /* __FreeBSD_kernel__ */
+#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
+
+#ifdef HAVE_OPENDISK
+# include <util.h>
+#endif /* HAVE_OPENDISK */
+
+#ifdef __linux__
+/* Check if we have devfs support.  */
+static int
+have_devfs (void)
+{
+  struct stat st;
+  return stat ("/dev/.devfsd", &st) == 0;
+}
+#endif /* __linux__ */
+
+/* These three functions are quite different among OSes.  */
+static void
+get_floppy_disk_name (char *name, int unit)
+{
+#if defined(__linux__)
+  /* GNU/Linux */
+  if (have_devfs ())
+    sprintf (name, "/dev/floppy/%d", unit);
+  else
+    sprintf (name, "/dev/fd%d", unit);
+#elif defined(__GNU__)
+  /* GNU/Hurd */
+  sprintf (name, "/dev/fd%d", unit);
+#elif defined(__FreeBSD_kernel__)
+  /* kFreeBSD */
+  if (get_kfreebsd_version () >= 400000)
+    sprintf (name, "/dev/fd%d", unit);
+  else
+    sprintf (name, "/dev/rfd%d", unit);
+#elif defined(__NetBSD__)
+  /* NetBSD */
+  /* opendisk() doesn't work for floppies.  */
+  sprintf (name, "/dev/rfd%da", unit);
+#elif defined(__OpenBSD__)
+  /* OpenBSD */
+  sprintf (name, "/dev/rfd%dc", unit);
+#elif defined(__QNXNTO__)
+  /* QNX RTP */
+  sprintf (name, "/dev/fd%d", unit);
+#elif defined(__CYGWIN__)
+  /* Cygwin */
+  sprintf (name, "/dev/fd%d", unit);
+#elif defined(__MINGW32__)
+  (void) unit;
+  *name = 0;
+#else
+# warning "BIOS floppy drives cannot be guessed in your operating system."
+  /* Set NAME to a bogus string.  */
+  *name = 0;
+#endif
+}
+
+static void
+get_ide_disk_name (char *name, int unit)
+{
+#if defined(__linux__)
+  /* GNU/Linux */
+  sprintf (name, "/dev/hd%c", unit + 'a');
+#elif defined(__GNU__)
+  /* GNU/Hurd */
+  sprintf (name, "/dev/hd%d", unit);
+#elif defined(__FreeBSD_kernel__)
+  /* kFreeBSD */
+  if (get_kfreebsd_version () >= 400000)
+    sprintf (name, "/dev/ad%d", unit);
+  else
+    sprintf (name, "/dev/rwd%d", unit);
+#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
+  /* NetBSD */
+  char shortname[16];
+  int fd;
+
+  sprintf (shortname, "wd%d", unit);
+  fd = opendisk (shortname, O_RDONLY, name,
+		 16,	/* length of NAME */
+		 0	/* char device */
+		 );
+  close (fd);
+#elif defined(__OpenBSD__)
+  /* OpenBSD */
+  sprintf (name, "/dev/rwd%dc", unit);
+#elif defined(__QNXNTO__)
+  /* QNX RTP */
+  /* Actually, QNX RTP doesn't distinguish IDE from SCSI, so this could
+     contain SCSI disks.  */
+  sprintf (name, "/dev/hd%d", unit);
+#elif defined(__CYGWIN__)
+  /* Cygwin emulates all disks as /dev/sdX.  */
+  (void) unit;
+  *name = 0;
+#elif defined(__MINGW32__)
+  sprintf (name, "//./PHYSICALDRIVE%d", unit);
+#else
+# warning "BIOS IDE drives cannot be guessed in your operating system."
+  /* Set NAME to a bogus string.  */
+  *name = 0;
+#endif
+}
+
+static void
+get_scsi_disk_name (char *name, int unit)
+{
+#if defined(__linux__)
+  /* GNU/Linux */
+  sprintf (name, "/dev/sd%c", unit + 'a');
+#elif defined(__GNU__)
+  /* GNU/Hurd */
+  sprintf (name, "/dev/sd%d", unit);
+#elif defined(__FreeBSD_kernel__)
+  /* kFreeBSD */
+  if (get_kfreebsd_version () >= 400000)
+    sprintf (name, "/dev/da%d", unit);
+  else
+    sprintf (name, "/dev/rda%d", unit);
+#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
+  /* NetBSD */
+  char shortname[16];
+  int fd;
+
+  sprintf (shortname, "sd%d", unit);
+  fd = opendisk (shortname, O_RDONLY, name,
+		 16,	/* length of NAME */
+		 0	/* char device */
+		 );
+  close (fd);
+#elif defined(__OpenBSD__)
+  /* OpenBSD */
+  sprintf (name, "/dev/rsd%dc", unit);
+#elif defined(__QNXNTO__)
+  /* QNX RTP */
+  /* QNX RTP doesn't distinguish SCSI from IDE, so it is better to
+     disable the detection of SCSI disks here.  */
+  *name = 0;
+#elif defined(__CYGWIN__)
+  /* Cygwin emulates all disks as /dev/sdX.  */
+  sprintf (name, "/dev/sd%c", unit + 'a');
+#elif defined(__MINGW32__)
+  (void) unit;
+  *name = 0;
+#else
+# warning "BIOS SCSI drives cannot be guessed in your operating system."
+  /* Set NAME to a bogus string.  */
+  *name = 0;
+#endif
+}
+
+#ifdef __linux__
+static void
+get_virtio_disk_name (char *name, int unit)
+{
+#ifdef __sparc__
+  sprintf (name, "/dev/vdisk%c", unit + 'a');
+#else
+  sprintf (name, "/dev/vd%c", unit + 'a');
+#endif
+}
+
+static void
+get_dac960_disk_name (char *name, int controller, int drive)
+{
+  sprintf (name, "/dev/rd/c%dd%d", controller, drive);
+}
+
+static void
+get_acceleraid_disk_name (char *name, int controller, int drive)
+{
+  sprintf (name, "/dev/rs/c%dd%d", controller, drive);
+}
+
+static void
+get_ataraid_disk_name (char *name, int unit)
+{
+  sprintf (name, "/dev/ataraid/d%c", unit + '0');
+}
+
+static void
+get_i2o_disk_name (char *name, char unit)
+{
+  sprintf (name, "/dev/i2o/hd%c", unit);
+}
+
+static void
+get_cciss_disk_name (char *name, int controller, int drive)
+{
+  sprintf (name, "/dev/cciss/c%dd%d", controller, drive);
+}
+
+static void
+get_ida_disk_name (char *name, int controller, int drive)
+{
+  sprintf (name, "/dev/ida/c%dd%d", controller, drive);
+}
+
+static void
+get_mmc_disk_name (char *name, int unit)
+{
+  sprintf (name, "/dev/mmcblk%d", unit);
+}
+
+static void
+get_xvd_disk_name (char *name, int unit)
+{
+  sprintf (name, "/dev/xvd%c", unit + 'a');
+}
+#endif
+
+/* Check if DEVICE can be read. If an error occurs, return zero,
+   otherwise return non-zero.  */
+static int
+check_device (const char *device)
+{
+  char buf[512];
+  FILE *fp;
+
+  /* If DEVICE is empty, just return error.  */
+  if (*device == 0)
+    return 0;
+
+  fp = fopen (device, "r");
+  if (! fp)
+    {
+      switch (errno)
+	{
+#ifdef ENOMEDIUM
+	case ENOMEDIUM:
+# if 0
+	  /* At the moment, this finds only CDROMs, which can't be
+	     read anyway, so leave it out. Code should be
+	     reactivated if `removable disks' and CDROMs are
+	     supported.  */
+	  /* Accept it, it may be inserted.  */
+	  return 1;
+# endif
+	  break;
+#endif /* ENOMEDIUM */
+	default:
+	  /* Break case and leave.  */
+	  break;
+	}
+      /* Error opening the device.  */
+      return 0;
+    }
+
+  /* Make sure CD-ROMs don't get assigned a BIOS disk number
+     before SCSI disks!  */
+#ifdef __linux__
+# ifdef CDROM_GET_CAPABILITY
+  if (ioctl (fileno (fp), CDROM_GET_CAPABILITY, 0) >= 0)
+    return 0;
+# else /* ! CDROM_GET_CAPABILITY */
+  /* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl.  */
+  {
+    struct hd_geometry hdg;
+    struct stat st;
+
+    if (fstat (fileno (fp), &st))
+      return 0;
+
+    /* If it is a block device and isn't a floppy, check if HDIO_GETGEO
+       succeeds.  */
+    if (S_ISBLK (st.st_mode)
+	&& MAJOR (st.st_rdev) != FLOPPY_MAJOR
+	&& ioctl (fileno (fp), HDIO_GETGEO, &hdg))
+      return 0;
+  }
+# endif /* ! CDROM_GET_CAPABILITY */
+#endif /* __linux__ */
+
+#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# ifdef CDIOCCLRDEBUG
+  if (ioctl (fileno (fp), CDIOCCLRDEBUG, 0) >= 0)
+    return 0;
+# endif /* CDIOCCLRDEBUG */
+#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
+
+  /* Attempt to read the first sector.  */
+  if (fread (buf, 1, 512, fp) != 512)
+    {
+      fclose (fp);
+      return 0;
+    }
+
+  fclose (fp);
+  return 1;
+}
+
+void
+grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
+			   int floppy_disks)
+{
+  int i;
+
+  /* Floppies.  */
+  for (i = 0; i < floppy_disks; i++)
+    {
+      char name[16];
+      struct stat st;
+
+      get_floppy_disk_name (name, i);
+      if (stat (name, &st) < 0)
+	break;
+      /* In floppies, write the map, whether check_device succeeds
+	 or not, because the user just may not insert floppies.  */
+      if (hook (name, 1))
+	return;
+    }
+
+#ifdef __linux__
+  if (have_devfs ())
+    {
+      i = 0;
+      while (1)
+	{
+	  char discn[32];
+	  char name[PATH_MAX];
+	  struct stat st;
+
+	  /* Linux creates symlinks "/dev/discs/discN" for convenience.
+	     The way to number disks is the same as GRUB's.  */
+	  sprintf (discn, "/dev/discs/disc%d", i++);
+	  if (stat (discn, &st) < 0)
+	    break;
+
+	  if (realpath (discn, name))
+	    {
+	      strcat (name, "/disc");
+	      if (hook (name, 0))
+		return;
+	    }
+	}
+      return;
+    }
+#endif /* __linux__ */
+
+  /* IDE disks.  */
+  for (i = 0; i < 26; i++)
+    {
+      char name[16];
+
+      get_ide_disk_name (name, i);
+      if (check_device (name))
+	{
+	  if (hook (name, 0))
+	    return;
+	}
+    }
+
+#ifdef __linux__
+  /* Virtio disks.  */
+  for (i = 0; i < 26; i++)
+    {
+      char name[16];
+
+      get_virtio_disk_name (name, i);
+      if (check_device (name))
+	{
+	  if (hook (name, 0))
+	    return;
+	}
+    }
+
+  /* ATARAID disks.  */
+  for (i = 0; i < 8; i++)
+    {
+      char name[20];
+
+      get_ataraid_disk_name (name, i);
+      if (check_device (name))
+	{
+	  if (hook (name, 0))
+	    return;
+        }
+    }
+
+  /* Xen virtual block devices.  */
+  for (i = 0; i < 26; i++)
+    {
+      char name[16];
+
+      get_xvd_disk_name (name, i);
+      if (check_device (name))
+	{
+	  if (hook (name, 0))
+	    return;
+	}
+    }
+#endif /* __linux__ */
+
+  /* The rest is SCSI disks.  */
+  for (i = 0; i < 26; i++)
+    {
+      char name[16];
+
+      get_scsi_disk_name (name, i);
+      if (check_device (name))
+	{
+	  if (hook (name, 0))
+	    return;
+	}
+    }
+
+#ifdef __linux__
+  /* This is for DAC960 - we have
+     /dev/rd/c<controller>d<logical drive>p<partition>.
+
+     DAC960 driver currently supports up to 8 controllers, 32 logical
+     drives, and 7 partitions.  */
+  {
+    int controller, drive;
+
+    for (controller = 0; controller < 8; controller++)
+      {
+	for (drive = 0; drive < 15; drive++)
+	  {
+	    char name[24];
+
+	    get_dac960_disk_name (name, controller, drive);
+	    if (check_device (name))
+	      {
+		if (hook (name, 0))
+		  return;
+	      }
+	  }
+      }
+  }
+
+  /* This is for Mylex Acceleraid - we have
+     /dev/rd/c<controller>d<logical drive>p<partition>.  */
+  {
+    int controller, drive;
+
+    for (controller = 0; controller < 8; controller++)
+      {
+	for (drive = 0; drive < 15; drive++)
+	  {
+	    char name[24];
+
+	    get_acceleraid_disk_name (name, controller, drive);
+	    if (check_device (name))
+	      {
+		if (hook (name, 0))
+		  return;
+	      }
+	  }
+      }
+  }
+
+  /* This is for CCISS - we have
+     /dev/cciss/c<controller>d<logical drive>p<partition>.  */
+  {
+    int controller, drive;
+
+    for (controller = 0; controller < 3; controller++)
+      {
+	for (drive = 0; drive < 16; drive++)
+	  {
+	    char name[24];
+
+	    get_cciss_disk_name (name, controller, drive);
+	    if (check_device (name))
+	      {
+		if (hook (name, 0))
+		  return;
+	      }
+	  }
+      }
+  }
+
+  /* This is for Compaq Intelligent Drive Array - we have
+     /dev/ida/c<controller>d<logical drive>p<partition>.  */
+  {
+    int controller, drive;
+
+    for (controller = 0; controller < 3; controller++)
+      {
+	for (drive = 0; drive < 16; drive++)
+	  {
+	    char name[24];
+
+	    get_ida_disk_name (name, controller, drive);
+	    if (check_device (name))
+	      {
+		if (hook (name, 0))
+		  return;
+	      }
+	  }
+      }
+  }
+
+  /* This is for I2O - we have /dev/i2o/hd<logical drive><partition> */
+  {
+    char unit;
+
+    for (unit = 'a'; unit < 'f'; unit++)
+      {
+	char name[24];
+
+	get_i2o_disk_name (name, unit);
+	if (check_device (name))
+	  {
+	    if (hook (name, 0))
+	      return;
+	  }
+      }
+  }
+
+  /* MultiMediaCard (MMC).  */
+  for (i = 0; i < 10; i++)
+    {
+      char name[16];
+
+      get_mmc_disk_name (name, i);
+      if (check_device (name))
+	{
+	  if (hook (name, 0))
+	    return;
+	}
+    }
+#endif /* __linux__ */
+}
+
diff --git a/util/devicemap.c b/util/devicemap.c
new file mode 100644
index 0000000..c618644
--- /dev/null
+++ b/util/devicemap.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+#include <grub/util/deviceiter.h>
+
+void
+grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy,
+				int *num_fd, int *num_hd)
+{
+    if (is_floppy)
+      fprintf (fp, "(fd%d)\t%s\n", (*num_fd)++, name);
+    else
+      fprintf (fp, "(hd%d)\t%s\n", (*num_hd)++, name);
+}
diff --git a/util/elf/grub-mkimage.c b/util/elf/grub-mkimage.c
new file mode 100644
index 0000000..5354272
--- /dev/null
+++ b/util/elf/grub-mkimage.c
@@ -0,0 +1,425 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/util/misc.h>
+#include <grub/util/resolve.h>
+#include <grub/kernel.h>
+#include <grub/cpu/kernel.h>
+
+#define GRUB_IEEE1275_NOTE_NAME "PowerPC"
+#define GRUB_IEEE1275_NOTE_TYPE 0x1275
+
+/* These structures are defined according to the CHRP binding to IEEE1275,
+   "Client Program Format" section.  */
+
+struct grub_ieee1275_note_hdr
+{
+  grub_uint32_t namesz;
+  grub_uint32_t descsz;
+  grub_uint32_t type;
+  char name[sizeof (GRUB_IEEE1275_NOTE_NAME)];
+};
+
+struct grub_ieee1275_note_desc
+{
+  grub_uint32_t real_mode;
+  grub_uint32_t real_base;
+  grub_uint32_t real_size;
+  grub_uint32_t virt_base;
+  grub_uint32_t virt_size;
+  grub_uint32_t load_base;
+};
+
+struct grub_ieee1275_note
+{
+  struct grub_ieee1275_note_hdr header;
+  struct grub_ieee1275_note_desc descriptor;
+};
+
+void
+load_note (Elf32_Phdr *phdr, FILE *out)
+{
+  struct grub_ieee1275_note note;
+  int note_size = sizeof (struct grub_ieee1275_note);
+
+  grub_util_info ("adding CHRP NOTE segment");
+
+  note.header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME));
+  note.header.descsz = grub_host_to_target32 (note_size);
+  note.header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE);
+  strcpy (note.header.name, GRUB_IEEE1275_NOTE_NAME);
+  note.descriptor.real_mode = grub_host_to_target32 (0xffffffff);
+  note.descriptor.real_base = grub_host_to_target32 (0x00c00000);
+  note.descriptor.real_size = grub_host_to_target32 (0xffffffff);
+  note.descriptor.virt_base = grub_host_to_target32 (0xffffffff);
+  note.descriptor.virt_size = grub_host_to_target32 (0xffffffff);
+  note.descriptor.load_base = grub_host_to_target32 (0x00004000);
+
+  /* Write the note data to the new segment.  */
+  grub_util_write_image_at (&note, note_size,
+			    grub_target_to_host32 (phdr->p_offset), out);
+
+  /* Fill in the rest of the segment header.  */
+  phdr->p_type = grub_host_to_target32 (PT_NOTE);
+  phdr->p_flags = grub_host_to_target32 (PF_R);
+  phdr->p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG);
+  phdr->p_vaddr = 0;
+  phdr->p_paddr = 0;
+  phdr->p_filesz = grub_host_to_target32 (note_size);
+  phdr->p_memsz = 0;
+}
+
+void
+load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir,
+	      char *mods[], FILE *out, char *memdisk_path)
+{
+  char *module_img;
+  struct grub_util_path_list *path_list;
+  struct grub_util_path_list *p;
+  struct grub_module_info *modinfo;
+  size_t offset;
+  size_t total_module_size;
+  size_t memdisk_size = 0;
+
+  path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
+
+  offset = sizeof (struct grub_module_info);
+  total_module_size = sizeof (struct grub_module_info);
+
+  if (memdisk_path)
+    {
+      memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
+      grub_util_info ("the size of memory disk is 0x%x", memdisk_size);
+      total_module_size += memdisk_size + sizeof (struct grub_module_header);
+    }
+
+  for (p = path_list; p; p = p->next)
+    {
+      total_module_size += (grub_util_get_image_size (p->name)
+	  + sizeof (struct grub_module_header));
+    }
+
+  grub_util_info ("the total module size is 0x%x", total_module_size);
+
+  module_img = xmalloc (total_module_size);
+  modinfo = (struct grub_module_info *) module_img;
+  modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
+  modinfo->offset = grub_host_to_target32 (sizeof (struct grub_module_info));
+  modinfo->size = grub_host_to_target32 (total_module_size);
+
+  /* Load all the modules, with headers, into module_img.  */
+  for (p = path_list; p; p = p->next)
+    {
+      struct grub_module_header *header;
+      size_t mod_size;
+
+      grub_util_info ("adding module %s", p->name);
+
+      mod_size = grub_util_get_image_size (p->name);
+
+      header = (struct grub_module_header *) (module_img + offset);
+      header->type = OBJ_TYPE_ELF;
+      header->size = grub_host_to_target32 (mod_size + sizeof (*header));
+
+      grub_util_load_image (p->name, module_img + offset + sizeof (*header));
+
+      offset += sizeof (*header) + mod_size;
+    }
+
+  if (memdisk_path)
+    {
+      struct grub_module_header *header;
+
+      header = (struct grub_module_header *) (module_img + offset);
+      header->type = OBJ_TYPE_MEMDISK;
+      header->size = grub_host_to_target32 (memdisk_size + sizeof (*header));
+      offset += sizeof (*header);
+
+      grub_util_load_image (memdisk_path, module_img + offset);
+      offset += memdisk_size;
+    }
+
+
+  /* Write the module data to the new segment.  */
+  grub_util_write_image_at (module_img, total_module_size,
+			    grub_host_to_target32 (phdr->p_offset), out);
+
+  /* Fill in the rest of the segment header.  */
+  phdr->p_type = grub_host_to_target32 (PT_LOAD);
+  phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X);
+  phdr->p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG);
+  phdr->p_vaddr = grub_host_to_target32 (modbase);
+  phdr->p_paddr = grub_host_to_target32 (modbase);
+  phdr->p_filesz = grub_host_to_target32 (total_module_size);
+  phdr->p_memsz = grub_host_to_target32 (total_module_size);
+}
+
+void
+add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char *memdisk_path)
+{
+  Elf32_Ehdr ehdr;
+  Elf32_Phdr *phdrs = NULL;
+  Elf32_Phdr *phdr;
+  FILE *in;
+  char *kernel_path;
+  grub_addr_t grub_end = 0;
+  off_t offset, first_segment;
+  int i, phdr_size;
+
+  /* Read ELF header.  */
+  kernel_path = grub_util_get_path (dir, "kernel.img");
+  in = fopen (kernel_path, "rb");
+  if (! in)
+    grub_util_error ("cannot open %s", kernel_path);
+
+  grub_util_read_at (&ehdr, sizeof (ehdr), 0, in);
+
+  offset = ALIGN_UP (sizeof (ehdr), GRUB_TARGET_SIZEOF_LONG);
+  ehdr.e_phoff = grub_host_to_target32 (offset);
+
+  phdr_size = (grub_target_to_host16 (ehdr.e_phentsize) *
+               grub_target_to_host16 (ehdr.e_phnum));
+
+  if (mods[0] != NULL)
+    phdr_size += grub_target_to_host16 (ehdr.e_phentsize);
+
+  if (chrp)
+    phdr_size += grub_target_to_host16 (ehdr.e_phentsize);
+
+  phdrs = xmalloc (phdr_size);
+  offset += ALIGN_UP (phdr_size, GRUB_TARGET_SIZEOF_LONG);
+
+  first_segment = offset;
+
+  /* Copy all existing segments.  */
+  for (i = 0; i < grub_target_to_host16 (ehdr.e_phnum); i++)
+    {
+      char *segment_img;
+      grub_size_t segment_end;
+
+      phdr = phdrs + i;
+
+      /* Read segment header.  */
+      grub_util_read_at (phdr, sizeof (Elf32_Phdr),
+			 (grub_target_to_host32 (ehdr.e_phoff)
+			  + (i * grub_target_to_host16 (ehdr.e_phentsize))),
+			 in);
+      grub_util_info ("copying segment %d, type %d", i,
+		      grub_target_to_host32 (phdr->p_type));
+
+      /* Locate _end.  */
+      segment_end = grub_target_to_host32 (phdr->p_paddr)
+		    + grub_target_to_host32 (phdr->p_memsz);
+      grub_util_info ("segment %u end 0x%lx", i, segment_end);
+      if (segment_end > grub_end)
+	grub_end = segment_end;
+
+      /* Read segment data and write it to new file.  */
+      segment_img = xmalloc (grub_target_to_host32 (phdr->p_filesz));
+
+      grub_util_read_at (segment_img, grub_target_to_host32 (phdr->p_filesz),
+			 grub_target_to_host32 (phdr->p_offset), in);
+
+      phdr->p_offset = grub_host_to_target32 (offset);
+      grub_util_write_image_at (segment_img, grub_target_to_host32 (phdr->p_filesz),
+				offset, out);
+      offset += ALIGN_UP (grub_target_to_host32 (phdr->p_filesz),
+			  GRUB_TARGET_SIZEOF_LONG);
+
+      free (segment_img);
+    }
+
+  if (mods[0] != NULL)
+    {
+      grub_addr_t modbase;
+
+      /* Place modules just after grub segment.  */
+      modbase = ALIGN_UP(grub_end + GRUB_MOD_GAP, GRUB_MOD_ALIGN);
+
+      /* Construct new segment header for modules.  */
+      phdr = phdrs + grub_target_to_host16 (ehdr.e_phnum);
+      ehdr.e_phnum = grub_host_to_target16 (grub_target_to_host16 (ehdr.e_phnum) + 1);
+
+      /* Fill in p_offset so the callees know where to write.  */
+      phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out),
+							GRUB_TARGET_SIZEOF_LONG));
+
+      load_modules (modbase, phdr, dir, mods, out, memdisk_path);
+    }
+
+  if (chrp)
+    {
+      /* Construct new segment header for the CHRP note.  */
+      phdr = phdrs + grub_target_to_host16 (ehdr.e_phnum);
+      ehdr.e_phnum = grub_host_to_target16 (grub_target_to_host16 (ehdr.e_phnum) + 1);
+
+      /* Fill in p_offset so the callees know where to write.  */
+      phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out),
+							GRUB_TARGET_SIZEOF_LONG));
+
+      load_note (phdr, out);
+    }
+
+  /* Don't bother preserving the section headers.  */
+  ehdr.e_shoff = 0;
+  ehdr.e_shnum = 0;
+  ehdr.e_shstrndx = 0;
+
+  /* Write entire segment table to the file.  */
+  grub_util_write_image_at (phdrs, phdr_size, grub_target_to_host32 (ehdr.e_phoff), out);
+
+  /* Write ELF header.  */
+  grub_util_write_image_at (&ehdr, sizeof (ehdr), 0, out);
+
+  if (prefix)
+    {
+      if (GRUB_KERNEL_CPU_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_CPU_DATA_END)
+        grub_util_error ("prefix too long");
+      grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_CPU_PREFIX, out);
+    }
+
+  free (phdrs);
+  free (kernel_path);
+}
+
+static struct option options[] =
+  {
+    {"directory", required_argument, 0, 'd'},
+    {"prefix", required_argument, 0, 'p'},
+    {"memdisk", required_argument, 0, 'm'},
+    {"output", required_argument, 0, 'o'},
+    {"help", no_argument, 0, 'h'},
+    {"note", no_argument, 0, 'n'},
+    {"version", no_argument, 0, 'V'},
+    {"verbose", no_argument, 0, 'v'},
+    { 0, 0, 0, 0 },
+  };
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``grub-mkimage --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-mkimage -o FILE [OPTION]... [MODULES]\n\
+\n\
+Make a bootable image of GRUB.\n\
+\n\
+  -d, --directory=DIR     use images and modules under DIR [default=%s]\n\
+  -p, --prefix=DIR        set grub_prefix directory\n\
+  -m, --memdisk=FILE      embed FILE as a memdisk image\n\
+  -o, --output=FILE       output a generated image to FILE\n\
+  -h, --help              display this message and exit\n\
+  -n, --note              add NOTE segment for CHRP Open Firmware\n\
+  -V, --version           print version information and exit\n\
+  -v, --verbose           print verbose messages\n\
+\n\
+Report bugs to <%s>.\n\
+", GRUB_LIBDIR, PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+int
+main (int argc, char *argv[])
+{
+  FILE *fp;
+  char *output = NULL;
+  char *dir = NULL;
+  char *prefix = NULL;
+  char *memdisk = NULL;
+  int chrp = 0;
+
+  progname = "grub-mkimage";
+
+  while (1)
+    {
+      int c = getopt_long (argc, argv, "d:p:m:o:hVvn", options, 0);
+      if (c == -1)
+	break;
+
+      switch (c)
+	{
+	  case 'd':
+	    if (dir)
+	      free (dir);
+	    dir = xstrdup (optarg);
+	    break;
+	  case 'p':
+	    if (prefix)
+	      free (prefix);
+	    prefix = xstrdup (optarg);
+	    break;
+	  case 'm':
+	    if (memdisk)
+	      free (memdisk);
+	    memdisk = xstrdup (optarg);
+
+	    if (prefix)
+	      free (prefix);
+	    prefix = xstrdup ("(memdisk)/boot/grub");
+
+	    break;
+	  case 'h':
+	    usage (0);
+	    break;
+	  case 'n':
+	    chrp = 1;
+	    break;
+	  case 'o':
+	    if (output)
+	      free (output);
+	    output = xstrdup (optarg);
+	    break;
+	  case 'V':
+	    printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
+	    return 0;
+	  case 'v':
+	    verbosity++;
+	    break;
+	  default:
+	    usage (1);
+	    break;
+	}
+  }
+
+  if (!output)
+    usage (1);
+
+  fp = fopen (output, "wb");
+  if (! fp)
+    grub_util_error ("cannot open %s", output);
+
+  add_segments (dir ? : GRUB_LIBDIR, prefix, fp, chrp, argv + optind, memdisk);
+
+  fclose (fp);
+
+  return 0;
+}
diff --git a/util/getroot.c b/util/getroot.c
new file mode 100644
index 0000000..120ab13
--- /dev/null
+++ b/util/getroot.c
@@ -0,0 +1,540 @@
+/* getroot.c - Get root device */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <dirent.h>
+
+#ifdef __CYGWIN__
+# include <sys/fcntl.h>
+# include <sys/cygwin.h>
+# include <limits.h>
+# define DEV_CYGDRIVE_MAJOR 98
+#endif
+
+#include <grub/util/misc.h>
+#include <grub/util/hostdisk.h>
+#include <grub/util/getroot.h>
+
+static void
+strip_extra_slashes (char *dir)
+{
+  char *p = dir;
+
+  while ((p = strchr (p, '/')) != 0)
+    {
+      if (p[1] == '/')
+	{
+	  memmove (p, p + 1, strlen (p));
+	  continue;
+	}
+      else if (p[1] == '\0')
+	{
+	  if (p > dir)
+	    p[0] = '\0';
+	  break;
+	}
+
+      p++;
+    }
+}
+
+static char *
+xgetcwd (void)
+{
+  size_t size = 10;
+  char *path;
+
+  path = xmalloc (size);
+  while (! getcwd (path, size))
+    {
+      size <<= 1;
+      path = xrealloc (path, size);
+    }
+
+  return path;
+}
+
+#ifdef __CYGWIN__
+/* Convert POSIX path to Win32 path,
+   remove drive letter, replace backslashes.  */
+static char *
+get_win32_path (const char *path)
+{
+  char winpath[PATH_MAX];
+  cygwin_conv_to_full_win32_path (path, winpath);
+
+  int len = strlen (winpath);
+  if (len > 2 && winpath[1] == ':')
+    {
+      len -= 2;
+      memmove (winpath, winpath + 2, len + 1);
+    }
+
+  int i;
+  for (i = 0; i < len; i++)
+    if (winpath[i] == '\\')
+      winpath[i] = '/';
+  return xstrdup (winpath);
+}
+#endif
+
+char *
+grub_get_prefix (const char *dir)
+{
+  char *saved_cwd;
+  char *abs_dir, *prev_dir;
+  char *prefix;
+  struct stat st, prev_st;
+
+  /* Save the current directory.  */
+  saved_cwd = xgetcwd ();
+
+  if (chdir (dir) < 0)
+    grub_util_error ("Cannot change directory to `%s'", dir);
+
+  abs_dir = xgetcwd ();
+  strip_extra_slashes (abs_dir);
+  prev_dir = xstrdup (abs_dir);
+
+  if (stat (".", &prev_st) < 0)
+    grub_util_error ("Cannot stat `%s'", dir);
+
+  if (! S_ISDIR (prev_st.st_mode))
+    grub_util_error ("`%s' is not a directory", dir);
+
+  while (1)
+    {
+      if (chdir ("..") < 0)
+	grub_util_error ("Cannot change directory to the parent");
+
+      if (stat (".", &st) < 0)
+	grub_util_error ("Cannot stat current directory");
+
+      if (! S_ISDIR (st.st_mode))
+	grub_util_error ("Current directory is not a directory???");
+
+      if (prev_st.st_dev != st.st_dev || prev_st.st_ino == st.st_ino)
+	break;
+
+      free (prev_dir);
+      prev_dir = xgetcwd ();
+      prev_st = st;
+    }
+
+  strip_extra_slashes (prev_dir);
+  prefix = xmalloc (strlen (abs_dir) - strlen (prev_dir) + 2);
+  prefix[0] = '/';
+  strcpy (prefix + 1, abs_dir + strlen (prev_dir));
+  strip_extra_slashes (prefix);
+
+  if (chdir (saved_cwd) < 0)
+    grub_util_error ("Cannot change directory to `%s'", dir);
+
+#ifdef __CYGWIN__
+  if (st.st_dev != (DEV_CYGDRIVE_MAJOR << 16))
+    {
+      /* Reached some mount point not below /cygdrive.
+	 GRUB does not know Cygwin's emulated mounts,
+	 convert to Win32 path.  */
+      grub_util_info ("Cygwin prefix = %s", prefix);
+      char * wprefix = get_win32_path (prefix);
+      free (prefix);
+      prefix = wprefix;
+    }
+#endif
+
+  free (saved_cwd);
+  free (abs_dir);
+  free (prev_dir);
+
+  grub_util_info ("prefix = %s", prefix);
+  return prefix;
+}
+
+#ifdef __MINGW32__
+
+static char *
+find_root_device (const char *dir __attribute__ ((unused)),
+                  dev_t dev __attribute__ ((unused)))
+{
+  return 0;
+}
+
+#elif ! defined(__CYGWIN__)
+
+static char *
+find_root_device (const char *dir, dev_t dev)
+{
+  DIR *dp;
+  char *saved_cwd;
+  struct dirent *ent;
+
+  dp = opendir (dir);
+  if (! dp)
+    return 0;
+
+  saved_cwd = xgetcwd ();
+
+  grub_util_info ("changing current directory to %s", dir);
+  if (chdir (dir) < 0)
+    {
+      free (saved_cwd);
+      closedir (dp);
+      return 0;
+    }
+
+  while ((ent = readdir (dp)) != 0)
+    {
+      struct stat st;
+
+      /* Avoid:
+	 - dotfiles (like "/dev/.tmp.md0") since they could be duplicates.
+	 - dotdirs (like "/dev/.static") since they could contain duplicates.  */
+      if (ent->d_name[0] == '.')
+	continue;
+
+      if (lstat (ent->d_name, &st) < 0)
+	/* Ignore any error.  */
+	continue;
+
+      if (S_ISLNK (st.st_mode))
+	/* Don't follow symbolic links.  */
+	continue;
+
+      if (S_ISDIR (st.st_mode))
+	{
+	  /* Find it recursively.  */
+	  char *res;
+
+	  res = find_root_device (ent->d_name, dev);
+
+	  if (res)
+	    {
+	      if (chdir (saved_cwd) < 0)
+		grub_util_error ("Cannot restore the original directory");
+
+	      free (saved_cwd);
+	      closedir (dp);
+	      return res;
+	    }
+	}
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
+      if (S_ISCHR (st.st_mode) && st.st_rdev == dev)
+#else
+      if (S_ISBLK (st.st_mode) && st.st_rdev == dev)
+#endif
+	{
+#ifdef __linux__
+	  /* Skip device names like /dev/dm-0, which are short-hand aliases
+	     to more descriptive device names, e.g. those under /dev/mapper */
+	  if (ent->d_name[0] == 'd' &&
+	      ent->d_name[1] == 'm' &&
+	      ent->d_name[2] == '-' &&
+	      ent->d_name[3] >= '0' &&
+	      ent->d_name[3] <= '9')
+	    continue;
+#endif
+
+	  /* Found!  */
+	  char *res;
+	  char *cwd;
+
+	  cwd = xgetcwd ();
+	  res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 2);
+	  sprintf (res, "%s/%s", cwd, ent->d_name);
+	  strip_extra_slashes (res);
+	  free (cwd);
+
+	  /* /dev/root is not a real block device keep looking, takes care
+	     of situation where root filesystem is on the same partition as
+	     grub files */
+
+	  if (strcmp(res, "/dev/root") == 0)
+		continue;
+
+	  if (chdir (saved_cwd) < 0)
+	    grub_util_error ("Cannot restore the original directory");
+
+	  free (saved_cwd);
+	  closedir (dp);
+	  return res;
+	}
+    }
+
+  if (chdir (saved_cwd) < 0)
+    grub_util_error ("Cannot restore the original directory");
+
+  free (saved_cwd);
+  closedir (dp);
+  return 0;
+}
+
+#else /* __CYGWIN__ */
+
+/* Read drive/partition serial number from mbr/boot sector,
+   return 0 on read error, ~0 on unknown serial.  */
+static unsigned
+get_bootsec_serial (const char *os_dev, int mbr)
+{
+  /* Read boot sector.  */
+  int fd = open (os_dev, O_RDONLY);
+  if (fd < 0)
+    return 0;
+  unsigned char buf[0x200];
+  int n = read (fd, buf, sizeof (buf));
+  close (fd);
+  if (n != sizeof(buf))
+    return 0;
+
+  /* Check signature.  */
+  if (!(buf[0x1fe] == 0x55 && buf[0x1ff] == 0xaa))
+    return ~0;
+
+  /* Serial number offset depends on boot sector type.  */
+  if (mbr)
+    n = 0x1b8;
+  else if (memcmp (buf + 0x03, "NTFS", 4) == 0)
+    n = 0x048;
+  else if (memcmp (buf + 0x52, "FAT32", 5) == 0)
+    n = 0x043;
+  else if (memcmp (buf + 0x36, "FAT", 3) == 0)
+    n = 0x027;
+  else
+    return ~0;
+
+  unsigned serial = *(unsigned *)(buf + n);
+  if (serial == 0)
+    return ~0;
+  return serial;
+}
+
+static char *
+find_cygwin_root_device (const char *path, dev_t dev)
+{
+  /* No root device for /cygdrive.  */
+  if (dev == (DEV_CYGDRIVE_MAJOR << 16))
+    return 0;
+
+  /* Convert to full POSIX and Win32 path.  */
+  char fullpath[PATH_MAX], winpath[PATH_MAX];
+  cygwin_conv_to_full_posix_path (path, fullpath);
+  cygwin_conv_to_full_win32_path (fullpath, winpath);
+
+  /* If identical, this is no real filesystem path.  */
+  if (strcmp (fullpath, winpath) == 0)
+    return 0;
+
+  /* Check for floppy drive letter.  */
+  if (winpath[0] && winpath[1] == ':' && strchr ("AaBb", winpath[0]))
+    return xstrdup (strchr ("Aa", winpath[0]) ? "/dev/fd0" : "/dev/fd1");
+
+  /* Cygwin returns the partition serial number in stat.st_dev.
+     This is never identical to the device number of the emulated
+     /dev/sdXN device, so above find_root_device () does not work.
+     Search the partition with the same serial in boot sector instead.  */
+  char devpath[sizeof ("/dev/sda15") + 13]; /* Size + Paranoia.  */
+  int d;
+  for (d = 'a'; d <= 'z'; d++)
+    {
+      sprintf (devpath, "/dev/sd%c", d);
+      if (get_bootsec_serial (devpath, 1) == 0)
+	continue;
+      int p;
+      for (p = 1; p <= 15; p++)
+	{
+	  sprintf (devpath, "/dev/sd%c%d", d, p);
+	  unsigned ser = get_bootsec_serial (devpath, 0);
+	  if (ser == 0)
+	    break;
+	  if (ser != (unsigned)~0 && dev == (dev_t)ser)
+	    return xstrdup (devpath);
+	}
+    }
+  return 0;
+}
+
+#endif /* __CYGWIN__ */
+
+char *
+grub_guess_root_device (const char *dir)
+{
+  struct stat st;
+  char *os_dev;
+
+  if (stat (dir, &st) < 0)
+    grub_util_error ("Cannot stat `%s'", dir);
+
+#ifdef __CYGWIN__
+  /* Cygwin specific function.  */
+  os_dev = find_cygwin_root_device (dir, st.st_dev);
+
+#else
+
+  /* This might be truly slow, but is there any better way?  */
+  os_dev = find_root_device ("/dev", st.st_dev);
+#endif
+
+  return os_dev;
+}
+
+int
+grub_util_get_dev_abstraction (const char *os_dev UNUSED)
+{
+#ifdef __linux__
+  /* Check for LVM.  */
+  if (!strncmp (os_dev, "/dev/mapper/", 12))
+    return GRUB_DEV_ABSTRACTION_LVM;
+
+  /* Check for RAID.  */
+  if (!strncmp (os_dev, "/dev/md", 7))
+    return GRUB_DEV_ABSTRACTION_RAID;
+#endif
+
+  /* No abstraction found.  */
+  return GRUB_DEV_ABSTRACTION_NONE;
+}
+
+char *
+grub_util_get_grub_dev (const char *os_dev)
+{
+  char *grub_dev;
+
+  switch (grub_util_get_dev_abstraction (os_dev))
+    {
+    case GRUB_DEV_ABSTRACTION_LVM:
+
+      {
+	unsigned short i, len;
+	grub_size_t offset = sizeof ("/dev/mapper/") - 1;
+
+	len = strlen (os_dev) - offset + 1;
+	grub_dev = xmalloc (len);
+
+	for (i = 0; i < len; i++, offset++)
+	  {
+	    grub_dev[i] = os_dev[offset];
+	    if (os_dev[offset] == '-' && os_dev[offset + 1] == '-')
+	      offset++;
+	  }
+      }
+
+      break;
+
+    case GRUB_DEV_ABSTRACTION_RAID:
+
+      if (os_dev[7] == '_' && os_dev[8] == 'd')
+	{
+	  /* This a partitionable RAID device of the form /dev/md_dNNpMM. */
+
+	  char *p, *q;
+
+	  p = strdup (os_dev + sizeof ("/dev/md_d") - 1);
+
+	  q = strchr (p, 'p');
+	  if (q)
+	    *q = ',';
+
+	  asprintf (&grub_dev, "md%s", p);
+	  free (p);
+	}
+      else if (os_dev[7] == '/' && os_dev[8] == 'd')
+	{
+	  /* This a partitionable RAID device of the form /dev/md/dNNpMM. */
+
+	  char *p, *q;
+
+	  p = strdup (os_dev + sizeof ("/dev/md/d") - 1);
+
+	  q = strchr (p, 'p');
+	  if (q)
+	    *q = ',';
+
+	  asprintf (&grub_dev, "md%s", p);
+	  free (p);
+	}
+      else if (os_dev[7] >= '0' && os_dev[7] <= '9')
+	{
+	  char *p , *q;
+
+	  p = strdup (os_dev + sizeof ("/dev/md") - 1);
+
+	  q = strchr (p, 'p');
+	  if (q)
+	    *q = ',';
+
+	  asprintf (&grub_dev, "md%s", p);
+	  free (p);
+	}
+      else if (os_dev[7] == '/' && os_dev[8] >= '0' && os_dev[8] <= '9')
+	{
+	  char *p , *q;
+
+	  p = strdup (os_dev + sizeof ("/dev/md/") - 1);
+
+	  q = strchr (p, 'p');
+	  if (q)
+	    *q = ',';
+
+	  asprintf (&grub_dev, "md%s", p);
+	  free (p);
+	}
+      else
+	grub_util_error ("Unknown kind of RAID device `%s'", os_dev);
+
+      break;
+
+    default:  /* GRUB_DEV_ABSTRACTION_NONE */
+      grub_dev = grub_util_biosdisk_get_grub_dev (os_dev);
+    }
+
+  return grub_dev;
+}
+
+const char *
+grub_util_check_block_device (const char *blk_dev)
+{
+  struct stat st;
+
+  if (stat (blk_dev, &st) < 0)
+    grub_util_error ("Cannot stat `%s'", blk_dev);
+
+  if (S_ISBLK (st.st_mode))
+    return (blk_dev);
+  else
+    return 0;
+}
+
+const char *
+grub_util_check_char_device (const char *blk_dev)
+{
+  struct stat st;
+
+  if (stat (blk_dev, &st) < 0)
+    grub_util_error ("Cannot stat `%s'", blk_dev);
+
+  if (S_ISCHR (st.st_mode))
+    return (blk_dev);
+  else
+    return 0;
+}
+
diff --git a/util/grub-editenv.c b/util/grub-editenv.c
new file mode 100644
index 0000000..a8dc137
--- /dev/null
+++ b/util/grub-editenv.c
@@ -0,0 +1,313 @@
+/* grub-editenv.c - tool to edit environment block.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/util/misc.h>
+#include <grub/lib/envblk.h>
+#include <grub/handler.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#define DEFAULT_ENVBLK_SIZE	1024
+
+void
+grub_putchar (int c)
+{
+  putchar (c);
+}
+
+void
+grub_refresh (void)
+{
+  fflush (stdout);
+}
+
+struct grub_handler_class grub_term_input_class;
+struct grub_handler_class grub_term_output_class;
+
+int
+grub_getkey (void)
+{
+  return 0;
+}
+
+char *
+grub_env_get (const char *name __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static struct option options[] = {
+  {"help", no_argument, 0, 'h'},
+  {"version", no_argument, 0, 'V'},
+  {"verbose", no_argument, 0, 'v'},
+  {0, 0, 0, 0}
+};
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``grub-editenv --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-editenv [OPTIONS] FILENAME COMMAND\n\
+\n\
+Tool to edit environment block.\n\
+\nCommands:\n\
+  create                    create a blank environment block file\n\
+  list                      list the current variables\n\
+  set [name=value ...]      set variables\n\
+  unset [name ....]         delete variables\n\
+\nOptions:\n\
+  -h, --help                display this message and exit\n\
+  -V, --version             print version information and exit\n\
+  -v, --verbose             print verbose messages\n\
+\n\
+Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+static void
+create_envblk_file (const char *name)
+{
+  FILE *fp;
+  char *buf;
+  char *namenew;
+
+  buf = malloc (DEFAULT_ENVBLK_SIZE);
+  if (! buf)
+    grub_util_error ("out of memory");
+
+  asprintf (&namenew, "%s.new", name);
+  fp = fopen (namenew, "wb");
+  if (! fp)
+    grub_util_error ("cannot open the file %s", namenew);
+
+  memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
+  memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#',
+          DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
+
+  if (fwrite (buf, 1, DEFAULT_ENVBLK_SIZE, fp) != DEFAULT_ENVBLK_SIZE)
+    grub_util_error ("cannot write to the file %s", namenew);
+
+  fsync (fileno (fp));
+  free (buf);
+  fclose (fp);
+
+  if (rename (namenew, name) < 0)
+    grub_util_error ("cannot rename the file %s to %s", namenew, name);
+  free (namenew);
+}
+
+static grub_envblk_t
+open_envblk_file (const char *name)
+{
+  FILE *fp;
+  char *buf;
+  size_t size;
+  grub_envblk_t envblk;
+
+  fp = fopen (name, "rb");
+  if (! fp)
+    {
+      /* Create the file implicitly.  */
+      create_envblk_file (name);
+      fp = fopen (name, "rb");
+      if (! fp)
+        grub_util_error ("cannot open the file %s", name);
+    }
+
+  if (fseek (fp, 0, SEEK_END) < 0)
+    grub_util_error ("cannot seek the file %s", name);
+
+  size = (size_t) ftell (fp);
+
+  if (fseek (fp, 0, SEEK_SET) < 0)
+    grub_util_error ("cannot seek the file %s", name);
+
+  buf = malloc (size);
+  if (! buf)
+    grub_util_error ("out of memory");
+
+  if (fread (buf, 1, size, fp) != size)
+    grub_util_error ("cannot read the file %s", name);
+
+  fclose (fp);
+
+  envblk = grub_envblk_open (buf, size);
+  if (! envblk)
+    grub_util_error ("invalid environment block");
+
+  return envblk;
+}
+
+static void
+list_variables (const char *name)
+{
+  grub_envblk_t envblk;
+
+  auto int print_var (const char *name, const char *value);
+  int print_var (const char *name, const char *value)
+    {
+      printf ("%s=%s\n", name, value);
+      return 0;
+    }
+
+  envblk = open_envblk_file (name);
+  grub_envblk_iterate (envblk, print_var);
+  grub_envblk_close (envblk);
+}
+
+static void
+write_envblk (const char *name, grub_envblk_t envblk)
+{
+  FILE *fp;
+
+  fp = fopen (name, "wb");
+  if (! fp)
+    grub_util_error ("cannot open the file %s", name);
+
+  if (fwrite (grub_envblk_buffer (envblk), 1, grub_envblk_size (envblk), fp)
+      != grub_envblk_size (envblk))
+    grub_util_error ("cannot write to the file %s", name);
+
+  fsync (fileno (fp));
+  fclose (fp);
+}
+
+static void
+set_variables (const char *name, int argc, char *argv[])
+{
+  grub_envblk_t envblk;
+
+  envblk = open_envblk_file (name);
+  while (argc)
+    {
+      char *p;
+
+      p = strchr (argv[0], '=');
+      if (! p)
+        grub_util_error ("invalid parameter %s", argv[0]);
+
+      *(p++) = 0;
+
+      if (! grub_envblk_set (envblk, argv[0], p))
+        grub_util_error ("environment block too small");
+
+      argc--;
+      argv++;
+    }
+
+  write_envblk (name, envblk);
+  grub_envblk_close (envblk);
+}
+
+static void
+unset_variables (const char *name, int argc, char *argv[])
+{
+  grub_envblk_t envblk;
+
+  envblk = open_envblk_file (name);
+  while (argc)
+    {
+      grub_envblk_delete (envblk, argv[0]);
+
+      argc--;
+      argv++;
+    }
+
+  write_envblk (name, envblk);
+  grub_envblk_close (envblk);
+}
+
+int
+main (int argc, char *argv[])
+{
+  char *filename;
+  char *command;
+
+  progname = "grub-editenv";
+
+  /* Check for options.  */
+  while (1)
+    {
+      int c = getopt_long (argc, argv, "hVv", options, 0);
+
+      if (c == -1)
+	break;
+      else
+	switch (c)
+	  {
+	  case 'h':
+	    usage (0);
+	    break;
+
+	  case 'V':
+	    printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION);
+	    return 0;
+
+	  case 'v':
+	    verbosity++;
+	    break;
+
+	  default:
+	    usage (1);
+	    break;
+	  }
+    }
+
+  /* Obtain the filename.  */
+  if (optind >= argc)
+    {
+      fprintf (stderr, "no filename specified\n");
+      usage (1);
+    }
+
+  if (optind + 1 >= argc)
+    {
+      fprintf (stderr, "no command specified\n");
+      usage (1);
+    }
+
+  filename = argv[optind];
+  command = argv[optind + 1];
+
+  if (strcmp (command, "create") == 0)
+    create_envblk_file (filename);
+  else if (strcmp (command, "list") == 0)
+    list_variables (filename);
+  else if (strcmp (command, "set") == 0)
+    set_variables (filename, argc - optind - 2, argv + optind + 2);
+  else if (strcmp (command, "unset") == 0)
+    unset_variables (filename, argc - optind - 2, argv + optind + 2);
+  else
+    {
+      fprintf (stderr, "unknown command %s\n", command);
+      usage (1);
+    }
+
+  return 0;
+}
diff --git a/util/grub-emu.c b/util/grub-emu.c
new file mode 100644
index 0000000..97f1886
--- /dev/null
+++ b/util/grub-emu.c
@@ -0,0 +1,243 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <getopt.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <grub/mm.h>
+#include <grub/setjmp.h>
+#include <grub/fs.h>
+#include <grub/util/hostdisk.h>
+#include <grub/dl.h>
+#include <grub/util/console.h>
+#include <grub/util/misc.h>
+#include <grub/kernel.h>
+#include <grub/normal.h>
+#include <grub/util/getroot.h>
+#include <grub/env.h>
+#include <grub/partition.h>
+
+#include <grub_emu_init.h>
+
+/* Used for going back to the main function.  */
+static jmp_buf main_env;
+
+/* Store the prefix specified by an argument.  */
+static char *prefix = 0;
+
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  return 0;
+}
+
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  (void) ehdr;
+
+  return GRUB_ERR_BAD_MODULE;
+}
+
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  (void) mod;
+  (void) ehdr;
+
+  return GRUB_ERR_BAD_MODULE;
+}
+
+void
+grub_reboot (void)
+{
+  longjmp (main_env, 1);
+}
+
+void
+grub_halt (
+#ifdef GRUB_MACHINE_PCBIOS
+	   int no_apm __attribute__ ((unused))
+#endif
+	   )
+{
+  grub_reboot ();
+}
+
+void
+grub_machine_init (void)
+{
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  grub_env_set ("prefix", prefix);
+  free (prefix);
+  prefix = 0;
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_console_fini ();
+}
+
+void
+read_command_list (void)
+{
+}
+
+
+static struct option options[] =
+  {
+    {"root-device", required_argument, 0, 'r'},
+    {"device-map", required_argument, 0, 'm'},
+    {"directory", required_argument, 0, 'd'},
+    {"hold", optional_argument, 0, 'H'},
+    {"help", no_argument, 0, 'h'},
+    {"version", no_argument, 0, 'V'},
+    {"verbose", no_argument, 0, 'v'},
+    { 0, 0, 0, 0 }
+  };
+
+static int
+usage (int status)
+{
+  if (status)
+    fprintf (stderr,
+	     "Try ``grub-emu --help'' for more information.\n");
+  else
+    printf (
+      "Usage: grub-emu [OPTION]...\n"
+      "\n"
+      "GRUB emulator.\n"
+      "\n"
+      "  -r, --root-device=DEV     use DEV as the root device [default=guessed]\n"
+      "  -m, --device-map=FILE     use FILE as the device map [default=%s]\n"
+      "  -d, --directory=DIR       use GRUB files in the directory DIR [default=%s]\n"
+      "  -v, --verbose             print verbose messages\n"
+      "  -H, --hold[=SECONDS]      wait until a debugger will attach\n"
+      "  -h, --help                display this message and exit\n"
+      "  -V, --version             print version information and exit\n"
+      "\n"
+      "Report bugs to <%s>.\n", DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT);
+  return status;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  char *root_dev = 0;
+  char *dir = DEFAULT_DIRECTORY;
+  char *dev_map = DEFAULT_DEVICE_MAP;
+  volatile int hold = 0;
+  int opt;
+
+  progname = "grub-emu";
+
+  while ((opt = getopt_long (argc, argv, "r:d:m:vH:hV", options, 0)) != -1)
+    switch (opt)
+      {
+      case 'r':
+        root_dev = optarg;
+        break;
+      case 'd':
+        dir = optarg;
+        break;
+      case 'm':
+        dev_map = optarg;
+        break;
+      case 'v':
+        verbosity++;
+        break;
+      case 'H':
+        hold = (optarg ? atoi (optarg) : -1);
+        break;
+      case 'h':
+        return usage (0);
+      case 'V':
+        printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION);
+        return 0;
+      default:
+        return usage (1);
+      }
+
+  if (optind < argc)
+    {
+      fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind]);
+      return usage (1);
+    }
+
+  /* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */
+  if (hold && verbosity > 0)
+    printf ("Run \"gdb %s %d\", and set ARGS.HOLD to zero.\n",
+            progname, (int) getpid ());
+  while (hold)
+    {
+      if (hold > 0)
+        hold--;
+
+      sleep (1);
+    }
+
+  signal (SIGINT, SIG_IGN);
+  grub_console_init ();
+
+  /* XXX: This is a bit unportable.  */
+  grub_util_biosdisk_init (dev_map);
+
+  grub_init_all ();
+
+  /* Make sure that there is a root device.  */
+  if (! root_dev)
+    {
+      char *device_name = grub_guess_root_device (dir);
+      if (! device_name)
+        grub_util_error ("cannot find a device for %s.\n", dir);
+
+      root_dev = grub_util_get_grub_dev (device_name);
+      if (! root_dev)
+	{
+	  grub_util_info ("guessing the root device failed, because of `%s'",
+			  grub_errmsg);
+	  grub_util_error ("Cannot guess the root device. Specify the option ``--root-device''.");
+	}
+    }
+
+  dir = grub_get_prefix (dir);
+  prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1);
+  sprintf (prefix, "(%s)%s", root_dev, dir);
+  free (dir);
+
+  /* Start GRUB!  */
+  if (setjmp (main_env) == 0)
+    grub_main ();
+
+  grub_fini_all ();
+
+  grub_machine_fini ();
+
+  return 0;
+}
diff --git a/util/grub-fstest.c b/util/grub-fstest.c
new file mode 100644
index 0000000..1bb3706
--- /dev/null
+++ b/util/grub-fstest.c
@@ -0,0 +1,561 @@
+/* grub-fstest.c - debug tool for filesystem driver */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/util/misc.h>
+#include <grub/misc.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/fs.h>
+#include <grub/env.h>
+#include <grub/term.h>
+#include <grub/mm.h>
+#include <grub/lib/hexdump.h>
+#include <grub/lib/crc.h>
+#include <grub/command.h>
+
+#include <grub_fstest_init.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+void
+grub_putchar (int c)
+{
+  putchar (c);
+}
+
+int
+grub_getkey (void)
+{
+  return -1;
+}
+
+struct grub_handler_class grub_term_input_class;
+struct grub_handler_class grub_term_output_class;
+
+void
+grub_refresh (void)
+{
+  fflush (stdout);
+}
+
+static grub_err_t
+execute_command (char *name, int n, char **args)
+{
+  grub_command_t cmd;
+
+  cmd = grub_command_find (name);
+  if (! cmd)
+    grub_util_error ("Can\'t find command %s", name);
+
+  return (cmd->func) (cmd, n, args);
+}
+
+#define CMD_LS          1
+#define CMD_CP          2
+#define CMD_CMP         3
+#define CMD_HEX         4
+#define CMD_CRC         6
+#define CMD_BLOCKLIST   7
+
+#define BUF_SIZE  32256
+
+static grub_off_t skip, leng;
+
+static void
+read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len))
+{
+  static char buf[BUF_SIZE];
+  grub_file_t file;
+  grub_off_t ofs, len;
+
+  if ((pathname[0] == '-') && (pathname[1] == 0))
+    {
+      grub_device_t dev;
+
+      dev = grub_device_open (0);
+      if ((! dev) || (! dev->disk))
+        grub_util_error ("Can\'t open device.");
+
+      grub_util_info ("total sectors : %lld.",
+                      (unsigned long long) dev->disk->total_sectors);
+
+      if (! leng)
+        leng = (dev->disk->total_sectors << GRUB_DISK_SECTOR_BITS) - skip;
+
+      while (leng)
+        {
+          grub_size_t len;
+
+          len = (leng > BUF_SIZE) ? BUF_SIZE : leng;
+
+          if (grub_disk_read (dev->disk, 0, skip, len, buf))
+            grub_util_error ("Disk read fails at offset %lld, length %d.",
+                             skip, len);
+
+          if (hook (skip, buf, len))
+            break;
+
+          skip += len;
+          leng -= len;
+        }
+
+      grub_device_close (dev);
+      return;
+    }
+
+  file = grub_file_open (pathname);
+  if (!file)
+    {
+      grub_util_error ("cannot open file %s.", pathname);
+      return;
+    }
+
+  grub_util_info ("file size : %lld.", (unsigned long long) file->size);
+
+  if (skip > file->size)
+    {
+      grub_util_error ("invalid skip value %d.");
+      return;
+    }
+
+  ofs = skip;
+  len = file->size - skip;
+  if ((leng) && (leng < len))
+    len = leng;
+
+  file->offset = skip;
+
+  while (len)
+    {
+      grub_ssize_t sz;
+
+      sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len);
+      if (sz < 0)
+	{
+	  grub_util_error ("read error at offset %llu.", ofs);
+	  break;
+	}
+
+      if ((sz == 0) || (hook (ofs, buf, sz)))
+	break;
+
+      ofs += sz;
+      len -= sz;
+    }
+
+  grub_file_close (file);
+}
+
+static void
+cmd_cp (char *src, char *dest)
+{
+  FILE *ff;
+
+  auto int cp_hook (grub_off_t ofs, char *buf, int len);
+  int cp_hook (grub_off_t ofs, char *buf, int len)
+  {
+    (void) ofs;
+
+    if ((int) fwrite (buf, 1, len, ff) != len)
+      {
+	grub_util_error ("write error.");
+	return 1;
+      }
+
+    return 0;
+  }
+
+  ff = fopen (dest, "wb");
+  if (ff == NULL)
+    {
+      grub_util_error ("open error.");
+      return;
+    }
+  read_file (src, cp_hook);
+  fclose (ff);
+}
+
+static void
+cmd_cmp (char *src, char *dest)
+{
+  FILE *ff;
+  static char buf_1[BUF_SIZE];
+
+  auto int cmp_hook (grub_off_t ofs, char *buf, int len);
+  int cmp_hook (grub_off_t ofs, char *buf, int len)
+  {
+    if ((int) fread (buf_1, 1, len, ff) != len)
+      {
+	grub_util_error ("read error at offset %llu.", ofs);
+	return 1;
+      }
+
+    if (grub_memcmp (buf, buf_1, len))
+      {
+	int i;
+
+	for (i = 0; i < len; i++, ofs++)
+	  if (buf_1[i] != buf[i])
+	    {
+	      grub_util_error ("compare fail at offset %llu.", ofs);
+	      return 1;
+	    }
+      }
+    return 0;
+  }
+
+  ff = fopen (dest, "rb");
+  if (ff == NULL)
+    {
+      grub_util_error ("open error.");
+      return;
+    }
+
+  if ((skip) && (fseeko (ff, skip, SEEK_SET)))
+    grub_util_error ("seek error.");
+
+  read_file (src, cmp_hook);
+  fclose (ff);
+}
+
+static void
+cmd_hex (char *pathname)
+{
+  auto int hex_hook (grub_off_t ofs, char *buf, int len);
+  int hex_hook (grub_off_t ofs, char *buf, int len)
+  {
+    hexdump (ofs, buf, len);
+    return 0;
+  }
+
+  read_file (pathname, hex_hook);
+}
+
+static void
+cmd_crc (char *pathname)
+{
+  grub_uint32_t crc = 0;
+
+  auto int crc_hook (grub_off_t ofs, char *buf, int len);
+  int crc_hook (grub_off_t ofs, char *buf, int len)
+  {
+    (void) ofs;
+
+    crc = grub_getcrc32 (crc, buf, len);
+    return 0;
+  }
+
+  read_file (pathname, crc_hook);
+  printf ("%08x\n", crc);
+}
+
+static void
+fstest (char **images, int num_disks, int cmd, int n, char **args)
+{
+  char host_file[128];
+  char loop_name[8];
+  char *argv[3] = { "-p", loop_name, host_file};
+  int i;
+
+  for (i = 0; i < num_disks; i++)
+    {
+      if (grub_strlen (images[i]) + 7 > sizeof (host_file))
+        grub_util_error ("Pathname %s too long.", images[i]);
+
+      grub_sprintf (loop_name, "loop%d", i);
+      grub_sprintf (host_file, "(host)%s", images[i]);
+
+      if (execute_command ("loopback", 3, argv))
+        grub_util_error ("loopback command fails.");
+    }
+
+  grub_lvm_fini ();
+  grub_mdraid_fini ();
+  grub_raid_fini ();
+  grub_raid_init ();
+  grub_mdraid_init ();
+  grub_lvm_init ();
+
+  switch (cmd)
+    {
+    case CMD_LS:
+      execute_command ("ls", n, args);
+      break;
+    case CMD_CP:
+      cmd_cp (args[0], args[1]);
+      break;
+    case CMD_CMP:
+      cmd_cmp (args[0], args[1]);
+      break;
+    case CMD_HEX:
+      cmd_hex (args[0]);
+      break;
+    case CMD_CRC:
+      cmd_crc (args[0]);
+      break;
+    case CMD_BLOCKLIST:
+      execute_command ("blocklist", n, args);
+      grub_printf ("\n");
+    }
+
+  argv[0] = "-d";
+
+  for (i = 0; i < num_disks; i++)
+    {
+      grub_sprintf (loop_name, "loop%d", i);
+      execute_command ("loopback", 2, argv);
+    }
+}
+
+static struct option options[] = {
+  {"root", required_argument, 0, 'r'},
+  {"skip", required_argument, 0, 's'},
+  {"length", required_argument, 0, 'n'},
+  {"diskcount", required_argument, 0, 'c'},
+  {"debug", required_argument, 0, 'd'},
+  {"help", no_argument, 0, 'h'},
+  {"version", no_argument, 0, 'V'},
+  {"verbose", no_argument, 0, 'v'},
+  {0, 0, 0, 0}
+};
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``grub-fstest --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-fstest [OPTION]... IMAGE_PATH COMMANDS\n\
+\n\
+Debug tool for filesystem driver.\n\
+\nCommands:\n\
+  ls PATH                   list files in PATH\n\
+  cp FILE LOCAL             copy FILE to local file LOCAL\n\
+  cmp FILE LOCAL            compare FILE with local file LOCAL\n\
+  hex FILE                  Hex dump FILE\n\
+  crc FILE                  Get crc32 checksum of FILE\n\
+  blocklist FILE            display blocklist of FILE\n\
+\nOptions:\n\
+  -r, --root=DEVICE_NAME    set root device\n\
+  -s, --skip=N              skip N bytes from output file\n\
+  -n, --length=N            handle N bytes in output file\n\
+  -c, --diskcount=N         N input files\n\
+  -d, --debug=S             Set debug environment variable\n\
+  -h, --help                display this message and exit\n\
+  -V, --version             print version information and exit\n\
+  -v, --verbose             print verbose messages\n\
+\n\
+Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+int
+main (int argc, char *argv[])
+{
+  char *debug_str = 0, *root = 0, *default_root, *alloc_root;
+  int i, cmd, num_opts, image_index, num_disks = 1;
+
+  progname = "grub-fstest";
+
+  /* Find the first non option entry.  */
+  for (num_opts = 1; num_opts < argc; num_opts++)
+    if (argv[num_opts][0] == '-')
+      {
+        if ((argv[num_opts][2] == 0) && (num_opts < argc - 1) &&
+            ((argv[num_opts][1] == 'r') ||
+             (argv[num_opts][1] == 's') ||
+             (argv[num_opts][1] == 'n') ||
+             (argv[num_opts][1] == 'c') ||
+             (argv[num_opts][1] == 'd')))
+            num_opts++;
+      }
+    else
+      break;
+
+  /* Check for options.  */
+  while (1)
+    {
+      int c = getopt_long (num_opts, argv, "r:s:n:c:d:hVv", options, 0);
+      char *p;
+
+      if (c == -1)
+	break;
+      else
+	switch (c)
+	  {
+	  case 'r':
+	    root = optarg;
+	    break;
+
+	  case 's':
+	    skip = grub_strtoul (optarg, &p, 0);
+            if (*p == 's')
+              skip <<= GRUB_DISK_SECTOR_BITS;
+	    break;
+
+	  case 'n':
+	    leng = grub_strtoul (optarg, &p, 0);
+            if (*p == 's')
+              leng <<= GRUB_DISK_SECTOR_BITS;
+	    break;
+
+          case 'c':
+            num_disks = grub_strtoul (optarg, NULL, 0);
+            if (num_disks < 1)
+              {
+                fprintf (stderr, "Invalid disk count.\n");
+                usage (1);
+              }
+            break;
+
+          case 'd':
+            debug_str = optarg;
+            break;
+
+	  case 'h':
+	    usage (0);
+	    break;
+
+	  case 'V':
+	    printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION);
+	    return 0;
+
+	  case 'v':
+	    verbosity++;
+	    break;
+
+	  default:
+	    usage (1);
+	    break;
+	  }
+    }
+
+  /* Obtain PATH.  */
+  if (optind + num_disks - 1 >= argc)
+    {
+      fprintf (stderr, "Not enough pathname.\n");
+      usage (1);
+    }
+
+  image_index = optind;
+  for (i = 0; i < num_disks; i++, optind++)
+    if (argv[optind][0] != '/')
+      {
+        fprintf (stderr, "Must use absolute path.\n");
+        usage (1);
+      }
+
+  cmd = 0;
+  if (optind < argc)
+    {
+      int nparm = 0;
+
+      if (!grub_strcmp (argv[optind], "ls"))
+        {
+          cmd = CMD_LS;
+        }
+      else if (!grub_strcmp (argv[optind], "cp"))
+	{
+	  cmd = CMD_CP;
+          nparm = 2;
+	}
+      else if (!grub_strcmp (argv[optind], "cmp"))
+	{
+	  cmd = CMD_CMP;
+          nparm = 2;
+	}
+      else if (!grub_strcmp (argv[optind], "hex"))
+	{
+	  cmd = CMD_HEX;
+          nparm = 1;
+	}
+      else if (!grub_strcmp (argv[optind], "crc"))
+	{
+	  cmd = CMD_CRC;
+          nparm = 1;
+	}
+      else if (!grub_strcmp (argv[optind], "blocklist"))
+	{
+	  cmd = CMD_BLOCKLIST;
+          nparm = 1;
+	}
+      else
+	{
+	  fprintf (stderr, "Invalid command %s.\n", argv[optind]);
+	  usage (1);
+	}
+
+      if (optind + 1 + nparm > argc)
+	{
+	  fprintf (stderr, "Invalid parameter for command %s.\n",
+		   argv[optind]);
+	  usage (1);
+	}
+
+      optind++;
+    }
+  else
+    {
+      fprintf (stderr, "No command is specified.\n");
+      usage (1);
+    }
+
+  /* Initialize all modules. */
+  grub_init_all ();
+
+  if (debug_str)
+    grub_env_set ("debug", debug_str);
+
+  default_root = (num_disks == 1) ? "loop0" : "md0";
+  alloc_root = 0;
+  if (root)
+    {
+      if ((*root >= '0') && (*root <= '9'))
+        {
+          alloc_root = xmalloc (strlen (default_root) + strlen (root) + 2);
+
+          sprintf (alloc_root, "%s,%s", default_root, root);
+          root = alloc_root;
+        }
+    }
+  else
+    root = default_root;
+
+  grub_env_set ("root", root);
+
+  if (alloc_root)
+    free (alloc_root);
+
+  /* Do it.  */
+  fstest (argv + image_index, num_disks, cmd, argc - optind, argv + optind);
+
+  /* Free resources.  */
+  grub_fini_all ();
+
+  return 0;
+}
diff --git a/util/grub-macho2img.c b/util/grub-macho2img.c
new file mode 100644
index 0000000..8683587
--- /dev/null
+++ b/util/grub-macho2img.c
@@ -0,0 +1,116 @@
+/* macho2img.c - tool to convert Mach-O to raw imagw.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/macho.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* XXX: this file assumes particular Mach-O layout and does no checks. */
+/* However as build system ensures correct usage of this tool this
+   shouldn't be a problem. */
+
+int
+main (int argc, char **argv)
+{
+  FILE *in, *out;
+  int do_bss = 0;
+  char *buf;
+  int bufsize;
+  struct grub_macho_header32 *head;
+  struct grub_macho_segment32 *curcmd;
+  unsigned i;
+  unsigned bssstart = 0;
+  unsigned bssend = 0;
+
+  if (argc && strcmp (argv[1], "--bss") == 0)
+    do_bss = 1;
+  if (argc < 2 + do_bss)
+    {
+      printf ("Usage: %s [--bss] filename.exec filename.img\n"
+	      "Convert Mach-O into raw image\n", argv[0]);
+      return 0;
+    }
+  in = fopen (argv[1 + do_bss], "rb");
+  if (! in)
+    {
+      printf ("Couldn't open %s\n", argv[1 + do_bss]);
+      return 1;
+    }
+  out = fopen (argv[2 + do_bss], "wb");
+  if (! out)
+    {
+      fclose (in);
+      printf ("Couldn't open %s\n", argv[2 + do_bss]);
+      return 2;
+    }
+  fseek (in, 0, SEEK_END);
+  bufsize = ftell (in);
+  fseek (in, 0, SEEK_SET);
+  buf = malloc (bufsize);
+  if (! buf)
+    {
+      fclose (in);
+      fclose (out);
+      printf ("Couldn't allocate buffer\n");
+      return 3;
+    }
+  fread (buf, 1, bufsize, in);
+  head = (struct grub_macho_header32 *) buf;
+  if (grub_le_to_cpu32 (head->magic) != GRUB_MACHO_MAGIC32)
+    {
+      fclose (in);
+      fclose (out);
+      free (buf);
+      printf ("Invalid Mach-O fle\n");
+      return 4;
+    }
+  curcmd = (struct grub_macho_segment32 *) (buf + sizeof (*head));
+  for (i = 0; i < grub_le_to_cpu32 (head->ncmds); i++,
+	 curcmd = (struct grub_macho_segment32 *)
+	 (((char *) curcmd) + curcmd->cmdsize))
+    {
+      if (curcmd->cmd != GRUB_MACHO_CMD_SEGMENT32)
+	continue;
+      fwrite (buf + grub_le_to_cpu32 (curcmd->fileoff), 1,
+	      grub_le_to_cpu32 (curcmd->filesize), out);
+      if (grub_le_to_cpu32 (curcmd->vmsize)
+	  > grub_le_to_cpu32 (curcmd->filesize))
+	{
+	  bssstart = grub_le_to_cpu32 (curcmd->vmaddr)
+	    + grub_le_to_cpu32 (curcmd->filesize) ;
+	  bssend = grub_le_to_cpu32 (curcmd->vmaddr)
+	    + grub_le_to_cpu32 (curcmd->vmsize) ;
+	}
+    }
+  if (do_bss)
+    {
+      grub_uint32_t tmp;
+      fseek (out, 0x5c, SEEK_SET);
+      tmp = grub_cpu_to_le32 (bssstart);
+      fwrite (&tmp, 4, 1, out);
+      tmp = grub_cpu_to_le32 (bssend);
+      fwrite (&tmp, 4, 1, out);
+    }
+  fclose (in);
+  fclose (out);
+  printf("macho2img complete\n");
+  return 0;
+}
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
new file mode 100644
index 0000000..a8c2675
--- /dev/null
+++ b/util/grub-mkconfig.in
@@ -0,0 +1,269 @@
+#! /bin/sh -e
+
+# Generate grub.cfg by inspecting /boot contents.
+# Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+transform="@program_transform_name@"
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libdir=@libdir@
+sysconfdir=@sysconfdir@
+package_version=@PACKAGE_VERSION@
+datarootdir=@datarootdir@
+datadir=@datadir@
+pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"`
+grub_prefix=`echo /boot/grub | sed ${transform}`
+grub_cfg=""
+grub_mkconfig_dir=${sysconfdir}/grub.d
+
+grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
+grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: $0 [OPTION]
+Generate a grub config file
+
+  -o, --output=FILE       output generated config to FILE [default=stdout]
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "$0 (GNU GRUB ${package_version})"
+	exit 0 ;;
+    -o)
+	shift
+	grub_cfg=$1
+	;;
+    --output=*)
+	grub_cfg=`echo "$option" | sed 's/--output=//'`
+	;;
+    -*)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    esac
+done
+
+. ${libdir}/grub/grub-mkconfig_lib
+
+if [ "x$EUID" = "x" ] ; then
+  EUID=`id -u`
+fi
+
+if [ "$EUID" != 0 ] ; then
+  root=f
+  case "`uname 2>/dev/null`" in
+    CYGWIN*)
+      # Cygwin: Assume root if member of admin group
+      for g in `id -G 2>/dev/null` ; do
+	case $g in
+	  0|544) root=t ;;
+	esac
+      done ;;
+  esac
+  if [ $root != t ] ; then
+    echo "$0: You must run this as root" >&2
+    exit 1
+  fi
+fi
+
+set $grub_mkdevicemap dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+set $grub_probe dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+mkdir -p ${grub_prefix}
+
+if test -e ${grub_prefix}/device.map ; then : ; else
+  ${grub_mkdevicemap}
+fi
+
+# Device containing our userland.  Typically used for root= parameter.
+GRUB_DEVICE="`${grub_probe} --target=device /`"
+GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true
+
+# Device containing our /boot partition.  Usually the same as GRUB_DEVICE.
+GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`"
+GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true
+
+# Filesystem for the device containing our userland.  Used for stuff like
+# choosing Hurd filesystem module.
+GRUB_FS="`${grub_probe} --target=fs / 2> /dev/null || echo unknown`"
+
+if test -f ${sysconfdir}/default/grub ; then
+  . ${sysconfdir}/default/grub
+fi
+
+# XXX: should this be deprecated at some point?
+if [ "x${GRUB_TERMINAL}" != "x" ] ; then
+  GRUB_TERMINAL_INPUT="${GRUB_TERMINAL}"
+  GRUB_TERMINAL_OUTPUT="${GRUB_TERMINAL}"
+fi
+
+case x${GRUB_TERMINAL_OUTPUT} in
+  x | xgfxterm)
+    # If this platform supports gfxterm, try to use it.
+    if test -e ${grub_prefix}/gfxterm.mod ; then
+      GRUB_VIDEO_BACKEND=
+      for i in vbe ; do
+        if test -e ${grub_prefix}/$i.mod ; then
+          GRUB_VIDEO_BACKEND=$i
+          break
+        fi
+      done
+      if [ -n "${GRUB_VIDEO_BACKEND}" ] ; then
+        GRUB_TERMINAL_OUTPUT=gfxterm
+      elif [ "${GRUB_TERMINAL_OUTPUT}" = "gfxterm" ] ; then
+        echo "No suitable backend could be found for gfxterm." >&2 ; exit 1
+      fi
+    fi
+  ;;
+  xconsole | xserial | xofconsole) ;;
+  *) echo "Invalid output terminal \"${GRUB_TERMINAL_OUTPUT}\"" >&2 ; exit 1 ;;
+esac
+
+# check for terminals that require fonts
+case ${GRUB_TERMINAL_OUTPUT} in
+  gfxterm)
+    if [ -n "$GRUB_FONT" ] ; then
+      if is_path_readable_by_grub ${GRUB_FONT} > /dev/null ; then
+        GRUB_FONT_PATH=${GRUB_FONT}
+	else
+	  echo "No such font or not readable by grub: ${GRUB_FONT}" >&2
+	  exit 1
+	fi
+    else
+      for dir in ${pkgdatadir} /boot/grub /usr/share/grub ; do
+        for basename in unicode unifont ascii; do
+	  path="${dir}/${basename}.pf2"
+          if is_path_readable_by_grub ${path} > /dev/null ; then
+	    GRUB_FONT_PATH=${path}
+	  else
+	    continue
+	  fi
+	  if [ "${basename}" = "ascii" ] ; then
+	    # make sure all our children behave in conformance with ascii..
+	    export LANG=C
+	  fi
+	  break 2
+        done
+      done
+    fi
+    if [ -z "${GRUB_FONT_PATH}" ] ; then
+      # fallback to the native terminal for this platform
+      unset GRUB_TERMINAL_OUTPUT
+    fi
+  ;;
+  *)
+    # make sure all our children behave in conformance with ascii..
+    export LANG=C
+esac
+
+# These are defined in this script, export them here so that user can
+# override them.
+export GRUB_DEVICE \
+  GRUB_DEVICE_UUID \
+  GRUB_DEVICE_BOOT \
+  GRUB_DEVICE_BOOT_UUID \
+  GRUB_FS \
+  GRUB_FONT_PATH \
+  GRUB_PRELOAD_MODULES \
+  GRUB_VIDEO_BACKEND
+
+# These are optional, user-defined variables.
+export GRUB_DEFAULT \
+  GRUB_HIDDEN_TIMEOUT \
+  GRUB_HIDDEN_TIMEOUT_QUIET \
+  GRUB_TIMEOUT \
+  GRUB_DISTRIBUTOR \
+  GRUB_CMDLINE_LINUX \
+  GRUB_CMDLINE_LINUX_DEFAULT \
+  GRUB_TERMINAL_INPUT \
+  GRUB_TERMINAL_OUTPUT \
+  GRUB_SERIAL_COMMAND \
+  GRUB_DISABLE_LINUX_UUID \
+  GRUB_DISABLE_LINUX_RECOVERY \
+  GRUB_GFXMODE \
+  GRUB_DISABLE_OS_PROBER
+
+if test "x${grub_cfg}" != "x"; then
+  rm -f ${grub_cfg}.new
+  exec > ${grub_cfg}.new
+
+  # Allow this to fail, since /boot/grub/ might need to be fatfs to support some
+  # firmware implementations (e.g. OFW or EFI).
+  chmod 400 ${grub_cfg}.new || grub_warn "Could not make ${grub_cfg}.new readable by only root.\
+  This means that if the generated config contains a password it is readable by everyone"
+fi
+echo "Generating grub.cfg ..." >&2
+
+cat << EOF
+#
+# DO NOT EDIT THIS FILE
+#
+# It is automatically generated by $0 using templates
+# from ${grub_mkconfig_dir} and settings from ${sysconfdir}/default/grub
+#
+EOF
+
+for i in ${grub_mkconfig_dir}/* ; do
+  case "$i" in
+    # emacsen backup files. FIXME: support other editors
+    *~) ;;
+    *)
+      if grub_file_is_not_garbage "$i" && test -x "$i" ; then
+        echo
+        echo "### BEGIN $i ###"
+        "$i"
+        echo "### END $i ###"
+      fi
+    ;;
+  esac
+done
+
+if test "x${grub_cfg}" != "x" ; then
+  # none of the children aborted with error, install the new grub.cfg
+  mv -f ${grub_cfg}.new ${grub_cfg}
+fi
+
+echo "done" >&2
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
new file mode 100644
index 0000000..bb30cc4
--- /dev/null
+++ b/util/grub-mkconfig_lib.in
@@ -0,0 +1,217 @@
+# Helper library for grub-mkconfig
+# Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+transform="@program_transform_name@"
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+datarootdir=@datarootdir@
+datadir=@datadir@
+sbindir=@sbindir@
+pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"`
+
+grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
+
+grub_warn ()
+{
+  echo "Warning: $@" >&2
+}
+
+make_system_path_relative_to_its_root ()
+{
+  path=$1
+  # abort if file doesn't exist
+  if test -e $path ; then : ;else
+    return 1
+  fi
+
+  # canonicalize
+  if path=`readlink -f $path` ; then : ; else
+    return 1
+  fi
+
+  # if not a directory, climb up to the directory containing it
+  if test -d $path ; then
+    dir=$path
+  else
+    dir=`echo $path | sed -e "s,/[^/]*$,,g"`
+  fi
+
+  num=`stat -c %d $dir`
+
+  # this loop sets $dir to the root directory of the filesystem we're inspecting
+  while : ; do
+    parent=`readlink -f $dir/..`
+    if [ "x`stat -c %d $parent`" = "x$num" ] ; then : ; else
+      # $parent is another filesystem; we found it.
+      break
+    fi
+    if [ "x$dir" = "x/" ] ; then
+      # / is our root.
+      break
+    fi
+    dir=$parent
+  done
+
+  # This function never prints trailing slashes (so that its output can be
+  # appended a slash unconditionally).  Each slash in $dir is considered a
+  # preceding slash, and therefore the root directory is an empty string.
+  if [ "$dir" = "/" ] ; then
+    dir=""
+  fi
+
+  # XXX: This fails if $dir contains ','.
+  path=`echo "$path" | sed -e "s,^$dir,,g"` || return 1
+
+  case "`uname 2>/dev/null`" in
+    CYGWIN*)
+      # Cygwin: Check if regular or emulated mount.
+      if [ -z "$dir" ] || [ "`stat -c %D "$dir/.."`" != 620000 ] ; then
+        # Reached some mount point not below /cygdrive.
+        # GRUB does not know Cygwin's emulated mounts,
+        # convert to Win32 path and remove drive letter.
+        path=`cygpath -m "$path" | sed -n 's,^[A-Za-z]:,,p'`
+        test ! -z "$path" || return 1
+      fi ;;
+  esac
+
+  echo "$path"
+}
+
+is_path_readable_by_grub ()
+{
+  path=$1
+
+  # abort if path doesn't exist
+  if test -e $path ; then : ;else
+    return 1
+  fi
+
+  # abort if file is in a filesystem we can't read
+  if ${grub_probe} -t fs $path > /dev/null 2>&1 ; then : ; else
+    return 1
+  fi
+
+  return 0
+}
+
+convert_system_path_to_grub_path ()
+{
+  path=$1
+
+  grub_warn "convert_system_path_to_grub_path() is deprecated.  Use prepare_grub_to_access_device() instead."
+
+  # abort if GRUB can't access the path
+  if is_path_readable_by_grub ${path} ; then : ; else
+    return 1
+  fi
+
+  if drive=`${grub_probe} -t drive $path` ; then : ; else
+    return 1
+  fi
+
+  if relative_path=`make_system_path_relative_to_its_root $path` ; then : ; else
+    return 1
+  fi
+
+  echo ${drive}${relative_path}
+}
+
+prepare_grub_to_access_device ()
+{
+  device=$1
+
+  # Abstraction modules aren't auto-loaded.
+  abstraction="`${grub_probe} --device ${device} --target=abstraction`"
+  for module in ${abstraction} ; do 
+    echo "insmod ${module}"
+  done
+
+  fs="`${grub_probe} --device ${device} --target=fs`"
+  for module in ${fs} ; do
+    echo "insmod ${module}"
+  done
+
+  # If there's a filesystem UUID that GRUB is capable of identifying, use it;
+  # otherwise set root as per value in device.map.
+  echo "set root=`${grub_probe} --device ${device} --target=drive`"
+  if fs_uuid="`${grub_probe} --device ${device} --target=fs_uuid 2> /dev/null`" ; then
+    echo "search --no-floppy --fs-uuid --set ${fs_uuid}"
+  fi
+}
+
+grub_file_is_not_garbage ()
+{
+  if test -f "$1" ; then
+    case "$1" in
+      *.dpkg-*) return 1 ;; # debian dpkg
+    esac
+  else
+    return 1
+  fi
+  return 0
+}
+
+version_test_numeric ()
+{
+  local a=$1
+  local cmp=$2
+  local b=$3
+  if [ "$a" = "$b" ] ; then
+    case $cmp in
+      ge|eq|le) return 0 ;;
+      gt|lt) return 1 ;;
+    esac
+  fi
+  if [ "$cmp" = "lt" ] ; then
+    c=$a
+    a=$b
+    b=$c
+  fi
+  if (echo $a ; echo $b) | sort -n | head -n 1 | grep -qx $b ; then
+    return 0
+  else
+    return 1
+  fi
+}
+
+version_test_gt ()
+{
+  local a=`echo $1 | sed -e "s/[^-]*-//"`
+  local b=`echo $2 | sed -e "s/[^-]*-//"`
+  local cmp=gt
+  if [ "x$b" = "x" ] ; then
+    return 0
+  fi
+  case $a:$b in
+    *.old:*.old) ;;
+    *.old:*) a=`echo -n $a | sed -e s/\.old$//` ; cmp=gt ;;
+    *:*.old) b=`echo -n $b | sed -e s/\.old$//` ; cmp=ge ;;
+  esac
+  version_test_numeric $a $cmp $b
+  return $?
+}
+
+version_find_latest ()
+{
+  local a=""
+  for i in $@ ; do
+    if version_test_gt "$i" "$a" ; then
+      a="$i"
+    fi
+  done
+  echo "$a"
+}
diff --git a/util/grub-mkdevicemap.c b/util/grub-mkdevicemap.c
new file mode 100644
index 0000000..ec43b34
--- /dev/null
+++ b/util/grub-mkdevicemap.c
@@ -0,0 +1,161 @@
+/* grub-mkdevicemap.c - make a device map file automatically */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+
+#include <grub/util/misc.h>
+#include <grub/util/deviceiter.h>
+
+#define _GNU_SOURCE	1
+#include <getopt.h>
+
+static void
+make_device_map (const char *device_map, int floppy_disks)
+{
+  int num_hd = 0;
+  int num_fd = 0;
+  FILE *fp;
+
+  auto int NESTED_FUNC_ATTR process_device (const char *name, int is_floppy);
+
+  int NESTED_FUNC_ATTR process_device (const char *name, int is_floppy)
+  {
+    grub_util_emit_devicemap_entry (fp, (char *) name,
+				    is_floppy, &num_fd, &num_hd);
+    return 0;
+  }
+
+  if (strcmp (device_map, "-") == 0)
+    fp = stdout;
+  else
+    fp = fopen (device_map, "w");
+
+  if (! fp)
+    grub_util_error ("cannot open %s", device_map);
+
+  grub_util_iterate_devices (process_device, floppy_disks);
+
+  if (fp != stdout)
+    fclose (fp);
+}
+
+static struct option options[] =
+  {
+    {"device-map", required_argument, 0, 'm'},
+    {"probe-second-floppy", no_argument, 0, 's'},
+    {"no-floppy", no_argument, 0, 'n'},
+    {"help", no_argument, 0, 'h'},
+    {"version", no_argument, 0, 'V'},
+    {"verbose", no_argument, 0, 'v'},
+    {0, 0, 0, 0}
+  };
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr,
+	     "Try ``grub-mkdevicemap --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-mkdevicemap [OPTION]...\n\
+\n\
+Generate a device map file automatically.\n\
+\n\
+  -n, --no-floppy           do not probe any floppy drive\n\
+  -s, --probe-second-floppy probe the second floppy drive\n\
+  -m, --device-map=FILE     use FILE as the device map [default=%s]\n\
+  -h, --help                display this message and exit\n\
+  -V, --version             print version information and exit\n\
+  -v, --verbose             print verbose messages\n\
+\n\
+Report bugs to <%s>.\n\
+",
+	    DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+int
+main (int argc, char *argv[])
+{
+  char *dev_map = 0;
+  int floppy_disks = 1;
+
+  progname = "grub-mkdevicemap";
+
+  /* Check for options.  */
+  while (1)
+    {
+      int c = getopt_long (argc, argv, "snm:r:hVv", options, 0);
+
+      if (c == -1)
+	break;
+      else
+	switch (c)
+	  {
+	  case 'm':
+	    if (dev_map)
+	      free (dev_map);
+
+	    dev_map = xstrdup (optarg);
+	    break;
+
+	  case 'n':
+	    floppy_disks = 0;
+	    break;
+
+	  case 's':
+	    floppy_disks = 2;
+	    break;
+
+	  case 'h':
+	    usage (0);
+	    break;
+
+	  case 'V':
+	    printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION);
+	    return 0;
+
+	  case 'v':
+	    verbosity++;
+	    break;
+
+	  default:
+	    usage (1);
+	    break;
+	  }
+    }
+
+  make_device_map (dev_map ? : DEFAULT_DEVICE_MAP, floppy_disks);
+
+  free (dev_map);
+
+  return 0;
+}
diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c
new file mode 100644
index 0000000..cfd6f9d
--- /dev/null
+++ b/util/grub-mkfont.c
@@ -0,0 +1,620 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/util/misc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include <freetype/ftsynth.h>
+
+#define GRUB_FONT_DEFAULT_SIZE		16
+
+#define GRUB_FONT_RANGE_BLOCK		1024
+
+struct grub_glyph_info
+{
+  struct grub_glyph_info *next;
+  grub_uint32_t char_code;
+  int width;
+  int height;
+  int x_ofs;
+  int y_ofs;
+  int device_width;
+  int bitmap_size;
+  grub_uint8_t bitmap[0];
+};
+
+#define GRUB_FONT_FLAG_BOLD		1
+#define GRUB_FONT_FLAG_NOBITMAP		2
+#define GRUB_FONT_FLAG_NOHINTING	4
+#define GRUB_FONT_FLAG_FORCEHINT	8
+
+struct grub_font_info
+{
+  char* name;
+  int style;
+  int desc;
+  int size;
+  int max_width;
+  int max_height;
+  int min_y;
+  int flags;
+  int num_range;
+  grub_uint32_t *ranges;
+  struct grub_glyph_info *glyph;
+};
+
+static struct option options[] =
+{
+  {"output", required_argument, 0, 'o'},
+  {"name", required_argument, 0, 'n'},
+  {"index", required_argument, 0, 'i'},
+  {"range", required_argument, 0, 'r'},
+  {"size", required_argument, 0, 's'},
+  {"desc", required_argument, 0, 'd'},
+  {"bold", no_argument, 0, 'b'},
+  {"no-bitmap", no_argument, 0, 0x100},
+  {"no-hinting", no_argument, 0, 0x101},
+  {"force-autohint", no_argument, 0, 'a'},
+  {"help", no_argument, 0, 'h'},
+  {"version", no_argument, 0, 'V'},
+  {"verbose", no_argument, 0, 'v'},
+  {0, 0, 0, 0}
+};
+
+int font_verbosity;
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``grub-mkfont --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-mkfont [OPTIONS] FONT_FILES\n\
+\nOptions:\n\
+  -o, --output=FILE_NAME    set output file name\n\
+  -i, --index=N             set face index\n\
+  -r, --range=A-B[,C-D]     set font range\n\
+  -n, --name=S              set font family name\n\
+  -s, --size=N              set font size\n\
+  -d, --desc=N              set font descent\n\
+  -b, --bold                convert to bold font\n\
+  -a, --force-autohint      force autohint\n\
+  --no-hinting              disable hinting\n\
+  --no-bitmap               ignore bitmap strikes when loading\n\
+  -h, --help                display this message and exit\n\
+  -V, --version             print version information and exit\n\
+  -v, --verbose             print verbose messages\n\
+\n\
+Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+void
+add_pixel (grub_uint8_t **data, int *mask, int not_blank)
+{
+  if (*mask == 0)
+    {
+      (*data)++;
+      **data = 0;
+      *mask = 128;
+    }
+
+  if (not_blank)
+    **data |= *mask;
+
+  *mask >>= 1;
+}
+
+void
+add_char (struct grub_font_info *font_info, FT_Face face,
+	  grub_uint32_t char_code)
+{
+  struct grub_glyph_info *glyph_info, **p_glyph;
+  int width, height;
+  grub_uint8_t *data;
+  int mask, i, j, bitmap_size;
+  FT_GlyphSlot glyph;
+  int flag = FT_LOAD_RENDER | FT_LOAD_MONOCHROME;
+
+  if (font_info->flags & GRUB_FONT_FLAG_NOBITMAP)
+    flag |= FT_LOAD_NO_BITMAP;
+
+  if (font_info->flags & GRUB_FONT_FLAG_NOHINTING)
+    flag |= FT_LOAD_NO_HINTING;
+  else if (font_info->flags & GRUB_FONT_FLAG_FORCEHINT)
+    flag |= FT_LOAD_FORCE_AUTOHINT;
+
+  if (FT_Load_Char (face, char_code, flag))
+    return;
+
+  glyph = face->glyph;
+
+  if (font_info->flags & GRUB_FONT_FLAG_BOLD)
+    FT_GlyphSlot_Embolden (glyph);
+
+  p_glyph = &font_info->glyph;
+  while ((*p_glyph) && ((*p_glyph)->char_code > char_code))
+    {
+      p_glyph = &(*p_glyph)->next;
+    }
+
+  /* Ignore duplicated glyph.  */
+  if ((*p_glyph) && ((*p_glyph)->char_code == char_code))
+    return;
+
+  width = glyph->bitmap.width;
+  height = glyph->bitmap.rows;
+
+  bitmap_size = ((width * height + 7) / 8);
+  glyph_info = xmalloc (sizeof (struct grub_glyph_info) + bitmap_size);
+  glyph_info->bitmap_size = bitmap_size;
+
+  glyph_info->next = *p_glyph;
+  *p_glyph = glyph_info;
+
+  glyph_info->char_code = char_code;
+  glyph_info->width = width;
+  glyph_info->height = height;
+  glyph_info->x_ofs = glyph->bitmap_left;
+  glyph_info->y_ofs = glyph->bitmap_top - height;
+  glyph_info->device_width = glyph->metrics.horiAdvance / 64;
+
+  if (width > font_info->max_width)
+    font_info->max_width = width;
+
+  if (height > font_info->max_height)
+    font_info->max_height = height;
+
+  if (glyph_info->y_ofs < font_info->min_y)
+    font_info->min_y = glyph_info->y_ofs;
+
+  mask = 0;
+  data = &glyph_info->bitmap[0] - 1;
+  for (j = 0; j < height; j++)
+    for (i = 0; i < width; i++)
+      add_pixel (&data, &mask,
+		 glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] &
+		 (1 << (7 - (i & 7))));
+}
+
+void
+add_font (struct grub_font_info *font_info, FT_Face face)
+{
+  if (font_info->num_range)
+    {
+      int i;
+      grub_uint32_t j;
+
+      for (i = 0; i < font_info->num_range; i++)
+	for (j = font_info->ranges[i * 2]; j <= font_info->ranges[i * 2 + 1];
+	     j++)
+	  add_char (font_info, face, j);
+    }
+  else
+    {
+      grub_uint32_t char_code, glyph_index;
+
+      for (char_code = FT_Get_First_Char (face, &glyph_index);
+	   glyph_index;
+	   char_code = FT_Get_Next_Char (face, char_code, &glyph_index))
+	add_char (font_info, face, char_code);
+    }
+}
+
+void
+write_string_section (char *name, char *str, int* offset, FILE* file)
+{
+  grub_uint32_t leng, leng_be32;
+
+  leng = strlen (str) + 1;
+  leng_be32 = grub_cpu_to_be32 (leng);
+
+  grub_util_write_image (name, 4, file);
+  grub_util_write_image ((char *) &leng_be32, 4, file);
+  grub_util_write_image (str, leng, file);
+
+  *offset += 8 + leng;
+}
+
+void
+write_be16_section (char *name, grub_uint16_t data, int* offset, FILE* file)
+{
+  grub_uint32_t leng;
+
+  leng = grub_cpu_to_be32 (2);
+  data = grub_cpu_to_be16 (data);
+  grub_util_write_image (name, 4, file);
+  grub_util_write_image ((char *) &leng, 4, file);
+  grub_util_write_image ((char *) &data, 2, file);
+
+  *offset += 10;
+}
+
+void
+print_glyphs (struct grub_font_info *font_info)
+{
+  int num;
+  struct grub_glyph_info *glyph;
+  char line[512];
+
+  for (glyph = font_info->glyph, num = 0; glyph; glyph = glyph->next, num++)
+    {
+      int x, y, xmax, xmin, ymax, ymin;
+      grub_uint8_t *bitmap, mask;
+
+      printf ("\nGlyph #%d, U+%04x\n", num, glyph->char_code);
+      printf ("Width %d, Height %d, X offset %d, Y offset %d, Device width %d\n",
+	      glyph->width, glyph->height, glyph->x_ofs, glyph->y_ofs,
+	      glyph->device_width);
+
+      xmax = glyph->x_ofs + glyph->width;
+      if (xmax < glyph->device_width)
+	xmax = glyph->device_width;
+
+      xmin = glyph->x_ofs;
+      if (xmin > 0)
+	xmin = 0;
+
+      ymax = glyph->y_ofs + glyph->height;
+      if (ymax < font_info->size - font_info->desc)
+	ymax = font_info->size - font_info->desc;
+
+      ymin = glyph->y_ofs;
+      if (ymin > - font_info->desc)
+	ymin = - font_info->desc;
+
+      bitmap = glyph->bitmap;
+      mask = 0x80;
+      for (y = ymax - 1; y >= ymin; y--)
+	{
+	  int line_pos;
+
+	  line_pos = 0;
+	  for (x = xmin; x < xmax; x++)
+	    {
+	      if ((x >= glyph->x_ofs) &&
+		  (x < glyph->x_ofs + glyph->width) &&
+		  (y >= glyph->y_ofs) &&
+		  (y < glyph->y_ofs + glyph->height))
+		{
+		  line[line_pos++] = (*bitmap & mask) ? '#' : '_';
+		  mask >>= 1;
+		  if (mask == 0)
+		    {
+		      mask = 0x80;
+		      bitmap++;
+		    }
+		}
+	      else if ((x >= 0) &&
+		       (x < glyph->device_width) &&
+		       (y >= - font_info->desc) &&
+		       (y < font_info->size - font_info->desc))
+		{
+		  line[line_pos++] = ((x == 0) || (y == 0)) ? '+' : '.';
+		}
+	      else
+		line[line_pos++] = '*';
+	    }
+	  line[line_pos] = 0;
+	  printf ("%s\n", line);
+	}
+    }
+}
+
+void
+write_font (struct grub_font_info *font_info, char *output_file)
+{
+  FILE *file;
+  grub_uint32_t leng, data;
+  char style_name[20], *font_name;
+  struct grub_glyph_info *cur, *pre;
+  int num, offset;
+
+  file = fopen (output_file, "wb");
+  if (! file)
+    grub_util_error ("Can\'t write to file %s.", output_file);
+
+  offset = 0;
+
+  leng = grub_cpu_to_be32 (4);
+  grub_util_write_image ("FILE", 4, file);
+  grub_util_write_image ((char *) &leng, 4, file);
+  grub_util_write_image ("PFF2", 4, file);
+  offset += 12;
+
+  if (! font_info->name)
+    font_info->name = "Unknown";
+
+  if (font_info->flags & GRUB_FONT_FLAG_BOLD)
+    font_info->style |= FT_STYLE_FLAG_BOLD;
+
+  style_name[0] = 0;
+  if (font_info->style & FT_STYLE_FLAG_BOLD)
+    strcpy (style_name, " Bold");
+
+  if (font_info->style & FT_STYLE_FLAG_ITALIC)
+    strcat (style_name, " Italic");
+
+  if (! style_name[0])
+    strcpy (style_name, " Regular");
+
+  asprintf (&font_name, "%s %s %d", font_info->name, &style_name[1],
+	    font_info->size);
+
+  write_string_section ("NAME", font_name, &offset, file);
+  write_string_section ("FAMI", font_info->name, &offset, file);
+  write_string_section ("WEIG",
+			(font_info->style & FT_STYLE_FLAG_BOLD) ?
+			"bold" : "normal",
+			&offset, file);
+  write_string_section ("SLAN",
+			(font_info->style & FT_STYLE_FLAG_ITALIC) ?
+			"italic" : "normal",
+			&offset, file);
+
+  write_be16_section ("PTSZ", font_info->size, &offset, file);
+  write_be16_section ("MAXW", font_info->max_width, &offset, file);
+  write_be16_section ("MAXH", font_info->max_height, &offset, file);
+
+  if (! font_info->desc)
+    {
+      if (font_info->min_y >= 0)
+	font_info->desc = 1;
+      else
+	font_info->desc = - font_info->min_y;
+    }
+
+  write_be16_section ("ASCE", font_info->size - font_info->desc, &offset, file);
+  write_be16_section ("DESC", font_info->desc, &offset, file);
+
+  if (font_verbosity > 0)
+    {
+      printf ("Font name: %s\n", font_name);
+      printf ("Max width: %d\n", font_info->max_width);
+      printf ("Max height: %d\n", font_info->max_height);
+      printf ("Font ascent: %d\n", font_info->size - font_info->desc);
+      printf ("Font descent: %d\n", font_info->desc);
+    }
+
+  num = 0;
+  pre = 0;
+  cur = font_info->glyph;
+  while (cur)
+    {
+      struct grub_glyph_info *nxt;
+
+      nxt = cur->next;
+      cur->next = pre;
+      pre = cur;
+      cur = nxt;
+      num++;
+    }
+
+  font_info->glyph = pre;
+
+  if (font_verbosity > 0)
+    printf ("Number of glyph: %d\n", num);
+
+  leng = grub_cpu_to_be32 (num * 9);
+  grub_util_write_image ("CHIX", 4, file);
+  grub_util_write_image ((char *) &leng, 4, file);
+  offset += 8 + num * 9 + 8;
+
+  for (cur = font_info->glyph; cur; cur = cur->next)
+    {
+      data = grub_cpu_to_be32 (cur->char_code);
+      grub_util_write_image ((char *) &data, 4, file);
+      data = 0;
+      grub_util_write_image ((char *) &data, 1, file);
+      data = grub_cpu_to_be32 (offset);
+      grub_util_write_image ((char *) &data, 4, file);
+      offset += 10 + cur->bitmap_size;
+    }
+
+  leng = 0xffffffff;
+  grub_util_write_image ("DATA", 4, file);
+  grub_util_write_image ((char *) &leng, 4, file);
+
+  for (cur = font_info->glyph; cur; cur = cur->next)
+    {
+      data = grub_cpu_to_be16 (cur->width);
+      grub_util_write_image ((char *) &data, 2, file);
+      data = grub_cpu_to_be16 (cur->height);
+      grub_util_write_image ((char *) &data, 2, file);
+      data = grub_cpu_to_be16 (cur->x_ofs);
+      grub_util_write_image ((char *) &data, 2, file);
+      data = grub_cpu_to_be16 (cur->y_ofs);
+      grub_util_write_image ((char *) &data, 2, file);
+      data = grub_cpu_to_be16 (cur->device_width);
+      grub_util_write_image ((char *) &data, 2, file);
+      grub_util_write_image ((char *) &cur->bitmap[0], cur->bitmap_size, file);
+    }
+
+  if (font_verbosity > 1)
+    print_glyphs (font_info);
+
+  fclose (file);
+}
+
+int
+main (int argc, char *argv[])
+{
+  struct grub_font_info font_info;
+  FT_Library ft_lib;
+  int font_index = 0;
+  int font_size = 0;
+  char *output_file = NULL;
+
+  memset (&font_info, 0, sizeof (font_info));
+
+  progname = "grub-mkfont";
+
+  /* Check for options.  */
+  while (1)
+    {
+      int c = getopt_long (argc, argv, "bao:n:i:s:d:r:hVv", options, 0);
+
+      if (c == -1)
+	break;
+      else
+	switch (c)
+	  {
+	  case 'b':
+	    font_info.flags |= GRUB_FONT_FLAG_BOLD;
+	    break;
+
+	  case 0x100:
+	    font_info.flags |= GRUB_FONT_FLAG_NOBITMAP;
+	    break;
+
+	  case 0x101:
+	    font_info.flags |= GRUB_FONT_FLAG_NOHINTING;
+	    break;
+
+	  case 'a':
+	    font_info.flags |= GRUB_FONT_FLAG_FORCEHINT;
+	    break;
+
+	  case 'o':
+	    output_file = optarg;
+	    break;
+
+	  case 'n':
+	    font_info.name = optarg;
+	    break;
+
+	  case 'i':
+	    font_index = strtoul (optarg, NULL, 0);
+	    break;
+
+	  case 's':
+	    font_size = strtoul (optarg, NULL, 0);
+	    break;
+
+	  case 'r':
+	    {
+	      char *p = optarg;
+
+	      while (1)
+		{
+		  grub_uint32_t a, b;
+
+		  a = strtoul (p, &p, 0);
+		  if (*p != '-')
+		    grub_util_error ("Invalid font range");
+		  b = strtoul (p + 1, &p, 0);
+		  if ((font_info.num_range & (GRUB_FONT_RANGE_BLOCK - 1)) == 0)
+		    font_info.ranges = xrealloc (font_info.ranges,
+						 (font_info.num_range +
+						  GRUB_FONT_RANGE_BLOCK) *
+						 sizeof (int) * 2);
+
+		  font_info.ranges[font_info.num_range * 2] = a;
+		  font_info.ranges[font_info.num_range * 2 + 1] = b;
+		  font_info.num_range++;
+
+		  if (*p)
+		    {
+		      if (*p != ',')
+			grub_util_error ("Invalid font range");
+		      else
+			p++;
+		    }
+		  else
+		    break;
+		}
+	      break;
+	    }
+
+	  case 'd':
+	    font_info.desc = strtoul (optarg, NULL, 0);
+	    break;
+
+	  case 'h':
+	    usage (0);
+	    break;
+
+	  case 'V':
+	    printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION);
+	    return 0;
+
+	  case 'v':
+	    font_verbosity++;
+	    break;
+
+	  default:
+	    usage (1);
+	    break;
+	  }
+    }
+
+  if (! output_file)
+    grub_util_error ("No output file is specified.");
+
+  if (FT_Init_FreeType (&ft_lib))
+    grub_util_error ("FT_Init_FreeType fails");
+
+  for (; optind < argc; optind++)
+    {
+      FT_Face ft_face;
+      int size;
+
+      if (FT_New_Face (ft_lib, argv[optind], font_index, &ft_face))
+	{
+	  grub_util_info ("Can't open file %s, index %d\n", argv[optind],
+			  font_index);
+	  continue;
+	}
+
+      if ((! font_info.name) && (ft_face->family_name))
+	font_info.name = xstrdup (ft_face->family_name);
+
+      size = font_size;
+      if (! size)
+	{
+	  if ((ft_face->face_flags & FT_FACE_FLAG_SCALABLE) ||
+	      (! ft_face->num_fixed_sizes))
+	    size = GRUB_FONT_DEFAULT_SIZE;
+	  else
+	    size = ft_face->available_sizes[0].height;
+	}
+
+      font_info.style = ft_face->style_flags;
+      font_info.size = size;
+
+      FT_Set_Pixel_Sizes (ft_face, size, size);
+      add_font (&font_info, ft_face);
+      FT_Done_Face (ft_face);
+    }
+
+  FT_Done_FreeType (ft_lib);
+
+  write_font (&font_info, output_file);
+
+  return 0;
+}
diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c
new file mode 100644
index 0000000..2b2a43a
--- /dev/null
+++ b/util/grub-pe2elf.c
@@ -0,0 +1,521 @@
+/* grub-pe2elf.c - tool to convert pe image to elf.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/util/misc.h>
+#include <grub/elf.h>
+#include <grub/efi/pe32.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+static struct option options[] = {
+  {"help", no_argument, 0, 'h'},
+  {"version", no_argument, 0, 'V'},
+  {"verbose", no_argument, 0, 'v'},
+  {0, 0, 0, 0}
+};
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``grub-pe2elf --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-pe2elf [OPTIONS] input [output]\n\
+\n\
+Tool to convert pe image to elf.\n\
+\nOptions:\n\
+  -h, --help                display this message and exit\n\
+  -V, --version             print version information and exit\n\
+  -v, --verbose             print verbose messages\n\
+\n\
+Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+/*
+ *  Section layout
+ *
+ *    null
+ *    .text
+ *    .rdata
+ *    .data
+ *    .bss
+ *    .modname
+ *    .moddeps
+ *    .symtab
+ *    .strtab
+ *    relocation sections
+ */
+
+#define TEXT_SECTION	1
+#define RDATA_SECTION	2
+#define DATA_SECTION	3
+#define BSS_SECTION	4
+#define MODNAME_SECTION	5
+#define MODDEPS_SECTION	6
+#define SYMTAB_SECTION	7
+#define STRTAB_SECTION	8
+
+#define REL_SECTION	9
+#define MAX_SECTIONS	12
+
+#define STRTAB_BLOCK	256
+
+static char *strtab;
+static int strtab_max, strtab_len;
+
+Elf32_Ehdr ehdr;
+Elf32_Shdr shdr[MAX_SECTIONS];
+int num_sections;
+grub_uint32_t offset;
+
+static int
+insert_string (char *name)
+{
+  int len, result;
+
+  if (*name == '_')
+    name++;
+
+  len = strlen (name);
+  if (strtab_len + len >= strtab_max)
+    {
+      strtab_max += STRTAB_BLOCK;
+      strtab = xrealloc (strtab, strtab_max);
+    }
+
+  strcpy (strtab + strtab_len, name);
+  result = strtab_len;
+  strtab_len += len + 1;
+
+  return result;
+}
+
+static int *
+write_section_data (FILE* fp, char *image,
+                    struct grub_pe32_coff_header *pe_chdr,
+                    struct grub_pe32_section_table *pe_shdr)
+{
+  int *section_map;
+  int i;
+
+  section_map = xmalloc ((pe_chdr->num_sections + 1) * sizeof (int));
+  section_map[0] = 0;
+
+  for (i = 0; i < pe_chdr->num_sections; i++, pe_shdr++)
+    {
+      grub_uint32_t idx;
+
+      if (! strcmp (pe_shdr->name, ".text"))
+        {
+          idx = TEXT_SECTION;
+          shdr[idx].sh_flags = SHF_ALLOC | SHF_EXECINSTR;
+        }
+      else if (! strcmp (pe_shdr->name, ".rdata"))
+        {
+          idx = RDATA_SECTION;
+          shdr[idx].sh_flags = SHF_ALLOC;
+        }
+      else if (! strcmp (pe_shdr->name, ".data"))
+        {
+          idx = DATA_SECTION;
+          shdr[idx].sh_flags = SHF_ALLOC | SHF_WRITE;
+        }
+      else if (! strcmp (pe_shdr->name, ".bss"))
+        {
+          idx = BSS_SECTION;
+          shdr[idx].sh_flags = SHF_ALLOC | SHF_WRITE;
+        }
+      else if (! strcmp (pe_shdr->name, ".modname"))
+        idx = MODNAME_SECTION;
+      else if (! strcmp (pe_shdr->name, ".moddeps"))
+        idx = MODDEPS_SECTION;
+      else
+        {
+          section_map[i + 1] = -1;
+          continue;
+        }
+
+      section_map[i + 1] = idx;
+
+      shdr[idx].sh_type = (idx == BSS_SECTION) ? SHT_NOBITS : SHT_PROGBITS;
+      shdr[idx].sh_size = pe_shdr->raw_data_size;
+      shdr[idx].sh_addralign = 1 << (((pe_shdr->characteristics >>
+                                       GRUB_PE32_SCN_ALIGN_SHIFT) &
+                                      GRUB_PE32_SCN_ALIGN_MASK) - 1);
+
+      if (idx != BSS_SECTION)
+        {
+          shdr[idx].sh_offset = offset;
+          grub_util_write_image_at (image + pe_shdr->raw_data_offset,
+                                    pe_shdr->raw_data_size, offset, fp);
+
+          offset += pe_shdr->raw_data_size;
+        }
+
+      if (pe_shdr->relocations_offset)
+        {
+          char name[5 + strlen (pe_shdr->name)];
+
+          if (num_sections >= MAX_SECTIONS)
+            grub_util_error ("Too many sections");
+
+          sprintf (name, ".rel%s", pe_shdr->name);
+
+          shdr[num_sections].sh_name = insert_string (name);
+          shdr[num_sections].sh_link = i;
+          shdr[num_sections].sh_info = idx;
+
+          shdr[idx].sh_name = shdr[num_sections].sh_name + 4;
+
+          num_sections++;
+        }
+      else
+        shdr[idx].sh_name = insert_string (pe_shdr->name);
+    }
+
+  return section_map;
+}
+
+static void
+write_reloc_section (FILE* fp, char *image,
+                     struct grub_pe32_coff_header *pe_chdr,
+                     struct grub_pe32_section_table *pe_shdr,
+                     Elf32_Sym *symtab,
+                     int *symtab_map)
+{
+  int i;
+
+  for (i = REL_SECTION; i < num_sections; i++)
+    {
+      struct grub_pe32_section_table *pe_sec;
+      struct grub_pe32_reloc *pe_rel;
+      Elf32_Rel *rel;
+      int num_rels, j, modified;
+
+      pe_sec = pe_shdr + shdr[i].sh_link;
+      pe_rel = (struct grub_pe32_reloc *) (image + pe_sec->relocations_offset);
+      rel = (Elf32_Rel *) xmalloc (pe_sec->num_relocations * sizeof (Elf32_Rel));
+      num_rels = 0;
+      modified = 0;
+
+      for (j = 0; j < pe_sec->num_relocations; j++, pe_rel++)
+        {
+          int type;
+          grub_uint32_t ofs, *addr;
+
+          if ((pe_rel->symtab_index >= pe_chdr->num_symbols) ||
+              (symtab_map[pe_rel->symtab_index] == -1))
+            grub_util_error ("Invalid symbol");
+
+          if (pe_rel->type == GRUB_PE32_REL_I386_DIR32)
+            type = R_386_32;
+          else if (pe_rel->type == GRUB_PE32_REL_I386_REL32)
+            type = R_386_PC32;
+          else
+            grub_util_error ("Unknown pe relocation type %d\n", pe_rel->type);
+
+          ofs = pe_rel->offset - pe_sec->virtual_address;
+          addr = (grub_uint32_t *)(image + pe_sec->raw_data_offset + ofs);
+          if (type == R_386_PC32)
+            {
+              unsigned char code;
+
+              code = image[pe_sec->raw_data_offset + ofs - 1];
+
+              if (((code != 0xe8) && (code != 0xe9)) || (*addr))
+                grub_util_error ("Invalid relocation (%x %x)", code, *addr);
+
+              modified = 1;
+              if (symtab[symtab_map[pe_rel->symtab_index]].st_shndx)
+                {
+                  if (symtab[symtab_map[pe_rel->symtab_index]].st_shndx
+                      != shdr[i].sh_info)
+                    grub_util_error ("Cross section call is not allowed");
+
+                  *addr = (symtab[symtab_map[pe_rel->symtab_index]].st_value
+                           - ofs - 4);
+
+                  continue;
+                }
+              else
+                *addr = -4;
+            }
+
+          rel[num_rels].r_offset = ofs;
+          rel[num_rels].r_info = ELF32_R_INFO (symtab_map[pe_rel->symtab_index],
+                                               type);
+          num_rels++;
+        }
+
+      if (modified)
+        grub_util_write_image_at (image + pe_sec->raw_data_offset,
+                                  shdr[shdr[i].sh_info].sh_size,
+                                  shdr[shdr[i].sh_info].sh_offset,
+                                  fp);
+
+      shdr[i].sh_type = SHT_REL;
+      shdr[i].sh_offset = offset;
+      shdr[i].sh_link = SYMTAB_SECTION;
+      shdr[i].sh_addralign = 4;
+      shdr[i].sh_entsize = sizeof (Elf32_Rel);
+      shdr[i].sh_size = num_rels * sizeof (Elf32_Rel);
+
+      grub_util_write_image_at (rel, shdr[i].sh_size, offset, fp);
+      offset += shdr[i].sh_size;
+      free (rel);
+    }
+}
+
+static void
+write_symbol_table (FILE* fp, char *image,
+                    struct grub_pe32_coff_header *pe_chdr,
+                    struct grub_pe32_section_table *pe_shdr,
+                    int *section_map)
+{
+  struct grub_pe32_symbol *pe_symtab;
+  char *pe_strtab;
+  Elf32_Sym *symtab;
+  int *symtab_map, num_syms;
+  int i;
+
+  pe_symtab = (struct grub_pe32_symbol *) (image + pe_chdr->symtab_offset);
+  pe_strtab = (char *) (pe_symtab + pe_chdr->num_symbols);
+
+  symtab = (Elf32_Sym *) xmalloc ((pe_chdr->num_symbols + 1) *
+                                  sizeof (Elf32_Sym));
+  memset (symtab, 0, (pe_chdr->num_symbols + 1) * sizeof (Elf32_Sym));
+  num_syms = 1;
+
+  symtab_map = (int *) xmalloc (pe_chdr->num_symbols * sizeof (int));
+
+  for (i = 0; i < (int) pe_chdr->num_symbols;
+       i += pe_symtab->num_aux + 1, pe_symtab += pe_symtab->num_aux + 1)
+    {
+      int bind, type;
+
+      symtab_map[i] = -1;
+      if ((pe_symtab->section > pe_chdr->num_sections) ||
+          (section_map[pe_symtab->section] == -1))
+        continue;
+
+      if (! pe_symtab->section)
+        type = STT_NOTYPE;
+      else if (pe_symtab->type == GRUB_PE32_DT_FUNCTION)
+        type = STT_FUNC;
+      else
+        type = STT_OBJECT;
+
+      if (pe_symtab->storage_class == GRUB_PE32_SYM_CLASS_EXTERNAL)
+        bind = STB_GLOBAL;
+      else
+        bind = STB_LOCAL;
+
+      if ((type != STT_FUNC) && (pe_symtab->num_aux))
+        {
+          if (! pe_symtab->value)
+            type = STT_SECTION;
+
+          symtab[num_syms].st_name = shdr[section_map[pe_symtab->section]].sh_name;
+        }
+      else
+        {
+	  char short_name[9];
+          char *name;
+
+	  if (pe_symtab->long_name[0])
+	    {
+	      strncpy (short_name, pe_symtab->short_name, 8);
+	      short_name[8] = 0;
+	      name = short_name;
+	    }
+	  else
+	    name = pe_strtab + pe_symtab->long_name[1];
+
+          if ((strcmp (name, "_grub_mod_init")) &&
+              (strcmp (name, "_grub_mod_fini")) &&
+              (bind == STB_LOCAL))
+              continue;
+
+          symtab[num_syms].st_name = insert_string (name);
+        }
+
+      symtab[num_syms].st_shndx = section_map[pe_symtab->section];
+      symtab[num_syms].st_value = pe_symtab->value;
+      symtab[num_syms].st_info = ELF32_ST_INFO (bind, type);
+
+      symtab_map[i] = num_syms;
+      num_syms++;
+    }
+
+  write_reloc_section (fp, image, pe_chdr, pe_shdr, symtab, symtab_map);
+
+  shdr[SYMTAB_SECTION].sh_name = insert_string (".symtab");
+  shdr[SYMTAB_SECTION].sh_type = SHT_SYMTAB;
+  shdr[SYMTAB_SECTION].sh_offset = offset;
+  shdr[SYMTAB_SECTION].sh_size = num_syms * sizeof (Elf32_Sym);
+  shdr[SYMTAB_SECTION].sh_entsize = sizeof (Elf32_Sym);
+  shdr[SYMTAB_SECTION].sh_link = STRTAB_SECTION;
+  shdr[SYMTAB_SECTION].sh_addralign = 4;
+
+  grub_util_write_image_at (symtab, shdr[SYMTAB_SECTION].sh_size,
+                            offset, fp);
+  offset += shdr[SYMTAB_SECTION].sh_size;
+
+  free (symtab);
+  free (symtab_map);
+}
+
+static void
+write_string_table (FILE* fp)
+{
+  shdr[STRTAB_SECTION].sh_name = insert_string (".strtab");
+  shdr[STRTAB_SECTION].sh_type = SHT_STRTAB;
+  shdr[STRTAB_SECTION].sh_offset = offset;
+  shdr[STRTAB_SECTION].sh_size = strtab_len;
+  shdr[STRTAB_SECTION].sh_addralign = 1;
+  grub_util_write_image_at (strtab, strtab_len, offset, fp);
+  offset += strtab_len;
+
+  free (strtab);
+}
+
+static void
+write_section_header (FILE* fp)
+{
+  ehdr.e_ident[EI_MAG0] = ELFMAG0;
+  ehdr.e_ident[EI_MAG1] = ELFMAG1;
+  ehdr.e_ident[EI_MAG2] = ELFMAG2;
+  ehdr.e_ident[EI_MAG3] = ELFMAG3;
+  ehdr.e_ident[EI_VERSION] = EV_CURRENT;
+  ehdr.e_version = EV_CURRENT;
+  ehdr.e_type = ET_REL;
+
+  ehdr.e_ident[EI_CLASS] = ELFCLASS32;
+  ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
+  ehdr.e_machine = EM_386;
+
+  ehdr.e_ehsize = sizeof (ehdr);
+  ehdr.e_shentsize = sizeof (Elf32_Shdr);
+  ehdr.e_shstrndx = STRTAB_SECTION;
+
+  ehdr.e_shoff = offset;
+  ehdr.e_shnum = num_sections;
+  grub_util_write_image_at (&shdr, sizeof (Elf32_Shdr) * num_sections,
+                            offset, fp);
+
+  grub_util_write_image_at (&ehdr, sizeof (Elf32_Ehdr), 0, fp);
+}
+
+static void
+convert_pe (FILE* fp, char *image)
+{
+  struct grub_pe32_coff_header *pe_chdr;
+  struct grub_pe32_section_table *pe_shdr;
+  int *section_map;
+
+  pe_chdr = (struct grub_pe32_coff_header *) image;
+  if (grub_le_to_cpu16 (pe_chdr->machine) != GRUB_PE32_MACHINE_I386)
+    grub_util_error ("Invalid coff image");
+
+  strtab = xmalloc (STRTAB_BLOCK);
+  strtab_max = STRTAB_BLOCK;
+  strtab[0] = 0;
+  strtab_len = 1;
+
+  offset = sizeof (ehdr);
+  pe_shdr = (struct grub_pe32_section_table *) (pe_chdr + 1);
+  num_sections = REL_SECTION;
+
+  section_map = write_section_data (fp, image, pe_chdr, pe_shdr);
+
+  write_symbol_table (fp, image, pe_chdr, pe_shdr, section_map);
+  free (section_map);
+
+  write_string_table (fp);
+
+  write_section_header (fp);
+}
+
+int
+main (int argc, char *argv[])
+{
+  char *image;
+  FILE* fp;
+
+  progname = "grub-pe2elf";
+
+    /* Check for options.  */
+  while (1)
+    {
+      int c = getopt_long (argc, argv, "hVv", options, 0);
+
+      if (c == -1)
+	break;
+      else
+	switch (c)
+	  {
+	  case 'h':
+	    usage (0);
+	    break;
+
+	  case 'V':
+	    printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION);
+	    return 0;
+
+	  case 'v':
+	    verbosity++;
+	    break;
+
+	  default:
+	    usage (1);
+	    break;
+	  }
+    }
+
+  /* Obtain PATH.  */
+  if (optind >= argc)
+    {
+      fprintf (stderr, "Filename not specified.\n");
+      usage (1);
+    }
+
+  image = grub_util_read_image (argv[optind]);
+
+  if (optind + 1 < argc)
+    optind++;
+
+  fp = fopen (argv[optind], "wb");
+  if (! fp)
+    grub_util_error ("cannot open %s", argv[optind]);
+
+  convert_pe (fp, image);
+
+  fclose (fp);
+
+  return 0;
+}
diff --git a/util/grub-probe.c b/util/grub-probe.c
new file mode 100644
index 0000000..4e3f964
--- /dev/null
+++ b/util/grub-probe.c
@@ -0,0 +1,428 @@
+/* grub-probe.c - probe device information for a given path */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/util/misc.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/fs.h>
+#include <grub/partition.h>
+#include <grub/msdos_partition.h>
+#include <grub/util/hostdisk.h>
+#include <grub/util/getroot.h>
+#include <grub/term.h>
+#include <grub/env.h>
+#include <grub/raid.h>
+
+#include <grub_probe_init.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#define _GNU_SOURCE	1
+#include <getopt.h>
+
+enum {
+  PRINT_FS,
+  PRINT_FS_UUID,
+  PRINT_DRIVE,
+  PRINT_DEVICE,
+  PRINT_PARTMAP,
+  PRINT_ABSTRACTION,
+};
+
+int print = PRINT_FS;
+static unsigned int argument_is_device = 0;
+
+void
+grub_putchar (int c)
+{
+  putchar (c);
+}
+
+int
+grub_getkey (void)
+{
+  return -1;
+}
+
+struct grub_handler_class grub_term_input_class;
+struct grub_handler_class grub_term_output_class;
+
+void
+grub_refresh (void)
+{
+  fflush (stdout);
+}
+
+static void
+probe_partmap (grub_disk_t disk)
+{
+  if (disk->partition == NULL)
+    {
+      grub_util_info ("No partition map found for %s", disk->name);
+      return;
+    }
+
+  printf ("%s\n", disk->partition->partmap->name);
+}
+
+static int
+probe_raid_level (grub_disk_t disk)
+{
+  if (disk->dev->id != GRUB_DISK_DEVICE_RAID_ID)
+    return -1;
+
+  return ((struct grub_raid_array *) disk->data)->level;
+}
+
+static void
+probe (const char *path, char *device_name)
+{
+  char *drive_name = NULL;
+  char *grub_path = NULL;
+  char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL;
+  grub_device_t dev = NULL;
+  grub_fs_t fs;
+
+  if (path == NULL)
+    {
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+      if (! grub_util_check_char_device (device_name))
+        grub_util_error ("%s is not a character device.\n", device_name);
+#else
+      if (! grub_util_check_block_device (device_name))
+        grub_util_error ("%s is not a block device.\n", device_name);
+#endif
+    }
+  else
+    device_name = grub_guess_root_device (path);
+
+  if (! device_name)
+    grub_util_error ("cannot find a device for %s.\n", path);
+
+  if (print == PRINT_DEVICE)
+    {
+      printf ("%s\n", device_name);
+      goto end;
+    }
+
+  drive_name = grub_util_get_grub_dev (device_name);
+  if (! drive_name)
+    grub_util_error ("Cannot find a GRUB drive for %s.  Check your device.map.\n", device_name);
+
+  if (print == PRINT_DRIVE)
+    {
+      printf ("(%s)\n", drive_name);
+      goto end;
+    }
+
+  grub_util_info ("opening %s", drive_name);
+  dev = grub_device_open (drive_name);
+  if (! dev)
+    grub_util_error ("%s", grub_errmsg);
+
+  if (print == PRINT_ABSTRACTION)
+    {
+      grub_disk_memberlist_t list = NULL, tmp;
+      const int is_lvm = (dev->disk->dev->id == GRUB_DISK_DEVICE_LVM_ID);
+      int is_raid = 0;
+      int is_raid5 = 0;
+      int is_raid6 = 0;
+      int raid_level;
+
+      raid_level = probe_raid_level (dev->disk);
+      if (raid_level >= 0)
+	{
+	  is_raid = 1;
+	  is_raid5 |= (raid_level == 5);
+	  is_raid6 |= (raid_level == 6);
+	}
+
+      if ((is_lvm) && (dev->disk->dev->memberlist))
+	list = dev->disk->dev->memberlist (dev->disk);
+      while (list)
+	{
+	  raid_level = probe_raid_level (list->disk);
+	  if (raid_level >= 0)
+	    {
+	      is_raid = 1;
+	      is_raid5 |= (raid_level == 5);
+	      is_raid6 |= (raid_level == 6);
+	    }
+
+	  tmp = list->next;
+	  free (list);
+	  list = tmp;
+	}
+
+      if (is_raid)
+	{
+	  printf ("raid ");
+	  if (is_raid5)
+	    printf ("raid5rec ");
+	  if (is_raid6)
+	    printf ("raid6rec ");
+	  printf ("mdraid ");
+	}
+
+      if (is_lvm)
+	printf ("lvm ");
+
+      printf ("\n");
+
+      goto end;
+    }
+
+  if (print == PRINT_PARTMAP)
+    {
+      grub_disk_memberlist_t list = NULL, tmp;
+
+      /* Check if dev->disk itself is contained in a partmap.  */
+      probe_partmap (dev->disk);
+
+      /* In case of LVM/RAID, check the member devices as well.  */
+      if (dev->disk->dev->memberlist)
+	list = dev->disk->dev->memberlist (dev->disk);
+      while (list)
+	{
+	  probe_partmap (list->disk);
+	  /* LVM on RAID  */
+	  if (list->disk->dev->memberlist)
+	    {
+	      grub_disk_memberlist_t sub_list;
+
+	      sub_list = list->disk->dev->memberlist (list->disk);
+	      while (sub_list)
+		{
+		  probe_partmap (sub_list->disk);
+		  tmp = sub_list->next;
+		  free (sub_list);
+		  sub_list = tmp;
+		}
+	    }
+	  tmp = list->next;
+	  free (list);
+	  list = tmp;
+	}
+      goto end;
+    }
+
+  fs = grub_fs_probe (dev);
+  if (! fs)
+    grub_util_error ("%s", grub_errmsg);
+
+  if (print == PRINT_FS)
+    {
+      /* FIXME: `path' can't be used to read a file via GRUB facilities,
+         because it's not relative to its root.  */
+#if 0
+      struct stat st;
+
+      stat (path, &st);
+
+      if (S_ISREG (st.st_mode))
+	{
+	  /* Regular file.  Verify that we can read it properly.  */
+
+	  grub_file_t file;
+	  grub_util_info ("reading %s via OS facilities", path);
+	  filebuf_via_sys = grub_util_read_image (path);
+
+	  grub_util_info ("reading %s via GRUB facilities", path);
+	  asprintf (&grub_path, "(%s)%s", drive_name, path);
+	  file = grub_file_open (grub_path);
+	  filebuf_via_grub = xmalloc (file->size);
+	  grub_file_read (file, filebuf_via_grub, file->size);
+
+	  grub_util_info ("comparing");
+
+	  if (memcmp (filebuf_via_grub, filebuf_via_sys, file->size))
+	    grub_util_error ("files differ");
+	}
+#endif
+
+      printf ("%s\n", fs->name);
+    }
+
+  if (print == PRINT_FS_UUID)
+    {
+      char *uuid;
+      if (! fs->uuid)
+	grub_util_error ("%s does not support UUIDs", fs->name);
+
+      fs->uuid (dev, &uuid);
+
+      printf ("%s\n", uuid);
+    }
+
+ end:
+  if (dev)
+    grub_device_close (dev);
+  free (grub_path);
+  free (filebuf_via_grub);
+  free (filebuf_via_sys);
+  free (drive_name);
+}
+
+static struct option options[] =
+  {
+    {"device", no_argument, 0, 'd'},
+    {"device-map", required_argument, 0, 'm'},
+    {"target", required_argument, 0, 't'},
+    {"help", no_argument, 0, 'h'},
+    {"version", no_argument, 0, 'V'},
+    {"verbose", no_argument, 0, 'v'},
+    {0, 0, 0, 0}
+  };
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr,
+	     "Try ``grub-probe --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-probe [OPTION]... [PATH|DEVICE]\n\
+\n\
+Probe device information for a given path (or device, if the -d option is given).\n\
+\n\
+  -d, --device              given argument is a system device, not a path\n\
+  -m, --device-map=FILE     use FILE as the device map [default=%s]\n\
+  -t, --target=(fs|fs_uuid|drive|device|partmap|abstraction)\n\
+                            print filesystem module, GRUB drive, system device, partition map module or abstraction module [default=fs]\n\
+  -h, --help                display this message and exit\n\
+  -V, --version             print version information and exit\n\
+  -v, --verbose             print verbose messages\n\
+\n\
+Report bugs to <%s>.\n\
+",
+	    DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+int
+main (int argc, char *argv[])
+{
+  char *dev_map = 0;
+  char *argument;
+
+  progname = "grub-probe";
+
+  /* Check for options.  */
+  while (1)
+    {
+      int c = getopt_long (argc, argv, "dm:t:hVv", options, 0);
+
+      if (c == -1)
+	break;
+      else
+	switch (c)
+	  {
+	  case 'd':
+	    argument_is_device = 1;
+	    break;
+
+	  case 'm':
+	    if (dev_map)
+	      free (dev_map);
+
+	    dev_map = xstrdup (optarg);
+	    break;
+
+	  case 't':
+	    if (!strcmp (optarg, "fs"))
+	      print = PRINT_FS;
+	    else if (!strcmp (optarg, "fs_uuid"))
+	      print = PRINT_FS_UUID;
+	    else if (!strcmp (optarg, "drive"))
+	      print = PRINT_DRIVE;
+	    else if (!strcmp (optarg, "device"))
+	      print = PRINT_DEVICE;
+	    else if (!strcmp (optarg, "partmap"))
+	      print = PRINT_PARTMAP;
+	    else if (!strcmp (optarg, "abstraction"))
+	      print = PRINT_ABSTRACTION;
+	    else
+	      usage (1);
+	    break;
+
+	  case 'h':
+	    usage (0);
+	    break;
+
+	  case 'V':
+	    printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION);
+	    return 0;
+
+	  case 'v':
+	    verbosity++;
+	    break;
+
+	  default:
+	    usage (1);
+	    break;
+	  }
+    }
+
+  if (verbosity > 1)
+    grub_env_set ("debug", "all");
+
+  /* Obtain ARGUMENT.  */
+  if (optind >= argc)
+    {
+      fprintf (stderr, "No path or device is specified.\n");
+      usage (1);
+    }
+
+  if (optind + 1 != argc)
+    {
+      fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]);
+      usage (1);
+    }
+
+  argument = argv[optind];
+
+  /* Initialize the emulated biosdisk driver.  */
+  grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
+
+  /* Initialize all modules. */
+  grub_init_all ();
+
+  /* Do it.  */
+  if (argument_is_device)
+    probe (NULL, argument);
+  else
+    probe (argument, NULL);
+
+  /* Free resources.  */
+  grub_fini_all ();
+  grub_util_biosdisk_fini ();
+
+  free (dev_map);
+
+  return 0;
+}
diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in
new file mode 100644
index 0000000..9f421dc
--- /dev/null
+++ b/util/grub.d/00_header.in
@@ -0,0 +1,118 @@
+#! /bin/sh -e
+
+# grub-mkconfig helper script.
+# Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+transform="@program_transform_name@"
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+grub_prefix=`echo /boot/grub | sed ${transform}`
+
+. ${libdir}/grub/grub-mkconfig_lib
+
+# Do this as early as possible, since other commands might depend on it.
+# (e.g. the `loadfont' command might need lvm or raid modules)
+for i in ${GRUB_PRELOAD_MODULES} ; do
+  echo "insmod $i"
+done
+
+if [ "x${GRUB_DEFAULT}" = "x" ] ; then GRUB_DEFAULT=0 ; fi
+if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi
+if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=640x480 ; fi
+
+cat << EOF
+set default=${GRUB_DEFAULT}
+EOF
+
+case ${GRUB_TERMINAL_INPUT}:${GRUB_TERMINAL_OUTPUT} in
+  serial:* | *:serial)
+    if ! test -e ${grub_prefix}/serial.mod ; then
+      echo "Serial terminal not available on this platform." >&2 ; exit 1
+    fi
+
+    if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then
+      grub_warn "Requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used."
+      GRUB_SERIAL_COMMAND=serial
+    fi
+    echo "${GRUB_SERIAL_COMMAND}"
+  ;;
+esac
+
+case x${GRUB_TERMINAL_INPUT} in
+  x)
+    # Just use the native terminal
+  ;;
+  x*)
+    cat << EOF
+if terminal_input ${GRUB_TERMINAL_INPUT} ; then true ; else
+  # For backward compatibility with versions of terminal.mod that don't
+  # understand terminal_input
+  terminal ${GRUB_TERMINAL_INPUT}
+fi
+EOF
+  ;;
+esac
+
+case x${GRUB_TERMINAL_OUTPUT} in
+ xgfxterm)
+    # Make the font accessible
+    prepare_grub_to_access_device `${grub_probe} --target=device ${GRUB_FONT_PATH}`
+
+    cat << EOF
+if loadfont `make_system_path_relative_to_its_root ${GRUB_FONT_PATH}` ; then
+  set gfxmode=${GRUB_GFXMODE}
+  insmod gfxterm
+  insmod ${GRUB_VIDEO_BACKEND}
+  if terminal_output gfxterm ; then true ; else
+    # For backward compatibility with versions of terminal.mod that don't
+    # understand terminal_output
+    terminal gfxterm
+  fi
+fi
+EOF
+  ;;
+  x)
+    # Just use the native terminal
+  ;;
+  x*)
+    cat << EOF
+if terminal_output ${GRUB_TERMINAL_OUTPUT} ; then true ; else
+  # For backward compatibility with versions of terminal.mod that don't
+  # understand terminal_output
+  terminal ${GRUB_TERMINAL_OUTPUT}
+fi
+EOF
+  ;;
+esac
+
+if [ "x${GRUB_HIDDEN_TIMEOUT}" != "x" ] ; then
+  if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then 
+    verbose=
+  else
+    verbose=" --verbose"
+  fi
+  cat << EOF
+if sleep$verbose --interruptible ${GRUB_HIDDEN_TIMEOUT} ; then
+  set timeout=${GRUB_TIMEOUT}
+fi
+EOF
+else
+  cat << EOF
+set timeout=${GRUB_TIMEOUT}
+EOF
+fi
diff --git a/util/grub.d/10_freebsd.in b/util/grub.d/10_freebsd.in
new file mode 100644
index 0000000..02694d3
--- /dev/null
+++ b/util/grub.d/10_freebsd.in
@@ -0,0 +1,76 @@
+#! /bin/sh -e
+
+# grub-mkconfig helper script.
+# Copyright (C) 2008,2009  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+. ${libdir}/grub/grub-mkconfig_lib
+
+case "${GRUB_DISTRIBUTOR}" in
+  Debian)	OS="${GRUB_DISTRIBUTOR} GNU/kFreeBSD" ;;
+  *)		OS="FreeBSD" ;;
+esac
+
+if test -e /boot/device.hints ; then
+  devices=/boot/device.hints
+fi
+
+if test -e /boot/kernel/kernel ; then
+  kfreebsd=/boot/kernel/kernel
+fi
+if test -e /boot/kernel/kernel.gz ; then
+  kfreebsd=/boot/kernel/kernel.gz
+fi
+
+if [ "x$kfreebsd" != "x" ] ; then
+  echo "Found kernel of FreeBSD: $kfreebsd" >&2
+
+  kfreebsd_basename=`basename $kfreebsd`
+  kfreebsd_dirname=`dirname $kfreebsd`
+  kfreebsd_rel_dirname=`make_system_path_relative_to_its_root $kfreebsd_dirname`
+
+  if [ x"$devices" != "x" ] ; then
+    devices_basename=`basename $devices`
+    devices_dirname=`dirname $devices`
+    devices_rel_dirname=`make_system_path_relative_to_its_root $devices_dirname`
+  fi
+
+  case ${GRUB_FS} in
+    ufs1 | ufs2)	kfreebsd_fs=ufs ;;
+    *)			kfreebsd_fs=${GRUB_FS} ;;
+  esac
+
+  cat << EOF
+menuentry "${OS}" {
+EOF
+  prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
+  cat << EOF
+	kfreebsd			${kfreebsd_rel_dirname}/${kfreebsd_basename}
+EOF
+
+  if [ x"$devices" != "x" ] ; then
+    cat << EOF
+	kfreebsd_loadenv		${devices_rel_dirname}/${devices_basename}
+EOF
+  fi
+  cat << EOF
+	set kFreeBSD.vfs.root.mountfrom=${kfreebsd_fs}:${GRUB_DEVICE}
+	set kFreeBSD.vfs.root.mountfrom.options=rw
+}
+EOF
+fi
diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in
new file mode 100644
index 0000000..b52f374
--- /dev/null
+++ b/util/grub.d/10_hurd.in
@@ -0,0 +1,85 @@
+#! /bin/sh -e
+
+# grub-mkconfig helper script.
+# Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+. ${libdir}/grub/grub-mkconfig_lib
+
+if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
+  OS=GNU
+else
+  OS="${GRUB_DISTRIBUTOR} GNU/Hurd"
+fi
+
+at_least_one=false
+all_of_them=true
+
+# FIXME: add l4 here?
+kernel=
+for i in /boot/gnumach.gz /boot/gnumach ; do
+  if test -e $i ; then
+    basename=`basename $i`
+    dirname=`dirname $i`
+    rel_dirname=`make_system_path_relative_to_its_root $dirname`
+    echo "Found GNU Mach: $i" >&2
+    kernel=${rel_dirname}/${basename}
+    at_least_one=true
+  fi
+done
+
+# FIXME: This works for ext2.  For other filesystems we might need special-casing
+case "${GRUB_FS}" in
+  *fs)	hurd_fs="${GRUB_FS}" ;;
+  *)	hurd_fs="${GRUB_FS}fs" ;;
+esac
+
+for i in /hurd/${hurd_fs}.static /hurd/exec ; do
+  if test -e "$i" ; then
+    echo "Found Hurd module: $i" >&2
+    at_least_one=true
+  else
+    all_of_them=false
+  fi
+done
+
+if ${at_least_one} ; then : ; else
+  # no hurd here, aborting silently
+  exit 0
+fi
+
+if ${all_of_them} && test -e /lib/ld.so.1 ; then : ; else
+  echo "Some Hurd stuff found, but not enough to boot." >&2
+  exit 1
+fi
+
+cat << EOF
+menuentry "${OS}" {
+EOF
+prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/"
+cat << EOF
+	multiboot ${kernel} root=device:${GRUB_DEVICE}
+	module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\
+			--multiboot-command-line='\${kernel-command-line}' \\
+			--host-priv-port='\${host-port}' \\
+			--device-master-port='\${device-port}' \\
+			--exec-server-task='\${exec-task}' -T typed '\${root}' \\
+			'\$(task-create)' '\$(task-resume)'
+	module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)'
+}
+EOF
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
new file mode 100644
index 0000000..1473a42
--- /dev/null
+++ b/util/grub.d/10_linux.in
@@ -0,0 +1,102 @@
+#! /bin/sh -e
+
+# grub-mkconfig helper script.
+# Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+. ${libdir}/grub/grub-mkconfig_lib
+
+if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
+  OS=GNU/Linux
+else
+  OS="${GRUB_DISTRIBUTOR} GNU/Linux"
+fi
+
+# loop-AES arranges things so that /dev/loop/X can be our root device, but
+# the initrds that Linux uses don't like that.
+case ${GRUB_DEVICE} in
+  /dev/loop/*|/dev/loop[0-9])
+    GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
+  ;;
+esac
+
+if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
+    || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then
+  LINUX_ROOT_DEVICE=${GRUB_DEVICE}
+else
+  LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
+fi
+
+linux_entry ()
+{
+  cat << EOF
+menuentry "$1" {
+EOF
+  prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
+  cat << EOF
+	linux	${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro $2
+EOF
+  if test -n "${initrd}" ; then
+    cat << EOF
+	initrd	${rel_dirname}/${initrd}
+EOF
+  fi
+  cat << EOF
+}
+EOF
+}
+
+list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do
+        if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
+      done`
+
+while [ "x$list" != "x" ] ; do
+  linux=`version_find_latest $list`
+  echo "Found linux image: $linux" >&2
+  basename=`basename $linux`
+  dirname=`dirname $linux`
+  rel_dirname=`make_system_path_relative_to_its_root $dirname`
+  version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
+  alt_version=`echo $version | sed -e "s,\.old$,,g"`
+  linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
+
+  initrd=
+  for i in "initrd.img-${version}" "initrd-${version}.img" \
+	   "initrd-${version}" "initrd.img-${alt_version}" \
+	   "initrd-${alt_version}.img" "initrd-${alt_version}"; do
+    if test -e "${dirname}/${i}" ; then
+      initrd="$i"
+      break
+    fi
+  done
+  if test -n "${initrd}" ; then
+    echo "Found initrd image: ${dirname}/${initrd}" >&2
+  else
+    # "UUID=" magic is parsed by initrds.  Since there's no initrd, it can't work here.
+    linux_root_device_thisversion=${GRUB_DEVICE}
+  fi
+
+  linux_entry "${OS}, with Linux ${version}" \
+      "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
+  if [ "x${GRUB_DISABLE_LINUX_RECOVERY}" != "xtrue" ]; then
+    linux_entry "${OS}, with Linux ${version} (recovery mode)" \
+	"single ${GRUB_CMDLINE_LINUX}"
+  fi
+
+  list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
+done
diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in
new file mode 100644
index 0000000..055258e
--- /dev/null
+++ b/util/grub.d/10_windows.in
@@ -0,0 +1,83 @@
+#! /bin/sh -e
+
+# grub-mkconfig helper script.
+# Copyright (C) 2008  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+. ${libdir}/grub/grub-mkconfig_lib
+
+case "`uname 2>/dev/null`" in
+  CYGWIN*)  ;;
+  *) exit 0 ;;
+esac
+
+# Try C: even if current system is on other partition.
+case "$SYSTEMDRIVE" in
+  [Cc]:)     dirlist="C:"              ;;
+  [D-Zd-z]:) dirlist="C: $SYSTEMDRIVE" ;;
+  *) exit 0 ;;
+esac
+
+get_os_name_from_boot_ini ()
+{
+  # Fail if no or more than one partition.
+  test "`sed -n 's,^\(\(multi\|scsi\)[^=]*\)=.*$,\1,p' "$1" 2>/dev/null | \
+    sort | uniq | wc -l`" = 1 || return 1
+
+  # Search 'default=PARTITION'
+  local part=`sed -n 's,^default=,,p' "$1" | sed 's,\\\\,/,g;s,[ \t\r]*$,,;1q'`
+  test -n "$part" || return 1
+
+  # Search 'PARTITION="NAME" ...'
+  local name=`sed -n 's,\\\\,/,g;s,^'"$part"'="\([^"]*\)".*$,\1,p' "$1" | sed 1q`
+  test -n "$name" || return 1
+
+  echo "$name"
+}
+
+
+for dir in $dirlist ; do
+
+  # Check for Vista bootmgr.
+  if [ -f "$dir"/bootmgr -a -f "$dir"/boot/bcd ] ; then
+    OS="Windows Vista bootmgr"
+
+  # Check for NTLDR.
+  elif [ -f "$dir"/ntldr -a -f "$dir"/ntdetect.com -a -f "$dir"/boot.ini ] ; then
+    OS=`get_os_name_from_boot_ini "$dir"/boot.ini` || OS="Windows NT/2000/XP loader"
+
+  else
+    continue
+  fi
+
+  # Get boot /dev/ice.
+  dev=`${grub_probe} -t device "$dir" 2>/dev/null` || continue
+
+  echo "Found $OS on $dir ($dev)" >&2
+  cat << EOF
+menuentry "$OS" {
+EOF
+
+  prepare_grub_to_access_device "$dev" | sed 's,^,\t,'
+
+  cat << EOF
+	chainloader +1
+}
+EOF
+done
+
diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in
new file mode 100644
index 0000000..84e227e
--- /dev/null
+++ b/util/grub.d/30_os-prober.in
@@ -0,0 +1,161 @@
+#! /bin/sh -e
+
+# grub-mkconfig helper script.
+# Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+
+. ${libdir}/grub/grub-mkconfig_lib
+
+if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then
+  exit 0
+fi
+
+if [ -z "`which os-prober 2> /dev/null`" -o -z "`which linux-boot-prober 2> /dev/null`" ] ; then
+  # missing os-prober and/or linux-boot-prober
+  exit 0
+fi
+
+OSPROBED="`os-prober | tr ' ' '^' | paste -s -d ' '`"
+if [ -z "${OSPROBED}" ] ; then
+  # empty os-prober output, nothing doing
+  exit 0
+fi
+
+for OS in ${OSPROBED} ; do
+  DEVICE="`echo ${OS} | cut -d ':' -f 1`"
+  LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`"
+  LABEL="`echo ${OS} | cut -d ':' -f 3 | tr '^' ' '`"
+  BOOT="`echo ${OS} | cut -d ':' -f 4`"
+
+  if [ -z "${LONGNAME}" ] ; then
+    LONGNAME="${LABEL}"
+  fi
+
+  echo "Found ${LONGNAME} on ${DEVICE}" >&2
+
+  case ${BOOT} in
+    chain)
+
+      cat << EOF
+menuentry "${LONGNAME} (on ${DEVICE})" {
+EOF
+      prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
+
+      case ${LONGNAME} in
+	Windows\ Vista*|Windows\ 7*)
+	;;
+	*)
+	  cat << EOF
+	drivemap -s (hd0) \${root}
+EOF
+	;;
+      esac
+
+      cat <<EOF
+	chainloader +1
+}
+EOF
+    ;;
+    linux)
+      LINUXPROBED="`linux-boot-prober ${DEVICE} 2> /dev/null | tr ' ' '^' | paste -s -d ' '`"
+
+      for LINUX in ${LINUXPROBED} ; do
+        LROOT="`echo ${LINUX} | cut -d ':' -f 1`"
+        LBOOT="`echo ${LINUX} | cut -d ':' -f 2`"
+        LLABEL="`echo ${LINUX} | cut -d ':' -f 3 | tr '^' ' '`"
+        LKERNEL="`echo ${LINUX} | cut -d ':' -f 4`"
+        LINITRD="`echo ${LINUX} | cut -d ':' -f 5`"
+        LPARAMS="`echo ${LINUX} | cut -d ':' -f 6- | tr '^' ' '`"
+
+        if [ -z "${LLABEL}" ] ; then
+          LLABEL="${LONGNAME}"
+        fi
+
+        cat << EOF
+menuentry "${LLABEL} (on ${DEVICE})" {
+EOF
+	prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
+	cat <<  EOF
+	linux ${LKERNEL} ${LPARAMS}
+EOF
+        if [ -n "${LINITRD}" ] ; then
+          cat << EOF
+	initrd ${LINITRD}
+EOF
+        fi
+        cat << EOF
+}
+EOF
+      done
+    ;;
+    macosx)
+      OSXUUID="`grub-probe --target=fs_uuid --device ${DEVICE} 2> /dev/null`"
+        cat << EOF
+menuentry "${LONGNAME} (on ${DEVICE})" {
+EOF
+	prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
+	cat << EOF
+        insmod vbe
+        do_resume=0
+        if [ /var/vm/sleepimage -nt10 / ]; then
+           if xnu_resume /var/vm/sleepimage; then
+             do_resume=1
+           fi
+        fi
+        if [ \$do_resume == 0 ]; then
+           xnu_uuid ${OSXUUID} uuid
+           if [ -f /Extra/DSDT.aml ]; then
+              acpi -e /Extra/DSDT.aml
+           fi
+           xnu_kernel /mach_kernel boot-uuid=\${uuid} rd=*uuid
+           if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then
+              xnu_mkext /System/Library/Extensions.mkext
+           else
+              xnu_kextdir /System/Library/Extensions
+           fi
+           if [ -f /Extra/Extensions.mkext ]; then
+              xnu_mkext /Extra/Extensions.mkext
+           fi
+           if [ -d /Extra/Extensions ]; then
+              xnu_kextdir /Extra/Extensions
+           fi
+           if [ -f /Extra/devtree.txt ]; then
+              xnu_devtree /Extra/devtree.txt
+           fi
+           if [ -f /Extra/splash.jpg ]; then
+              insmod jpeg
+              xnu_splash /Extra/splash.jpg
+           fi
+           if [ -f /Extra/splash.png ]; then
+              insmod png
+              xnu_splash /Extra/splash.png
+           fi
+           if [ -f /Extra/splash.tga ]; then
+              insmod tga
+              xnu_splash /Extra/splash.tga
+           fi
+        fi
+}
+EOF
+    ;;
+    hurd|*)
+      echo "  ${LONGNAME} is not yet supported by grub-mkconfig." >&2
+    ;;
+  esac
+done
diff --git a/util/grub.d/40_custom.in b/util/grub.d/40_custom.in
new file mode 100644
index 0000000..48068de
--- /dev/null
+++ b/util/grub.d/40_custom.in
@@ -0,0 +1,5 @@
+#!/bin/sh
+exec tail -n +3 $0
+# This file provides an easy way to add custom menu entries.  Simply type the
+# menu entries you want to add after this comment.  Be careful not to change
+# the 'exec tail' line above.
diff --git a/util/grub.d/README b/util/grub.d/README
new file mode 100644
index 0000000..3ea109d
--- /dev/null
+++ b/util/grub.d/README
@@ -0,0 +1,11 @@
+
+All executable files in this directory are processed in shell expansion order.
+
+  00_*: Reserved for 00_header.
+  10_*: Native boot entries.
+  20_*: Third party apps (e.g. memtest86+).
+
+The number namespace in-between is configurable by system installer and/or
+administrator.  For example, you can add an entry to boot another OS as
+01_otheros, 11_otheros, etc, depending on the position you want it to occupy in
+the menu; and then adjust the default setting via /etc/default/grub.
diff --git a/util/hostdisk.c b/util/hostdisk.c
new file mode 100644
index 0000000..22b856e
--- /dev/null
+++ b/util/hostdisk.c
@@ -0,0 +1,1109 @@
+/* hostdisk.c - emulate biosdisk */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/msdos_partition.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/util/misc.h>
+#include <grub/util/hostdisk.h>
+#include <grub/misc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+
+#ifdef __linux__
+# include <sys/ioctl.h>         /* ioctl */
+# if !defined(__GLIBC__) || \
+        ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
+/* Maybe libc doesn't have large file support.  */
+#  include <linux/unistd.h>     /* _llseek */
+# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
+# ifndef BLKFLSBUF
+#  define BLKFLSBUF     _IO (0x12,97)   /* flush buffer cache */
+# endif /* ! BLKFLSBUF */
+# include <sys/ioctl.h>		/* ioctl */
+# ifndef HDIO_GETGEO
+#  define HDIO_GETGEO	0x0301	/* get device geometry */
+/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is
+   defined.  */
+struct hd_geometry
+{
+  unsigned char heads;
+  unsigned char sectors;
+  unsigned short cylinders;
+  unsigned long start;
+};
+# endif /* ! HDIO_GETGEO */
+# ifndef BLKGETSIZE64
+#  define BLKGETSIZE64  _IOR(0x12,114,size_t)    /* return device size */
+# endif /* ! BLKGETSIZE64 */
+# ifndef MAJOR
+#  ifndef MINORBITS
+#   define MINORBITS	8
+#  endif /* ! MINORBITS */
+#  define MAJOR(dev)	((unsigned) ((dev) >> MINORBITS))
+# endif /* ! MAJOR */
+# ifndef FLOPPY_MAJOR
+#  define FLOPPY_MAJOR	2
+# endif /* ! FLOPPY_MAJOR */
+# ifndef LOOP_MAJOR
+#  define LOOP_MAJOR	7
+# endif /* ! LOOP_MAJOR */
+#endif /* __linux__ */
+
+#ifdef __CYGWIN__
+# include <sys/ioctl.h>
+# include <cygwin/fs.h> /* BLKGETSIZE64 */
+# include <cygwin/hdreg.h> /* HDIO_GETGEO */
+# define MAJOR(dev)	((unsigned) ((dev) >> 16))
+# define FLOPPY_MAJOR	2
+#endif
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+# include <sys/disk.h> /* DIOCGMEDIASIZE */
+# include <sys/param.h>
+# include <sys/sysctl.h>
+#endif
+
+#if defined(__APPLE__)
+# include <sys/disk.h>
+#endif
+
+struct
+{
+  char *drive;
+  char *device;
+} map[256];
+
+#ifdef __linux__
+/* Check if we have devfs support.  */
+static int
+have_devfs (void)
+{
+  static int dev_devfsd_exists = -1;
+
+  if (dev_devfsd_exists < 0)
+    {
+      struct stat st;
+
+      dev_devfsd_exists = stat ("/dev/.devfsd", &st) == 0;
+    }
+
+  return dev_devfsd_exists;
+}
+#endif /* __linux__ */
+
+static int
+find_grub_drive (const char *name)
+{
+  unsigned int i;
+
+  if (name)
+    {
+      for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
+	if (map[i].drive && ! strcmp (map[i].drive, name))
+	  return i;
+    }
+
+  return -1;
+}
+
+static int
+find_free_slot ()
+{
+  unsigned int i;
+
+  for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
+    if (! map[i].drive)
+      return i;
+
+  return -1;
+}
+
+static int
+grub_util_biosdisk_iterate (int (*hook) (const char *name))
+{
+  unsigned i;
+
+  for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
+    if (map[i].drive && hook (map[i].drive))
+      return 1;
+
+  return 0;
+}
+
+static grub_err_t
+grub_util_biosdisk_open (const char *name, grub_disk_t disk)
+{
+  int drive;
+  struct stat st;
+
+  drive = find_grub_drive (name);
+  if (drive < 0)
+    return grub_error (GRUB_ERR_BAD_DEVICE,
+		       "no mapping exists for `%s'", name);
+
+  disk->has_partitions = 1;
+  disk->id = drive;
+
+  /* Get the size.  */
+#if defined(__MINGW32__)
+  {
+    grub_uint64_t size;
+
+    size = grub_util_get_disk_size (map[drive].device);
+
+    if (size % 512)
+      grub_util_error ("unaligned device size");
+
+    disk->total_sectors = size >> 9;
+
+    grub_util_info ("the size of %s is %llu", name, disk->total_sectors);
+
+    return GRUB_ERR_NONE;
+  }
+#elif defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \
+      defined(__FreeBSD_kernel__) || defined(__APPLE__)
+  {
+    unsigned long long nr;
+    int fd;
+
+    fd = open (map[drive].device, O_RDONLY);
+    if (fd == -1)
+      return grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk size", map[drive].device);
+
+# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
+    if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
+# else
+    if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode))
+# endif
+      {
+	close (fd);
+	goto fail;
+      }
+
+# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+    if (ioctl (fd, DIOCGMEDIASIZE, &nr))
+# elif defined(__APPLE__)
+    if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr))
+# else
+    if (ioctl (fd, BLKGETSIZE64, &nr))
+# endif
+      {
+	close (fd);
+	goto fail;
+      }
+
+    close (fd);
+
+#if defined (__APPLE__)
+    disk->total_sectors = nr;
+#else
+    disk->total_sectors = nr / 512;
+
+    if (nr % 512)
+      grub_util_error ("unaligned device size");
+#endif
+
+    grub_util_info ("the size of %s is %llu", name, disk->total_sectors);
+
+    return GRUB_ERR_NONE;
+  }
+
+ fail:
+  /* In GNU/Hurd, stat() will return the right size.  */
+#elif !defined (__GNU__)
+# warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal."
+#endif
+  if (stat (map[drive].device, &st) < 0)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", map[drive].device);
+
+  disk->total_sectors = st.st_size >> GRUB_DISK_SECTOR_BITS;
+
+  grub_util_info ("the size of %s is %lu", name, disk->total_sectors);
+
+  return GRUB_ERR_NONE;
+}
+
+#ifdef __linux__
+static int
+linux_find_partition (char *dev, unsigned long sector)
+{
+  size_t len = strlen (dev);
+  const char *format;
+  char *p;
+  int i;
+  char real_dev[PATH_MAX];
+
+  strcpy(real_dev, dev);
+
+  if (have_devfs () && strcmp (real_dev + len - 5, "/disc") == 0)
+    {
+      p = real_dev + len - 4;
+      format = "part%d";
+    }
+  else if (real_dev[len - 1] >= '0' && real_dev[len - 1] <= '9')
+    {
+      p = real_dev + len;
+      format = "p%d";
+    }
+  else
+    {
+      p = real_dev + len;
+      format = "%d";
+    }
+
+  for (i = 1; i < 10000; i++)
+    {
+      int fd;
+      struct hd_geometry hdg;
+
+      sprintf (p, format, i);
+      fd = open (real_dev, O_RDONLY);
+      if (fd == -1)
+	return 0;
+
+      if (ioctl (fd, HDIO_GETGEO, &hdg))
+	{
+	  close (fd);
+	  return 0;
+	}
+
+      close (fd);
+
+      if (hdg.start == sector)
+	{
+	  strcpy (dev, real_dev);
+	  return 1;
+	}
+    }
+
+  return 0;
+}
+#endif /* __linux__ */
+
+static int
+open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
+{
+  int fd;
+
+#ifdef O_LARGEFILE
+  flags |= O_LARGEFILE;
+#endif
+#ifdef O_SYNC
+  flags |= O_SYNC;
+#endif
+#ifdef O_FSYNC
+  flags |= O_FSYNC;
+#endif
+#ifdef O_BINARY
+  flags |= O_BINARY;
+#endif
+
+#ifdef __linux__
+  /* Linux has a bug that the disk cache for a whole disk is not consistent
+     with the one for a partition of the disk.  */
+  {
+    int is_partition = 0;
+    char dev[PATH_MAX];
+
+    strcpy (dev, map[disk->id].device);
+    if (disk->partition && strncmp (map[disk->id].device, "/dev/", 5) == 0)
+      is_partition = linux_find_partition (dev, disk->partition->start);
+
+    /* Open the partition.  */
+    grub_dprintf ("hostdisk", "opening the device `%s' in open_device()", dev);
+    fd = open (dev, flags);
+    if (fd < 0)
+      {
+	grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev);
+	return -1;
+      }
+
+    /* Make the buffer cache consistent with the physical disk.  */
+    ioctl (fd, BLKFLSBUF, 0);
+
+    if (is_partition)
+      sector -= disk->partition->start;
+  }
+#else /* ! __linux__ */
+#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
+  int sysctl_flags, sysctl_oldflags;
+  size_t sysctl_size = sizeof (sysctl_flags);
+
+  if (sysctlbyname ("kern.geom.debugflags", &sysctl_oldflags, &sysctl_size, NULL, 0))
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current flags of sysctl kern.geom.debugflags");
+      return -1;
+    }
+  sysctl_flags = sysctl_oldflags | 0x10;
+  if (! (sysctl_oldflags & 0x10)
+      && sysctlbyname ("kern.geom.debugflags", NULL , 0, &sysctl_flags, sysctl_size))
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "cannot set flags of sysctl kern.geom.debugflags");
+      return -1;
+    }
+#endif
+
+  fd = open (map[disk->id].device, flags);
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+  if (! (sysctl_oldflags & 0x10)
+      && sysctlbyname ("kern.geom.debugflags", NULL , 0, &sysctl_oldflags, sysctl_size))
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "cannot set flags back to the old value for sysctl kern.geom.debugflags");
+      return -1;
+    }
+#endif
+
+#if defined(__APPLE__)
+  /* If we can't have exclusive access, try shared access */
+  if (fd < 0)
+    fd = open(map[disk->id].device, flags | O_SHLOCK);
+#endif
+
+  if (fd < 0)
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' in open_device()", map[disk->id].device);
+      return -1;
+    }
+#endif /* ! __linux__ */
+
+#if defined(__linux__) && (!defined(__GLIBC__) || \
+        ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
+  /* Maybe libc doesn't have large file support.  */
+  {
+    loff_t offset, result;
+    static int _llseek (uint filedes, ulong hi, ulong lo,
+                        loff_t *res, uint wh);
+    _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
+               loff_t *, res, uint, wh);
+
+    offset = (loff_t) sector << GRUB_DISK_SECTOR_BITS;
+    if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
+      {
+	grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device);
+	close (fd);
+	return -1;
+      }
+  }
+#else
+  {
+    off_t offset = (off_t) sector << GRUB_DISK_SECTOR_BITS;
+
+    if (lseek (fd, offset, SEEK_SET) != offset)
+      {
+	grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device);
+	close (fd);
+	return -1;
+      }
+  }
+#endif
+
+  return fd;
+}
+
+/* Read LEN bytes from FD in BUF. Return less than or equal to zero if an
+   error occurs, otherwise return LEN.  */
+static ssize_t
+nread (int fd, char *buf, size_t len)
+{
+  ssize_t size = len;
+
+  while (len)
+    {
+      ssize_t ret = read (fd, buf, len);
+
+      if (ret <= 0)
+        {
+          if (errno == EINTR)
+            continue;
+          else
+            return ret;
+        }
+
+      len -= ret;
+      buf += ret;
+    }
+
+  return size;
+}
+
+/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an
+   error occurs, otherwise return LEN.  */
+static ssize_t
+nwrite (int fd, const char *buf, size_t len)
+{
+  ssize_t size = len;
+
+  while (len)
+    {
+      ssize_t ret = write (fd, buf, len);
+
+      if (ret <= 0)
+        {
+          if (errno == EINTR)
+            continue;
+          else
+            return ret;
+        }
+
+      len -= ret;
+      buf += ret;
+    }
+
+  return size;
+}
+
+static grub_err_t
+grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
+			 grub_size_t size, char *buf)
+{
+  int fd;
+
+  fd = open_device (disk, sector, O_RDONLY);
+  if (fd < 0)
+    return grub_errno;
+
+#ifdef __linux__
+  if (sector == 0 && size > 1)
+    {
+      /* Work around a bug in Linux ez remapping.  Linux remaps all
+	 sectors that are read together with the MBR in one read.  It
+	 should only remap the MBR, so we split the read in two
+	 parts. -jochen  */
+      if (nread (fd, buf, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE)
+	{
+	  grub_error (GRUB_ERR_READ_ERROR, "cannot read `%s'", map[disk->id].device);
+	  close (fd);
+	  return grub_errno;
+	}
+
+      buf += GRUB_DISK_SECTOR_SIZE;
+      size--;
+    }
+#endif /* __linux__ */
+
+  if (nread (fd, buf, size << GRUB_DISK_SECTOR_BITS)
+      != (ssize_t) (size << GRUB_DISK_SECTOR_BITS))
+    grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id].device);
+
+  close (fd);
+  return grub_errno;
+}
+
+static grub_err_t
+grub_util_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
+			  grub_size_t size, const char *buf)
+{
+  int fd;
+
+  fd = open_device (disk, sector, O_WRONLY);
+  if (fd < 0)
+    return grub_errno;
+
+  if (nwrite (fd, buf, size << GRUB_DISK_SECTOR_BITS)
+      != (ssize_t) (size << GRUB_DISK_SECTOR_BITS))
+    grub_error (GRUB_ERR_WRITE_ERROR, "cannot write to `%s'", map[disk->id].device);
+
+  close (fd);
+  return grub_errno;
+}
+
+static struct grub_disk_dev grub_util_biosdisk_dev =
+  {
+    .name = "biosdisk",
+    .id = GRUB_DISK_DEVICE_BIOSDISK_ID,
+    .iterate = grub_util_biosdisk_iterate,
+    .open = grub_util_biosdisk_open,
+    .close = 0,
+    .read = grub_util_biosdisk_read,
+    .write = grub_util_biosdisk_write,
+    .next = 0
+  };
+
+static void
+read_device_map (const char *dev_map)
+{
+  FILE *fp;
+  char buf[1024];	/* XXX */
+  int lineno = 0;
+  struct stat st;
+
+  auto void show_error (const char *msg);
+  void show_error (const char *msg)
+    {
+      grub_util_error ("%s:%d: %s", dev_map, lineno, msg);
+    }
+
+  fp = fopen (dev_map, "r");
+  if (! fp)
+    grub_util_error ("Cannot open `%s'", dev_map);
+
+  while (fgets (buf, sizeof (buf), fp))
+    {
+      char *p = buf;
+      char *e;
+      int drive;
+
+      lineno++;
+
+      /* Skip leading spaces.  */
+      while (*p && isspace (*p))
+	p++;
+
+      /* If the first character is `#' or NUL, skip this line.  */
+      if (*p == '\0' || *p == '#')
+	continue;
+
+      if (*p != '(')
+	show_error ("No open parenthesis found");
+
+      p++;
+      /* Find a free slot.  */
+      drive = find_free_slot ();
+      if (drive < 0)
+	show_error ("Map table size exceeded");
+
+      e = p;
+      p = strchr (p, ')');
+      if (! p)
+	show_error ("No close parenthesis found");
+
+      map[drive].drive = xmalloc (p - e + sizeof ('\0'));
+      strncpy (map[drive].drive, e, p - e + sizeof ('\0'));
+      map[drive].drive[p - e] = '\0';
+
+      p++;
+      /* Skip leading spaces.  */
+      while (*p && isspace (*p))
+	p++;
+
+      if (*p == '\0')
+	show_error ("No filename found");
+
+      /* NUL-terminate the filename.  */
+      e = p;
+      while (*e && ! isspace (*e))
+	e++;
+      *e = '\0';
+
+#ifdef __MINGW32__
+      (void) st;
+      if (grub_util_get_disk_size (p) == -1LL)
+#else
+      if (stat (p, &st) == -1)
+#endif
+	{
+	  free (map[drive].drive);
+	  map[drive].drive = NULL;
+	  grub_util_info ("Cannot stat `%s', skipping", p);
+	  continue;
+	}
+
+#ifdef __linux__
+      /* On Linux, the devfs uses symbolic links horribly, and that
+	 confuses the interface very much, so use realpath to expand
+	 symbolic links.  */
+      map[drive].device = xmalloc (PATH_MAX);
+      if (! realpath (p, map[drive].device))
+	grub_util_error ("Cannot get the real path of `%s'", p);
+#else
+      map[drive].device = xstrdup (p);
+#endif
+    }
+
+  fclose (fp);
+}
+
+void
+grub_util_biosdisk_init (const char *dev_map)
+{
+  read_device_map (dev_map);
+  grub_disk_dev_register (&grub_util_biosdisk_dev);
+}
+
+void
+grub_util_biosdisk_fini (void)
+{
+  unsigned i;
+
+  for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
+    {
+      if (map[i].drive)
+	free (map[i].drive);
+      if (map[i].device)
+	free (map[i].device);
+      map[i].drive = map[i].device = NULL;
+    }
+
+  grub_disk_dev_unregister (&grub_util_biosdisk_dev);
+}
+
+static char *
+make_device_name (int drive, int dos_part, int bsd_part)
+{
+  int len = strlen(map[drive].drive);
+  char *p;
+
+  if (dos_part >= 0)
+    {
+      /* Add in char length of dos_part+1 */
+      int tmp = dos_part + 1;
+      len++;
+      while ((tmp /= 10) != 0)
+	len++;
+    }
+  if (bsd_part >= 0)
+    len += 2;
+
+  /* Length to alloc is: char length of map[drive].drive, plus
+   *                     char length of (dos_part+1) or of bsd_part, plus
+   *                     2 for the comma and a null/end of string (\0)
+   */
+  p = xmalloc (len + 2);
+  sprintf (p, "%s", map[drive].drive);
+
+  if (dos_part >= 0)
+    sprintf (p + strlen (p), ",%d", dos_part + 1);
+
+  if (bsd_part >= 0)
+    sprintf (p + strlen (p), ",%c", bsd_part + 'a');
+
+  return p;
+}
+
+static char *
+convert_system_partition_to_system_disk (const char *os_dev)
+{
+#if defined(__linux__)
+  char *path = xmalloc (PATH_MAX);
+  if (! realpath (os_dev, path))
+    return 0;
+
+  if (strncmp ("/dev/", path, 5) == 0)
+    {
+      char *p = path + 5;
+
+      /* If this is an IDE disk.  */
+      if (strncmp ("ide/", p, 4) == 0)
+	{
+	  p = strstr (p, "part");
+	  if (p)
+	    strcpy (p, "disc");
+
+	  return path;
+	}
+
+      /* If this is a SCSI disk.  */
+      if (strncmp ("scsi/", p, 5) == 0)
+	{
+	  p = strstr (p, "part");
+	  if (p)
+	    strcpy (p, "disc");
+
+	  return path;
+	}
+
+      /* If this is a DAC960 disk.  */
+      if (strncmp ("rd/c", p, 4) == 0)
+	{
+	  /* /dev/rd/c[0-9]+d[0-9]+(p[0-9]+)? */
+	  p = strchr (p, 'p');
+	  if (p)
+	    *p = '\0';
+
+	  return path;
+	}
+
+      /* If this is a Mylex AcceleRAID Array.  */
+      if (strncmp ("rs/c", p, 4) == 0)
+	{
+	  /* /dev/rd/c[0-9]+d[0-9]+(p[0-9]+)? */
+	  p = strchr (p, 'p');
+	  if (p)
+	    *p = '\0';
+
+	  return path;
+	}
+      /* If this is a CCISS disk.  */
+      if (strncmp ("cciss/c", p, sizeof ("cciss/c") - 1) == 0)
+	{
+	  /* /dev/cciss/c[0-9]+d[0-9]+(p[0-9]+)? */
+	  p = strchr (p, 'p');
+	  if (p)
+	    *p = '\0';
+
+	  return path;
+	}
+
+      /* If this is a Compaq Intelligent Drive Array.  */
+      if (strncmp ("ida/c", p, sizeof ("ida/c") - 1) == 0)
+	{
+	  /* /dev/ida/c[0-9]+d[0-9]+(p[0-9]+)? */
+	  p = strchr (p, 'p');
+	  if (p)
+	    *p = '\0';
+
+	  return path;
+	}
+
+      /* If this is an I2O disk.  */
+      if (strncmp ("i2o/hd", p, sizeof ("i2o/hd") - 1) == 0)
+      	{
+	  /* /dev/i2o/hd[a-z]([0-9]+)? */
+	  p[sizeof ("i2o/hda") - 1] = '\0';
+	  return path;
+	}
+
+      /* If this is a MultiMediaCard (MMC).  */
+      if (strncmp ("mmcblk", p, sizeof ("mmcblk") - 1) == 0)
+	{
+	  /* /dev/mmcblk[0-9]+(p[0-9]+)? */
+	  p = strchr (p, 'p');
+	  if (p)
+	    *p = '\0';
+
+	  return path;
+	}
+
+      /* If this is an IDE, SCSI or Virtio disk.  */
+      if (strncmp ("vdisk", p, 5) == 0
+	  && p[5] >= 'a' && p[5] <= 'z')
+	{
+	  /* /dev/vdisk[a-z][0-9]* */
+	  p[6] = '\0';
+	  return path;
+	}
+      if ((strncmp ("hd", p, 2) == 0
+	   || strncmp ("vd", p, 2) == 0
+	   || strncmp ("sd", p, 2) == 0)
+	  && p[2] >= 'a' && p[2] <= 'z')
+	{
+	  /* /dev/[hsv]d[a-z][0-9]* */
+	  p[3] = '\0';
+	  return path;
+	}
+
+      /* If this is a Xen virtual block device.  */
+      if ((strncmp ("xvd", p, 3) == 0) && p[3] >= 'a' && p[3] <= 'z')
+	{
+	  /* /dev/xvd[a-z][0-9]* */
+	  p[4] = '\0';
+	  return path;
+	}
+    }
+
+  return path;
+
+#elif defined(__GNU__)
+  char *path = xstrdup (os_dev);
+  if (strncmp ("/dev/sd", path, 7) == 0 || strncmp ("/dev/hd", path, 7) == 0)
+    {
+      char *p = strchr (path + 7, 's');
+      if (p)
+	*p = '\0';
+    }
+  return path;
+
+#elif defined(__CYGWIN__)
+  char *path = xstrdup (os_dev);
+  if (strncmp ("/dev/sd", path, 7) == 0 && 'a' <= path[7] && path[7] <= 'z')
+    path[8] = 0;
+  return path;
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
+  char *path = xstrdup (os_dev);
+  if (strncmp ("/dev/", path, 5) == 0)
+    {
+      char *p;
+      for (p = path + 5; *p; ++p)
+        if (grub_isdigit(*p))
+          {
+            p = strchr (p, 's');
+            if (p)
+              *p = '\0';
+            break;
+          }
+    }
+  return path;
+
+#else
+# warning "The function `convert_system_partition_to_system_disk' might not work on your OS correctly."
+  return xstrdup (os_dev);
+#endif
+}
+
+#if defined(__linux__) || defined(__CYGWIN__)
+static int
+device_is_wholedisk (const char *os_dev)
+{
+  int len = strlen (os_dev);
+
+  if (os_dev[len - 1] < '0' || os_dev[len - 1] > '9')
+    return 1;
+  return 0;
+}
+#endif
+
+static int
+find_system_device (const char *os_dev)
+{
+  int i;
+  char *os_disk;
+
+  os_disk = convert_system_partition_to_system_disk (os_dev);
+  if (! os_disk)
+    return -1;
+
+  for (i = 0; i < (int) (sizeof (map) / sizeof (map[0])); i++)
+    if (map[i].device && strcmp (map[i].device, os_disk) == 0)
+      {
+	free (os_disk);
+	return i;
+      }
+
+  free (os_disk);
+  return -1;
+}
+
+char *
+grub_util_biosdisk_get_grub_dev (const char *os_dev)
+{
+  struct stat st;
+  int drive;
+
+  if (stat (os_dev, &st) < 0)
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", os_dev);
+      return 0;
+    }
+
+  drive = find_system_device (os_dev);
+  if (drive < 0)
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE,
+		  "no mapping exists for `%s'", os_dev);
+      return 0;
+    }
+
+  if (grub_strcmp (os_dev, convert_system_partition_to_system_disk (os_dev))
+      == 0)
+    return make_device_name (drive, -1, -1);
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
+  if (! S_ISCHR (st.st_mode))
+#else
+  if (! S_ISBLK (st.st_mode))
+#endif
+    return make_device_name (drive, -1, -1);
+
+#if defined(__linux__) || defined(__CYGWIN__)
+  /* Linux counts partitions uniformly, whether a BSD partition or a DOS
+     partition, so mapping them to GRUB devices is not trivial.
+     Here, get the start sector of a partition by HDIO_GETGEO, and
+     compare it with each partition GRUB recognizes.
+
+     Cygwin /dev/sdXN emulation uses Windows partition mapping. It
+     does not count the extended partition and missing primary
+     partitions.  Use same method as on Linux here.  */
+  {
+    char *name;
+    grub_disk_t disk;
+    int fd;
+    struct hd_geometry hdg;
+    int dos_part = -1;
+    int bsd_part = -1;
+    auto int find_partition (grub_disk_t disk,
+			     const grub_partition_t partition);
+
+    int find_partition (grub_disk_t disk __attribute__ ((unused)),
+			const grub_partition_t partition)
+      {
+ 	struct grub_msdos_partition *pcdata = NULL;
+
+	if (strcmp (partition->partmap->name, "part_msdos") == 0)
+	  pcdata = partition->data;
+
+	if (pcdata)
+	  {
+	    if (pcdata->bsd_part < 0)
+	      grub_util_info ("DOS partition %d starts from %lu",
+			      pcdata->dos_part, partition->start);
+	    else
+	      grub_util_info ("BSD partition %d,%c starts from %lu",
+			      pcdata->dos_part, pcdata->bsd_part + 'a',
+			      partition->start);
+	  }
+	else
+	  {
+	      grub_util_info ("Partition %d starts from %lu",
+			      partition->index, partition->start);
+	  }
+
+	if (hdg.start == partition->start)
+	  {
+	    if (pcdata)
+	      {
+		dos_part = pcdata->dos_part;
+		bsd_part = pcdata->bsd_part;
+	      }
+	    else
+	      {
+		dos_part = partition->index;
+		bsd_part = -1;
+	      }
+	    return 1;
+	  }
+
+	return 0;
+      }
+
+    name = make_device_name (drive, -1, -1);
+
+    if (MAJOR (st.st_rdev) == FLOPPY_MAJOR)
+      return name;
+
+    fd = open (os_dev, O_RDONLY);
+    if (fd == -1)
+      {
+	grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", os_dev);
+	free (name);
+	return 0;
+      }
+
+    if (ioctl (fd, HDIO_GETGEO, &hdg))
+      {
+	grub_error (GRUB_ERR_BAD_DEVICE,
+		    "cannot get geometry of `%s'", os_dev);
+	close (fd);
+	free (name);
+	return 0;
+      }
+
+    close (fd);
+
+    grub_util_info ("%s starts from %lu", os_dev, hdg.start);
+
+    if (hdg.start == 0 && device_is_wholedisk (os_dev))
+      return name;
+
+    grub_util_info ("opening the device %s", name);
+    disk = grub_disk_open (name);
+    free (name);
+
+    if (! disk)
+      return 0;
+
+    grub_partition_iterate (disk, find_partition);
+    if (grub_errno != GRUB_ERR_NONE)
+      {
+	grub_disk_close (disk);
+	return 0;
+      }
+
+    if (dos_part < 0)
+      {
+	grub_disk_close (disk);
+	grub_error (GRUB_ERR_BAD_DEVICE,
+		    "cannot find the partition of `%s'", os_dev);
+	return 0;
+      }
+
+    return make_device_name (drive, dos_part, bsd_part);
+  }
+
+#elif defined(__GNU__)
+  /* GNU uses "/dev/[hs]d[0-9]+(s[0-9]+[a-z]?)?".  */
+  {
+    char *p;
+    int dos_part = -1;
+    int bsd_part = -1;
+
+    p = strrchr (os_dev, 's');
+    if (p)
+      {
+	long int n;
+	char *q;
+
+	p++;
+	n = strtol (p, &q, 10);
+	if (p != q && n != GRUB_LONG_MIN && n != GRUB_LONG_MAX)
+	  {
+	    dos_part = (int) n;
+
+	    if (*q >= 'a' && *q <= 'g')
+	      bsd_part = *q - 'a';
+	  }
+      }
+
+    return make_device_name (drive, dos_part, bsd_part);
+  }
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
+  /* FreeBSD uses "/dev/[a-z]+[0-9]+(s[0-9]+[a-z]?)?".  */
+  {
+    int dos_part = -1;
+    int bsd_part = -1;
+
+    if (strncmp ("/dev/", os_dev, 5) == 0)
+      {
+        const char *p;
+        char *q;
+        long int n;
+
+        for (p = os_dev + 5; *p; ++p)
+          if (grub_isdigit(*p))
+            {
+              p = strchr (p, 's');
+              if (p)
+                {
+                  p++;
+                  n = strtol (p, &q, 10);
+                  if (p != q && n != GRUB_LONG_MIN && n != GRUB_LONG_MAX)
+                    {
+                      dos_part = (int) n - 1;
+
+                      if (*q >= 'a' && *q <= 'g')
+                        bsd_part = *q - 'a';
+                    }
+                }
+              break;
+            }
+      }
+
+    return make_device_name (drive, dos_part, bsd_part);
+  }
+
+#else
+# warning "The function `grub_util_biosdisk_get_grub_dev' might not work on your OS correctly."
+  return make_device_name (drive, -1, -1);
+#endif
+}
diff --git a/util/hostfs.c b/util/hostfs.c
new file mode 100644
index 0000000..83db2f1
--- /dev/null
+++ b/util/hostfs.c
@@ -0,0 +1,167 @@
+/* hostfs.c - Dummy filesystem to provide access to the hosts filesystem  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#define _BSD_SOURCE
+#include <grub/fs.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/dl.h>
+#include <grub/util/misc.h>
+
+#include <dirent.h>
+#include <stdio.h>
+
+
+/* dirent.d_type is a BSD extension, not part of POSIX */
+#include <sys/stat.h>
+#include <string.h>
+
+static int
+is_dir (const char *path, const char *name)
+{
+  int len1 = strlen(path);
+  int len2 = strlen(name);
+
+  char pathname[len1 + 1 + len2 + 1 + 13];
+  strcpy (pathname, path);
+
+  /* Avoid UNC-path "//name" on Cygwin.  */
+  if (len1 > 0 && pathname[len1 - 1] != '/')
+    strcat (pathname, "/");
+
+  strcat (pathname, name);
+
+  struct stat st;
+  if (stat (pathname, &st))
+    return 0;
+  return S_ISDIR (st.st_mode);
+}
+
+static grub_err_t
+grub_hostfs_dir (grub_device_t device, const char *path,
+		 int (*hook) (const char *filename,
+			      const struct grub_dirhook_info *info))
+{
+  DIR *dir;
+
+  /* Check if the disk is our dummy disk.  */
+  if (grub_strcmp (device->disk->name, "host"))
+    return grub_error (GRUB_ERR_BAD_FS, "not a hostfs");
+
+  dir = opendir (path);
+  if (! dir)
+    return grub_error (GRUB_ERR_BAD_FILENAME,
+		       "can't open the hostfs directory `%s'", path);
+
+  while (1)
+    {
+      struct dirent *de;
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+
+      de = readdir (dir);
+      if (! de)
+	break;
+
+      info.dir = !! is_dir (path, de->d_name);
+      hook (de->d_name, &info);
+
+    }
+
+  closedir (dir);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_hostfs_open (struct grub_file *file, const char *name)
+{
+  FILE *f;
+
+  f = fopen (name, "rb");
+  if (! f)
+    return grub_error (GRUB_ERR_BAD_FILENAME,
+		       "can't open `%s'", name);
+  file->data = f;
+
+#ifdef __MINGW32__
+  file->size = grub_util_get_disk_size (name);
+#else
+  fseeko (f, 0, SEEK_END);
+  file->size = ftello (f);
+  fseeko (f, 0, SEEK_SET);
+#endif
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_ssize_t
+grub_hostfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  FILE *f;
+
+  f = (FILE *) file->data;
+  fseeko (f, file->offset, SEEK_SET);
+  int s = fread (buf, 1, len, f);
+
+  return s;
+}
+
+static grub_err_t
+grub_hostfs_close (grub_file_t file)
+{
+  FILE *f;
+
+  f = (FILE *) file->data;
+  fclose (f);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_hostfs_label (grub_device_t device __attribute ((unused)),
+		   char **label __attribute ((unused)))
+{
+  *label = 0;
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_fs grub_hostfs_fs =
+  {
+    .name = "hostfs",
+    .dir = grub_hostfs_dir,
+    .open = grub_hostfs_open,
+    .read = grub_hostfs_read,
+    .close = grub_hostfs_close,
+    .label = grub_hostfs_label,
+    .next = 0
+  };
+
+
+
+GRUB_MOD_INIT(hostfs)
+{
+  grub_fs_register (&grub_hostfs_fs);
+}
+
+GRUB_MOD_FINI(hostfs)
+{
+  grub_fs_unregister (&grub_hostfs_fs);
+}
diff --git a/util/i386/efi/grub-dumpdevtree b/util/i386/efi/grub-dumpdevtree
new file mode 100644
index 0000000..bc13e3c
--- /dev/null
+++ b/util/i386/efi/grub-dumpdevtree
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Copyright (C) 2009  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+hexify()
+{
+  echo -n "$@" | od -A n -t x1 - | sed -e 's/ //g' | tr '\n' '\0'
+}
+
+echo "`hexify efi`{	`hexify device-properties`:"
+ioreg -lw0 -p IODeviceTree -n efi -r -x |grep device-properties | sed 's/.*<//;s/>.*//;'
+echo ";}"
diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in
new file mode 100644
index 0000000..a5f97e3
--- /dev/null
+++ b/util/i386/efi/grub-install.in
@@ -0,0 +1,211 @@
+#! /bin/sh
+
+# Install GRUB on your EFI partition.
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+# Initialize some variables.
+transform="@program_transform_name@"
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+bindir=@bindir@
+libdir=@libdir@
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+target_cpu=@target_cpu@
+platform=@platform@
+pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
+
+grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
+grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
+grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
+rootdir=
+grub_prefix=`echo /boot/grub | sed ${transform}`
+modules=
+
+no_floppy=
+force_lba=
+recheck=no
+debug=no
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: grub-install [OPTION]
+Install GRUB on your EFI partition.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --modules=MODULES       pre-load specified modules MODULES
+  --root-directory=DIR    install GRUB images under the directory DIR
+                          instead of the root directory
+  --grub-mkimage=FILE     use FILE as grub-mkimage
+  --grub-mkdevicemap=FILE use FILE as grub-mkdevicemap
+  --grub-probe=FILE       use FILE as grub-probe
+  --no-floppy             do not probe any floppy drive
+  --recheck               probe a device map even if it already exists
+
+grub-install copies GRUB images into the DIR/boot directory specified by
+--root-directory.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-install (GNU GRUB ${PACKAGE_VERSION})"
+	exit 0 ;;
+    --modules=*)
+	modules=`echo "$option" | sed 's/--modules=//'` ;;
+    --root-directory=*)
+	rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
+    --grub-mkimage=*)
+	grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
+    --grub-mkdevicemap=*)
+	grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;;
+    --grub-probe=*)
+	grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;;
+    --no-floppy)
+	no_floppy="--no-floppy" ;;
+    --recheck)
+	recheck=yes ;;
+    # This is an undocumented feature...
+    --debug)
+	debug=yes ;;
+    *)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    esac
+done
+
+# If the debugging feature is enabled, print commands.
+if test $debug = yes; then
+    set -x
+fi
+
+# Initialize these directories here, since ROOTDIR was initialized.
+case "$host_os" in
+netbsd* | openbsd*)
+    # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub
+    # instead of /boot/grub.
+    grub_prefix=`echo /grub | sed ${transform}`
+    bootdir=${rootdir}
+    ;;
+*)
+    # Use /boot/grub by default.
+    bootdir=${rootdir}/boot
+    ;;
+esac
+
+grubdir=${bootdir}/`echo grub | sed ${transform}`
+device_map=${grubdir}/device.map
+
+# Check if GRUB is installed.
+set $grub_mkimage dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+set $grub_mkdevicemap dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+# Create the GRUB directory if it is not present.
+test -d "$bootdir" || mkdir "$bootdir" || exit 1
+test -d "$grubdir" || mkdir "$grubdir" || exit 1
+
+# If --recheck is specified, remove the device map, if present.
+if test $recheck = yes; then
+    rm -f $device_map
+fi
+
+# Create the device map file if it is not present.
+if test -f "$device_map"; then
+    :
+else
+    # Create a safe temporary file.
+    test -n "$mklog" && log_file=`$mklog`
+
+    $grub_mkdevicemap --device-map=$device_map $no_floppy || exit 1
+fi
+
+# Make sure that there is no duplicated entry.
+tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \
+    | sort | uniq -d | sed -n 1p`
+if test -n "$tmp"; then
+    echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2
+    exit 1
+fi
+
+# Copy the GRUB images to the GRUB directory.
+for file in ${grubdir}/*.mod ${grubdir}/*.lst; do
+    if test -f $file && [ "`basename $file`" != menu.lst ]; then
+	rm -f $file || exit 1
+    fi
+done
+for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do
+    cp -f $file ${grubdir} || exit 1
+done
+
+# Create the core image. First, auto-detect the filesystem module.
+fs_module=`$grub_probe --target=fs --device-map=${device_map} ${grubdir}`
+if test "x$fs_module" = xfat; then :; else
+    echo "${grubdir} doesn't look like an EFI partition." 1>&2
+    exit 1
+fi
+
+# Then the partition map module.  In order to support partition-less media,
+# this command is allowed to fail (--target=fs already grants us that the
+# filesystem will be accessible).
+partmap_module=`$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`
+
+# Device abstraction module, if any (lvm, raid).
+devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}`
+
+# The order in this list is critical.  Be careful when modifying it.
+modules="$modules $fs_module $partmap_module $devabstraction_module"
+
+$grub_mkimage --output=${grubdir}/grub.efi $modules || exit 1
+
+# Prompt the user to check if the device map is correct.
+echo "Installation finished. No error reported."
+echo "This is the contents of the device map $device_map."
+echo "Check if this is correct or not. If any of the lines is incorrect,"
+echo "fix it and re-run the script \`grub-install'."
+echo
+
+cat $device_map
+
+# Bye.
+exit 0
diff --git a/util/i386/efi/grub-mkimage.c b/util/i386/efi/grub-mkimage.c
new file mode 100644
index 0000000..29a823e
--- /dev/null
+++ b/util/i386/efi/grub-mkimage.c
@@ -0,0 +1,1111 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <grub/elf.h>
+#include <grub/util/misc.h>
+#include <grub/util/resolve.h>
+#include <grub/kernel.h>
+#include <grub/efi/pe32.h>
+#include <grub/machine/kernel.h>
+
+#if GRUB_TARGET_WORDSIZE == 32
+# define grub_le_to_cpu(val) grub_le_to_cpu32(val)
+#elif GRUB_TARGET_WORDSIZE == 64
+# define grub_le_to_cpu(val) grub_le_to_cpu64(val)
+#endif
+
+static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;
+
+static inline Elf_Addr
+align_address (Elf_Addr addr, unsigned alignment)
+{
+  return (addr + alignment - 1) & ~(alignment - 1);
+}
+
+static inline Elf_Addr
+align_pe32_section (Elf_Addr addr)
+{
+  return align_address (addr, GRUB_PE32_SECTION_ALIGNMENT);
+}
+
+/* Read the whole kernel image. Return the pointer to a read image,
+   and store the size in bytes in *SIZE.  */
+static char *
+read_kernel_module (const char *dir, size_t *size)
+{
+  char *kernel_image;
+  char *kernel_path;
+
+  kernel_path = grub_util_get_path (dir, "kernel.mod");
+  *size = grub_util_get_image_size (kernel_path);
+  kernel_image = grub_util_read_image (kernel_path);
+  free (kernel_path);
+
+  return kernel_image;
+}
+
+/* Return if the ELF header is valid.  */
+static int
+check_elf_header (Elf_Ehdr *e, size_t size)
+{
+  if (size < sizeof (*e)
+      || 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_VERSION] != EV_CURRENT
+      || e->e_version != grub_cpu_to_le32 (EV_CURRENT)
+      || ((e->e_ident[EI_CLASS] != ELFCLASS32) &&
+          (e->e_ident[EI_CLASS] != ELFCLASS64))
+      || e->e_ident[EI_DATA] != ELFDATA2LSB
+      || ((e->e_machine != grub_cpu_to_le16 (EM_386)) &&
+          (e->e_machine != grub_cpu_to_le16 (EM_X86_64))))
+    return 0;
+
+  return 1;
+}
+
+/* Return the starting address right after the header,
+   aligned by the section alignment. Allocate 4 section tables for
+   .text, .data, .reloc, and mods.  */
+static Elf_Addr
+get_starting_section_address (void)
+{
+  return align_pe32_section (sizeof (struct grub_pe32_header)
+			     + 4 * sizeof (struct grub_pe32_section_table));
+}
+
+/* Determine if this section is a text section. Return false if this
+   section is not allocated.  */
+static int
+is_text_section (Elf_Shdr *s)
+{
+  return ((s->sh_flags & grub_cpu_to_le32 (SHF_EXECINSTR | SHF_ALLOC))
+	  == grub_cpu_to_le32 (SHF_EXECINSTR | SHF_ALLOC));
+}
+
+/* Determine if this section is a data section. This assumes that
+   BSS is also a data section, since the converter initializes BSS
+   when producing PE32 to avoid a bug in EFI implementations.  */
+static int
+is_data_section (Elf_Shdr *s)
+{
+  return (s->sh_flags & grub_cpu_to_le32 (SHF_ALLOC)
+	  && ! (s->sh_flags & grub_cpu_to_le32 (SHF_EXECINSTR)));
+}
+
+/* Locate section addresses by merging code sections and data sections
+   into .text and .data, respectively. Return the array of section
+   addresses.  */
+static Elf_Addr *
+locate_sections (Elf_Shdr *sections, Elf_Half section_entsize,
+		 Elf_Half num_sections, const char *strtab)
+{
+  int i;
+  Elf_Addr current_address;
+  Elf_Addr *section_addresses;
+  Elf_Shdr *s;
+
+  section_addresses = xmalloc (sizeof (*section_addresses) * num_sections);
+  memset (section_addresses, 0, sizeof (*section_addresses) * num_sections);
+
+  current_address = get_starting_section_address ();
+
+  /* .text */
+  for (i = 0, s = sections;
+       i < num_sections;
+       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+    if (is_text_section (s))
+      {
+	Elf_Word align = grub_le_to_cpu32 (s->sh_addralign);
+	const char *name = strtab + grub_le_to_cpu32 (s->sh_name);
+
+	if (align)
+	  current_address = align_address (current_address, align);
+
+	grub_util_info ("locating the section %s at 0x%x",
+			name, current_address);
+	section_addresses[i] = current_address;
+	current_address += grub_le_to_cpu32 (s->sh_size);
+      }
+
+  current_address = align_pe32_section (current_address);
+
+  /* .data */
+  for (i = 0, s = sections;
+       i < num_sections;
+       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+    if (is_data_section (s))
+      {
+	Elf_Word align = grub_le_to_cpu32 (s->sh_addralign);
+	const char *name = strtab + grub_le_to_cpu32 (s->sh_name);
+
+	if (align)
+	  current_address = align_address (current_address, align);
+
+	grub_util_info ("locating the section %s at 0x%x",
+			name, current_address);
+	section_addresses[i] = current_address;
+	current_address += grub_le_to_cpu32 (s->sh_size);
+      }
+
+  return section_addresses;
+}
+
+/* Return the symbol table section, if any.  */
+static Elf_Shdr *
+find_symtab_section (Elf_Shdr *sections,
+		     Elf_Half section_entsize, Elf_Half num_sections)
+{
+  int i;
+  Elf_Shdr *s;
+
+  for (i = 0, s = sections;
+       i < num_sections;
+       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+    if (s->sh_type == grub_cpu_to_le32 (SHT_SYMTAB))
+      return s;
+
+  return 0;
+}
+
+/* Return the address of the string table.  */
+static const char *
+find_strtab (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Half section_entsize)
+{
+  Elf_Shdr *s;
+  char *strtab;
+
+  s = (Elf_Shdr *) ((char *) sections
+		      + grub_le_to_cpu16 (e->e_shstrndx) * section_entsize);
+  strtab = (char *) e + grub_le_to_cpu32 (s->sh_offset);
+  return strtab;
+}
+
+/* Relocate symbols; note that this function overwrites the symbol table.
+   Return the address of a start symbol.  */
+static Elf_Addr
+relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections,
+		  Elf_Shdr *symtab_section, Elf_Addr *section_addresses,
+		  Elf_Half section_entsize, Elf_Half num_sections)
+{
+  Elf_Word symtab_size, sym_size, num_syms;
+  Elf_Off symtab_offset;
+  Elf_Addr start_address = 0;
+  Elf_Sym *sym;
+  Elf_Word i;
+  Elf_Shdr *strtab_section;
+  const char *strtab;
+
+  strtab_section
+    = (Elf_Shdr *) ((char *) sections
+		      + (grub_le_to_cpu32 (symtab_section->sh_link)
+			 * section_entsize));
+  strtab = (char *) e + grub_le_to_cpu32 (strtab_section->sh_offset);
+
+  symtab_size = grub_le_to_cpu32 (symtab_section->sh_size);
+  sym_size = grub_le_to_cpu32 (symtab_section->sh_entsize);
+  symtab_offset = grub_le_to_cpu32 (symtab_section->sh_offset);
+  num_syms = symtab_size / sym_size;
+
+  for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset);
+       i < num_syms;
+       i++, sym = (Elf_Sym *) ((char *) sym + sym_size))
+    {
+      Elf_Section index;
+      const char *name;
+
+      name = strtab + grub_le_to_cpu32 (sym->st_name);
+
+      index = grub_le_to_cpu16 (sym->st_shndx);
+      if (index == STN_ABS)
+        {
+          continue;
+        }
+      else if ((index == STN_UNDEF))
+	{
+	  if (sym->st_name)
+	    grub_util_error ("undefined symbol %s", name);
+	  else
+	    continue;
+	}
+      else if (index >= num_sections)
+	grub_util_error ("section %d does not exist", index);
+
+      sym->st_value = (grub_le_to_cpu32 (sym->st_value)
+		       + section_addresses[index]);
+      grub_util_info ("locating %s at 0x%x", name, sym->st_value);
+
+      if (! start_address)
+	if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0)
+	  start_address = sym->st_value;
+    }
+
+  return start_address;
+}
+
+/* Return the address of a symbol at the index I in the section S.  */
+static Elf_Addr
+get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i)
+{
+  Elf_Sym *sym;
+
+  sym = (Elf_Sym *) ((char *) e
+		       + grub_le_to_cpu32 (s->sh_offset)
+		       + i * grub_le_to_cpu32 (s->sh_entsize));
+  return sym->st_value;
+}
+
+/* Return the address of a modified value.  */
+static Elf_Addr *
+get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset)
+{
+  return (Elf_Addr *) ((char *) e + grub_le_to_cpu32 (s->sh_offset) + offset);
+}
+
+/* Deal with relocation information. This function relocates addresses
+   within the virtual address space starting from 0. So only relative
+   addresses can be fully resolved. Absolute addresses must be relocated
+   again by a PE32 relocator when loaded.  */
+static void
+relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections,
+		    Elf_Addr *section_addresses,
+		    Elf_Half section_entsize, Elf_Half num_sections,
+		    const char *strtab)
+{
+  Elf_Half i;
+  Elf_Shdr *s;
+
+  for (i = 0, s = sections;
+       i < num_sections;
+       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+    if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) ||
+        (s->sh_type == grub_cpu_to_le32 (SHT_RELA)))
+      {
+	Elf_Rela *r;
+	Elf_Word rtab_size, r_size, num_rs;
+	Elf_Off rtab_offset;
+	Elf_Shdr *symtab_section;
+	Elf_Word target_section_index;
+	Elf_Addr target_section_addr;
+	Elf_Shdr *target_section;
+	Elf_Word j;
+
+	symtab_section = (Elf_Shdr *) ((char *) sections
+					 + (grub_le_to_cpu32 (s->sh_link)
+					    * section_entsize));
+	target_section_index = grub_le_to_cpu32 (s->sh_info);
+	target_section_addr = section_addresses[target_section_index];
+	target_section = (Elf_Shdr *) ((char *) sections
+					 + (target_section_index
+					    * section_entsize));
+
+	grub_util_info ("dealing with the relocation section %s for %s",
+			strtab + grub_le_to_cpu32 (s->sh_name),
+			strtab + grub_le_to_cpu32 (target_section->sh_name));
+
+	rtab_size = grub_le_to_cpu32 (s->sh_size);
+	r_size = grub_le_to_cpu32 (s->sh_entsize);
+	rtab_offset = grub_le_to_cpu32 (s->sh_offset);
+	num_rs = rtab_size / r_size;
+
+	for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset);
+	     j < num_rs;
+	     j++, r = (Elf_Rela *) ((char *) r + r_size))
+	  {
+            Elf_Addr info;
+	    Elf_Addr offset;
+	    Elf_Addr sym_addr;
+	    Elf_Addr *target;
+	    Elf_Addr addend;
+
+	    offset = grub_le_to_cpu (r->r_offset);
+	    target = get_target_address (e, target_section, offset);
+	    info = grub_le_to_cpu (r->r_info);
+	    sym_addr = get_symbol_address (e, symtab_section,
+					   ELF_R_SYM (info));
+
+            addend = (s->sh_type == grub_cpu_to_le32 (SHT_RELA)) ?
+	      r->r_addend : 0;
+
+            switch (ELF_R_TYPE (info))
+	      {
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+	      case R_386_NONE:
+		break;
+
+	      case R_386_32:
+		/* This is absolute.  */
+		*target = grub_cpu_to_le32 (grub_le_to_cpu32 (*target)
+                                            + addend + sym_addr);
+		grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x",
+				*target, offset);
+		break;
+
+	      case R_386_PC32:
+		/* This is relative.  */
+		*target = grub_cpu_to_le32 (grub_le_to_cpu32 (*target)
+					    + addend + sym_addr
+					    - target_section_addr - offset);
+		grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x",
+				*target, offset);
+		break;
+
+#else
+
+              case R_X86_64_NONE:
+                break;
+
+              case R_X86_64_64:
+		*target = grub_cpu_to_le64 (grub_le_to_cpu64 (*target)
+					    + addend + sym_addr);
+		grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx",
+				*target, offset);
+		break;
+
+              case R_X86_64_PC32:
+                {
+                  grub_uint32_t *t32 = (grub_uint32_t *) target;
+                  *t32 = grub_cpu_to_le64 (grub_le_to_cpu32 (*t32)
+                                           + addend + sym_addr
+                                           - target_section_addr - offset);
+                  grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx",
+                                  *t32, offset);
+                  break;
+                }
+
+              case R_X86_64_32:
+              case R_X86_64_32S:
+                {
+                  grub_uint32_t *t32 = (grub_uint32_t *) target;
+                  *t32 = grub_cpu_to_le64 (grub_le_to_cpu32 (*t32)
+                                           + addend + sym_addr);
+                  grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx",
+                                  *t32, offset);
+                  break;
+                }
+
+#endif
+	      default:
+		grub_util_error ("unknown relocation type %d",
+				 ELF_R_TYPE (info));
+		break;
+	      }
+	  }
+      }
+}
+
+void
+write_padding (FILE *out, size_t size)
+{
+  size_t i;
+
+  for (i = 0; i < size; i++)
+    if (fputc (0, out) == EOF)
+      grub_util_error ("padding failed");
+}
+
+/* Add a PE32's fixup entry for a relocation. Return the resulting address
+   after having written to the file OUT.  */
+Elf_Addr
+add_fixup_entry (struct grub_pe32_fixup_block **block, grub_uint16_t type,
+		 Elf_Addr addr, int flush, Elf_Addr current_address,
+		 FILE *out)
+{
+  struct grub_pe32_fixup_block *b = *block;
+
+  /* First, check if it is necessary to write out the current block.  */
+  if (b)
+    {
+      if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr)
+	{
+	  grub_uint32_t size;
+
+	  if (flush)
+	    {
+	      /* Add as much padding as necessary to align the address
+		 with a section boundary.  */
+	      Elf_Addr next_address;
+	      unsigned padding_size;
+              size_t index;
+
+	      next_address = current_address + b->block_size;
+	      padding_size = ((align_pe32_section (next_address)
+			       - next_address)
+			      >> 1);
+              index = ((b->block_size - sizeof (*b)) >> 1);
+              grub_util_info ("adding %d padding fixup entries", padding_size);
+	      while (padding_size--)
+		{
+		  b->entries[index++] = 0;
+		  b->block_size += 2;
+		}
+	    }
+          else if (b->block_size & (8 - 1))
+            {
+	      /* If not aligned with a 32-bit boundary, add
+		 a padding entry.  */
+              size_t index;
+
+              grub_util_info ("adding a padding fixup entry");
+              index = ((b->block_size - sizeof (*b)) >> 1);
+              b->entries[index] = 0;
+              b->block_size += 2;
+            }
+
+          /* Flush it.  */
+          grub_util_info ("writing %d bytes of a fixup block starting at 0x%x",
+                          b->block_size, b->page_rva);
+          size = b->block_size;
+	  current_address += size;
+	  b->page_rva = grub_cpu_to_le32 (b->page_rva);
+	  b->block_size = grub_cpu_to_le32 (b->block_size);
+	  if (fwrite (b, size, 1, out) != 1)
+	    grub_util_error ("write failed");
+	  free (b);
+	  *block = b = 0;
+	}
+    }
+
+  if (! flush)
+    {
+      grub_uint16_t entry;
+      size_t index;
+
+      /* If not allocated yet, allocate a block with enough entries.  */
+      if (! b)
+	{
+	  *block = b = xmalloc (sizeof (*b) + 2 * 0x1000);
+
+	  /* The spec does not mention the requirement of a Page RVA.
+	     Here, align the address with a 4K boundary for safety.  */
+	  b->page_rva = (addr & ~(0x1000 - 1));
+	  b->block_size = sizeof (*b);
+	}
+
+      /* Sanity check.  */
+      if (b->block_size >= sizeof (*b) + 2 * 0x1000)
+	grub_util_error ("too many fixup entries");
+
+      /* Add a new entry.  */
+      index = ((b->block_size - sizeof (*b)) >> 1);
+      entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva);
+      b->entries[index] = grub_cpu_to_le16 (entry);
+      b->block_size += 2;
+    }
+
+  return current_address;
+}
+
+/* Write out zeros to make space for the header.  */
+static Elf_Addr
+make_header_space (FILE *out)
+{
+  Elf_Addr addr;
+
+  addr = get_starting_section_address ();
+  write_padding (out, addr);
+
+  return addr;
+}
+
+/* Write text sections.  */
+static Elf_Addr
+write_text_sections (FILE *out, Elf_Addr current_address,
+		     Elf_Ehdr *e, Elf_Shdr *sections,
+		     Elf_Half section_entsize, Elf_Half num_sections,
+		     const char *strtab)
+{
+  Elf_Half i;
+  Elf_Shdr *s;
+  Elf_Addr addr;
+
+  for (i = 0, s = sections;
+       i < num_sections;
+       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+    if (is_text_section (s))
+      {
+	Elf_Word align = grub_le_to_cpu32 (s->sh_addralign);
+	Elf_Off offset = grub_le_to_cpu32 (s->sh_offset);
+	Elf_Word size = grub_le_to_cpu32 (s->sh_size);
+	const char *name = strtab + grub_le_to_cpu32 (s->sh_name);
+
+	if (align)
+	  {
+	    addr = align_address (current_address, align);
+	    if (current_address != addr)
+	      {
+		grub_util_info ("padding %d bytes for the ELF section alignment",
+				addr - current_address);
+		write_padding (out, addr - current_address);
+		current_address = addr;
+	      }
+	  }
+
+	grub_util_info ("writing the text section %s at 0x%x",
+			name, current_address);
+
+	if (fwrite ((char *) e + offset, size, 1, out) != 1)
+	  grub_util_error ("write failed");
+
+	current_address += size;
+      }
+
+  addr = align_pe32_section (current_address);
+  if (addr != current_address)
+    {
+      grub_util_info ("padding %d bytes for the PE32 section alignment",
+		      addr - current_address);
+      write_padding (out, addr - current_address);
+    }
+
+  return addr;
+}
+
+/* Write data sections.  */
+static Elf_Addr
+write_data_sections (FILE *out, Elf_Addr current_address,
+		     Elf_Ehdr *e, Elf_Shdr *sections,
+		     Elf_Half section_entsize, Elf_Half num_sections,
+		     const char *strtab)
+{
+  Elf_Half i;
+  Elf_Shdr *s;
+  Elf_Addr addr;
+
+  for (i = 0, s = sections;
+       i < num_sections;
+       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+    if (is_data_section (s))
+      {
+	Elf_Word align = grub_le_to_cpu32 (s->sh_addralign);
+	Elf_Off offset = grub_le_to_cpu32 (s->sh_offset);
+	Elf_Word size = grub_le_to_cpu32 (s->sh_size);
+	const char *name = strtab + grub_le_to_cpu32 (s->sh_name);
+
+	if (align)
+	  {
+	    addr = align_address (current_address, align);
+	    if (current_address != addr)
+	      {
+		grub_util_info ("padding %d bytes for the ELF section alignment",
+				addr - current_address);
+		write_padding (out, addr - current_address);
+		current_address = addr;
+	      }
+	  }
+
+	grub_util_info ("writing the data section %s at 0x%x",
+			name, current_address);
+
+	if (s->sh_type == grub_cpu_to_le32 (SHT_NOBITS))
+	  write_padding (out, size);
+	else
+	  if (fwrite ((char *) e + offset, size, 1, out) != 1)
+	    grub_util_error ("write failed");
+
+	current_address += size;
+      }
+
+  addr = align_pe32_section (current_address);
+  if (addr != current_address)
+    {
+      grub_util_info ("padding %d bytes for the PE32 section alignment",
+		      addr - current_address);
+      write_padding (out, addr - current_address);
+    }
+
+  return addr;
+}
+
+/* Write modules.  */
+static Elf_Addr
+make_mods_section (FILE *out, Elf_Addr current_address,
+		   const char *dir, char *mods[])
+{
+  struct grub_util_path_list *path_list;
+  grub_size_t total_module_size;
+  struct grub_util_path_list *p;
+  struct grub_module_info modinfo;
+  Elf_Addr addr;
+
+  memset (&modinfo, 0, sizeof (modinfo));
+
+  path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
+
+  total_module_size = sizeof (struct grub_module_info);
+  for (p = path_list; p; p = p->next)
+    {
+      total_module_size += (grub_util_get_image_size (p->name)
+			    + sizeof (struct grub_module_header));
+    }
+
+  grub_util_info ("the total module size is 0x%x", total_module_size);
+
+  modinfo.magic = grub_cpu_to_le32 (GRUB_MODULE_MAGIC);
+  modinfo.offset = grub_cpu_to_le32 (sizeof (modinfo));
+  modinfo.size = grub_cpu_to_le32 (total_module_size);
+
+  if (fwrite (&modinfo, sizeof (modinfo), 1, out) != 1)
+    grub_util_error ("write failed");
+
+  for (p = path_list; p; p = p->next)
+    {
+      struct grub_module_header header;
+      size_t mod_size;
+      char *mod_image;
+
+      memset (&header, 0, sizeof (header));
+
+      grub_util_info ("adding module %s", p->name);
+
+      mod_size = grub_util_get_image_size (p->name);
+      header.type = OBJ_TYPE_ELF;
+      header.size = grub_host_to_target32 (mod_size + sizeof (header));
+
+      mod_image = grub_util_read_image (p->name);
+
+      if (fwrite (&header, sizeof (header), 1, out) != 1
+	  || fwrite (mod_image, mod_size, 1, out) != 1)
+	grub_util_error ("write failed");
+
+      free (mod_image);
+    }
+
+  for (p = path_list; p; )
+    {
+      struct grub_util_path_list *q;
+
+      q = p->next;
+      free (p);
+      p = q;
+    }
+
+  current_address += total_module_size;
+
+  addr = align_pe32_section (current_address);
+  if (addr != current_address)
+    {
+      grub_util_info ("padding %d bytes for the PE32 section alignment",
+		      addr - current_address);
+      write_padding (out, addr - current_address);
+    }
+
+  return addr;
+}
+
+/* Make a .reloc section.  */
+static Elf_Addr
+make_reloc_section (FILE *out, Elf_Addr current_address, Elf_Ehdr *e,
+		    Elf_Addr *section_addresses, Elf_Shdr *sections,
+		    Elf_Half section_entsize, Elf_Half num_sections,
+		    const char *strtab)
+{
+  Elf_Half i;
+  Elf_Shdr *s;
+  struct grub_pe32_fixup_block *fixup_block = 0;
+
+  for (i = 0, s = sections;
+       i < num_sections;
+       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+    if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) ||
+        (s->sh_type == grub_cpu_to_le32 (SHT_RELA)))
+      {
+	Elf_Rel *r;
+	Elf_Word rtab_size, r_size, num_rs;
+	Elf_Off rtab_offset;
+	Elf_Addr section_address;
+	Elf_Word j;
+
+	grub_util_info ("translating the relocation section %s",
+			strtab + grub_le_to_cpu32 (s->sh_name));
+
+	rtab_size = grub_le_to_cpu32 (s->sh_size);
+	r_size = grub_le_to_cpu32 (s->sh_entsize);
+	rtab_offset = grub_le_to_cpu32 (s->sh_offset);
+	num_rs = rtab_size / r_size;
+
+	section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)];
+
+	for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset);
+	     j < num_rs;
+	     j++, r = (Elf_Rel *) ((char *) r + r_size))
+	  {
+	    Elf_Addr info;
+	    Elf_Addr offset;
+
+	    offset = grub_le_to_cpu32 (r->r_offset);
+	    info = grub_le_to_cpu32 (r->r_info);
+
+	    /* Necessary to relocate only absolute addresses.  */
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+	    if (ELF_R_TYPE (info) == R_386_32)
+	      {
+		Elf_Addr addr;
+
+		addr = section_address + offset;
+		grub_util_info ("adding a relocation entry for 0x%x", addr);
+		current_address = add_fixup_entry (&fixup_block,
+						   GRUB_PE32_REL_BASED_HIGHLOW,
+						   addr, 0, current_address,
+						   out);
+	      }
+#else
+	    if ((ELF_R_TYPE (info) == R_X86_64_32) ||
+                (ELF_R_TYPE (info) == R_X86_64_32S))
+	      {
+		grub_util_error ("Can\'t add fixup entry for R_X86_64_32(S)");
+	      }
+	    else if (ELF_R_TYPE (info) == R_X86_64_64)
+	      {
+		Elf_Addr addr;
+
+		addr = section_address + offset;
+		grub_util_info ("adding a relocation entry for 0x%llx", addr);
+		current_address = add_fixup_entry (&fixup_block,
+						   GRUB_PE32_REL_BASED_DIR64,
+						   addr,
+						   0, current_address,
+						   out);
+	      }
+#endif
+	  }
+      }
+
+  current_address = add_fixup_entry (&fixup_block, 0, 0, 1,
+				     current_address, out);
+
+  return current_address;
+}
+
+/* Create the header.  */
+static void
+make_header (FILE *out, Elf_Addr text_address, Elf_Addr data_address,
+	     Elf_Addr mods_address, Elf_Addr reloc_address,
+	     Elf_Addr end_address, Elf_Addr start_address)
+{
+  struct grub_pe32_header header;
+  struct grub_pe32_coff_header *c;
+  struct grub_pe32_optional_header *o;
+  struct grub_pe32_section_table text_section, data_section;
+  struct grub_pe32_section_table mods_section, reloc_section;
+
+  /* The magic.  */
+  memset (&header, 0, sizeof (header));
+  memcpy (header.msdos_stub, stub, sizeof (header.msdos_stub));
+  memcpy (header.signature, "PE\0\0", sizeof (header.signature));
+
+  /* The COFF file header.  */
+  c = &header.coff_header;
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+  c->machine = grub_cpu_to_le16 (GRUB_PE32_MACHINE_I386);
+#else
+  c->machine = grub_cpu_to_le16 (GRUB_PE32_MACHINE_X86_64);
+#endif
+
+  c->num_sections = grub_cpu_to_le16 (4);
+  c->time = grub_cpu_to_le32 (time (0));
+  c->optional_header_size = grub_cpu_to_le16 (sizeof (header.optional_header));
+  c->characteristics = grub_cpu_to_le16 (GRUB_PE32_EXECUTABLE_IMAGE
+					 | GRUB_PE32_LINE_NUMS_STRIPPED
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+                                         | GRUB_PE32_32BIT_MACHINE
+#endif
+					 | GRUB_PE32_LOCAL_SYMS_STRIPPED
+                                         | GRUB_PE32_DEBUG_STRIPPED);
+
+  /* The PE Optional header.  */
+  o = &header.optional_header;
+  o->magic = grub_cpu_to_le16 (GRUB_PE32_PE32_MAGIC);
+  o->code_size = grub_cpu_to_le32 (data_address - text_address);
+  o->data_size = grub_cpu_to_le32 (reloc_address - data_address);
+  o->bss_size = 0;
+  o->entry_addr = grub_cpu_to_le32 (start_address);
+  o->code_base = grub_cpu_to_le32 (text_address);
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+  o->data_base = grub_cpu_to_le32 (data_address);
+#endif
+  o->image_base = 0;
+  o->section_alignment = grub_cpu_to_le32 (GRUB_PE32_SECTION_ALIGNMENT);
+  o->file_alignment = grub_cpu_to_le32 (GRUB_PE32_FILE_ALIGNMENT);
+  o->image_size = grub_cpu_to_le32 (end_address);
+  o->header_size = grub_cpu_to_le32 (text_address);
+  o->subsystem = grub_cpu_to_le16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
+
+  /* Do these really matter? */
+  o->stack_reserve_size = grub_cpu_to_le32 (0x10000);
+  o->stack_commit_size = grub_cpu_to_le32 (0x10000);
+  o->heap_reserve_size = grub_cpu_to_le32 (0x10000);
+  o->heap_commit_size = grub_cpu_to_le32 (0x10000);
+
+  o->num_data_directories = grub_cpu_to_le32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
+
+  o->base_relocation_table.rva = grub_cpu_to_le32 (reloc_address);
+  o->base_relocation_table.size = grub_cpu_to_le32 (end_address
+						    - reloc_address);
+
+  /* The sections.  */
+  memset (&text_section, 0, sizeof (text_section));
+  strcpy (text_section.name, ".text");
+  text_section.virtual_size = grub_cpu_to_le32 (data_address - text_address);
+  text_section.virtual_address = grub_cpu_to_le32 (text_address);
+  text_section.raw_data_size = grub_cpu_to_le32 (data_address - text_address);
+  text_section.raw_data_offset = grub_cpu_to_le32 (text_address);
+  text_section.characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE
+						   | GRUB_PE32_SCN_MEM_EXECUTE
+						   | GRUB_PE32_SCN_MEM_READ);
+
+  memset (&data_section, 0, sizeof (data_section));
+  strcpy (data_section.name, ".data");
+  data_section.virtual_size = grub_cpu_to_le32 (mods_address - data_address);
+  data_section.virtual_address = grub_cpu_to_le32 (data_address);
+  data_section.raw_data_size = grub_cpu_to_le32 (mods_address - data_address);
+  data_section.raw_data_offset = grub_cpu_to_le32 (data_address);
+  data_section.characteristics
+    = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
+			| GRUB_PE32_SCN_MEM_READ
+			| GRUB_PE32_SCN_MEM_WRITE);
+
+  memset (&mods_section, 0, sizeof (mods_section));
+  strcpy (mods_section.name, "mods");
+  mods_section.virtual_size = grub_cpu_to_le32 (reloc_address - mods_address);
+  mods_section.virtual_address = grub_cpu_to_le32 (mods_address);
+  mods_section.raw_data_size = grub_cpu_to_le32 (reloc_address - mods_address);
+  mods_section.raw_data_offset = grub_cpu_to_le32 (mods_address);
+  mods_section.characteristics
+    = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
+			| GRUB_PE32_SCN_MEM_READ
+			| GRUB_PE32_SCN_MEM_WRITE);
+
+  memset (&reloc_section, 0, sizeof (reloc_section));
+  strcpy (reloc_section.name, ".reloc");
+  reloc_section.virtual_size = grub_cpu_to_le32 (end_address - reloc_address);
+  reloc_section.virtual_address = grub_cpu_to_le32 (reloc_address);
+  reloc_section.raw_data_size = grub_cpu_to_le32 (end_address - reloc_address);
+  reloc_section.raw_data_offset = grub_cpu_to_le32 (reloc_address);
+  reloc_section.characteristics
+    = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
+			| GRUB_PE32_SCN_MEM_DISCARDABLE
+			| GRUB_PE32_SCN_MEM_READ);
+
+  /* Write them out.  */
+  if (fseeko (out, 0, SEEK_SET) < 0)
+    grub_util_error ("seek failed");
+
+  if (fwrite (&header, sizeof (header), 1, out) != 1
+      || fwrite (&text_section, sizeof (text_section), 1, out) != 1
+      || fwrite (&data_section, sizeof (data_section), 1, out) != 1
+      || fwrite (&mods_section, sizeof (mods_section), 1, out) != 1
+      || fwrite (&reloc_section, sizeof (reloc_section), 1, out) != 1)
+    grub_util_error ("write failed");
+}
+
+/* Convert an ELF relocatable object into an EFI Application (PE32).  */
+void
+convert_elf (const char *dir, char *prefix, FILE *out, char *mods[])
+{
+  char *kernel_image;
+  size_t kernel_size;
+  const char *strtab;
+  Elf_Ehdr *e;
+  Elf_Shdr *sections;
+  Elf_Off section_offset;
+  Elf_Half section_entsize;
+  Elf_Half num_sections;
+  Elf_Addr *section_addresses;
+  Elf_Shdr *symtab_section;
+  Elf_Addr start_address;
+  Elf_Addr text_address, data_address, reloc_address, mods_address;
+  Elf_Addr end_address;
+  Elf_Shdr *s;
+  int i;
+
+  /* Get the kernel image and check the format.  */
+  kernel_image = read_kernel_module (dir, &kernel_size);
+  e = (Elf_Ehdr *) kernel_image;
+  if (! check_elf_header (e, kernel_size))
+    grub_util_error ("invalid ELF header");
+
+  section_offset = grub_cpu_to_le32 (e->e_shoff);
+  section_entsize = grub_cpu_to_le16 (e->e_shentsize);
+  num_sections = grub_cpu_to_le16 (e->e_shnum);
+
+  if (kernel_size < section_offset + section_entsize * num_sections)
+    grub_util_error ("invalid ELF format");
+
+  sections = (Elf_Shdr *) (kernel_image + section_offset);
+  strtab = find_strtab (e, sections, section_entsize);
+
+  for (i = 0, s = sections;
+       i < num_sections;
+       i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
+    if (is_text_section (s))
+      {
+	  Elf_Off offset = grub_le_to_cpu32 (s->sh_offset);
+
+	  if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END)
+	    grub_util_error ("prefix too long");
+
+	  strcpy (kernel_image + offset + GRUB_KERNEL_MACHINE_PREFIX, prefix);
+	  break;
+      }
+
+  /* Relocate sections then symbols in the virtual address space.  */
+  section_addresses = locate_sections (sections, section_entsize,
+				       num_sections, strtab);
+
+  symtab_section = find_symtab_section (sections,
+					section_entsize, num_sections);
+  if (! symtab_section)
+    grub_util_error ("no symbol table");
+
+  start_address = relocate_symbols (e, sections, symtab_section,
+				    section_addresses, section_entsize,
+				    num_sections);
+  if (start_address == 0)
+    grub_util_error ("start symbol is not defined");
+
+  /* Resolve addresses in the virtual address space.  */
+  relocate_addresses (e, sections, section_addresses, section_entsize,
+		      num_sections, strtab);
+
+  /* Generate a PE32 image file. The strategy is to dump binary data first,
+     then fill up the header.  */
+  text_address = make_header_space (out);
+  data_address = write_text_sections (out, text_address, e, sections,
+				      section_entsize, num_sections,
+				      strtab);
+  mods_address = write_data_sections (out, data_address, e, sections,
+				      section_entsize, num_sections,
+				      strtab);
+  reloc_address = make_mods_section (out, mods_address, dir, mods);
+  end_address = make_reloc_section (out, reloc_address, e, section_addresses,
+				    sections, section_entsize, num_sections,
+				    strtab);
+  make_header (out, text_address, data_address, mods_address,
+	       reloc_address, end_address, start_address);
+
+  /* Clean up.  */
+  free (section_addresses);
+  free (kernel_image);
+}
+
+static struct option options[] =
+  {
+    {"directory", required_argument, 0, 'd'},
+    {"prefix", required_argument, 0, 'p'},
+    {"output", required_argument, 0, 'o'},
+    {"help", no_argument, 0, 'h'},
+    {"version", no_argument, 0, 'V'},
+    {"verbose", no_argument, 0, 'v'},
+    { 0, 0, 0, 0 }
+  };
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``grub-mkimage --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-mkimage -o FILE [OPTION]... [MODULES]\n\
+\n\
+Make a bootable image of GRUB.\n\
+\n\
+  -d, --directory=DIR     use images and modules under DIR [default=%s]\n\
+  -p, --prefix=DIR        set grub_prefix directory [default=%s]\n\
+  -o, --output=FILE       output a generated image to FILE\n\
+  -h, --help              display this message and exit\n\
+  -V, --version           print version information and exit\n\
+  -v, --verbose           print verbose messages\n\
+\n\
+Report bugs to <%s>.\n\
+", GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+int
+main (int argc, char *argv[])
+{
+  FILE *fp;
+  char *output = NULL;
+  char *dir = NULL;
+  char *prefix = NULL;
+
+  progname = "grub-mkimage";
+
+  while (1)
+    {
+      int c = getopt_long (argc, argv, "d:p:o:hVv", options, 0);
+      if (c == -1)
+	break;
+
+      switch (c)
+	{
+	  case 'd':
+	    if (dir)
+	      free (dir);
+	    dir = xstrdup (optarg);
+	    break;
+	  case 'h':
+	    usage (0);
+	    break;
+	  case 'o':
+	    if (output)
+	      free (output);
+	    output = xstrdup (optarg);
+	    break;
+	  case 'p':
+	    if (prefix)
+	      free (prefix);
+	    prefix = xstrdup (optarg);
+	    break;
+	  case 'V':
+	    printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
+	    return 0;
+	  case 'v':
+	    verbosity++;
+	    break;
+	  default:
+	    usage (1);
+	    break;
+	}
+  }
+
+  if (! output)
+    usage (1);
+
+  fp = fopen (output, "wb");
+  if (! fp)
+    grub_util_error ("cannot open %s", output);
+
+  convert_elf (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind);
+
+  fclose (fp);
+
+  return 0;
+}
diff --git a/util/i386/pc/grub-install.in b/util/i386/pc/grub-install.in
new file mode 100644
index 0000000..69028b6
--- /dev/null
+++ b/util/i386/pc/grub-install.in
@@ -0,0 +1,332 @@
+#! /bin/sh
+
+# Install GRUB on your drive.
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+# Initialize some variables.
+transform="@program_transform_name@"
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+bindir=@bindir@
+libdir=@libdir@
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+target_cpu=@target_cpu@
+platform=@platform@
+pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
+
+# for make_system_path_relative_to_its_root()
+. ${libdir}/grub/grub-mkconfig_lib
+
+grub_setup=${sbindir}/`echo grub-setup | sed ${transform}`
+if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
+    grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
+else
+    grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}`
+fi
+grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
+grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
+rootdir=
+grub_prefix=`echo /boot/grub | sed ${transform}`
+modules=
+
+install_device=
+no_floppy=
+force_lba=
+recheck=no
+debug=no
+
+if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
+    disk_module=biosdisk
+else
+    disk_module=ata
+fi
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: grub-install [OPTION] install_device
+Install GRUB on your drive.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --modules=MODULES       pre-load specified modules MODULES
+  --root-directory=DIR    install GRUB images under the directory DIR
+                          instead of the root directory
+  --grub-setup=FILE       use FILE as grub-setup
+  --grub-mkimage=FILE     use FILE as grub-mkimage
+  --grub-mkdevicemap=FILE use FILE as grub-mkdevicemap
+  --grub-probe=FILE       use FILE as grub-probe
+  --no-floppy             do not probe any floppy drive
+  --recheck               probe a device map even if it already exists
+  --force                 install even if problems are detected
+EOF
+if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
+    cat <<EOF
+  --disk-module=MODULE    disk module to use
+EOF
+fi
+    cat <<EOF
+
+INSTALL_DEVICE can be a GRUB device name or a system device filename.
+
+grub-install copies GRUB images into the DIR/boot directory specified by
+--root-directory, and uses grub-setup to install grub into the boot
+sector.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-install (GNU GRUB ${PACKAGE_VERSION})"
+	exit 0 ;;
+    --modules=*)
+	modules=`echo "$option" | sed 's/--modules=//'` ;;
+    --root-directory=*)
+	rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
+    --grub-setup=*)
+	grub_setup=`echo "$option" | sed 's/--grub-setup=//'` ;;
+    --grub-mkimage=*)
+	grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
+    --grub-mkdevicemap=*)
+	grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;;
+    --grub-probe=*)
+	grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;;
+    --no-floppy)
+	no_floppy="--no-floppy" ;;
+    --recheck)
+	recheck=yes ;;
+    --disk-module=*)
+	if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
+           disk_module=`echo "$option" | sed 's/--disk-module=//'`
+        fi ;;
+    # This is an undocumented feature...
+    --debug)
+	debug=yes ;;
+    -f | --force)
+        setup_force="--force" ;;
+    -*)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    *)
+	if test "x$install_device" != x; then
+	    echo "More than one install_devices?" 1>&2
+	    usage
+	    exit 1
+	fi
+	install_device="${option}" ;;
+    esac
+done
+
+if test "x$install_device" = x; then
+    echo "install_device not specified." 1>&2
+    usage
+    exit 1
+fi
+
+# If the debugging feature is enabled, print commands.
+setup_verbose=
+if test $debug = yes; then
+    set -x
+    setup_verbose="--verbose"
+fi
+
+# Initialize these directories here, since ROOTDIR was initialized.
+case "$host_os" in
+netbsd* | openbsd*)
+    # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub
+    # instead of /boot/grub.
+    grub_prefix=`echo /grub | sed ${transform}`
+    bootdir=${rootdir}
+    ;;
+*)
+    # Use /boot/grub by default.
+    bootdir=${rootdir}/boot
+    ;;
+esac
+
+grubdir=${bootdir}/`echo grub | sed ${transform}`
+device_map=${grubdir}/device.map
+
+grub_probe="${grub_probe} --device-map=${device_map}"
+
+# Check if GRUB is installed.
+if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
+    set $grub_setup dummy
+    if test -f "$1"; then
+        :
+    else
+        echo "$1: Not found." 1>&2
+        exit 1
+    fi
+fi
+
+set $grub_mkimage dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+set $grub_mkdevicemap dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+# Create the GRUB directory if it is not present.
+test -d "$bootdir" || mkdir "$bootdir" || exit 1
+test -d "$grubdir" || mkdir "$grubdir" || exit 1
+
+# If --recheck is specified, remove the device map, if present.
+if test $recheck = yes; then
+    rm -f $device_map
+fi
+
+# Create the device map file if it is not present.
+if test -f "$device_map"; then
+    :
+else
+    # Create a safe temporary file.
+    test -n "$mklog" && log_file=`$mklog`
+
+    $grub_mkdevicemap --device-map=$device_map $no_floppy || exit 1
+fi
+
+# Make sure that there is no duplicated entry.
+tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \
+    | sort | uniq -d | sed -n 1p`
+if test -n "$tmp"; then
+    echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2
+    exit 1
+fi
+
+# Copy the GRUB images to the GRUB directory.
+for file in ${grubdir}/*.mod ${grubdir}/*.lst ${grubdir}/*.img ${grubdir}/efiemu??.o; do
+    if test -f $file && [ "`basename $file`" != menu.lst ]; then
+	rm -f $file || exit 1
+    fi
+done
+for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do
+    cp -f $file ${grubdir} || exit 1
+done
+if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
+    for file in ${pkglibdir}/*.img ${pkglibdir}/efiemu??.o; do
+	if test -f $file; then
+	    cp -f $file ${grubdir} || exit 1
+	fi
+    done
+fi
+
+# Write device to a variable so we don't have to traverse /dev every time.
+grub_device=`$grub_probe --target=device ${grubdir}`
+
+# Create the core image. First, auto-detect the filesystem module.
+fs_module=`$grub_probe --target=fs --device ${grub_device}`
+if test "x$fs_module" = x -a "x$modules" = x; then
+    echo "Auto-detection of a filesystem module failed." 1>&2
+    echo "Please specify the module with the option \`--modules' explicitly." 1>&2
+    exit 1
+fi
+
+# Then the partition map module.  In order to support partition-less media,
+# this command is allowed to fail (--target=fs already grants us that the
+# filesystem will be accessible).
+partmap_module=`$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`
+
+# Device abstraction module, if any (lvm, raid).
+devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}`
+
+# The order in this list is critical.  Be careful when modifying it.
+modules="$modules $disk_module"
+modules="$modules $fs_module $partmap_module $devabstraction_module"
+
+prefix_drive=
+if [ "x${devabstraction_module}" = "x" ] ; then
+    if echo "${install_device}" | grep -qx "(.*)" ; then
+      install_drive="${install_device}"
+    else
+      install_drive="`$grub_probe --target=drive --device ${install_device}`"
+    fi
+    grub_drive="`$grub_probe --target=drive --device ${grub_device}`"
+
+    # Strip partition number
+    install_drive="`echo ${install_drive} | sed -e s/,[0-9]*[a-z]*//g`"
+    grub_drive="`echo ${grub_drive} | sed -e s/,[0-9]*[a-z]*//g`"
+    if [ "$disk_module" = ata ] ; then
+        # generic method (used on coreboot and ata mod)
+        uuid="`$grub_probe --target=fs_uuid --device ${grub_device}`"
+        if [ "x${uuid}" = "x" ] ; then
+          echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
+          exit 1
+        fi
+        prefix_drive="(UUID=${uuid})"
+        modules="$modules fs_uuid"
+    elif [ "x${grub_drive}" != "x${install_drive}" ] ; then
+        uuid="`$grub_probe --target=fs_uuid --device ${grub_device}`"
+        if [ "x${uuid}" = "x" ] ; then
+          echo "You attempted a cross-disk install, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
+          exit 1
+        fi
+        prefix_drive="(UUID=${uuid})"
+        modules="$modules fs_uuid"
+    fi
+else
+    prefix_drive=`$grub_probe --target=drive --device ${grub_device}`
+fi
+
+relative_grubdir=`make_system_path_relative_to_its_root ${grubdir}` || exit 1
+if [ "x${relative_grubdir}" = "x" ] ; then
+    relative_grubdir=/
+fi
+
+if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then
+    $grub_mkimage --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1
+
+    # Now perform the installation.
+    $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \
+        ${install_device} || exit 1
+else
+    $grub_mkimage -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1
+fi
+
+# Prompt the user to check if the device map is correct.
+echo "Installation finished. No error reported."
+echo "This is the contents of the device map $device_map."
+echo "Check if this is correct or not. If any of the lines is incorrect,"
+echo "fix it and re-run the script \`grub-install'."
+echo
+
+cat $device_map
+
+# Bye.
+exit 0
diff --git a/util/i386/pc/grub-mkimage.c b/util/i386/pc/grub-mkimage.c
new file mode 100644
index 0000000..15168f8
--- /dev/null
+++ b/util/i386/pc/grub-mkimage.c
@@ -0,0 +1,436 @@
+/* grub-mkimage.c - make a bootable image */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+#include <grub/machine/memory.h>
+#include <grub/kernel.h>
+#include <grub/disk.h>
+#include <grub/util/misc.h>
+#include <grub/util/resolve.h>
+#include <grub/misc.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define _GNU_SOURCE	1
+#include <getopt.h>
+
+#ifdef ENABLE_LZMA
+#include <grub/lib/LzmaEnc.h>
+
+static void *SzAlloc(void *p, size_t size) { p = p; return xmalloc(size); }
+static void SzFree(void *p, void *address) { p = p; free(address); }
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+static void
+compress_kernel (char *kernel_img, size_t kernel_size,
+		 char **core_img, size_t *core_size)
+{
+  CLzmaEncProps props;
+  unsigned char out_props[5];
+  size_t out_props_size = 5;
+
+  LzmaEncProps_Init(&props);
+  props.dictSize = 1 << 16;
+  props.lc = 3;
+  props.lp = 0;
+  props.pb = 2;
+  props.numThreads = 1;
+
+  if (kernel_size < GRUB_KERNEL_MACHINE_RAW_SIZE)
+    grub_util_error ("the core image is too small");
+
+  *core_img = xmalloc (kernel_size);
+  memcpy (*core_img, kernel_img, GRUB_KERNEL_MACHINE_RAW_SIZE);
+
+  *core_size = kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE;
+  if (LzmaEncode((unsigned char *) *core_img + GRUB_KERNEL_MACHINE_RAW_SIZE,
+                 core_size,
+                 (unsigned char *) kernel_img + GRUB_KERNEL_MACHINE_RAW_SIZE,
+                 kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE,
+                 &props, out_props, &out_props_size,
+                 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK)
+    grub_util_error ("cannot compress the kernel image");
+
+  *core_size += GRUB_KERNEL_MACHINE_RAW_SIZE;
+}
+
+#else	/* No lzma compression */
+
+static void
+compress_kernel (char *kernel_img, size_t kernel_size,
+               char **core_img, size_t *core_size)
+{
+  *core_img = xmalloc (kernel_size);
+  memcpy (*core_img, kernel_img, kernel_size);
+  *core_size = kernel_size;
+}
+
+#endif	/* No lzma compression */
+
+static void
+generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
+		char *memdisk_path, char *config_path)
+{
+  char *kernel_img, *boot_img, *core_img;
+  size_t kernel_size, boot_size, total_module_size, core_size;
+  size_t memdisk_size = 0, config_size = 0;
+  char *kernel_path, *boot_path;
+  size_t offset;
+  struct grub_util_path_list *path_list, *p, *next;
+  struct grub_module_info *modinfo;
+
+  path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
+
+  kernel_path = grub_util_get_path (dir, "kernel.img");
+  kernel_size = grub_util_get_image_size (kernel_path);
+
+  total_module_size = sizeof (struct grub_module_info);
+
+  if (memdisk_path)
+    {
+      memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
+      grub_util_info ("the size of memory disk is 0x%x", memdisk_size);
+      total_module_size += memdisk_size + sizeof (struct grub_module_header);
+    }
+
+  if (config_path)
+    {
+      config_size = grub_util_get_image_size (config_path) + 1;
+      grub_util_info ("the size of config file is 0x%x", config_size);
+      total_module_size += config_size + sizeof (struct grub_module_header);
+    }
+
+  for (p = path_list; p; p = p->next)
+    total_module_size += (grub_util_get_image_size (p->name)
+			  + sizeof (struct grub_module_header));
+
+  grub_util_info ("the total module size is 0x%x", total_module_size);
+
+  kernel_img = xmalloc (kernel_size + total_module_size);
+  grub_util_load_image (kernel_path, kernel_img);
+
+  if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END)
+    grub_util_error ("prefix too long");
+  strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix);
+
+  /* Fill in the grub_module_info structure.  */
+  modinfo = (struct grub_module_info *) (kernel_img + kernel_size);
+  memset (modinfo, 0, sizeof (struct grub_module_info));
+  modinfo->magic = GRUB_MODULE_MAGIC;
+  modinfo->offset = sizeof (struct grub_module_info);
+  modinfo->size = total_module_size;
+
+  offset = kernel_size + sizeof (struct grub_module_info);
+  for (p = path_list; p; p = p->next)
+    {
+      struct grub_module_header *header;
+      size_t mod_size;
+
+      mod_size = grub_util_get_image_size (p->name);
+
+      header = (struct grub_module_header *) (kernel_img + offset);
+      memset (header, 0, sizeof (struct grub_module_header));
+      header->type = OBJ_TYPE_ELF;
+      header->size = grub_host_to_target32 (mod_size + sizeof (*header));
+      offset += sizeof (*header);
+
+      grub_util_load_image (p->name, kernel_img + offset);
+      offset += mod_size;
+    }
+
+  if (memdisk_path)
+    {
+      struct grub_module_header *header;
+
+      header = (struct grub_module_header *) (kernel_img + offset);
+      memset (header, 0, sizeof (struct grub_module_header));
+      header->type = OBJ_TYPE_MEMDISK;
+      header->size = grub_host_to_target32 (memdisk_size + sizeof (*header));
+      offset += sizeof (*header);
+
+      grub_util_load_image (memdisk_path, kernel_img + offset);
+      offset += memdisk_size;
+    }
+
+  if (config_path)
+    {
+      struct grub_module_header *header;
+
+      header = (struct grub_module_header *) (kernel_img + offset);
+      memset (header, 0, sizeof (struct grub_module_header));
+      header->type = OBJ_TYPE_CONFIG;
+      header->size = grub_host_to_target32 (config_size + sizeof (*header));
+      offset += sizeof (*header);
+
+      grub_util_load_image (config_path, kernel_img + offset);
+      offset += config_size;
+      *(kernel_img + offset - 1) = 0;
+    }
+
+  grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size);
+  compress_kernel (kernel_img, kernel_size + total_module_size,
+		   &core_img, &core_size);
+
+  grub_util_info ("the core size is 0x%x", core_size);
+
+#if defined(GRUB_MACHINE_PCBIOS)
+  {
+    unsigned num;
+    num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
+    if (num > 0xffff)
+      grub_util_error ("the core image is too big");
+    
+    boot_path = grub_util_get_path (dir, "diskboot.img");
+    boot_size = grub_util_get_image_size (boot_path);
+    if (boot_size != GRUB_DISK_SECTOR_SIZE)
+      grub_util_error ("diskboot.img is not one sector size");
+    
+    boot_img = grub_util_read_image (boot_path);
+    
+    /* i386 is a little endian architecture.  */
+    *((grub_uint16_t *) (boot_img + GRUB_DISK_SECTOR_SIZE
+			 - GRUB_BOOT_MACHINE_LIST_SIZE + 8))
+      = grub_cpu_to_le16 (num);
+    
+    grub_util_write_image (boot_img, boot_size, out);
+    free (boot_img);
+    free (boot_path);
+  }
+#elif defined(GRUB_MACHINE_QEMU)
+  {
+    char *rom_img;
+    size_t rom_size;
+
+    boot_path = grub_util_get_path (dir, "boot.img");
+    boot_size = grub_util_get_image_size (boot_path);
+    boot_img = grub_util_read_image (boot_path);
+
+    /* Rom sizes must be 64k-aligned.  */
+    rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024);
+
+    rom_img = xmalloc (rom_size);
+    memset (rom_img, 0, rom_size);
+
+    *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR))
+      = grub_cpu_to_le32 ((grub_uint32_t) -rom_size);
+
+    memcpy (rom_img, core_img, core_size);
+
+    *((grub_int32_t *) (boot_img + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR))
+      = grub_cpu_to_le32 ((grub_uint32_t) -rom_size);
+
+    memcpy (rom_img + rom_size - boot_size, boot_img, boot_size);
+
+    free (core_img);
+    core_img = rom_img;
+    core_size = rom_size;
+
+    free (boot_img);
+    free (boot_path);
+  }
+
+#endif
+
+#ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
+  *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE))
+    = grub_cpu_to_le32 (total_module_size);
+#endif
+  *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE))
+    = grub_cpu_to_le32 (kernel_size);
+#ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE
+  *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE))
+    = grub_cpu_to_le32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE);
+#endif
+
+#if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)
+  /* If we included a drive in our prefix, let GRUB know it doesn't have to
+     prepend the drive told by BIOS.  */
+  if (prefix[0] == '(')
+    {
+      *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART))
+	= grub_cpu_to_le32 (-2);
+      *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART))
+	= grub_cpu_to_le32 (-2);
+    }
+#endif
+
+#ifdef GRUB_MACHINE_PCBIOS
+  if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER)
+    grub_util_error ("Core image is too big (%p > %p)\n",
+ 		     GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, GRUB_MEMORY_MACHINE_UPPER);
+#endif
+
+  grub_util_write_image (core_img, core_size, out);
+  free (kernel_img);
+  free (core_img);
+  free (kernel_path);
+
+  while (path_list)
+    {
+      next = path_list->next;
+      free ((void *) path_list->name);
+      free (path_list);
+      path_list = next;
+    }
+}
+
+
+
+static struct option options[] =
+  {
+    {"directory", required_argument, 0, 'd'},
+    {"prefix", required_argument, 0, 'p'},
+    {"memdisk", required_argument, 0, 'm'},
+    {"config", required_argument, 0, 'c'},
+    {"output", required_argument, 0, 'o'},
+    {"help", no_argument, 0, 'h'},
+    {"version", no_argument, 0, 'V'},
+    {"verbose", no_argument, 0, 'v'},
+    {0, 0, 0, 0}
+  };
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``grub-mkimage --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-mkimage [OPTION]... [MODULES]\n\
+\n\
+Make a bootable image of GRUB.\n\
+\n\
+  -d, --directory=DIR     use images and modules under DIR [default=%s]\n\
+  -p, --prefix=DIR        set grub_prefix directory [default=%s]\n\
+  -m, --memdisk=FILE      embed FILE as a memdisk image\n\
+  -c, --config=FILE       embed FILE as boot config\n\
+  -o, --output=FILE       output a generated image to FILE [default=stdout]\n\
+  -h, --help              display this message and exit\n\
+  -V, --version           print version information and exit\n\
+  -v, --verbose           print verbose messages\n\
+\n\
+Report bugs to <%s>.\n\
+", GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+int
+main (int argc, char *argv[])
+{
+  char *output = NULL;
+  char *dir = NULL;
+  char *prefix = NULL;
+  char *memdisk = NULL;
+  char *config = NULL;
+  FILE *fp = stdout;
+
+  progname = "grub-mkimage";
+
+  while (1)
+    {
+      int c = getopt_long (argc, argv, "d:p:m:c:o:hVv", options, 0);
+
+      if (c == -1)
+	break;
+      else
+	switch (c)
+	  {
+	  case 'o':
+	    if (output)
+	      free (output);
+
+	    output = xstrdup (optarg);
+	    break;
+
+	  case 'd':
+	    if (dir)
+	      free (dir);
+
+	    dir = xstrdup (optarg);
+	    break;
+
+	  case 'm':
+	    if (memdisk)
+	      free (memdisk);
+
+	    memdisk = xstrdup (optarg);
+
+	    if (prefix)
+	      free (prefix);
+
+	    prefix = xstrdup ("(memdisk)/boot/grub");
+	    break;
+
+	  case 'c':
+	    if (config)
+	      free (config);
+
+	    config = xstrdup (optarg);
+	    break;
+
+	  case 'h':
+	    usage (0);
+	    break;
+
+	  case 'p':
+	    if (prefix)
+	      free (prefix);
+
+	    prefix = xstrdup (optarg);
+	    break;
+
+	  case 'V':
+	    printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
+	    return 0;
+
+	  case 'v':
+	    verbosity++;
+	    break;
+
+	  default:
+	    usage (1);
+	    break;
+	  }
+    }
+
+  if (output)
+    {
+      fp = fopen (output, "wb");
+      if (! fp)
+	grub_util_error ("cannot open %s", output);
+      free (output);
+    }
+
+  generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp,
+		  argv + optind, memdisk, config);
+
+  fclose (fp);
+
+  if (dir)
+    free (dir);
+
+  return 0;
+}
diff --git a/util/i386/pc/grub-mkrescue.in b/util/i386/pc/grub-mkrescue.in
new file mode 100644
index 0000000..da93776
--- /dev/null
+++ b/util/i386/pc/grub-mkrescue.in
@@ -0,0 +1,180 @@
+#! /bin/sh -e
+
+# Make GRUB rescue image
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+# Initialize some variables.
+transform="@program_transform_name@"
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+libdir=@libdir@
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+target_cpu=@target_cpu@
+platform=@platform@
+pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
+
+grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: grub-mkrescue [OPTION] output_image
+Make GRUB rescue image.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --modules=MODULES       pre-load specified modules MODULES
+  --overlay=DIR           overlay directory DIR in the memdisk image
+                          (may be specified multiple times)
+  --pkglibdir=DIR         use images from directory DIR instead of ${pkglibdir}
+  --grub-mkimage=FILE     use FILE as grub-mkimage
+  --image-type=TYPE       select floppy or cdrom (default)
+  --emulation=TYPE        select El Torito boot emulation type floppy
+                          or none (default) (cdrom only)
+
+grub-mkimage generates a bootable rescue image of the specified type.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+image_type=cdrom
+input_dir=${pkglibdir}
+emulation=none
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-mkrescue (GNU GRUB ${PACKAGE_VERSION})"
+	exit 0 ;;
+    --modules=*)
+	modules=`echo "$option" | sed 's/--modules=//'` ;;
+    --overlay=*)
+	overlay=${overlay}${overlay:+ }`echo "$option" | sed 's/--overlay=//'` ;;
+    --pkglibdir=*)
+	input_dir=`echo "$option" | sed 's/--pkglibdir=//'` ;;
+    --grub-mkimage=*)
+	grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
+    --image-type=*)
+    	image_type=`echo "$option" | sed 's/--image-type=//'`
+        case "$image_type" in
+          floppy|cdrom) ;;
+          *)
+            echo "Unknown image type \`$image_type'" 1>&2
+            exit 1 ;;
+        esac ;;
+    --emulation=*)
+    	emulation=`echo "$option" | sed 's/--emulation=//'`
+        case "$emulation" in
+          floppy|none) ;;
+          *)
+            echo "Unknown emulation type \`$emulation'" 1>&2
+            exit 1 ;;
+        esac ;;
+    -*)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    *)
+	if test "x$output_image" != x; then
+	    echo "Unrecognized option \`$option'" 1>&2
+	    usage
+	    exit 1
+	fi
+	output_image="${option}" ;;
+    esac
+done
+
+if test "x$output_image" = x; then
+  usage
+  exit 1
+fi
+
+aux_dir=`mktemp -d`
+mkdir -p ${aux_dir}/boot/grub
+
+for file in ${input_dir}/*.mod ${input_dir}/efiemu??.o \
+  ${input_dir}/command.lst ${input_dir}/moddep.lst ${input_dir}/fs.lst \
+  ${input_dir}/handler.lst ${input_dir}/parttool.lst; do
+  if test -f "$file"; then
+    cp -f "$file" ${aux_dir}/boot/grub/
+  fi
+done
+
+modules="biosdisk `cat ${input_dir}/partmap.lst` ${modules}"
+for i in ${modules} ; do
+  echo "insmod $i"
+done > ${aux_dir}/boot/grub/grub.cfg
+
+for d in ${overlay}; do
+  echo "Overlaying $d"
+  cp -dpR "${d}"/* "${aux_dir}"/
+done
+
+if [ "x${image_type}" = xfloppy -o "x${emulation}" = xfloppy ] ; then
+  # build memdisk
+  memdisk_img=`mktemp`
+  tar -C ${aux_dir} -cf ${memdisk_img} boot
+  rm -rf ${aux_dir}
+
+  # build core.img
+  core_img=`mktemp`
+  ${grub_mkimage} -d ${input_dir}/ -m ${memdisk_img} -o ${core_img} memdisk tar
+  rm -f ${memdisk_img}
+
+  # build floppy image
+  if [ "x${image_type}" = xcdrom ] ; then
+    floppy_dir=`mktemp -d`
+    floppy_img=${floppy_dir}/grub_floppy.img
+  else
+    floppy_img=${output_image}
+  fi
+  cat ${input_dir}/boot.img ${core_img} /dev/zero | dd bs=1024 count=1440 > ${floppy_img}
+  rm -f ${core_img}
+
+  if [ "x${image_type}" = xcdrom ] ; then
+    # build iso image
+    genisoimage -b grub_floppy.img \
+      -o ${output_image} -r -J ${floppy_dir}
+    rm -rf ${floppy_dir}
+  fi
+else
+  # build core.img
+  core_img=`mktemp`
+  ${grub_mkimage} -d ${input_dir}/ -o ${core_img} biosdisk iso9660
+
+  # build grub_eltorito image
+  cat ${input_dir}/cdboot.img ${core_img} > ${aux_dir}/boot/grub/grub_eltorito
+  rm -f ${core_img}
+
+  # build iso image
+  genisoimage -b boot/grub/grub_eltorito \
+    -no-emul-boot -boot-load-size 4 -boot-info-table \
+    -o ${output_image} -r -J ${aux_dir}
+  rm -rf ${aux_dir}
+fi
+
+exit 0
diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c
new file mode 100644
index 0000000..c536be0
--- /dev/null
+++ b/util/i386/pc/grub-setup.c
@@ -0,0 +1,815 @@
+/* grub-setup.c - make GRUB usable */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/util/misc.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/fs.h>
+#include <grub/partition.h>
+#include <grub/msdos_partition.h>
+#include <grub/gpt_partition.h>
+#include <grub/env.h>
+#include <grub/util/hostdisk.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+#include <grub/term.h>
+#include <grub/util/raid.h>
+#include <grub/util/lvm.h>
+
+static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT;
+
+#include <grub_setup_init.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <grub/util/getroot.h>
+
+#define _GNU_SOURCE	1
+#include <getopt.h>
+
+#define DEFAULT_BOOT_FILE	"boot.img"
+#define DEFAULT_CORE_FILE	"core.img"
+
+/* This is the blocklist used in the diskboot image.  */
+struct boot_blocklist
+{
+  grub_uint64_t start;
+  grub_uint16_t len;
+  grub_uint16_t segment;
+} __attribute__ ((packed));
+
+void
+grub_putchar (int c)
+{
+  putchar (c);
+}
+
+int
+grub_getkey (void)
+{
+  return -1;
+}
+
+struct grub_handler_class grub_term_input_class;
+struct grub_handler_class grub_term_output_class;
+
+void
+grub_refresh (void)
+{
+  fflush (stdout);
+}
+
+static void
+setup (const char *dir,
+       const char *boot_file, const char *core_file,
+       const char *root, const char *dest, int must_embed, int force, int fs_probe)
+{
+  char *boot_path, *core_path, *core_path_dev;
+  char *boot_img, *core_img;
+  size_t boot_size, core_size;
+  grub_uint16_t core_sectors;
+  grub_device_t root_dev, dest_dev;
+  const char *dest_partmap;
+  grub_uint8_t *boot_drive;
+  grub_disk_addr_t *kernel_sector;
+  grub_uint16_t *boot_drive_check;
+  struct boot_blocklist *first_block, *block;
+  grub_int32_t *install_dos_part, *install_bsd_part;
+  grub_int32_t dos_part, bsd_part;
+  char *tmp_img;
+  int i;
+  grub_disk_addr_t first_sector;
+  grub_uint16_t current_segment
+    = GRUB_BOOT_MACHINE_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4);
+  grub_uint16_t last_length = GRUB_DISK_SECTOR_SIZE;
+  grub_file_t file;
+  FILE *fp;
+  struct { grub_uint64_t start; grub_uint64_t end; } embed_region;
+  embed_region.start = embed_region.end = ~0UL;
+
+  auto void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector, unsigned offset,
+			       unsigned length);
+  auto void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector, unsigned offset,
+			     unsigned length);
+
+  auto int NESTED_FUNC_ATTR find_usable_region_msdos (grub_disk_t disk,
+						      const grub_partition_t p);
+  int NESTED_FUNC_ATTR find_usable_region_msdos (grub_disk_t disk __attribute__ ((unused)),
+						 const grub_partition_t p)
+    {
+      struct grub_msdos_partition *pcdata = p->data;
+
+      /* There's always an embed region, and it starts right after the MBR.  */
+      embed_region.start = 1;
+
+      /* For its end offset, include as many dummy partitions as we can.  */
+      if (! grub_msdos_partition_is_empty (pcdata->dos_type)
+	  && ! grub_msdos_partition_is_bsd (pcdata->dos_type)
+	  && embed_region.end > p->start)
+	embed_region.end = p->start;
+
+      return 0;
+    }
+
+  auto int NESTED_FUNC_ATTR find_usable_region_gpt (grub_disk_t disk,
+						    const grub_partition_t p);
+  int NESTED_FUNC_ATTR find_usable_region_gpt (grub_disk_t disk __attribute__ ((unused)),
+					       const grub_partition_t p)
+    {
+      struct grub_gpt_partentry *gptdata = p->data;
+
+      /* If there's an embed region, it is in a dedicated partition.  */
+      if (! memcmp (&gptdata->type, &grub_gpt_partition_type_bios_boot, 16))
+	{
+	  embed_region.start = p->start;
+	  embed_region.end = p->start + p->len;
+
+	  return 1;
+	}
+
+      return 0;
+    }
+
+  void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector, unsigned offset,
+			  unsigned length)
+    {
+      grub_util_info ("the first sector is <%llu,%u,%u>",
+		      sector, offset, length);
+
+      if (offset != 0 || length != GRUB_DISK_SECTOR_SIZE)
+	grub_util_error ("The first sector of the core file is not sector-aligned");
+
+      first_sector = sector;
+    }
+
+  void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector, unsigned offset,
+			unsigned length)
+    {
+      struct boot_blocklist *prev = block + 1;
+
+      grub_util_info ("saving <%llu,%u,%u> with the segment 0x%x",
+		      sector, offset, length, (unsigned) current_segment);
+
+      if (offset != 0 || last_length != GRUB_DISK_SECTOR_SIZE)
+	grub_util_error ("Non-sector-aligned data is found in the core file");
+
+      if (block != first_block
+	  && (grub_le_to_cpu64 (prev->start)
+	      + grub_le_to_cpu16 (prev->len)) == sector)
+	prev->len = grub_cpu_to_le16 (grub_le_to_cpu16 (prev->len) + 1);
+      else
+	{
+	  block->start = grub_cpu_to_le64 (sector);
+	  block->len = grub_cpu_to_le16 (1);
+	  block->segment = grub_cpu_to_le16 (current_segment);
+
+	  block--;
+	  if (block->len)
+	    grub_util_error ("The sectors of the core file are too fragmented");
+	}
+
+      last_length = length;
+      current_segment += GRUB_DISK_SECTOR_SIZE >> 4;
+    }
+
+  /* Read the boot image by the OS service.  */
+  boot_path = grub_util_get_path (dir, boot_file);
+  boot_size = grub_util_get_image_size (boot_path);
+  if (boot_size != GRUB_DISK_SECTOR_SIZE)
+    grub_util_error ("The size of `%s' is not %d",
+		     boot_path, GRUB_DISK_SECTOR_SIZE);
+  boot_img = grub_util_read_image (boot_path);
+  free (boot_path);
+
+  /* Set the addresses of variables in the boot image.  */
+  boot_drive = (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_BOOT_DRIVE);
+  kernel_sector = (grub_disk_addr_t *) (boot_img
+				     + GRUB_BOOT_MACHINE_KERNEL_SECTOR);
+  boot_drive_check = (grub_uint16_t *) (boot_img
+					+ GRUB_BOOT_MACHINE_DRIVE_CHECK);
+
+  core_path = grub_util_get_path (dir, core_file);
+  core_size = grub_util_get_image_size (core_path);
+  core_sectors = ((core_size + GRUB_DISK_SECTOR_SIZE - 1)
+		  >> GRUB_DISK_SECTOR_BITS);
+  if (core_size < GRUB_DISK_SECTOR_SIZE)
+    grub_util_error ("The size of `%s' is too small", core_path);
+  else if (core_size > 0xFFFF * GRUB_DISK_SECTOR_SIZE)
+    grub_util_error ("The size of `%s' is too large", core_path);
+
+  core_img = grub_util_read_image (core_path);
+
+  /* Have FIRST_BLOCK to point to the first blocklist.  */
+  first_block = (struct boot_blocklist *) (core_img
+					   + GRUB_DISK_SECTOR_SIZE
+					   - sizeof (*block));
+
+  install_dos_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE
+				       + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART);
+  install_bsd_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE
+				       + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART);
+
+  /* Open the root device and the destination device.  */
+  root_dev = grub_device_open (root);
+  if (! root_dev)
+    grub_util_error ("%s", grub_errmsg);
+
+  dest_dev = grub_device_open (dest);
+  if (! dest_dev)
+    grub_util_error ("%s", grub_errmsg);
+
+  grub_util_info ("setting the root device to `%s'", root);
+  if (grub_env_set ("root", root) != GRUB_ERR_NONE)
+    grub_util_error ("%s", grub_errmsg);
+
+  /* Read the original sector from the disk.  */
+  tmp_img = xmalloc (GRUB_DISK_SECTOR_SIZE);
+  if (grub_disk_read (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_img))
+    grub_util_error ("%s", grub_errmsg);
+
+  if (dest_dev->disk->partition && fs_probe)
+    {
+      grub_fs_t fs;
+      fs = grub_fs_probe (dest_dev);
+      if (! fs)
+	grub_util_error ("Unable to identify a filesystem in %s; safety check can't be performed.",
+			 dest_dev->disk->name);
+
+      if (! fs->reserved_first_sector)
+	grub_util_error ("%s appears to contain a %s filesystem which isn't known to "
+			 "reserve space for DOS-style boot.  Installing GRUB there could "
+			 "result in FILESYSTEM DESTRUCTION if valuable data is overwritten "
+			 "by grub-setup (--skip-fs-probe disables this "
+			 "check, use at your own risk).", dest_dev->disk->name, fs->name);
+    }
+
+  /* Copy the possible DOS BPB.  */
+  memcpy (boot_img + GRUB_BOOT_MACHINE_BPB_START,
+	  tmp_img + GRUB_BOOT_MACHINE_BPB_START,
+	  GRUB_BOOT_MACHINE_BPB_END - GRUB_BOOT_MACHINE_BPB_START);
+
+  /* Copy the possible partition table.  */
+  if (dest_dev->disk->has_partitions)
+    memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC,
+	    tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC,
+	    GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC);
+
+  free (tmp_img);
+
+  /* If DEST_DRIVE is a hard disk, enable the workaround, which is
+     for buggy BIOSes which don't pass boot drive correctly. Instead,
+     they pass 0x00 or 0x01 even when booted from 0x80.  */
+  if (dest_dev->disk->id & 0x80)
+    /* Replace the jmp (2 bytes) with double nop's.  */
+    *boot_drive_check = 0x9090;
+
+  /* If we hardcoded drive as part of prefix, we don't want to
+     override the current setting.  */
+  if (*install_dos_part != -2)
+    {
+      /* Embed information about the installed location.  */
+      if (root_dev->disk->partition)
+	{
+	  if (strcmp (root_dev->disk->partition->partmap->name,
+		      "part_msdos") == 0)
+	    {
+	      struct grub_msdos_partition *pcdata =
+		root_dev->disk->partition->data;
+	      dos_part = pcdata->dos_part;
+	      bsd_part = pcdata->bsd_part;
+	    }
+	  else if (strcmp (root_dev->disk->partition->partmap->name,
+			   "part_gpt") == 0)
+	    {
+	      dos_part = root_dev->disk->partition->index;
+	      bsd_part = -1;
+	    }
+	  else
+	    grub_util_error ("No PC style partitions found");
+	}
+      else
+	dos_part = bsd_part = -1;
+    }
+  else
+    {
+      dos_part = grub_le_to_cpu32 (*install_dos_part);
+      bsd_part = grub_le_to_cpu32 (*install_bsd_part);
+    }
+
+  grub_util_info ("dos partition is %d, bsd partition is %d",
+		  dos_part, bsd_part);
+
+  if (! dest_dev->disk->has_partitions)
+    {
+      grub_util_warn ("Attempting to install GRUB to a partitionless disk.  This is a BAD idea.");
+      goto unable_to_embed;
+    }
+
+  if (dest_dev->disk->partition)
+    {
+      grub_util_warn ("Attempting to install GRUB to a partition instead of the MBR.  This is a BAD idea.");
+      goto unable_to_embed;
+    }
+
+  /* Unlike root_dev, with dest_dev we're interested in the partition map even
+     if dest_dev itself is a whole disk.  */
+  auto int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk,
+					      const grub_partition_t p);
+  int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk __attribute__ ((unused)),
+					 const grub_partition_t p)
+    {
+      dest_partmap = p->partmap->name;
+      return 1;
+    }
+  dest_partmap = 0;
+  grub_partition_iterate (dest_dev->disk, identify_partmap);
+
+  if (! dest_partmap)
+    {
+      grub_util_warn ("Attempting to install GRUB to a partitionless disk.  This is a BAD idea.");
+      goto unable_to_embed;
+    }
+
+  grub_partition_iterate (dest_dev->disk, (strcmp (dest_partmap, "part_msdos") ?
+					   find_usable_region_gpt : find_usable_region_msdos));
+
+  if (embed_region.end == embed_region.start)
+    {
+      if (! strcmp (dest_partmap, "part_msdos"))
+	grub_util_warn ("This msdos-style partition label has no post-MBR gap; embedding won't be possible!");
+      else
+	grub_util_warn ("This GPT partition label has no BIOS Boot Partition; embedding won't be possible!");
+      goto unable_to_embed;
+    }
+
+  if ((unsigned long) core_sectors > embed_region.end - embed_region.start)
+    {
+      if (core_sectors > 62)
+	grub_util_warn ("Your core.img is unusually large.  It won't fit in the embedding area.");
+      else if (embed_region.end - embed_region.start < 62)
+	grub_util_warn ("Your embedding area is unusually small.  core.img won't fit in it.");
+      else
+	grub_util_warn ("Embedding area is too small for core.img.");
+      goto unable_to_embed;
+    }
+
+
+  grub_util_info ("will embed the core image at sector 0x%llx", embed_region.start);
+
+  *install_dos_part = grub_cpu_to_le32 (dos_part);
+  *install_bsd_part = grub_cpu_to_le32 (bsd_part);
+
+  /* The first blocklist contains the whole sectors.  */
+  first_block->start = grub_cpu_to_le64 (embed_region.start + 1);
+  first_block->len = grub_cpu_to_le16 (core_sectors - 1);
+  first_block->segment
+    = grub_cpu_to_le16 (GRUB_BOOT_MACHINE_KERNEL_SEG
+			+ (GRUB_DISK_SECTOR_SIZE >> 4));
+
+  /* Make sure that the second blocklist is a terminator.  */
+  block = first_block - 1;
+  block->start = 0;
+  block->len = 0;
+  block->segment = 0;
+
+  /* Write the core image onto the disk.  */
+  if (grub_disk_write (dest_dev->disk, embed_region.start, 0, core_size, core_img))
+    grub_util_error ("%s", grub_errmsg);
+
+  /* FIXME: can this be skipped?  */
+  *boot_drive = 0xFF;
+
+  *kernel_sector = grub_cpu_to_le64 (embed_region.start);
+
+  /* Write the boot image onto the disk.  */
+  if (grub_disk_write (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE,
+		       boot_img))
+    grub_util_error ("%s", grub_errmsg);
+
+  goto finish;
+
+unable_to_embed:
+
+  if (must_embed)
+    grub_util_error ("Embedding is not possible, but this is required when "
+		     "the root device is on a RAID array or LVM volume.");
+
+  grub_util_warn ("Embedding is not possible.  GRUB can only be installed in this "
+		  "setup by using blocklists.  However, blocklists are UNRELIABLE and "
+		  "its use is discouraged.");
+  if (! force)
+    grub_util_error ("If you really want blocklists, use --force.");
+
+  /* Make sure that GRUB reads the identical image as the OS.  */
+  tmp_img = xmalloc (core_size);
+  core_path_dev = grub_util_get_path (dir, core_file);
+
+  /* It is a Good Thing to sync two times.  */
+  sync ();
+  sync ();
+
+#define MAX_TRIES	5
+
+  for (i = 0; i < MAX_TRIES; i++)
+    {
+      grub_util_info ("attempting to read the core image `%s' from GRUB%s",
+		      core_path_dev, (i == 0) ? "" : " again");
+
+      grub_disk_cache_invalidate_all ();
+
+      file = grub_file_open (core_path_dev);
+      if (file)
+	{
+	  if (grub_file_size (file) != core_size)
+	    grub_util_info ("succeeded in opening the core image but the size is different (%d != %d)",
+			    (int) grub_file_size (file), (int) core_size);
+	  else if (grub_file_read (file, tmp_img, core_size)
+		   != (grub_ssize_t) core_size)
+	    grub_util_info ("succeeded in opening the core image but cannot read %d bytes",
+			    (int) core_size);
+	  else if (memcmp (core_img, tmp_img, core_size) != 0)
+	    {
+#if 0
+	      FILE *dump;
+	      FILE *dump2;
+
+	      dump = fopen ("dump.img", "wb");
+	      if (dump)
+		{
+		  fwrite (tmp_img, 1, core_size, dump);
+		  fclose (dump);
+		}
+
+	      dump2 = fopen ("dump2.img", "wb");
+	      if (dump2)
+		{
+		  fwrite (core_img, 1, core_size, dump2);
+		  fclose (dump2);
+		}
+
+#endif
+	      grub_util_info ("succeeded in opening the core image but the data is different");
+	    }
+	  else
+	    {
+	      grub_file_close (file);
+	      break;
+	    }
+
+	  grub_file_close (file);
+	}
+      else
+	grub_util_info ("couldn't open the core image");
+
+      if (grub_errno)
+	grub_util_info ("error message = %s", grub_errmsg);
+
+      grub_errno = GRUB_ERR_NONE;
+      sync ();
+      sleep (1);
+    }
+
+  if (i == MAX_TRIES)
+    grub_util_error ("Cannot read `%s' correctly", core_path_dev);
+
+  /* Clean out the blocklists.  */
+  block = first_block;
+  while (block->len)
+    {
+      block->start = 0;
+      block->len = 0;
+      block->segment = 0;
+
+      block--;
+
+      if ((char *) block <= core_img)
+	grub_util_error ("No terminator in the core image");
+    }
+
+  /* Now read the core image to determine where the sectors are.  */
+  file = grub_file_open (core_path_dev);
+  if (! file)
+    grub_util_error ("%s", grub_errmsg);
+
+  file->read_hook = save_first_sector;
+  if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE)
+      != GRUB_DISK_SECTOR_SIZE)
+    grub_util_error ("Failed to read the first sector of the core image");
+
+  block = first_block;
+  file->read_hook = save_blocklists;
+  if (grub_file_read (file, tmp_img, core_size - GRUB_DISK_SECTOR_SIZE)
+      != (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE)
+    grub_util_error ("Failed to read the rest sectors of the core image");
+
+  grub_file_close (file);
+
+  free (core_path_dev);
+  free (tmp_img);
+
+  *kernel_sector = grub_cpu_to_le64 (first_sector);
+
+  /* FIXME: can this be skipped?  */
+  *boot_drive = 0xFF;
+
+  *install_dos_part = grub_cpu_to_le32 (dos_part);
+  *install_bsd_part = grub_cpu_to_le32 (bsd_part);
+
+  /* Write the first two sectors of the core image onto the disk.  */
+  grub_util_info ("opening the core image `%s'", core_path);
+  fp = fopen (core_path, "r+b");
+  if (! fp)
+    grub_util_error ("Cannot open `%s'", core_path);
+
+  grub_util_write_image (core_img, GRUB_DISK_SECTOR_SIZE * 2, fp);
+  fclose (fp);
+
+  /* Write the boot image onto the disk.  */
+  if (grub_disk_write (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, boot_img))
+    grub_util_error ("%s", grub_errmsg);
+
+ finish:
+
+  /* Sync is a Good Thing.  */
+  sync ();
+
+  free (core_path);
+  free (core_img);
+  free (boot_img);
+  grub_device_close (dest_dev);
+  grub_device_close (root_dev);
+}
+
+static struct option options[] =
+  {
+    {"boot-image", required_argument, 0, 'b'},
+    {"core-image", required_argument, 0, 'c'},
+    {"directory", required_argument, 0, 'd'},
+    {"device-map", required_argument, 0, 'm'},
+    {"root-device", required_argument, 0, 'r'},
+    {"force", no_argument, 0, 'f'},
+    {"skip-fs-probe", no_argument, 0, 's'},
+    {"help", no_argument, 0, 'h'},
+    {"version", no_argument, 0, 'V'},
+    {"verbose", no_argument, 0, 'v'},
+    {0, 0, 0, 0}
+  };
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``grub-setup --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-setup [OPTION]... DEVICE\n\
+\n\
+Set up images to boot from DEVICE.\n\
+DEVICE must be a GRUB device (e.g. ``(hd0,1)'').\n\
+\n\
+  -b, --boot-image=FILE   use FILE as the boot image [default=%s]\n\
+  -c, --core-image=FILE   use FILE as the core image [default=%s]\n\
+  -d, --directory=DIR     use GRUB files in the directory DIR [default=%s]\n\
+  -m, --device-map=FILE   use FILE as the device map [default=%s]\n\
+  -r, --root-device=DEV   use DEV as the root device [default=guessed]\n\
+  -f, --force             install even if problems are detected\n\
+  -s, --skip-fs-probe     do not probe for filesystems in DEVICE\n\
+  -h, --help              display this message and exit\n\
+  -V, --version           print version information and exit\n\
+  -v, --verbose           print verbose messages\n\
+\n\
+Report bugs to <%s>.\n\
+",
+	    DEFAULT_BOOT_FILE, DEFAULT_CORE_FILE, DEFAULT_DIRECTORY,
+	    DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+static char *
+get_device_name (char *dev)
+{
+  size_t len = strlen (dev);
+
+  if (dev[0] != '(' || dev[len - 1] != ')')
+    return 0;
+
+  dev[len - 1] = '\0';
+  return dev + 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+  char *boot_file = 0;
+  char *core_file = 0;
+  char *dir = 0;
+  char *dev_map = 0;
+  char *root_dev = 0;
+  char *dest_dev;
+  int must_embed = 0, force = 0, fs_probe = 1;
+
+  progname = "grub-setup";
+
+  /* Check for options.  */
+  while (1)
+    {
+      int c = getopt_long (argc, argv, "b:c:d:m:r:hVvf", options, 0);
+
+      if (c == -1)
+	break;
+      else
+	switch (c)
+	  {
+	  case 'b':
+	    if (boot_file)
+	      free (boot_file);
+
+	    boot_file = xstrdup (optarg);
+	    break;
+
+	  case 'c':
+	    if (core_file)
+	      free (core_file);
+
+	    core_file = xstrdup (optarg);
+	    break;
+
+	  case 'd':
+	    if (dir)
+	      free (dir);
+
+	    dir = xstrdup (optarg);
+	    break;
+
+	  case 'm':
+	    if (dev_map)
+	      free (dev_map);
+
+	    dev_map = xstrdup (optarg);
+	    break;
+
+	  case 'r':
+	    if (root_dev)
+	      free (root_dev);
+
+	    root_dev = xstrdup (optarg);
+	    break;
+
+	  case 'f':
+	    force = 1;
+	    break;
+
+	  case 's':
+	    fs_probe = 0;
+	    break;
+
+	  case 'h':
+	    usage (0);
+	    break;
+
+	  case 'V':
+	    printf ("grub-setup (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
+	    return 0;
+
+	  case 'v':
+	    verbosity++;
+	    break;
+
+	  default:
+	    usage (1);
+	    break;
+	  }
+    }
+
+  if (verbosity > 1)
+    grub_env_set ("debug", "all");
+
+  /* Obtain DEST_DEV.  */
+  if (optind >= argc)
+    {
+      fprintf (stderr, "No device is specified.\n");
+      usage (1);
+    }
+
+  if (optind + 1 != argc)
+    {
+      fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]);
+      usage (1);
+    }
+
+  /* Initialize the emulated biosdisk driver.  */
+  grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
+
+  /* Initialize all modules. */
+  grub_init_all ();
+
+  dest_dev = get_device_name (argv[optind]);
+  if (! dest_dev)
+    {
+      /* Possibly, the user specified an OS device file.  */
+      dest_dev = grub_util_get_grub_dev (argv[optind]);
+      if (! dest_dev)
+	{
+	  fprintf (stderr, "Invalid device `%s'.\n", argv[optind]);
+	  usage (1);
+	}
+    }
+  else
+    /* For simplicity.  */
+    dest_dev = xstrdup (dest_dev);
+
+  if (root_dev)
+    {
+      char *tmp = get_device_name (root_dev);
+
+      if (! tmp)
+	grub_util_error ("Invalid root device `%s'", root_dev);
+
+      tmp = xstrdup (tmp);
+      free (root_dev);
+      root_dev = tmp;
+    }
+  else
+    {
+      root_dev = grub_util_get_grub_dev (grub_guess_root_device (dir ? : DEFAULT_DIRECTORY));
+      if (! root_dev)
+	{
+	  grub_util_info ("guessing the root device failed, because of `%s'",
+			  grub_errmsg);
+	  grub_util_error ("Cannot guess the root device. Specify the option ``--root-device''.");
+	}
+    }
+
+#ifdef __linux__
+  if (grub_util_lvm_isvolume (root_dev))
+    must_embed = 1;
+
+  if (root_dev[0] == 'm' && root_dev[1] == 'd'
+      && root_dev[2] >= '0' && root_dev[2] <= '9')
+    {
+      /* FIXME: we can avoid this on RAID1.  */
+      must_embed = 1;
+    }
+
+  if (dest_dev[0] == 'm' && dest_dev[1] == 'd'
+      && dest_dev[2] >= '0' && dest_dev[2] <= '9')
+    {
+      char **devicelist;
+      int i;
+
+      devicelist = grub_util_raid_getmembers (dest_dev);
+
+      for (i = 0; devicelist[i]; i++)
+	{
+	  setup (dir ? : DEFAULT_DIRECTORY,
+		 boot_file ? : DEFAULT_BOOT_FILE,
+		 core_file ? : DEFAULT_CORE_FILE,
+		 root_dev, grub_util_get_grub_dev (devicelist[i]), 1, force, fs_probe);
+	}
+    }
+  else
+#endif
+  /* Do the real work.  */
+    setup (dir ? : DEFAULT_DIRECTORY,
+	   boot_file ? : DEFAULT_BOOT_FILE,
+	   core_file ? : DEFAULT_CORE_FILE,
+	   root_dev, dest_dev, must_embed, force, fs_probe);
+
+  /* Free resources.  */
+  grub_fini_all ();
+  grub_util_biosdisk_fini ();
+
+  free (boot_file);
+  free (core_file);
+  free (dir);
+  free (dev_map);
+  free (root_dev);
+  free (dest_dev);
+
+  return 0;
+}
diff --git a/util/ieee1275/devicemap.c b/util/ieee1275/devicemap.c
new file mode 100644
index 0000000..bddfc17
--- /dev/null
+++ b/util/ieee1275/devicemap.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <string.h>
+#include <grub/types.h>
+#include <grub/util/deviceiter.h>
+#include <grub/util/ofpath.h>
+#include <grub/util/misc.h>
+
+/* Since OF path names can have "," characters in them, and GRUB
+   internally uses "," to indicate partitions (unlike OF which uses
+   ":" for this purpose) we escape such commas.  */
+
+static char *
+escape_of_path (const char *orig_path)
+{
+  char *new_path, *d, c;
+  const char *p;
+
+  if (!strchr (orig_path, ','))
+    return (char *) orig_path;
+
+  new_path = xmalloc (strlen (orig_path) * 2);
+
+  p = orig_path;
+  d = new_path;
+  while ((c = *p++) != '\0')
+    {
+      if (c == ',')
+	*d++ = '\\';
+      *d++ = c;
+    }
+
+  free ((char *) orig_path);
+
+  return new_path;
+}
+
+void
+grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy UNUSED,
+				int *num_fd UNUSED, int *num_hd UNUSED)
+{
+  const char *orig_path = grub_util_devname_to_ofpath (name);
+  char *ofpath = escape_of_path (orig_path);
+
+  fprintf(fp, "(%s)\t%s\n", ofpath, name);
+
+  free (ofpath);
+}
diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in
new file mode 100644
index 0000000..710ed12
--- /dev/null
+++ b/util/ieee1275/grub-install.in
@@ -0,0 +1,233 @@
+#! /bin/sh
+
+# Install GRUB on your drive.
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+# This script uses `ofpathname', which is downloadable from
+# http://ppc64-utils.ozlabs.org .
+
+# Initialize some variables.
+transform="@program_transform_name@"
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+bindir=@bindir@
+libdir=@libdir@
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+target_cpu=@target_cpu@
+platform=@platform@
+pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
+
+grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}`
+grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
+grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
+rootdir=
+grub_prefix=`echo /boot/grub | sed ${transform}`
+modules=
+
+install_device=
+debug=no
+update_nvram=yes
+
+ofpathname=/usr/sbin/ofpathname
+nvsetenv=/sbin/nvsetenv
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: grub-install [OPTION] [install_device]
+Install GRUB on your drive.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --modules=MODULES       pre-load specified modules MODULES
+  --root-directory=DIR    install GRUB images under the directory DIR
+                          instead of the root directory
+  --grub-mkdevicemap=FILE use FILE as grub-mkdevicemap
+  --grub-mkimage=FILE     use FILE as grub-mkimage
+  --grub-probe=FILE       use FILE as grub-probe
+  --no-nvram              don't update the boot-device NVRAM variable
+
+grub-install copies GRUB images into the DIR/boot directory specified by
+--root-directory, and uses nvsetenv to set the Open Firmware boot-device
+variable.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-install (GNU GRUB ${PACKAGE_VERSION})"
+	exit 0 ;;
+    --modules=*)
+	modules=`echo "$option" | sed 's/--modules=//'` ;;
+    --root-directory=*)
+	rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
+    --grub-mkdevicemap=*)
+	grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;;
+    --grub-mkimage=*)
+	grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
+    --grub-probe=*)
+	grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;;
+    --no-nvram)
+	update_nvram=no ;;
+    # This is an undocumented feature...
+    --debug)
+	debug=yes ;;
+    -*)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    *)
+	if test "x$install_device" != x; then
+	    echo "More than one install_devices?" 1>&2
+	    usage
+	    exit 1
+	fi
+	install_device="${option}" ;;
+    esac
+done
+
+# If the debugging feature is enabled, print commands.
+if test $debug = yes; then
+    set -x
+fi
+
+# Initialize these directories here, since ROOTDIR was initialized.
+bootdir=${rootdir}/boot
+grubdir=${bootdir}/`echo grub | sed ${transform}`
+device_map=${grubdir}/device.map
+
+set $grub_mkimage dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+# Find the partition at the right mount point.
+install_device=`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${grubdir}`
+
+if test "x$install_device" = "x`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${bootdir}`"; then
+    echo "$grubdir must be a mount point."
+    exit 1
+fi
+# XXX warn on firmware-unreadable filesystems?
+
+# Create the GRUB directory if it is not present.
+test -d "$bootdir" || mkdir "$bootdir" || exit 1
+test -d "$grubdir" || mkdir "$grubdir" || exit 1
+
+# Create the device map file if it is not present.
+if test -f "$device_map"; then
+    :
+else
+    # Create a safe temporary file.
+    test -n "$mklog" && log_file=`$mklog`
+
+    $grub_mkdevicemap --device-map=$device_map $no_floppy || exit 1
+fi
+
+# Copy the GRUB images to the GRUB directory.
+for file in ${grubdir}/*.mod ${grubdir}/*.lst ; do
+    if test -f $file; then
+	rm -f $file || exit 1
+    fi
+done
+for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst ; do
+    cp -f $file ${grubdir} || exit 1
+done
+
+# Create the core image. First, auto-detect the filesystem module.
+fs_module=`$grub_probe --target=fs --device-map=${device_map} ${grubdir}`
+if test "x$fs_module" = x -a "x$modules" = x; then
+    echo "Auto-detection of a filesystem module failed." 1>&2
+    echo "Please specify the module with the option \`--modules' explicitly." 1>&2
+    exit 1
+fi
+
+# Then the partition map module.  In order to support partition-less media,
+# this command is allowed to fail (--target=fs already grants us that the
+# filesystem will be accessible).
+partmap_module=`$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`
+
+# Device abstraction module, if any (lvm, raid).
+devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}`
+
+modules="$modules $fs_module $partmap_module $devabstraction_module"
+
+# Now perform the installation.
+"$grub_mkimage" --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1
+
+if test $update_nvram = yes; then
+    set $ofpathname dummy
+    if test -f "$1"; then
+	:
+    else
+	echo "$1: Not found." 1>&2
+	exit 1
+    fi
+
+    set $nvsetenv dummy
+    if test -f "$1"; then
+	:
+    else
+	echo "$1: Not found." 1>&2
+	exit 1
+    fi
+
+    # Get the Open Firmware device tree path translation.
+    dev=`echo $install_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'`
+    partno=`echo $install_device | sed -e 's/.*[^0-9]\([0-9]\+\)$/\1/'`
+    ofpath=`$ofpathname $dev` || {
+	echo "Couldn't find Open Firmware device tree path for $dev."
+	echo "You will have to set boot-device manually."
+	exit 1
+    }
+
+    # Point boot-device at the new grub install
+    boot_device="boot-device $ofpath:$partno,\\grub"
+    "$nvsetenv" "$boot_device" || {
+	echo "$nvsetenv failed."
+	echo "You will have to set boot-device manually.  At the Open Firmware prompt, type:"
+	echo "  setenv $boot_device"
+	exit 1
+    }
+fi
+
+# Prompt the user to check if the device map is correct.
+echo "Installation finished. No error reported."
+echo "This is the contents of the device map $device_map."
+echo "Check if this is correct or not. If any of the lines is incorrect,"
+echo "fix it and re-run the script \`grub-install'."
+echo
+
+cat $device_map
+
+# Bye.
+exit 0
diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c
new file mode 100644
index 0000000..7b464bf
--- /dev/null
+++ b/util/ieee1275/ofpath.c
@@ -0,0 +1,415 @@
+/* ofpath.c - calculate OpenFirmware path names given an OS device */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#undef OFPATH_STANDALONE
+
+#ifndef OFPATH_STANDALONE
+#include <grub/types.h>
+#include <grub/util/misc.h>
+#include <grub/util/ofpath.h>
+#endif
+
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <malloc.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+
+#ifdef OFPATH_STANDALONE
+#define UNUSED __attribute__((unused))
+#define xmalloc malloc
+void
+grub_util_error (const char *fmt, ...)
+{
+  va_list ap;
+
+  fprintf (stderr, "ofpath: error: ");
+  va_start (ap, fmt);
+  vfprintf (stderr, fmt, ap);
+  va_end (ap);
+  fputc ('\n', stderr);
+  exit (1);
+}
+
+#endif
+
+static void
+kill_trailing_dir(char *path)
+{
+  char *end = path + strlen(path) - 1;
+
+  while (end >= path)
+    {
+      if (*end != '/')
+	{
+	  end--;
+	  continue;
+	}
+      *end = '\0';
+      break;
+    }
+}
+
+static void
+trim_newline (char *path)
+{
+  char *end = path + strlen(path) - 1;
+
+  while (*end == '\n')
+    *end-- = '\0';
+}
+
+#define OF_PATH_MAX	256
+
+static void
+find_obppath(char *of_path, const char *sysfs_path_orig)
+{
+  char *sysfs_path, *path;
+
+  sysfs_path = xmalloc (PATH_MAX);
+  path = xmalloc (PATH_MAX);
+
+  strcpy(sysfs_path, sysfs_path_orig);
+  while (1)
+    {
+      int fd;
+
+      snprintf(path, PATH_MAX, "%s/obppath", sysfs_path);
+#if 0
+      printf("Trying %s\n", path);
+#endif
+
+      fd = open(path, O_RDONLY);
+      if (fd < 0)
+	{
+	  kill_trailing_dir(sysfs_path);
+	  if (!strcmp(sysfs_path, "/sys"))
+	    grub_util_error("'obppath' not found in parent dirs of %s",
+			    sysfs_path_orig);
+	  continue;
+	}
+      memset(of_path, 0, OF_PATH_MAX);
+      read(fd, of_path, OF_PATH_MAX);
+      close(fd);
+
+      trim_newline(of_path);
+      break;
+    }
+
+  free (path);
+  free (sysfs_path);
+}
+
+static void
+block_device_get_sysfs_path_and_link(const char *devicenode,
+				     char *sysfs_path, int sysfs_path_len)
+{
+  char *rpath = xmalloc (PATH_MAX);
+
+  snprintf(sysfs_path, sysfs_path_len, "/sys/block/%s", devicenode);
+
+  if (!realpath (sysfs_path, rpath))
+    grub_util_error ("Cannot get the real path of `%s'", sysfs_path);
+
+  strcat(rpath, "/device");
+
+  if (!realpath (rpath, sysfs_path))
+    grub_util_error ("Cannot get the real path of `%s'", rpath);
+
+  free (rpath);
+}
+
+static const char *
+trailing_digits (const char *p)
+{
+  const char *end;
+
+  end = p + strlen(p) - 1;
+  while (end >= p)
+    {
+      if (! isdigit(*end))
+	break;
+      end--;
+    }
+
+  return end + 1;
+}
+
+static void
+__of_path_common(char *of_path, char *sysfs_path,
+		 const char *device, int devno)
+{
+  const char *digit_string;
+  char disk[64];
+
+  find_obppath(of_path, sysfs_path);
+
+  digit_string = trailing_digits (device);
+  if (*digit_string == '\0')
+    {
+      sprintf(disk, "/disk@%d", devno);
+    }
+  else
+    {
+      int part;
+
+      sscanf(digit_string, "%d", &part);
+      sprintf(disk, "/disk@%d:%c", devno, 'a' + (part - 1));
+    }
+  strcat(of_path, disk);
+}
+
+static char *
+get_basename(char *p)
+{
+  char *ret = p;
+
+  while (*p)
+    {
+      if (*p == '/')
+	ret = p + 1;
+      p++;
+    }
+
+  return ret;
+}
+
+static void
+of_path_of_vdisk(char *of_path,
+		 const char *devname UNUSED, const char *device,
+		 const char *devnode UNUSED, const char *devicenode)
+{
+  char *sysfs_path, *p;
+  int devno, junk;
+
+  sysfs_path = xmalloc (PATH_MAX);
+  block_device_get_sysfs_path_and_link(devicenode,
+				       sysfs_path, PATH_MAX);
+  p = get_basename (sysfs_path);
+  sscanf(p, "vdc-port-%d-%d", &devno, &junk);
+  __of_path_common(of_path, sysfs_path, device, devno);
+
+  free (sysfs_path);
+}
+
+static void
+of_path_of_ide(char *of_path,
+	       const char *devname UNUSED, const char *device,
+	       const char *devnode UNUSED, const char *devicenode)
+{
+  char *sysfs_path, *p;
+  int chan, devno;
+
+  sysfs_path = xmalloc (PATH_MAX);
+  block_device_get_sysfs_path_and_link(devicenode,
+				       sysfs_path, PATH_MAX);
+  p = get_basename (sysfs_path);
+  sscanf(p, "%d.%d", &chan, &devno);
+
+  __of_path_common(of_path, sysfs_path, device, devno);
+
+  free (sysfs_path);
+}
+
+static int
+vendor_is_ATA(const char *path)
+{
+  int fd, err;
+  char *buf;
+
+  buf = xmalloc (PATH_MAX);
+
+  snprintf(buf, PATH_MAX, "%s/vendor", path);
+  fd = open(buf, O_RDONLY);
+  if (fd < 0)
+    grub_util_error ("Cannot open 'vendor' node of `%s'", path);
+
+  memset(buf, 0, PATH_MAX);
+  err = read(fd, buf, PATH_MAX);
+  if (err < 0)
+    grub_util_error ("Cannot read 'vendor' node of `%s'", path);
+
+  close(fd);
+
+  free (buf);
+
+  if (!strncmp(buf, "ATA", 3))
+    return 1;
+  return 0;
+}
+
+static void
+check_sas (char *sysfs_path, int *tgt)
+{
+  char *ed = strstr (sysfs_path, "end_device");
+  char *p, *q, *path;
+  char phy[16];
+  int fd;
+
+  if (!ed)
+    return;
+
+  /* SAS devices are identified using disk@$PHY_ID */
+  p = strdup (sysfs_path);
+  ed = strstr(p, "end_device");
+
+  q = ed;
+  while (*q && *q != '/')
+    q++;
+  *q = '\0';
+
+  path = xmalloc (PATH_MAX);
+  sprintf (path, "%s/sas_device:%s/phy_identifier", p, ed);
+
+  fd = open(path, O_RDONLY);
+  if (fd < 0)
+    grub_util_error("Cannot open SAS PHY ID '%s'\n", path);
+
+  memset (phy, 0, sizeof (phy));
+  read (fd, phy, sizeof (phy));
+
+  sscanf (phy, "%d", tgt);
+
+  free (path);
+  free (p);
+}
+
+static void
+of_path_of_scsi(char *of_path,
+		const char *devname UNUSED, const char *device,
+		const char *devnode UNUSED, const char *devicenode)
+{
+  const char *p, *digit_string, *disk_name;
+  int host, bus, tgt, lun;
+  char *sysfs_path, disk[64];
+
+  sysfs_path = xmalloc (PATH_MAX);
+
+  block_device_get_sysfs_path_and_link(devicenode,
+				       sysfs_path, PATH_MAX);
+  p = get_basename (sysfs_path);
+  sscanf(p, "%d:%d:%d:%d", &host, &bus, &tgt, &lun);
+  check_sas (sysfs_path, &tgt);
+
+  if (vendor_is_ATA(sysfs_path))
+    {
+      __of_path_common(of_path, sysfs_path, device, tgt);
+      free (sysfs_path);
+      return;
+    }
+
+  find_obppath(of_path, sysfs_path);
+  free (sysfs_path);
+
+  if (strstr (of_path, "qlc"))
+    strcat (of_path, "/fp@0,0");
+
+  if (strstr (of_path, "sbus"))
+    disk_name = "sd";
+  else
+    disk_name = "disk";
+
+  digit_string = trailing_digits (device);
+  if (*digit_string == '\0')
+    {
+      sprintf(disk, "/%s@%x,%d", disk_name, tgt, lun);
+    }
+  else
+    {
+      int part;
+
+      sscanf(digit_string, "%d", &part);
+      sprintf(disk, "/%s@%x,%d:%c", disk_name, tgt, lun, 'a' + (part - 1));
+    }
+  strcat(of_path, disk);
+}
+
+static char *
+strip_trailing_digits (const char *p)
+{
+  char *new, *end;
+
+  new = strdup (p);
+  end = new + strlen(new) - 1;
+  while (end >= new)
+    {
+      if (! isdigit(*end))
+	break;
+      *end-- = '\0';
+    }
+
+  return new;
+}
+
+char *
+grub_util_devname_to_ofpath (char *devname)
+{
+  char *name_buf, *device, *devnode, *devicenode, *ofpath;
+
+  name_buf = xmalloc (PATH_MAX);
+  name_buf = realpath (devname, name_buf);
+  if (! name_buf)
+    grub_util_error ("Cannot get the real path of `%s'", devname);
+
+  device = get_basename (devname);
+  devnode = strip_trailing_digits (devname);
+  devicenode = strip_trailing_digits (device);
+
+  ofpath = xmalloc (OF_PATH_MAX);
+
+  if (device[0] == 'h' && device[1] == 'd')
+    of_path_of_ide(ofpath, name_buf, device, devnode, devicenode);
+  else if (device[0] == 's'
+	   && (device[1] == 'd' || device[1] == 'r'))
+    of_path_of_scsi(ofpath, name_buf, device, devnode, devicenode);
+  else if (device[0] == 'v' && device[1] == 'd' && device[2] == 'i'
+	   && device[3] == 's' && device[4] == 'k')
+    of_path_of_vdisk(ofpath, name_buf, device, devnode, devicenode);
+
+  free (devnode);
+  free (devicenode);
+  free (name_buf);
+
+  return ofpath;
+}
+
+#ifdef OFPATH_STANDALONE
+int main(int argc, char **argv)
+{
+  char *of_path;
+
+  if (argc != 2)
+    {
+      printf("Usage: grub-ofpathname DEVICE\n");
+      return 1;
+    }
+
+  of_path = grub_util_devname_to_ofpath (argv[1]);
+  printf("%s\n", of_path);
+
+  return 0;
+}
+#endif
diff --git a/util/lvm.c b/util/lvm.c
new file mode 100644
index 0000000..8a8ed1e
--- /dev/null
+++ b/util/lvm.c
@@ -0,0 +1,50 @@
+/* lvm.c - LVM support for GRUB utils.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* We only support LVM on Linux.  */
+#ifdef __linux__
+
+#include <grub/util/misc.h>
+#include <grub/util/lvm.h>
+
+#include <string.h>
+#include <sys/stat.h>
+
+int
+grub_util_lvm_isvolume (char *name)
+{
+  char *devname;
+  struct stat st;
+  int err;
+
+  devname = xmalloc (strlen (name) + 13);
+
+  strcpy (devname, "/dev/mapper/");
+  strcpy (devname+12, name);
+
+  err = stat (devname, &st);
+  free (devname);
+
+  if (err)
+    return 0;
+  else
+    return 1;
+}
+
+#endif /* ! __linux__ */
diff --git a/util/misc.c b/util/misc.c
new file mode 100644
index 0000000..37e7531
--- /dev/null
+++ b/util/misc.c
@@ -0,0 +1,451 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <time.h>
+
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/cache.h>
+#include <grub/util/misc.h>
+#include <grub/mm.h>
+#include <grub/term.h>
+#include <grub/time.h>
+#include <grub/machine/time.h>
+#include <grub/machine/machine.h>
+
+/* Include malloc.h, only if memalign is available. It is known that
+   memalign is declared in malloc.h in all systems, if present.  */
+#ifdef HAVE_MEMALIGN
+# include <malloc.h>
+#endif
+
+#ifdef __MINGW32__
+#include <windows.h>
+#include <winioctl.h>
+#endif
+
+char *progname = 0;
+int verbosity = 0;
+
+void
+grub_util_warn (const char *fmt, ...)
+{
+  va_list ap;
+
+  fprintf (stderr, "%s: warn: ", progname);
+  va_start (ap, fmt);
+  vfprintf (stderr, fmt, ap);
+  va_end (ap);
+  fputc ('\n', stderr);
+  fflush (stderr);
+}
+
+void
+grub_util_info (const char *fmt, ...)
+{
+  if (verbosity > 0)
+    {
+      va_list ap;
+
+      fprintf (stderr, "%s: info: ", progname);
+      va_start (ap, fmt);
+      vfprintf (stderr, fmt, ap);
+      va_end (ap);
+      fputc ('\n', stderr);
+      fflush (stderr);
+    }
+}
+
+void
+grub_util_error (const char *fmt, ...)
+{
+  va_list ap;
+
+  fprintf (stderr, "%s: error: ", progname);
+  va_start (ap, fmt);
+  vfprintf (stderr, fmt, ap);
+  va_end (ap);
+  fputc ('\n', stderr);
+  exit (1);
+}
+
+int
+grub_err_printf (const char *fmt, ...)
+{
+  va_list ap;
+  int ret;
+
+  va_start (ap, fmt);
+  ret = vfprintf (stderr, fmt, ap);
+  va_end (ap);
+
+  return ret;
+}
+
+void *
+xmalloc (size_t size)
+{
+  void *p;
+
+  p = malloc (size);
+  if (! p)
+    grub_util_error ("out of memory");
+
+  return p;
+}
+
+void *
+xrealloc (void *ptr, size_t size)
+{
+  ptr = realloc (ptr, size);
+  if (! ptr)
+    grub_util_error ("out of memory");
+
+  return ptr;
+}
+
+char *
+xstrdup (const char *str)
+{
+  size_t len;
+  char *dup;
+
+  len = strlen (str);
+  dup = (char *) xmalloc (len + 1);
+  memcpy (dup, str, len + 1);
+
+  return dup;
+}
+
+char *
+grub_util_get_path (const char *dir, const char *file)
+{
+  char *path;
+
+  path = (char *) xmalloc (strlen (dir) + 1 + strlen (file) + 1);
+  sprintf (path, "%s/%s", dir, file);
+  return path;
+}
+
+size_t
+grub_util_get_fp_size (FILE *fp)
+{
+  struct stat st;
+
+  if (fflush (fp) == EOF)
+    grub_util_error ("fflush failed");
+
+  if (fstat (fileno (fp), &st) == -1)
+    grub_util_error ("fstat failed");
+
+  return st.st_size;
+}
+
+size_t
+grub_util_get_image_size (const char *path)
+{
+  struct stat st;
+
+  grub_util_info ("getting the size of %s", path);
+
+  if (stat (path, &st) == -1)
+    grub_util_error ("cannot stat %s", path);
+
+  return st.st_size;
+}
+
+void
+grub_util_read_at (void *img, size_t size, off_t offset, FILE *fp)
+{
+  if (fseeko (fp, offset, SEEK_SET) == -1)
+    grub_util_error ("seek failed");
+
+  if (fread (img, 1, size, fp) != size)
+    grub_util_error ("read failed");
+}
+
+char *
+grub_util_read_image (const char *path)
+{
+  char *img;
+  FILE *fp;
+  size_t size;
+
+  grub_util_info ("reading %s", path);
+
+  size = grub_util_get_image_size (path);
+  img = (char *) xmalloc (size);
+
+  fp = fopen (path, "rb");
+  if (! fp)
+    grub_util_error ("cannot open %s", path);
+
+  grub_util_read_at (img, size, 0, fp);
+
+  fclose (fp);
+
+  return img;
+}
+
+void
+grub_util_load_image (const char *path, char *buf)
+{
+  FILE *fp;
+  size_t size;
+
+  grub_util_info ("reading %s", path);
+
+  size = grub_util_get_image_size (path);
+
+  fp = fopen (path, "rb");
+  if (! fp)
+    grub_util_error ("cannot open %s", path);
+
+  if (fread (buf, 1, size, fp) != size)
+    grub_util_error ("cannot read %s", path);
+
+  fclose (fp);
+}
+
+void
+grub_util_write_image_at (const void *img, size_t size, off_t offset, FILE *out)
+{
+  grub_util_info ("writing 0x%x bytes at offset 0x%x", size, offset);
+  if (fseeko (out, offset, SEEK_SET) == -1)
+    grub_util_error ("seek failed");
+  if (fwrite (img, 1, size, out) != size)
+    grub_util_error ("write failed");
+}
+
+void
+grub_util_write_image (const char *img, size_t size, FILE *out)
+{
+  grub_util_info ("writing 0x%x bytes", size);
+  if (fwrite (img, 1, size, out) != size)
+    grub_util_error ("write failed");
+}
+
+void *
+grub_malloc (grub_size_t size)
+{
+  return xmalloc (size);
+}
+
+void *
+grub_zalloc (grub_size_t size)
+{
+  void *ret;
+
+  ret = xmalloc (size);
+  memset (ret, 0, size);
+  return ret;
+}
+
+void
+grub_free (void *ptr)
+{
+  free (ptr);
+}
+
+void *
+grub_realloc (void *ptr, grub_size_t size)
+{
+  return xrealloc (ptr, size);
+}
+
+void *
+grub_memalign (grub_size_t align, grub_size_t size)
+{
+  void *p;
+
+#if defined(HAVE_POSIX_MEMALIGN)
+  if (posix_memalign (&p, align, size) != 0)
+    p = 0;
+#elif defined(HAVE_MEMALIGN)
+  p = memalign (align, size);
+#else
+  (void) align;
+  (void) size;
+  grub_util_error ("grub_memalign is not supported");
+#endif
+
+  if (! p)
+    grub_util_error ("out of memory");
+
+  return p;
+}
+
+/* Some functions that we don't use.  */
+void
+grub_mm_init_region (void *addr __attribute__ ((unused)),
+		     grub_size_t size __attribute__ ((unused)))
+{
+}
+
+void
+grub_register_exported_symbols (void)
+{
+}
+
+void
+grub_exit (void)
+{
+  exit (1);
+}
+
+grub_uint32_t
+grub_get_rtc (void)
+{
+  struct timeval tv;
+
+  gettimeofday (&tv, 0);
+
+  return (tv.tv_sec * GRUB_TICKS_PER_SECOND
+	  + (((tv.tv_sec % GRUB_TICKS_PER_SECOND) * 1000000 + tv.tv_usec)
+	     * GRUB_TICKS_PER_SECOND / 1000000));
+}
+
+grub_uint64_t
+grub_get_time_ms (void)
+{
+  struct timeval tv;
+
+  gettimeofday (&tv, 0);
+
+  return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
+}
+
+#ifdef __MINGW32__
+
+void
+grub_millisleep (grub_uint32_t ms)
+{
+  Sleep (ms);
+}
+
+#else
+
+void
+grub_millisleep (grub_uint32_t ms)
+{
+  struct timespec ts;
+
+  ts.tv_sec = ms / 1000;
+  ts.tv_nsec = (ms % 1000) * 1000000;
+  nanosleep (&ts, NULL);
+}
+
+#endif
+
+void
+grub_arch_sync_caches (void *address __attribute__ ((unused)),
+		       grub_size_t len __attribute__ ((unused)))
+{
+}
+
+#ifndef  HAVE_ASPRINTF
+
+int
+asprintf (char **buf, const char *fmt, ...)
+{
+  int status;
+  va_list ap;
+
+  /* Should be large enough.  */
+  *buf = xmalloc (512);
+
+  va_start (ap, fmt);
+  status = vsprintf (*buf, fmt, ap);
+  va_end (ap);
+
+  return status;
+}
+
+#endif
+
+#ifdef __MINGW32__
+
+void sync (void)
+{
+}
+
+int fsync (int fno __attribute__ ((unused)))
+{
+  return 0;
+}
+
+void sleep (int s)
+{
+  Sleep (s * 1000);
+}
+
+grub_int64_t
+grub_util_get_disk_size (char *name)
+{
+  HANDLE hd;
+  grub_int64_t size = -1LL;
+
+  hd = CreateFile (name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
+                   0, OPEN_EXISTING, 0, 0);
+
+  if (hd == INVALID_HANDLE_VALUE)
+    return size;
+
+  if (((name[0] == '/') || (name[0] == '\\')) &&
+      ((name[1] == '/') || (name[1] == '\\')) &&
+      (name[2] == '.') &&
+      ((name[3] == '/') || (name[3] == '\\')) &&
+      (! strncasecmp (name + 4, "PHYSICALDRIVE", 13)))
+    {
+      DWORD nr;
+      DISK_GEOMETRY g;
+
+      if (! DeviceIoControl (hd, IOCTL_DISK_GET_DRIVE_GEOMETRY,
+                             0, 0, &g, sizeof (g), &nr, 0))
+        goto fail;
+
+      size = g.Cylinders.QuadPart;
+      size *= g.TracksPerCylinder * g.SectorsPerTrack * g.BytesPerSector;
+    }
+  else
+    {
+      LARGE_INTEGER s;
+
+      s.LowPart = GetFileSize (hd, &s.HighPart);
+      size = s.QuadPart;
+    }
+
+fail:
+
+  CloseHandle (hd);
+
+  return size;
+}
+
+#endif /* __MINGW32__ */
diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in
new file mode 100644
index 0000000..63bc7d8
--- /dev/null
+++ b/util/powerpc/ieee1275/grub-mkrescue.in
@@ -0,0 +1,115 @@
+#! /bin/sh -e
+
+# Make GRUB rescue image
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+# Initialize some variables.
+transform="@program_transform_name@"
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+libdir=@libdir@
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+target_cpu=@target_cpu@
+platform=@platform@
+pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
+
+grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}`
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: grub-mkrescue [OPTION] output_image
+Make GRUB rescue image.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --modules=MODULES       pre-load specified modules MODULES
+  --pkglibdir=DIR         use images from directory DIR
+                          default: ${pkglibdir}
+  --grub-mkimage=FILE     use FILE as grub-mkimage
+
+grub-mkimage generates a bootable rescue CD image for PowerMac and CHRP.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+input_dir=${pkglibdir}
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-install (GNU GRUB ${PACKAGE_VERSION})"
+	exit 0 ;;
+    --modules=*)
+	modules=`echo "$option" | sed 's/--modules=//'` ;;
+    --pkglibdir=*)
+	input_dir=`echo "$option" | sed 's/--pkglibdir=//'` ;;
+    --grub-mkimage=*)
+	grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
+    -*)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    *)
+	if test "x$output_image" != x; then
+	    echo "Unrecognized option \`$option'" 1>&2
+	    usage
+	    exit 1
+	fi
+	output_image="${option}" ;;
+    esac
+done
+
+if test "x$output_image" = x; then
+  usage
+  exit 1
+fi
+
+if [ "x${modules}" = "x" ] ; then
+  modules=`cd ${input_dir}/ && ls *.mod`
+fi
+
+map_file=`mktemp`
+cat >${map_file} <<EOF
+# EXTN          XLate   CREATOR   TYPE     Comment
+grub.img        Raw     'UNIX'    'tbxi'   "bootstrap"
+EOF
+
+iso_dir=`mktemp -d`
+boot_dir=${iso_dir}/boot/grub
+mkdir ${iso_dir}/boot
+mkdir ${boot_dir}
+core_img=${boot_dir}/grub.img
+${grub_mkimage} -n -d ${input_dir}/ -o ${core_img} ${modules}
+genisoimage -hfs -part -no-desktop -r -J -o ${output_image} \
+ -map ${map_file} -hfs-bless ${boot_dir} -chrp-boot -sysid PPC \
+ ${iso_dir}
+
+rm -rf ${iso_dir}
+rm -f ${map_file}
+
+exit 0
diff --git a/util/raid.c b/util/raid.c
new file mode 100644
index 0000000..83a0ee6
--- /dev/null
+++ b/util/raid.c
@@ -0,0 +1,112 @@
+/* raid.c - RAID support for GRUB utils.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* We only support RAID on Linux.  */
+#ifdef __linux__
+#include <grub/util/misc.h>
+#include <grub/util/raid.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/raid/md_p.h>
+#include <linux/raid/md_u.h>
+
+static char *
+grub_util_getdiskname (int major, int minor)
+{
+  char *name = xmalloc (15);
+
+  if (major == LOOP_MAJOR)
+    sprintf (name, "/dev/loop%d", minor);
+  else if (major == IDE0_MAJOR)
+    sprintf (name, "/dev/hd%c", 'a' + minor / 64);
+  else if (major == IDE1_MAJOR)
+    sprintf (name, "/dev/hd%c", 'c' + minor / 64);
+  else if (major == IDE2_MAJOR)
+    sprintf (name, "/dev/hd%c", 'e' + minor / 64);
+  else if (major == IDE3_MAJOR)
+    sprintf (name, "/dev/hd%c", 'g' + minor / 64);
+  else if (major == SCSI_DISK0_MAJOR)
+    sprintf (name, "/dev/sd%c", 'a' + minor / 16);
+  else
+    grub_util_error ("Unknown device number: %d, %d", major, minor);
+
+  return name;
+}
+
+char **
+grub_util_raid_getmembers (char *name)
+{
+  int fd, ret, i, j;
+  char *devname;
+  char **devicelist;
+  mdu_version_t version;
+  mdu_array_info_t info;
+  mdu_disk_info_t disk;
+
+  devname = xmalloc (strlen (name) + 6);
+  strcpy (devname, "/dev/");
+  strcpy (devname+5, name);
+
+  fd = open (devname, O_RDONLY);
+
+  if (fd == -1)
+    grub_util_error ("Can't open %s: %s", devname, strerror (errno));
+
+  free (devname);
+
+  ret = ioctl (fd, RAID_VERSION, &version);
+  if (ret != 0)
+    grub_util_error ("ioctl RAID_VERSION error: %s", strerror (errno));
+
+  if (version.major != 0 || version.minor != 90)
+    grub_util_error ("Unsupported RAID version: %d.%d",
+		     version.major, version.minor);
+
+  ret = ioctl (fd, GET_ARRAY_INFO, &info);
+  if (ret != 0)
+    grub_util_error ("ioctl GET_ARRAY_INFO error: %s", strerror (errno));
+
+  devicelist = xmalloc ((info.nr_disks + 1) * sizeof (char *));
+
+  for (i = 0, j = 0; i <info.nr_disks; i++)
+    {
+      disk.number = i;
+      ret = ioctl (fd, GET_DISK_INFO, &disk);
+      if (ret != 0)
+	grub_util_error ("ioctl GET_DISK_INFO error: %s", strerror (errno));
+
+      if (disk.state & (1 << MD_DISK_ACTIVE))
+	{
+	  devicelist[j] = grub_util_getdiskname (disk.major, disk.minor);
+	  j++;
+	}
+    }
+
+  devicelist[j] = NULL;
+
+  return devicelist;
+}
+
+#endif /* ! __linux__ */
diff --git a/util/resolve.c b/util/resolve.c
new file mode 100644
index 0000000..8b33beb
--- /dev/null
+++ b/util/resolve.c
@@ -0,0 +1,267 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <grub/util/resolve.h>
+#include <grub/util/misc.h>
+
+/* Module.  */
+struct mod_list
+{
+  const char *name;
+  struct mod_list *next;
+};
+
+/* Dependency.  */
+struct dep_list
+{
+  const char *name;
+  struct mod_list *list;
+  struct dep_list *next;
+};
+
+static char buf[1024];
+
+static void
+free_mod_list (struct mod_list *head)
+{
+  while (head)
+    {
+      struct mod_list *next;
+
+      next = head->next;
+      free ((void *) head->name);
+      free (head);
+      head = next;
+    }
+}
+
+static void
+free_dep_list (struct dep_list *head)
+{
+  while (head)
+    {
+      struct dep_list *next;
+
+      next = head->next;
+      free ((void *) head->name);
+      free_mod_list (head->list);
+      free (head);
+      head = next;
+    }
+}
+
+/* Read the list of dependencies.  */
+static struct dep_list *
+read_dep_list (FILE *fp)
+{
+  struct dep_list *dep_list = 0;
+
+  while (fgets (buf, sizeof (buf), fp))
+    {
+      char *p;
+      struct dep_list *dep;
+
+      /* Get the target name.  */
+      p = strchr (buf, ':');
+      if (! p)
+	grub_util_error ("invalid line format: %s", buf);
+
+      *p++ = '\0';
+
+      dep = xmalloc (sizeof (*dep));
+      dep->name = xstrdup (buf);
+      dep->list = 0;
+
+      dep->next = dep_list;
+      dep_list = dep;
+
+      /* Add dependencies.  */
+      while (*p)
+	{
+	  struct mod_list *mod;
+	  char *name;
+
+	  /* Skip whitespace.  */
+	  while (*p && isspace (*p))
+	    p++;
+
+	  if (! *p)
+	    break;
+
+	  name = p;
+
+	  /* Skip non-whitespace.  */
+	  while (*p && ! isspace (*p))
+	    p++;
+
+	  *p++ = '\0';
+
+	  mod = (struct mod_list *) xmalloc (sizeof (*mod));
+	  mod->name = xstrdup (name);
+	  mod->next = dep->list;
+	  dep->list = mod;
+	}
+    }
+
+  return dep_list;
+}
+
+static char *
+get_module_name (const char *str)
+{
+  char *base;
+  char *ext;
+
+  base = strrchr (str, '/');
+  if (! base)
+    base = (char *) str;
+  else
+    base++;
+
+  ext = strrchr (base, '.');
+  if (ext && strcmp (ext, ".mod") == 0)
+    {
+      char *name;
+
+      name = xmalloc (ext - base + 1);
+      memcpy (name, base, ext - base);
+      name[ext - base] = '\0';
+      return name;
+    }
+
+  return xstrdup (base);
+}
+
+static char *
+get_module_path (const char *prefix, const char *str)
+{
+  char *dir;
+  char *base;
+  char *ext;
+  char *ret;
+
+  ext = strrchr (str, '.');
+  if (ext && strcmp (ext, ".mod") == 0)
+    base = xstrdup (str);
+  else
+    {
+      base = xmalloc (strlen (str) + 4 + 1);
+      sprintf (base, "%s.mod", str);
+    }
+
+  dir = strchr (str, '/');
+  if (dir)
+    return base;
+
+  ret = grub_util_get_path (prefix, base);
+  free (base);
+  return ret;
+}
+
+static void
+add_module (const char *dir,
+	    struct dep_list *dep_list,
+	    struct mod_list **mod_head,
+	    struct grub_util_path_list **path_head,
+	    const char *name)
+{
+  char *mod_name;
+  struct grub_util_path_list *path;
+  struct mod_list *mod;
+  struct dep_list *dep;
+
+  mod_name = get_module_name (name);
+
+  /* Check if the module has already been added.  */
+  for (mod = *mod_head; mod; mod = mod->next)
+    if (strcmp (mod->name, mod_name) == 0)
+      {
+	free (mod_name);
+	return;
+      }
+
+  /* Resolve dependencies.  */
+  for (dep = dep_list; dep; dep = dep->next)
+    if (strcmp (dep->name, mod_name) == 0)
+      {
+	for (mod = dep->list; mod; mod = mod->next)
+	  add_module (dir, dep_list, mod_head, path_head, mod->name);
+
+	break;
+      }
+
+  /* Add this module.  */
+  mod = (struct mod_list *) xmalloc (sizeof (*mod));
+  mod->name = mod_name;
+  mod->next = *mod_head;
+  *mod_head = mod;
+
+  /* Add this path.  */
+  path = (struct grub_util_path_list *) xmalloc (sizeof (*path));
+  path->name = get_module_path (dir, name);
+  path->next = *path_head;
+  *path_head = path;
+}
+
+struct grub_util_path_list *
+grub_util_resolve_dependencies (const char *prefix,
+				const char *dep_list_file,
+				char *modules[])
+{
+  char *path;
+  FILE *fp;
+  struct dep_list *dep_list;
+  struct mod_list *mod_list = 0;
+  struct grub_util_path_list *path_list = 0;
+
+  path = grub_util_get_path (prefix, dep_list_file);
+  fp = fopen (path, "r");
+  if (! fp)
+    grub_util_error ("cannot open %s", path);
+
+  free (path);
+  dep_list = read_dep_list (fp);
+  fclose (fp);
+
+  while (*modules)
+    {
+      add_module (prefix, dep_list, &mod_list, &path_list, *modules);
+      modules++;
+    }
+
+  free_dep_list (dep_list);
+  free_mod_list (mod_list);
+
+  { /* Reverse the path_list */
+    struct grub_util_path_list *p, *prev, *next;
+
+    for (p = path_list, prev = NULL; p; p = next)
+      {
+	next = p->next;
+	p->next = prev;
+	prev = p;
+      }
+
+    return prev;
+  }
+}
diff --git a/util/sparc64/ieee1275/grub-install.in b/util/sparc64/ieee1275/grub-install.in
new file mode 100644
index 0000000..a03869c
--- /dev/null
+++ b/util/sparc64/ieee1275/grub-install.in
@@ -0,0 +1,276 @@
+#! /bin/sh
+
+# Install GRUB on your drive.
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+# Initialize some variables.
+transform="@program_transform_name@"
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+bindir=@bindir@
+libdir=@libdir@
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_TARNAME=@PACKAGE_TARNAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+target_cpu=@target_cpu@
+platform=@platform@
+pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
+
+# for make_system_path_relative_to_its_root()
+. ${libdir}/grub/grub-mkconfig_lib
+
+grub_setup=${sbindir}/`echo grub-setup | sed ${transform}`
+grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
+grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
+grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
+rootdir=
+grub_prefix=`echo /boot/grub | sed ${transform}`
+modules=
+
+install_device=
+no_floppy=
+force_lba=
+recheck=no
+debug=no
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: grub-install [OPTION] install_device
+Install GRUB on your drive.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --modules=MODULES       pre-load specified modules MODULES
+  --root-directory=DIR    install GRUB images under the directory DIR
+                          instead of the root directory
+  --grub-setup=FILE       use FILE as grub-setup
+  --grub-mkimage=FILE     use FILE as grub-mkimage
+  --grub-mkdevicemap=FILE use FILE as grub-mkdevicemap
+  --grub-probe=FILE       use FILE as grub-probe
+  --no-floppy             do not probe any floppy drive
+  --recheck               probe a device map even if it already exists
+
+INSTALL_DEVICE can be a GRUB device name or a system device filename.
+
+grub-install copies GRUB images into the DIR/boot directory specified by
+--root-directory, and uses grub-setup to install grub into the boot
+sector.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-install (GNU GRUB ${PACKAGE_VERSION})"
+	exit 0 ;;
+    --modules=*)
+	modules=`echo "$option" | sed 's/--modules=//'` ;;
+    --root-directory=*)
+	rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
+    --grub-setup=*)
+	grub_setup=`echo "$option" | sed 's/--grub-setup=//'` ;;
+    --grub-mkimage=*)
+	grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
+    --grub-mkdevicemap=*)
+	grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;;
+    --grub-probe=*)
+	grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;;
+    --no-floppy)
+	no_floppy="--no-floppy" ;;
+    --recheck)
+	recheck=yes ;;
+    # This is an undocumented feature...
+    --debug)
+	debug=yes ;;
+    -*)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    *)
+	if test "x$install_device" != x; then
+	    echo "More than one install_devices?" 1>&2
+	    usage
+	    exit 1
+	fi
+	install_device="${option}" ;;
+    esac
+done
+
+if test "x$install_device" = x; then
+    echo "install_device not specified." 1>&2
+    usage
+    exit 1
+fi
+
+# If the debugging feature is enabled, print commands.
+setup_verbose=
+if test $debug = yes; then
+    set -x
+    setup_verbose="--verbose"
+fi
+
+# Initialize these directories here, since ROOTDIR was initialized.
+bootdir=${rootdir}/boot
+grubdir=${bootdir}/`echo grub | sed ${transform}`
+device_map=${grubdir}/device.map
+
+grub_probe="${grub_probe} --device-map=${device_map}"
+
+# Check if GRUB is installed.
+set $grub_setup dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+set $grub_mkimage dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+set $grub_mkdevicemap dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+# Create the GRUB directory if it is not present.
+test -d "$bootdir" || mkdir "$bootdir" || exit 1
+test -d "$grubdir" || mkdir "$grubdir" || exit 1
+
+# If --recheck is specified, remove the device map, if present.
+if test $recheck = yes; then
+    rm -f $device_map
+fi
+
+# Create the device map file if it is not present.
+if test -f "$device_map"; then
+    :
+else
+    # Create a safe temporary file.
+    test -n "$mklog" && log_file=`$mklog`
+
+    $grub_mkdevicemap --device-map=$device_map $no_floppy || exit 1
+fi
+
+# Make sure that there is no duplicated entry.
+tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \
+    | sort | uniq -d | sed -n 1p`
+if test -n "$tmp"; then
+    echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2
+    exit 1
+fi
+
+# Copy the GRUB images to the GRUB directory.
+for file in ${grubdir}/*.mod ${grubdir}/*.lst ${grubdir}/*.img; do
+    if test -f $file && [ "`basename $file`" != menu.lst ]; then
+	rm -f $file || exit 1
+    fi
+done
+for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do
+    cp -f $file ${grubdir} || exit 1
+done
+
+for file in ${pkglibdir}/*.img; do
+    cp -f $file ${grubdir} || exit 1
+done
+
+# Write device to a variable so we don't have to traverse /dev every time.
+grub_device=`$grub_probe --target=device ${grubdir}`
+
+# Create the core image. First, auto-detect the filesystem module.
+fs_module=`$grub_probe --target=fs --device ${grub_device}`
+if test "x$fs_module" = x -a "x$modules" = x; then
+    echo "Auto-detection of a filesystem module failed." 1>&2
+    echo "Please specify the module with the option \`--modules' explicitly." 1>&2
+    exit 1
+fi
+
+# Then the partition map module.  In order to support partition-less media,
+# this command is allowed to fail (--target=fs already grants us that the
+# filesystem will be accessible).
+partmap_module=`$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`
+
+# Device abstraction module, if any (lvm, raid).
+devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}`
+
+modules="$modules $fs_module $partmap_module $devabstraction_module"
+
+prefix_drive=
+if [ "x${devabstraction_module}" = "x" ] ; then
+    if echo "${install_device}" | grep -qx "(.*)" ; then
+      install_drive="${install_device}"
+    else
+      install_drive="`$grub_probe --target=drive --device ${install_device}`"
+    fi
+    grub_drive="`$grub_probe --target=drive --device ${grub_device}`"
+
+    # Strip partition number
+    install_drive="`echo ${install_drive} | sed -e 's/\([^\]\),[0-9]*/\1/g'`"
+    grub_drive="`echo ${grub_drive} | sed -e 's/\([^\]\),[0-9]*/\1/g'`"
+    if [ "x${grub_drive}" != "x${install_drive}" ] ; then
+        uuid="`$grub_probe --target=fs_uuid --device ${grub_device}`"
+        if [ "x${uuid}" = "x" ] ; then
+          echo "You attempted a cross-disk install, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
+          exit 1
+        fi
+        prefix_drive="(UUID=${uuid})"
+        modules="$modules fs_uuid"
+    fi
+else
+    prefix_drive=`$grub_probe --target=drive --device ${grub_device}`
+fi
+
+relative_grubdir=`make_system_path_relative_to_its_root ${grubdir}` || exit 1
+if [ "x${relative_grubdir}" = "x" ] ; then
+    relative_grubdir=/
+fi
+
+$grub_mkimage --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1
+
+# Now perform the installation.
+$grub_setup ${setup_verbose} --directory=${grubdir} --device-map=${device_map} \
+        ${install_device} || exit 1
+
+# Prompt the user to check if the device map is correct.
+echo "Installation finished. No error reported."
+echo "This is the contents of the device map $device_map."
+echo "Check if this is correct or not. If any of the lines is incorrect,"
+echo "fix it and re-run the script \`grub-install'."
+echo
+
+cat $device_map
+
+# Bye.
+exit 0
diff --git a/util/sparc64/ieee1275/grub-mkimage.c b/util/sparc64/ieee1275/grub-mkimage.c
new file mode 100644
index 0000000..0a611da
--- /dev/null
+++ b/util/sparc64/ieee1275/grub-mkimage.c
@@ -0,0 +1,294 @@
+/* grub-mkimage.c - make a bootable image */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <config.h>
+#include <grub/types.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+#include <grub/kernel.h>
+#include <grub/disk.h>
+#include <grub/util/misc.h>
+#include <grub/util/resolve.h>
+#include <grub/misc.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define _GNU_SOURCE	1
+#include <getopt.h>
+
+static void
+compress_kernel (char *kernel_img, size_t kernel_size,
+		 char **core_img, size_t *core_size)
+{
+  /* No compression support yet.  */
+  grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size);
+  *core_img = xmalloc (kernel_size);
+  memcpy (*core_img, kernel_img, kernel_size);
+  *core_size = kernel_size;
+}
+
+static void
+generate_image (const char *dir, const char *prefix, FILE *out, char *mods[], char *memdisk_path)
+{
+  size_t kernel_size, total_module_size, memdisk_size, core_size, boot_size, offset;
+  char *kernel_path, *kernel_img, *core_img, *boot_path, *boot_img;
+  struct grub_util_path_list *path_list, *p;
+  struct grub_module_info *modinfo;
+  grub_addr_t module_addr;
+  unsigned int num;
+
+  path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
+
+  kernel_path = grub_util_get_path (dir, "kernel.img");
+  kernel_size = grub_util_get_image_size (kernel_path);
+
+  total_module_size = sizeof (struct grub_module_info);
+  for (p = path_list; p; p = p->next)
+    total_module_size += (grub_util_get_image_size (p->name)
+			  + sizeof (struct grub_module_header));
+
+  memdisk_size = 0;
+  if (memdisk_path)
+    {
+      memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
+      grub_util_info ("the size of memory disk is 0x%x", memdisk_size);
+      total_module_size += memdisk_size + sizeof (struct grub_module_header);
+    }
+
+  grub_util_info ("the total module size is 0x%x", total_module_size);
+
+  kernel_img = xmalloc (kernel_size + total_module_size);
+  grub_util_load_image (kernel_path, kernel_img);
+
+  if ((GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1)
+      > GRUB_KERNEL_MACHINE_DATA_END)
+    grub_util_error ("prefix too long");
+  strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix);
+
+  /* Fill in the grub_module_info structure.  */
+  modinfo = (struct grub_module_info *) (kernel_img + kernel_size);
+  modinfo->magic = GRUB_MODULE_MAGIC;
+  modinfo->offset = sizeof (struct grub_module_info);
+  modinfo->size = total_module_size;
+
+  offset = kernel_size + sizeof (struct grub_module_info);
+  for (p = path_list; p; p = p->next)
+    {
+      struct grub_module_header *header;
+      size_t mod_size;
+
+      mod_size = grub_util_get_image_size (p->name);
+
+      header = (struct grub_module_header *) (kernel_img + offset);
+      header->type = OBJ_TYPE_ELF;
+      header->size = grub_host_to_target32 (mod_size + sizeof (*header));
+      offset += sizeof (*header);
+
+      grub_util_load_image (p->name, kernel_img + offset);
+      offset += mod_size;
+    }
+
+  if (memdisk_path)
+    {
+      struct grub_module_header *header;
+
+      header = (struct grub_module_header *) (kernel_img + offset);
+      header->type = OBJ_TYPE_MEMDISK;
+      header->size = grub_host_to_target32 (memdisk_size + sizeof (*header));
+      offset += sizeof (*header);
+
+      grub_util_load_image (memdisk_path, kernel_img + offset);
+      offset += memdisk_size;
+    }
+
+  compress_kernel (kernel_img, kernel_size + total_module_size,
+		   &core_img, &core_size);
+
+  grub_util_info ("the core size is 0x%x", core_size);
+
+  num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
+  num <<= GRUB_DISK_SECTOR_BITS;
+
+  boot_path = grub_util_get_path (dir, "diskboot.img");
+  boot_size = grub_util_get_image_size (boot_path);
+  if (boot_size != GRUB_DISK_SECTOR_SIZE)
+    grub_util_error ("diskboot.img is not one sector size");
+
+  boot_img = grub_util_read_image (boot_path);
+
+  /* sparc is a big endian architecture.  */
+  *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE
+		       - GRUB_BOOT_MACHINE_LIST_SIZE + 8))
+    = grub_cpu_to_be32 (num);
+
+  grub_util_write_image (boot_img, boot_size, out);
+  free (boot_img);
+  free (boot_path);
+
+  module_addr = (path_list
+		 ? (GRUB_BOOT_MACHINE_IMAGE_ADDRESS + kernel_size)
+		 : 0);
+
+  grub_util_info ("the first module address is 0x%x", module_addr);
+
+  *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE))
+    = grub_cpu_to_be32 (total_module_size);
+  *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE))
+    = grub_cpu_to_be32 (kernel_size);
+
+  /* No compression support yet.  */
+  *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE))
+    = grub_cpu_to_be32 (0);
+
+  grub_util_write_image (core_img, core_size, out);
+  free (kernel_img);
+  free (core_img);
+  free (kernel_path);
+
+  while (path_list)
+    {
+      struct grub_util_path_list *next = path_list->next;
+      free ((void *) path_list->name);
+      free (path_list);
+      path_list = next;
+    }
+}
+
+static struct option options[] =
+  {
+    {"directory", required_argument, 0, 'd'},
+    {"prefix", required_argument, 0, 'p'},
+    {"memdisk", required_argument, 0, 'm'},
+    {"output", required_argument, 0, 'o'},
+    {"help", no_argument, 0, 'h'},
+    {"version", no_argument, 0, 'V'},
+    {"verbose", no_argument, 0, 'v'},
+    {0, 0, 0, 0}
+  };
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``grub-mkimage --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-mkimage [OPTION]... [MODULES]\n\
+\n\
+Make a bootable image of GRUB.\n\
+\n\
+  -d, --directory=DIR     use images and modules under DIR [default=%s]\n\
+  -p, --prefix=DIR        set grub_prefix directory [default=%s]\n\
+  -m, --memdisk=FILE      embed FILE as a memdisk image\n\
+  -o, --output=FILE       output a generated image to FILE [default=stdout]\n\
+  -h, --help              display this message and exit\n\
+  -V, --version           print version information and exit\n\
+  -v, --verbose           print verbose messages\n\
+\n\
+Report bugs to <%s>.\n\
+", GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+int
+main (int argc, char *argv[])
+{
+  char *output = NULL;
+  char *dir = NULL;
+  char *prefix = NULL;
+  char *memdisk = NULL;
+  FILE *fp = stdout;
+
+  progname = "grub-mkimage";
+  while (1)
+    {
+      int c = getopt_long (argc, argv, "d:p:m:o:hVv", options, 0);
+
+      if (c == -1)
+	break;
+      else
+	switch (c)
+	  {
+	  case 'o':
+	    if (output)
+	      free (output);
+	    output = xstrdup (optarg);
+	    break;
+
+	  case 'd':
+	    if (dir)
+	      free (dir);
+	    dir = xstrdup (optarg);
+	    break;
+
+	  case 'm':
+	    if (memdisk)
+	      free (memdisk);
+	    memdisk = xstrdup (optarg);
+
+	    if (prefix)
+	      free (prefix);
+	    prefix = xstrdup ("(memdisk)/boot/grub");
+	    break;
+
+	  case 'h':
+	    usage (0);
+	    break;
+
+	  case 'p':
+	    if (prefix)
+	      free (prefix);
+	    prefix = xstrdup (optarg);
+	    break;
+
+	  case 'V':
+	    printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
+	    return 0;
+
+	  case 'v':
+	    verbosity++;
+	    break;
+
+	  default:
+	    usage (1);
+	    break;
+	  }
+    }
+
+  if (output)
+    {
+      fp = fopen (output, "wb");
+      if (! fp)
+	grub_util_error ("cannot open %s", output);
+    }
+
+  generate_image (dir ? : GRUB_LIBDIR,
+		  prefix ? : DEFAULT_DIRECTORY, fp,
+		  argv + optind, memdisk);
+
+  fclose (fp);
+
+  if (dir)
+    free (dir);
+
+  return 0;
+}
diff --git a/util/sparc64/ieee1275/grub-ofpathname.c b/util/sparc64/ieee1275/grub-ofpathname.c
new file mode 100644
index 0000000..358608b
--- /dev/null
+++ b/util/sparc64/ieee1275/grub-ofpathname.c
@@ -0,0 +1,41 @@
+/* grub-ofpathname.c - Find OpenBOOT path for a given device */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/util/misc.h>
+#include <grub/util/ofpath.h>
+
+int main(int argc, char **argv)
+{
+  char *of_path;
+
+  progname = "grub-ofpathname";
+
+  if (argc != 2)
+    {
+      printf("Usage: grub-ofpathname DEVICE\n");
+      return 1;
+    }
+
+  of_path = grub_util_devname_to_ofpath (argv[1]);
+  printf("%s\n", of_path);
+
+  free (of_path);
+
+  return 0;
+}
diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c
new file mode 100644
index 0000000..7008147
--- /dev/null
+++ b/util/sparc64/ieee1275/grub-setup.c
@@ -0,0 +1,650 @@
+/* grub-setup.c - make GRUB usable */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/util/misc.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/fs.h>
+#include <grub/partition.h>
+#include <grub/msdos_partition.h>
+#include <grub/gpt_partition.h>
+#include <grub/env.h>
+#include <grub/util/hostdisk.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+#include <grub/term.h>
+#include <grub/util/raid.h>
+#include <grub/util/lvm.h>
+
+#include <grub_setup_init.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <grub/util/getroot.h>
+
+#define _GNU_SOURCE	1
+#include <getopt.h>
+
+/* This program fills in various fields inside of the 'boot' and 'core'
+ * image files.
+ *
+ * The 'boot' image needs to know the OBP path name of the root
+ * device.  It also needs to know the initial block number of
+ * 'core' (which is 'diskboot' concatenated with 'kernel' and
+ * all the modules, this is created by grub-mkimage).  This resulting
+ * 'boot' image is 512 bytes in size and is placed in the second block
+ * of a partition.
+ *
+ * The initial 'diskboot' block acts as a loader for the actual GRUB
+ * kernel.  It contains the loading code and then a block list.
+ *
+ * The block list of 'core' starts at the end of the 'diskboot' image
+ * and works it's way backwards towards the end of the code of 'diskboot'.
+ *
+ * We patch up the images with the necessary values and write out the
+ * result.
+ */
+
+#define DEFAULT_BOOT_FILE	"boot.img"
+#define DEFAULT_CORE_FILE	"core.img"
+
+/* This is the blocklist used in the diskboot image.  */
+struct boot_blocklist
+{
+  grub_uint64_t start;
+  grub_uint32_t len;
+} __attribute__ ((packed));
+
+void
+grub_putchar (int c)
+{
+  putchar (c);
+}
+
+int
+grub_getkey (void)
+{
+  return -1;
+}
+
+struct grub_handler_class grub_term_input_class;
+struct grub_handler_class grub_term_output_class;
+
+void
+grub_refresh (void)
+{
+  fflush (stdout);
+}
+
+static char *compute_dest_ofpath (const char *dest)
+{
+  int len = strlen (dest);
+  char *res, *p, c;
+
+  res = xmalloc (len);
+  p = res;
+  while ((c = *dest++) != '\0')
+    {
+      if (c == '\\' && *dest == ',')
+	{
+	  *p++ = ',';
+	  dest++;
+	}
+      else
+	*p++ = c;
+    }
+  *p++ = '\0';
+
+  return res;
+}
+
+static void
+setup (const char *prefix, const char *dir,
+       const char *boot_file, const char *core_file,
+       const char *root, const char *dest)
+{
+  char *boot_path, *core_path;
+  char *boot_img, *core_img;
+  size_t boot_size, core_size;
+  grub_uint16_t core_sectors;
+  grub_device_t root_dev, dest_dev;
+  char *boot_devpath, *dest_ofpath;
+  grub_disk_addr_t *kernel_sector;
+  struct boot_blocklist *first_block, *block;
+  char *tmp_img;
+  int i;
+  grub_disk_addr_t first_sector;
+  grub_uint16_t last_length = GRUB_DISK_SECTOR_SIZE;
+  grub_file_t file;
+  FILE *fp;
+  struct { grub_uint64_t start; grub_uint64_t end; } embed_region;
+  embed_region.start = embed_region.end = ~0UL;
+
+  auto void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector,
+						unsigned int offset,
+						unsigned int length);
+  auto void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector,
+					      unsigned int offset,
+					      unsigned int length);
+
+  void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector,
+					   unsigned int offset,
+					   unsigned int length)
+    {
+      grub_util_info ("first sector is <%llu,%u,%u>", sector, offset, length);
+
+      if (offset != 0 || length != GRUB_DISK_SECTOR_SIZE)
+	grub_util_error ("The first sector of the core file "
+			 "is not sector-aligned");
+
+      first_sector = sector;
+    }
+
+  void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector,
+					 unsigned int offset,
+					 unsigned int length)
+    {
+      struct boot_blocklist *prev = block + 1;
+
+      grub_util_info ("saving <%llu,%u,%u>", sector, offset, length);
+
+      if (offset != 0 || last_length != GRUB_DISK_SECTOR_SIZE)
+	grub_util_error ("Non-sector-aligned data is found in the core file");
+
+      if (block != first_block
+	  && (grub_be_to_cpu64 (prev->start)
+	      + grub_be_to_cpu16 (prev->len)) == sector)
+	prev->len = grub_cpu_to_be16 (grub_be_to_cpu16 (prev->len) + 1);
+      else
+	{
+	  block->start = grub_cpu_to_be64 (sector);
+	  block->len = grub_cpu_to_be16 (1);
+
+	  block--;
+	  if (block->len)
+	    grub_util_error ("The sectors of the core file are too fragmented");
+	}
+
+      last_length = length;
+    }
+
+  dest_ofpath = compute_dest_ofpath (dest);
+
+  /* Read the boot image by the OS service.  */
+  boot_path = grub_util_get_path (dir, boot_file);
+  boot_size = grub_util_get_image_size (boot_path);
+  if (boot_size != GRUB_DISK_SECTOR_SIZE)
+    grub_util_error ("The size of `%s' is not %d",
+		     boot_path, GRUB_DISK_SECTOR_SIZE);
+  boot_img = grub_util_read_image (boot_path);
+  free (boot_path);
+
+  /* Set the addresses of variables in the boot image.  */
+  boot_devpath = (char *) (boot_img
+			   + GRUB_BOOT_AOUT_HEADER_SIZE
+			   + GRUB_BOOT_MACHINE_BOOT_DEVPATH);
+  kernel_sector = (grub_disk_addr_t *) (boot_img
+					+ GRUB_BOOT_AOUT_HEADER_SIZE
+					+ GRUB_BOOT_MACHINE_KERNEL_SECTOR);
+
+  core_path = grub_util_get_path (dir, core_file);
+  core_size = grub_util_get_image_size (core_path);
+  core_sectors = ((core_size + GRUB_DISK_SECTOR_SIZE - 1)
+		  >> GRUB_DISK_SECTOR_BITS);
+  if (core_size < GRUB_DISK_SECTOR_SIZE)
+    grub_util_error ("The size of `%s' is too small", core_path);
+
+  core_img = grub_util_read_image (core_path);
+  free (core_path);
+
+  /* Have FIRST_BLOCK to point to the first blocklist.  */
+  first_block = (struct boot_blocklist *) (core_img
+					   + GRUB_DISK_SECTOR_SIZE
+					   - sizeof (*block));
+
+  grub_util_info ("root is '%s', dest is '%s', and dest_ofpath is '%s'",
+		  root, dest, dest_ofpath);
+
+  /* Open the root device and the destination device.  */
+  grub_util_info ("Opening root");
+  root_dev = grub_device_open (root);
+  if (! root_dev)
+    grub_util_error ("%s", grub_errmsg);
+
+  grub_util_info ("Opening dest");
+  dest_dev = grub_device_open (dest);
+  if (! dest_dev)
+    grub_util_error ("%s", grub_errmsg);
+
+  grub_util_info ("setting the root device to `%s'", root);
+  if (grub_env_set ("root", root) != GRUB_ERR_NONE)
+    grub_util_error ("%s", grub_errmsg);
+
+  /* The core image must be put on a filesystem unfortunately.  */
+  grub_util_info ("will leave the core image on the filesystem");
+
+  /* Make sure that GRUB reads the identical image as the OS.  */
+  tmp_img = xmalloc (core_size);
+  core_path = grub_util_get_path (prefix, core_file);
+
+  /* It is a Good Thing to sync two times.  */
+  sync ();
+  sync ();
+
+#define MAX_TRIES	5
+
+  for (i = 0; i < MAX_TRIES; i++)
+    {
+      grub_util_info ("attempting to read the core image `%s' from GRUB%s",
+		      core_path, (i == 0) ? "" : " again");
+
+      grub_disk_cache_invalidate_all ();
+
+      file = grub_file_open (core_path);
+      if (file)
+	{
+	  if (grub_file_size (file) != core_size)
+	    grub_util_info ("succeeded in opening the core image but the size is different (%d != %d)",
+			    (int) grub_file_size (file), (int) core_size);
+	  else if (grub_file_read (file, tmp_img, core_size)
+		   != (grub_ssize_t) core_size)
+	    grub_util_info ("succeeded in opening the core image but cannot read %d bytes",
+			    (int) core_size);
+	  else if (memcmp (core_img, tmp_img, core_size) != 0)
+	    {
+#if 0
+	      FILE *dump;
+	      FILE *dump2;
+
+	      dump = fopen ("dump.img", "wb");
+	      if (dump)
+		{
+		  fwrite (tmp_img, 1, core_size, dump);
+		  fclose (dump);
+		}
+
+	      dump2 = fopen ("dump2.img", "wb");
+	      if (dump2)
+		{
+		  fwrite (core_img, 1, core_size, dump2);
+		  fclose (dump2);
+		}
+
+#endif
+	      grub_util_info ("succeeded in opening the core image but the data is different");
+	    }
+	  else
+	    {
+	      grub_file_close (file);
+	      break;
+	    }
+
+	  grub_file_close (file);
+	}
+      else
+	grub_util_info ("couldn't open the core image");
+
+      if (grub_errno)
+	grub_util_info ("error message = %s", grub_errmsg);
+
+      grub_errno = GRUB_ERR_NONE;
+      sync ();
+      sleep (1);
+    }
+
+  if (i == MAX_TRIES)
+    grub_util_error ("Cannot read `%s' correctly", core_path);
+
+  /* Clean out the blocklists.  */
+  block = first_block;
+  while (block->len)
+    {
+      block->start = 0;
+      block->len = 0;
+
+      block--;
+
+      if ((char *) block <= core_img)
+	grub_util_error ("No terminator in the core image");
+    }
+
+  /* Now read the core image to determine where the sectors are.  */
+  file = grub_file_open (core_path);
+  if (! file)
+    grub_util_error ("%s", grub_errmsg);
+
+  file->read_hook = save_first_sector;
+  if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE)
+      != GRUB_DISK_SECTOR_SIZE)
+    grub_util_error ("Failed to read the first sector of the core image");
+
+  block = first_block;
+  file->read_hook = save_blocklists;
+  if (grub_file_read (file, tmp_img, core_size - GRUB_DISK_SECTOR_SIZE)
+      != (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE)
+    grub_util_error ("Failed to read the rest sectors of the core image");
+
+  grub_file_close (file);
+
+  free (core_path);
+  free (tmp_img);
+
+  *kernel_sector = grub_cpu_to_be64 (first_sector);
+
+  strcpy(boot_devpath, dest_ofpath);
+
+  grub_util_info ("boot device path %s, prefix is %s, dest is %s",
+		  boot_devpath, prefix, dest);
+
+  /* Write the first two sectors of the core image onto the disk.  */
+  core_path = grub_util_get_path (dir, core_file);
+  grub_util_info ("opening the core image `%s'", core_path);
+  fp = fopen (core_path, "r+b");
+  if (! fp)
+    grub_util_error ("Cannot open `%s'", core_path);
+
+  grub_util_write_image (core_img, GRUB_DISK_SECTOR_SIZE, fp);
+  fclose (fp);
+  free (core_path);
+
+  /* Write the boot image onto the disk.  */
+  if (grub_disk_write (dest_dev->disk, 1, 0, GRUB_DISK_SECTOR_SIZE, boot_img))
+    grub_util_error ("%s", grub_errmsg);
+
+  /* Sync is a Good Thing.  */
+  sync ();
+
+  free (core_img);
+  free (boot_img);
+  grub_device_close (dest_dev);
+  grub_device_close (root_dev);
+}
+
+static struct option options[] =
+  {
+    {"boot-image", required_argument, 0, 'b'},
+    {"core-image", required_argument, 0, 'c'},
+    {"directory", required_argument, 0, 'd'},
+    {"device-map", required_argument, 0, 'm'},
+    {"root-device", required_argument, 0, 'r'},
+    {"help", no_argument, 0, 'h'},
+    {"version", no_argument, 0, 'V'},
+    {"verbose", no_argument, 0, 'v'},
+    {0, 0, 0, 0}
+  };
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``grub-setup --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub-setup [OPTION]... DEVICE\n\
+\n\
+Set up images to boot from DEVICE.\n\
+DEVICE must be a GRUB device (e.g. ``(hd0,1)'').\n\
+\n\
+  -b, --boot-image=FILE   use FILE as the boot image [default=%s]\n\
+  -c, --core-image=FILE   use FILE as the core image [default=%s]\n\
+  -d, --directory=DIR     use GRUB files in the directory DIR [default=%s]\n\
+  -m, --device-map=FILE   use FILE as the device map [default=%s]\n\
+  -r, --root-device=DEV   use DEV as the root device [default=guessed]\n\
+  -h, --help              display this message and exit\n\
+  -V, --version           print version information and exit\n\
+  -v, --verbose           print verbose messages\n\
+\n\
+Report bugs to <%s>.\n\
+",
+	    DEFAULT_BOOT_FILE, DEFAULT_CORE_FILE, DEFAULT_DIRECTORY,
+	    DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);
+
+  exit (status);
+}
+
+struct grub_setup_info
+{
+  char *boot_file;
+  char *core_file;
+  char *dir;
+  char *dev_map;
+  char *root_dev;
+  char *prefix;
+  char *dest_dev;
+};
+
+static void
+init_info (struct grub_setup_info *gp)
+{
+  gp->boot_file = NULL;
+  gp->core_file = NULL;
+  gp->dir = NULL;
+  gp->dev_map = NULL;
+  gp->root_dev = NULL;
+  gp->prefix = NULL;
+  gp->dest_dev = NULL;
+}
+
+static int
+parse_options (struct grub_setup_info *gp, int argc, char *argv[])
+{
+  while (1)
+    {
+      int c = getopt_long (argc, argv, "b:c:d:m:r:hVv", options, 0);
+
+      if (c == -1)
+	break;
+      else
+	switch (c)
+	  {
+	  case 'b':
+	    if (gp->boot_file)
+	      free (gp->boot_file);
+
+	    gp->boot_file = xstrdup (optarg);
+	    break;
+
+	  case 'c':
+	    if (gp->core_file)
+	      free (gp->core_file);
+
+	    gp->core_file = xstrdup (optarg);
+	    break;
+
+	  case 'd':
+	    if (gp->dir)
+	      free (gp->dir);
+
+	    gp->dir = xstrdup (optarg);
+	    break;
+
+	  case 'm':
+	    if (gp->dev_map)
+	      free (gp->dev_map);
+
+	    gp->dev_map = xstrdup (optarg);
+	    break;
+
+	  case 'r':
+	    if (gp->root_dev)
+	      free (gp->root_dev);
+
+	    gp->root_dev = xstrdup (optarg);
+	    break;
+
+	  case 'h':
+	    usage (0);
+	    break;
+
+	  case 'V':
+	    printf ("grub-setup (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
+	    return 0;
+
+	  case 'v':
+	    verbosity++;
+	    break;
+
+	  default:
+	    usage (1);
+	    break;
+	  }
+    }
+
+  if (verbosity > 1)
+    grub_env_set ("debug", "all");
+
+  if (optind >= argc)
+    {
+      fprintf (stderr, "No device is specified.\n");
+      usage (1);
+    }
+
+  if (optind + 1 != argc)
+    {
+      fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]);
+      usage (1);
+    }
+  return 1;
+}
+
+static char *
+get_device_name (char *dev)
+{
+  size_t len = strlen (dev);
+
+  if (dev[0] != '(' || dev[len - 1] != ')')
+    return 0;
+
+  dev[len - 1] = '\0';
+  return dev + 1;
+}
+
+static void
+find_dest_dev (struct grub_setup_info *gp, char *argv[])
+{
+  gp->dest_dev = get_device_name (argv[optind]);
+  if (! gp->dest_dev)
+    {
+      /* Possibly, the user specified an OS device file.  */
+      gp->dest_dev = grub_util_get_grub_dev (argv[optind]);
+      if (! gp->dest_dev)
+	{
+	  fprintf (stderr, "Invalid device `%s'.\n", argv[optind]);
+	  usage (1);
+	}
+      grub_util_info ("transformed OS device '%s' into GRUB device '%s'",
+		      argv[optind], gp->dest_dev);
+    }
+  else
+    {
+      /* For simplicity.  */
+      gp->dest_dev = xstrdup (gp->dest_dev);
+      grub_util_info ("Using '%s' as GRUB device", gp->dest_dev);
+    }
+}
+
+static void
+check_root_dev (struct grub_setup_info *gp)
+{
+  if (gp->root_dev)
+    {
+      char *tmp = get_device_name (gp->root_dev);
+
+      if (! tmp)
+	grub_util_error ("Invalid root device `%s'", gp->root_dev);
+
+      tmp = xstrdup (tmp);
+      free (gp->root_dev);
+      gp->root_dev = tmp;
+    }
+  else
+    {
+      char *dir = gp->dir ? gp->dir : DEFAULT_DIRECTORY;
+      char *root_device = grub_guess_root_device (dir);
+
+      gp->root_dev = grub_util_get_grub_dev (root_device);
+      if (! gp->root_dev)
+	{
+	  grub_util_info ("guessing the root device failed, because of `%s'",
+			  grub_errmsg);
+	  grub_util_error ("Cannot guess the root device. "
+			   "Specify the option ``--root-device''.");
+	}
+      grub_util_info ("Guessed root device '%s' and root_dev '%s' from "
+		      "dir '%s'", root_device, gp->root_dev, dir);
+    }
+}
+
+static void
+free_memory (struct grub_setup_info *gp)
+{
+  free (gp->boot_file);
+  free (gp->core_file);
+  free (gp->dir);
+  free (gp->dev_map);
+  free (gp->root_dev);
+  free (gp->prefix);
+  free (gp->dest_dev);
+}
+
+int
+main (int argc, char *argv[])
+{
+  struct grub_setup_info ginfo;
+
+  progname = "grub-setup";
+
+  init_info (&ginfo);
+  if (!parse_options (&ginfo, argc, argv))
+    return 0;
+
+  /* Initialize the emulated biosdisk driver.  */
+  grub_util_biosdisk_init (ginfo.dev_map ? ginfo.dev_map : DEFAULT_DEVICE_MAP);
+
+  /* Initialize all modules. */
+  grub_init_all ();
+
+  find_dest_dev (&ginfo, argv);
+
+  ginfo.prefix = grub_get_prefix (ginfo.dir ? : DEFAULT_DIRECTORY);
+
+  check_root_dev (&ginfo);
+
+  /* Do the real work.  */
+  setup (ginfo.prefix,
+	 ginfo.dir ? ginfo.dir : DEFAULT_DIRECTORY,
+	 ginfo.boot_file ? ginfo.boot_file : DEFAULT_BOOT_FILE,
+	 ginfo.core_file ? ginfo.core_file : DEFAULT_CORE_FILE,
+	 ginfo.root_dev, ginfo.dest_dev);
+
+  /* Free resources.  */
+  grub_fini_all ();
+
+  free_memory (&ginfo);
+
+  return 0;
+}
diff --git a/util/update-grub_lib.in b/util/update-grub_lib.in
new file mode 100644
index 0000000..998452e
--- /dev/null
+++ b/util/update-grub_lib.in
@@ -0,0 +1,23 @@
+# stub for new grub-mkconfig_lib
+# Copyright (C) 2007,2008  Free Software Foundation, Inc.
+#
+# GRUB 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 3 of the License, or
+# (at your option) any later version.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+
+. ${libdir}/grub/grub-mkconfig_lib
+
+grub_warn "update-grub_lib is deprecated, use grub-mkconfig_lib instead"
diff --git a/util/usb.c b/util/usb.c
new file mode 100644
index 0000000..a687eea
--- /dev/null
+++ b/util/usb.c
@@ -0,0 +1,195 @@
+/*  usb.c -- libusb USB support for GRUB.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <usb.h>
+#include <grub/usb.h>
+#include <grub/dl.h>
+
+
+static struct grub_usb_controller_dev usb_controller =
+{
+  .name = "libusb"
+};
+
+static struct grub_usb_device *grub_usb_devs[128];
+
+struct usb_bus *busses;
+
+static grub_err_t
+grub_libusb_devices (void)
+
+{
+  struct usb_bus *bus;
+  int last = 0;
+
+  busses = usb_get_busses();
+
+  for (bus = busses; bus; bus = bus->next)
+    {
+      struct usb_device *usbdev;
+      struct grub_usb_device *dev;
+
+      for (usbdev = bus->devices; usbdev; usbdev = usbdev->next)
+	{
+	  struct usb_device_descriptor *desc = &usbdev->descriptor;
+	  grub_err_t err;
+
+	  if (! desc->bcdUSB)
+	    continue;
+
+	  dev = grub_malloc (sizeof (*dev));
+	  if (! dev)
+	    return grub_errno;
+
+	  dev->data = usbdev;
+
+	  /* Fill in all descriptors.  */
+	  err = grub_usb_device_initialize (dev);
+	  if (err)
+	    {
+	      grub_errno = GRUB_ERR_NONE;
+	      continue;
+	    }
+
+	  /* Register the device.  */
+	  grub_usb_devs[last++] = dev;
+	}
+    }
+
+  return GRUB_USB_ERR_NONE;
+}
+
+
+int
+grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
+{
+  int i;
+
+  for (i = 0; i < 128; i++)
+    {
+      if (grub_usb_devs[i])
+	{
+	  if (hook (grub_usb_devs[i]))
+	      return 1;
+	}
+    }
+
+  return 0;
+}
+
+grub_usb_err_t
+grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused)))
+{
+  return GRUB_USB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype,
+		      grub_uint8_t request, grub_uint16_t value,
+		      grub_uint16_t index, grub_size_t size, char *data)
+{
+  usb_dev_handle *devh;
+  struct usb_device *d = dev->data;
+
+  devh = usb_open (d);
+  if (usb_control_msg (devh, reqtype, request,
+		       value, index, data, size, 20) < 0)
+    {
+      usb_close (devh);
+      return GRUB_USB_ERR_STALL;
+    }
+
+  usb_close (devh);
+
+  return GRUB_USB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_bulk_read (grub_usb_device_t dev,
+		    int endpoint, grub_size_t size, char *data)
+{
+  usb_dev_handle *devh;
+  struct usb_device *d = dev->data;
+
+  devh = usb_open (d);
+  if (usb_claim_interface (devh, 0) < 1)
+    {
+      usb_close (devh);
+      return GRUB_USB_ERR_STALL;
+    }
+
+  if (usb_bulk_read (devh, endpoint, data, size, 20) < 1)
+    {
+      usb_close (devh);
+      return GRUB_USB_ERR_STALL;
+    }
+
+  usb_release_interface (devh, 0);
+  usb_close (devh);
+
+  return GRUB_USB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_bulk_write (grub_usb_device_t dev,
+		     int endpoint, grub_size_t size, char *data)
+{
+  usb_dev_handle *devh;
+  struct usb_device *d = dev->data;
+
+  devh = usb_open (d);
+  if (usb_claim_interface (devh, 0) < 0)
+    goto fail;
+
+  if (usb_bulk_write (devh, endpoint, data, size, 20) < 0)
+    goto fail;
+
+  if (usb_release_interface (devh, 0) < 0)
+    goto fail;
+
+  usb_close (devh);
+
+  return GRUB_USB_ERR_NONE;
+
+ fail:
+  usb_close (devh);
+  return GRUB_USB_ERR_STALL;
+}
+
+GRUB_MOD_INIT (libusb)
+{
+  usb_init();
+  usb_find_busses();
+  usb_find_devices();
+
+  if (grub_libusb_devices ())
+    return;
+
+  grub_usb_controller_dev_register (&usb_controller);
+
+  return;
+}
+
+GRUB_MOD_FINI (libusb)
+{
+  return;
+}
diff --git a/video/bitmap.c b/video/bitmap.c
new file mode 100644
index 0000000..7b135a5
--- /dev/null
+++ b/video/bitmap.c
@@ -0,0 +1,253 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/video.h>
+#include <grub/bitmap.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+/* List of bitmap readers registered to system.  */
+static grub_video_bitmap_reader_t bitmap_readers_list;
+
+/* Register bitmap reader.  */
+void
+grub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader)
+{
+  reader->next = bitmap_readers_list;
+  bitmap_readers_list = reader;
+}
+
+/* Unregister bitmap reader.  */
+void
+grub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader)
+{
+  grub_video_bitmap_reader_t *p, q;
+
+  for (p = &bitmap_readers_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == reader)
+      {
+        *p = q->next;
+        break;
+      }
+}
+
+/* Creates new bitmap, saves created bitmap on success to *bitmap.  */
+grub_err_t
+grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
+                          unsigned int width, unsigned int height,
+                          enum grub_video_blit_format blit_format)
+{
+  struct grub_video_mode_info *mode_info;
+  unsigned int size;
+
+  if (!bitmap)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument.");
+
+  *bitmap = 0;
+
+  if (width == 0 || height == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument.");
+
+  *bitmap = (struct grub_video_bitmap *)grub_malloc (sizeof (struct grub_video_bitmap));
+  if (! *bitmap)
+    return grub_errno;
+
+  mode_info = &((*bitmap)->mode_info);
+
+  /* Populate mode_info.  */
+  mode_info->width = width;
+  mode_info->height = height;
+  mode_info->blit_format = blit_format;
+
+  switch (blit_format)
+    {
+      case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
+        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB
+                               | GRUB_VIDEO_MODE_TYPE_ALPHA;
+        mode_info->bpp = 32;
+        mode_info->bytes_per_pixel = 4;
+        mode_info->number_of_colors = 256;
+        mode_info->red_mask_size = 8;
+        mode_info->red_field_pos = 0;
+        mode_info->green_mask_size = 8;
+        mode_info->green_field_pos = 8;
+        mode_info->blue_mask_size = 8;
+        mode_info->blue_field_pos = 16;
+        mode_info->reserved_mask_size = 8;
+        mode_info->reserved_field_pos = 24;
+        break;
+
+      case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
+        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
+        mode_info->bpp = 24;
+        mode_info->bytes_per_pixel = 3;
+        mode_info->number_of_colors = 256;
+        mode_info->red_mask_size = 8;
+        mode_info->red_field_pos = 0;
+        mode_info->green_mask_size = 8;
+        mode_info->green_field_pos = 8;
+        mode_info->blue_mask_size = 8;
+        mode_info->blue_field_pos = 16;
+        mode_info->reserved_mask_size = 0;
+        mode_info->reserved_field_pos = 0;
+        break;
+
+      case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
+        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+        mode_info->bpp = 8;
+        mode_info->bytes_per_pixel = 1;
+        mode_info->number_of_colors = 256;
+        mode_info->red_mask_size = 0;
+        mode_info->red_field_pos = 0;
+        mode_info->green_mask_size = 0;
+        mode_info->green_field_pos = 0;
+        mode_info->blue_mask_size = 0;
+        mode_info->blue_field_pos = 0;
+        mode_info->reserved_mask_size = 0;
+        mode_info->reserved_field_pos = 0;
+        break;
+
+      default:
+        grub_free (*bitmap);
+        *bitmap = 0;
+
+        return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                           "Unsupported bitmap format");
+    }
+
+  mode_info->pitch = width * mode_info->bytes_per_pixel;
+
+  /* Calculate size needed for the data.  */
+  size = (width * mode_info->bytes_per_pixel) * height;
+
+  (*bitmap)->data = grub_zalloc (size);
+  if (! (*bitmap)->data)
+    {
+      grub_free (*bitmap);
+      *bitmap = 0;
+
+      return grub_errno;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Frees all resources allocated by bitmap.  */
+grub_err_t
+grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap)
+{
+  if (! bitmap)
+    return GRUB_ERR_NONE;
+
+  grub_free (bitmap->data);
+  grub_free (bitmap);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Match extension to filename.  */
+static int
+match_extension (const char *filename, const char *ext)
+{
+  int pos;
+  int ext_len;
+
+  pos = grub_strlen (filename);
+  ext_len = grub_strlen (ext);
+
+  if (! pos || ! ext_len || ext_len > pos)
+    return 0;
+
+  pos -= ext_len;
+
+  return grub_strcmp (filename + pos, ext) == 0;
+}
+
+/* Loads bitmap using registered bitmap readers.  */
+grub_err_t
+grub_video_bitmap_load (struct grub_video_bitmap **bitmap,
+                        const char *filename)
+{
+  grub_video_bitmap_reader_t reader = bitmap_readers_list;
+
+  if (!bitmap)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument.");
+
+  *bitmap = 0;
+
+  while (reader)
+    {
+      if (match_extension (filename, reader->extension))
+        return reader->reader (bitmap, filename);
+
+      reader = reader->next;
+    }
+
+  return grub_error(GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format");
+}
+
+/* Return bitmap width.  */
+unsigned int
+grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap)
+{
+  if (!bitmap)
+    return 0;
+
+  return bitmap->mode_info.width;
+}
+
+/* Return bitmap height.  */
+unsigned int
+grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap)
+{
+  if (!bitmap)
+    return 0;
+
+  return bitmap->mode_info.height;
+}
+
+/* Return mode info for bitmap.  */
+void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap,
+                                      struct grub_video_mode_info *mode_info)
+{
+  if (!bitmap)
+    return;
+
+  *mode_info = bitmap->mode_info;
+}
+
+/* Return pointer to bitmap's raw data.  */
+void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap)
+{
+  if (!bitmap)
+    return 0;
+
+  return bitmap->data;
+}
+
+/* Initialize bitmap module.  */
+GRUB_MOD_INIT(video_bitmap)
+{
+}
+
+/* Finalize bitmap module.  */
+GRUB_MOD_FINI(video_bitmap)
+{
+}
diff --git a/video/fb/fbblit.c b/video/fb/fbblit.c
new file mode 100644
index 0000000..a0f44d2
--- /dev/null
+++ b/video/fb/fbblit.c
@@ -0,0 +1,1415 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* SPECIAL NOTES!
+
+   Please note following when reading the code below:
+
+   - In this driver we assume that every memory can be accessed by same memory
+   bus.  If there are different address spaces do not use this code as a base
+   code for other archs.
+
+   - Every function in this code assumes that bounds checking has been done in
+   previous phase and they are opted out in here.  */
+
+#include <grub/video_fb.h>
+#include <grub/fbblit.h>
+#include <grub/fbutil.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+/* Generic replacing blitter (slow).  Works for every supported format.  */
+void
+grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
+			   struct grub_video_fbblit_info *src,
+			   int x, int y, int width, int height,
+			   int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t src_red;
+  grub_uint8_t src_green;
+  grub_uint8_t src_blue;
+  grub_uint8_t src_alpha;
+  grub_video_color_t src_color;
+  grub_video_color_t dst_color;
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+	{
+	  src_color = get_pixel (src, i + offset_x, j + offset_y);
+
+	  grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
+					 &src_blue, &src_alpha);
+
+	  dst_color = grub_video_fb_map_rgba (src_red, src_green,
+					      src_blue, src_alpha);
+
+	  set_pixel (dst, x + i, y + j, dst_color);
+	}
+    }
+}
+
+/* Block copy replacing blitter.  Works with modes multiple of 8 bits.  */
+void
+grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
+				   struct grub_video_fbblit_info *src,
+				   int x, int y, int width, int height,
+				   int offset_x, int offset_y)
+{
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint32_t *dstptr;
+  int bpp;
+
+  bpp = src->mode_info->bytes_per_pixel;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      grub_memmove (dstptr, srcptr, width * bpp);
+    }
+}
+
+/* Optimized replacing blitter for 1-bit to 32bit.  */
+void
+grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst,
+				      struct grub_video_fbblit_info *src,
+				      int x, int y,
+				      int width, int height,
+				      int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint32_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+				    src->mode_info->fg_green,
+				    src->mode_info->fg_blue,
+				    src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+				    src->mode_info->bg_green,
+				    src->mode_info->bg_blue,
+				    src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+	  if (*srcptr & srcmask)
+	    *(grub_uint32_t *) dstptr = fgcolor;
+	  else
+	    *(grub_uint32_t *) dstptr = bgcolor;
+	  srcmask >>= 1;
+	  if (!srcmask)
+	    {
+	      srcptr++;
+	      srcmask = 0x80;
+	    }
+
+	  dstptr += 4;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+	srcmask >>= srcrowskipbit;
+      else
+	{
+	  srcptr++;
+	  srcmask <<= 8 - srcrowskipbit;
+	}
+      dstptr += dstrowskip;
+    }
+}
+
+
+/* Optimized replacing blitter for 1-bit to 24-bit.  */
+void
+grub_video_fbblit_replace_24bit_1bit (struct grub_video_fbblit_info *dst,
+				      struct grub_video_fbblit_info *src,
+				      int x, int y,
+				      int width, int height,
+				      int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint32_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+				    src->mode_info->fg_green,
+				    src->mode_info->fg_blue,
+				    src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+				    src->mode_info->bg_green,
+				    src->mode_info->bg_blue,
+				    src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width - 1; i++)
+        {
+	  if (*srcptr & srcmask)
+	    *(grub_uint32_t *) dstptr = fgcolor;
+	  else
+	    *(grub_uint32_t *) dstptr = bgcolor;
+	  srcmask >>= 1;
+	  if (!srcmask)
+	    {
+	      srcptr++;
+	      srcmask = 0x80;
+	    }
+
+	  dstptr += 3;
+        }
+
+      if (*srcptr & srcmask)
+	{
+	  *dstptr++ = fgcolor & 0xff;
+	  *dstptr++ = (fgcolor & 0xff00) >> 8;
+	  *dstptr++ = (fgcolor & 0xff0000) >> 16;
+	}
+      else
+	{
+	  *dstptr++ = bgcolor & 0xff;
+	  *dstptr++ = (bgcolor & 0xff00) >> 8;
+	  *dstptr++ = (bgcolor & 0xff0000) >> 16;
+	}
+      srcmask >>= 1;
+      if (!srcmask)
+	{
+	  srcptr++;
+	  srcmask = 0x80;
+	}
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+	srcmask >>= srcrowskipbit;
+      else
+	{
+	  srcptr++;
+	  srcmask <<= 8 - srcrowskipbit;
+	}
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for 1-bit to 16-bit.  */
+void
+grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst,
+				      struct grub_video_fbblit_info *src,
+				      int x, int y,
+				      int width, int height,
+				      int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint16_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+				    src->mode_info->fg_green,
+				    src->mode_info->fg_blue,
+				    src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+				    src->mode_info->bg_green,
+				    src->mode_info->bg_blue,
+				    src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+	  if (*srcptr & srcmask)
+	    *(grub_uint16_t *) dstptr = fgcolor;
+	  else
+	    *(grub_uint16_t *) dstptr = bgcolor;
+	  srcmask >>= 1;
+	  if (!srcmask)
+	    {
+	      srcptr++;
+	      srcmask = 0x80;
+	    }
+
+	  dstptr += 2;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+	srcmask >>= srcrowskipbit;
+      else
+	{
+	  srcptr++;
+	  srcmask <<= 8 - srcrowskipbit;
+	}
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for 1-bit to 8-bit.  */
+void
+grub_video_fbblit_replace_8bit_1bit (struct grub_video_fbblit_info *dst,
+				      struct grub_video_fbblit_info *src,
+				      int x, int y,
+				      int width, int height,
+				      int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint8_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+				    src->mode_info->fg_green,
+				    src->mode_info->fg_blue,
+				    src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+				    src->mode_info->bg_green,
+				    src->mode_info->bg_blue,
+				    src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+	  if (*srcptr & srcmask)
+	    *(grub_uint8_t *) dstptr = fgcolor;
+	  else
+	    *(grub_uint8_t *) dstptr = bgcolor;
+	  srcmask >>= 1;
+	  if (!srcmask)
+	    {
+	      srcptr++;
+	      srcmask = 0x80;
+	    }
+
+	  dstptr++;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+	srcmask >>= srcrowskipbit;
+      else
+	{
+	  srcptr++;
+	  srcmask <<= 8 - srcrowskipbit;
+	}
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGBX8888 to BGRX8888.  */
+void
+grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
+					     struct grub_video_fbblit_info *src,
+					     int x, int y,
+					     int width, int height,
+					     int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint8_t r = *srcptr++;
+          grub_uint8_t g = *srcptr++;
+          grub_uint8_t b = *srcptr++;
+          grub_uint8_t a = *srcptr++;
+
+          *dstptr++ = b;
+          *dstptr++ = g;
+          *dstptr++ = r;
+          *dstptr++ = a;
+        }
+
+      srcptr += srcrowskip;
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGB888 to BGRX8888.  */
+void
+grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint8_t r = *srcptr++;
+          grub_uint8_t g = *srcptr++;
+          grub_uint8_t b = *srcptr++;
+
+          *dstptr++ = b;
+          *dstptr++ = g;
+          *dstptr++ = r;
+
+          /* Set alpha component as opaque.  */
+          *dstptr++ = 255;
+        }
+
+      srcptr += srcrowskip;
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGBX8888 to BGR888.  */
+void
+grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y)
+{
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+  int i;
+  int j;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint32_t color;
+          grub_uint8_t sr;
+          grub_uint8_t sg;
+          grub_uint8_t sb;
+
+          color = *srcptr++;
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          *dstptr++ = sb;
+          *dstptr++ = sg;
+          *dstptr++ = sr;
+        }
+
+      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGB888 to BGR888.  */
+void
+grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
+					 struct grub_video_fbblit_info *src,
+					 int x, int y,
+					 int width, int height,
+					 int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint8_t r = *srcptr++;
+          grub_uint8_t g = *srcptr++;
+          grub_uint8_t b = *srcptr++;
+
+          *dstptr++ = b;
+          *dstptr++ = g;
+          *dstptr++ = r;
+        }
+
+      srcptr += srcrowskip;
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGB888 to RGBX8888.  */
+void
+grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint32_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          sr = *srcptr++;
+          sg = *srcptr++;
+          sb = *srcptr++;
+
+          /* Set alpha as opaque.  */
+          color = 0xFF000000 | (sb << 16) | (sg << 8) | sr;
+
+          *dstptr++ = color;
+        }
+    }
+}
+
+/* Optimized replacing blitter for RGBX8888 to RGB888.  */
+void
+grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+	{
+	  color = *srcptr++;
+
+	  sr = (color >> 0) & 0xFF;
+	  sg = (color >> 8) & 0xFF;
+	  sb = (color >> 16) & 0xFF;
+
+	  *dstptr++ = sr;
+	  *dstptr++ = sg;
+	  *dstptr++ = sb;
+	}
+    }
+}
+
+/* Optimized replacing blitter for RGBX8888 to indexed color.  */
+void
+grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
+					  struct grub_video_fbblit_info *src,
+					  int x, int y,
+					  int width, int height,
+					  int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+	{
+	  color = *srcptr++;
+
+	  sr = (color >> 0) & 0xFF;
+	  sg = (color >> 8) & 0xFF;
+	  sb = (color >> 16) & 0xFF;
+
+	  color = grub_video_fb_map_rgb(sr, sg, sb);
+	  *dstptr++ = color & 0xFF;
+	}
+    }
+}
+
+/* Optimized replacing blitter for RGB888 to indexed color.  */
+void
+grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
+					struct grub_video_fbblit_info *src,
+					int x, int y,
+					int width, int height,
+					int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          sr = *srcptr++;
+          sg = *srcptr++;
+          sb = *srcptr++;
+
+          color = grub_video_fb_map_rgb(sr, sg, sb);
+
+          *dstptr++ = color & 0xFF;
+        }
+    }
+}
+
+/* Generic blending blitter.  Works for every supported format.  */
+void
+grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
+			 struct grub_video_fbblit_info *src,
+			 int x, int y, int width, int height,
+			 int offset_x, int offset_y)
+{
+  int i;
+  int j;
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint8_t src_red;
+          grub_uint8_t src_green;
+          grub_uint8_t src_blue;
+          grub_uint8_t src_alpha;
+          grub_uint8_t dst_red;
+          grub_uint8_t dst_green;
+          grub_uint8_t dst_blue;
+          grub_uint8_t dst_alpha;
+          grub_video_color_t src_color;
+          grub_video_color_t dst_color;
+
+          src_color = get_pixel (src, i + offset_x, j + offset_y);
+          grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
+					 &src_blue, &src_alpha);
+
+          if (src_alpha == 0)
+            continue;
+
+          if (src_alpha == 255)
+            {
+              dst_color = grub_video_fb_map_rgba (src_red, src_green,
+						  src_blue, src_alpha);
+              set_pixel (dst, x + i, y + j, dst_color);
+              continue;
+            }
+
+          dst_color = get_pixel (dst, x + i, y + j);
+
+          grub_video_fb_unmap_color_int (dst, dst_color, &dst_red,
+					 &dst_green, &dst_blue, &dst_alpha);
+
+          dst_red = (((src_red * src_alpha)
+                      + (dst_red * (255 - src_alpha))) / 255);
+          dst_green = (((src_green * src_alpha)
+                        + (dst_green * (255 - src_alpha))) / 255);
+          dst_blue = (((src_blue * src_alpha)
+                       + (dst_blue * (255 - src_alpha))) / 255);
+
+          dst_alpha = src_alpha;
+          dst_color = grub_video_fb_map_rgba (dst_red, dst_green, dst_blue,
+					      dst_alpha);
+
+          set_pixel (dst, x + i, y + j, dst_color);
+        }
+    }
+}
+
+/* Optimized blending blitter for RGBA8888 to BGRA8888.  */
+void
+grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y)
+{
+  grub_uint32_t *srcptr;
+  grub_uint32_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+  int i;
+  int j;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint32_t color;
+          unsigned int sr;
+          unsigned int sg;
+          unsigned int sb;
+          unsigned int a;
+          unsigned int dr;
+          unsigned int dg;
+          unsigned int db;
+
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              /* Skip transparent source pixels.  */
+              dstptr++;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              /* Opaque pixel shortcut.  */
+              dr = sr;
+              dg = sg;
+              db = sb;
+            }
+          else
+            {
+              /* General pixel color blending.  */
+              color = *dstptr;
+
+              dr = (color >> 16) & 0xFF;
+              dr = (dr * (255 - a) + sr * a) / 255;
+              dg = (color >> 8) & 0xFF;
+              dg = (dg * (255 - a) + sg * a) / 255;
+              db = (color >> 0) & 0xFF;
+              db = (db * (255 - a) + sb * a) / 255;
+            }
+
+          color = (a << 24) | (dr << 16) | (dg << 8) | db;
+
+          *dstptr++ = color;
+        }
+
+      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
+      dstptr = (grub_uint32_t *) (((grub_uint8_t *) dstptr) + dstrowskip);
+    }
+}
+
+/* Optimized blending blitter for RGBA8888 to BGR888.  */
+void
+grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					 struct grub_video_fbblit_info *src,
+					 int x, int y,
+					 int width, int height,
+					 int offset_x, int offset_y)
+{
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+  int i;
+  int j;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint32_t color;
+          unsigned int sr;
+          unsigned int sg;
+          unsigned int sb;
+          unsigned int a;
+          unsigned int dr;
+          unsigned int dg;
+          unsigned int db;
+
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              /* Skip transparent source pixels.  */
+              dstptr += 3;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              /* Opaque pixel shortcut.  */
+              dr = sr;
+              dg = sg;
+              db = sb;
+            }
+          else
+            {
+              /* General pixel color blending.  */
+              color = *dstptr;
+
+              db = dstptr[0];
+              db = (db * (255 - a) + sb * a) / 255;
+              dg = dstptr[1];
+              dg = (dg * (255 - a) + sg * a) / 255;
+              dr = dstptr[2];
+              dr = (dr * (255 - a) + sr * a) / 255;
+            }
+
+          *dstptr++ = db;
+          *dstptr++ = dg;
+          *dstptr++ = dr;
+        }
+
+      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized blending blitter for RGBA888 to RGBA8888.  */
+void
+grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					   struct grub_video_fbblit_info *src,
+					   int x, int y,
+					   int width, int height,
+					   int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint32_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+  unsigned int a;
+  unsigned int dr;
+  unsigned int dg;
+  unsigned int db;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              dstptr++;
+              continue;
+            }
+
+          if (a == 255)
+            {
+              *dstptr++ = color;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          color = *dstptr;
+
+          dr = (color >> 0) & 0xFF;
+          dg = (color >> 8) & 0xFF;
+          db = (color >> 16) & 0xFF;
+
+          dr = (dr * (255 - a) + sr * a) / 255;
+          dg = (dg * (255 - a) + sg * a) / 255;
+          db = (db * (255 - a) + sb * a) / 255;
+
+          color = (a << 24) | (db << 16) | (dg << 8) | dr;
+
+          *dstptr++ = color;
+        }
+    }
+}
+
+/* Optimized blending blitter for RGBA8888 to RGB888.  */
+void
+grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
+					 struct grub_video_fbblit_info *src,
+					 int x, int y,
+					 int width, int height,
+					 int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+  unsigned int a;
+  unsigned int dr;
+  unsigned int dg;
+  unsigned int db;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              dstptr += 3;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              *dstptr++ = sr;
+              *dstptr++ = sg;
+              *dstptr++ = sb;
+
+              continue;
+            }
+
+          dr = dstptr[0];
+          dg = dstptr[1];
+          db = dstptr[2];
+
+          dr = (dr * (255 - a) + sr * a) / 255;
+          dg = (dg * (255 - a) + sg * a) / 255;
+          db = (db * (255 - a) + sb * a) / 255;
+
+          *dstptr++ = dr;
+          *dstptr++ = dg;
+          *dstptr++ = db;
+        }
+    }
+}
+
+/* Optimized blending blitter for RGBA8888 to indexed color.  */
+void
+grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
+					struct grub_video_fbblit_info *src,
+					int x, int y,
+					int width, int height,
+					int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+  unsigned int a;
+  unsigned char dr;
+  unsigned char dg;
+  unsigned char db;
+  unsigned char da;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              dstptr++;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              color = grub_video_fb_map_rgb(sr, sg, sb);
+              *dstptr++ = color & 0xFF;
+              continue;
+            }
+
+          grub_video_fb_unmap_color_int (dst, *dstptr, &dr, &dg, &db, &da);
+
+          dr = (dr * (255 - a) + sr * a) / 255;
+          dg = (dg * (255 - a) + sg * a) / 255;
+          db = (db * (255 - a) + sb * a) / 255;
+
+          color = grub_video_fb_map_rgb(dr, dg, db);
+
+          *dstptr++ = color & 0xFF;
+        }
+    }
+}
+
+/* Optimized blending blitter for 1-bit to XXXA8888.  */
+void
+grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst,
+				       struct grub_video_fbblit_info *src,
+				       int x, int y,
+				       int width, int height,
+				       int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint32_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+				    src->mode_info->fg_green,
+				    src->mode_info->fg_blue,
+				    src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+				    src->mode_info->bg_green,
+				    src->mode_info->bg_blue,
+				    src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+	  grub_uint32_t color;
+	  grub_uint8_t a;
+
+	  if (*srcptr & srcmask)
+	    color = fgcolor;
+	  else
+	    color = bgcolor;
+	  a = (color >> 24) & 0xff;
+
+	  if (a == 255)
+	    *(grub_uint32_t *) dstptr = color;
+	  else if (a != 0)
+	    {
+	      grub_uint8_t s1 = (color >> 0) & 0xFF;
+	      grub_uint8_t s2 = (color >> 8) & 0xFF;
+	      grub_uint8_t s3 = (color >> 16) & 0xFF;
+
+	      grub_uint8_t d1 = (*(grub_uint32_t *) dstptr >> 0) & 0xFF;
+	      grub_uint8_t d2 = (*(grub_uint32_t *) dstptr >> 8) & 0xFF;
+	      grub_uint8_t d3 = (*(grub_uint32_t *) dstptr >> 16) & 0xFF;
+
+	      d1 = (d1 * (255 - a) + s1 * a) / 255;
+	      d2 = (d2 * (255 - a) + s2 * a) / 255;
+	      d3 = (d3 * (255 - a) + s3 * a) / 255;
+
+	      *(grub_uint32_t *) dstptr = (a << 24) | (d3 << 16) | (d2 << 8)
+		| d1;
+	    }
+
+	  srcmask >>= 1;
+	  if (!srcmask)
+	    {
+	      srcptr++;
+	      srcmask = 0x80;
+	    }
+
+	  dstptr += 4;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+	srcmask >>= srcrowskipbit;
+      else
+	{
+	  srcptr++;
+	  srcmask <<= 8 - srcrowskipbit;
+	}
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized blending blitter for 1-bit to XXX888.  */
+void
+grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst,
+				     struct grub_video_fbblit_info *src,
+				     int x, int y,
+				     int width, int height,
+				     int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint32_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+				    src->mode_info->fg_green,
+				    src->mode_info->fg_blue,
+				    src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+				    src->mode_info->bg_green,
+				    src->mode_info->bg_blue,
+				    src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+	  grub_uint32_t color;
+	  grub_uint8_t a;
+	  if (*srcptr & srcmask)
+	    {
+	      color = fgcolor;
+	      a = src->mode_info->fg_alpha;
+	    }
+	  else
+	    {
+	      color = bgcolor;
+	      a = src->mode_info->bg_alpha;
+	    }
+
+	  if (a == 255)
+	    {
+	      ((grub_uint8_t *) dstptr)[0] = color & 0xff;
+	      ((grub_uint8_t *) dstptr)[1] = (color & 0xff00) >> 8;
+	      ((grub_uint8_t *) dstptr)[2] = (color & 0xff0000) >> 16;
+	    }
+	  else if (a != 0)
+	    {
+	      grub_uint8_t s1 = (color >> 0) & 0xFF;
+	      grub_uint8_t s2 = (color >> 8) & 0xFF;
+	      grub_uint8_t s3 = (color >> 16) & 0xFF;
+
+	      grub_uint8_t d1 = (*(grub_uint32_t *) dstptr >> 0) & 0xFF;
+	      grub_uint8_t d2 = (*(grub_uint32_t *) dstptr >> 8) & 0xFF;
+	      grub_uint8_t d3 = (*(grub_uint32_t *) dstptr >> 16) & 0xFF;
+
+	      ((grub_uint8_t *) dstptr)[0] = (d1 * (255 - a) + s1 * a) / 255;
+	      ((grub_uint8_t *) dstptr)[1] = (d2 * (255 - a) + s2 * a) / 255;
+	      ((grub_uint8_t *) dstptr)[2] = (d3 * (255 - a) + s3 * a) / 255;
+	    }
+
+	  srcmask >>= 1;
+	  if (!srcmask)
+	    {
+	      srcptr++;
+	      srcmask = 0x80;
+	    }
+
+	  dstptr += 3;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+	srcmask >>= srcrowskipbit;
+      else
+	{
+	  srcptr++;
+	  srcmask <<= 8 - srcrowskipbit;
+	}
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized blending blitter for 1-bit to XXX888.  */
+void
+grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst,
+				     struct grub_video_fbblit_info *src,
+				     int x, int y,
+				     int width, int height,
+				     int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint16_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+				    src->mode_info->fg_green,
+				    src->mode_info->fg_blue,
+				    src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+				    src->mode_info->bg_green,
+				    src->mode_info->bg_blue,
+				    src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+	  grub_uint32_t color;
+	  grub_uint8_t a;
+	  if (*srcptr & srcmask)
+	    {
+	      color = fgcolor;
+	      a = src->mode_info->fg_alpha;
+	    }
+	  else
+	    {
+	      color = bgcolor;
+	      a = src->mode_info->bg_alpha;
+	    }
+
+	  if (a == 255)
+	    *(grub_uint16_t *) dstptr = color;
+	  else if (a != 0)
+	    {
+	      grub_uint8_t s1 = (color >> 0) & 0x1F;
+	      grub_uint8_t s2 = (color >> 5) & 0x3F;
+	      grub_uint8_t s3 = (color >> 11) & 0x1F;
+
+	      grub_uint8_t d1 = (*(grub_uint16_t *) dstptr >> 0) & 0x1F;
+	      grub_uint8_t d2 = (*(grub_uint16_t *) dstptr >> 5) & 0x3F;
+	      grub_uint8_t d3 = (*(grub_uint16_t *) dstptr >> 11) & 0x1F;
+
+	      d1 = (d1 * (255 - a) + s1 * a) / 255;
+	      d2 = (d2 * (255 - a) + s2 * a) / 255;
+	      d3 = (d3 * (255 - a) + s3 * a) / 255;
+
+	      *(grub_uint16_t *) dstptr = (d1 & 0x1f) | ((d2 & 0x3f) << 5)
+		| ((d3 & 0x1f) << 11);
+	    }
+
+	  srcmask >>= 1;
+	  if (!srcmask)
+	    {
+	      srcptr++;
+	      srcmask = 0x80;
+	    }
+
+	  dstptr += 2;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+	srcmask >>= srcrowskipbit;
+      else
+	{
+	  srcptr++;
+	  srcmask <<= 8 - srcrowskipbit;
+	}
+      dstptr += dstrowskip;
+    }
+}
diff --git a/video/fb/fbfill.c b/video/fb/fbfill.c
new file mode 100644
index 0000000..a4ca7c2
--- /dev/null
+++ b/video/fb/fbfill.c
@@ -0,0 +1,177 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* SPECIAL NOTES!
+
+   Please note following when reading the code below:
+
+   - In this driver we assume that every memory can be accessed by same memory
+     bus.  If there are different address spaces do not use this code as a base
+     code for other archs.
+
+   - Every function in this code assumes that bounds checking has been done in
+     previous phase and they are opted out in here.  */
+
+#include <grub/video_fb.h>
+#include <grub/fbfill.h>
+#include <grub/fbutil.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+/* Generic filler that works for every supported mode.  */
+void
+grub_video_fbfill (struct grub_video_fbblit_info *dst,
+		   grub_video_color_t color, int x, int y,
+		   int width, int height)
+{
+  int i;
+  int j;
+
+  for (j = 0; j < height; j++)
+    for (i = 0; i < width; i++)
+      set_pixel (dst, x + i, y + j, color);
+}
+
+/* Optimized filler for direct color 32 bit modes.  It is assumed that color
+   is already mapped to destination format.  */
+void
+grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst,
+			    grub_video_color_t color, int x, int y,
+			    int width, int height)
+{
+  int i;
+  int j;
+  grub_uint32_t *dstptr;
+  grub_size_t rowskip;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  /* Get the start address.  */
+  dstptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        *dstptr++ = color;
+
+      /* Advance the dest pointer to the right location on the next line.  */
+      dstptr = (grub_uint32_t *) (((char *) dstptr) + rowskip);
+    }
+}
+
+/* Optimized filler for direct color 24 bit modes.  It is assumed that color
+   is already mapped to destination format.  */
+void
+grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst,
+			    grub_video_color_t color, int x, int y,
+			    int width, int height)
+{
+  int i;
+  int j;
+  grub_size_t rowskip;
+  grub_uint8_t *dstptr;
+  grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
+  grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
+  grub_uint8_t fill2 = (grub_uint8_t)((color >> 16) & 0xFF);
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  /* Get the start address.  */
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          *dstptr++ = fill0;
+          *dstptr++ = fill1;
+          *dstptr++ = fill2;
+        }
+
+      /* Advance the dest pointer to the right location on the next line.  */
+      dstptr += rowskip;
+    }
+}
+
+/* Optimized filler for direct color 16 bit modes.  It is assumed that color
+   is already mapped to destination format.  */
+void
+grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
+			    grub_video_color_t color, int x, int y,
+			    int width, int height)
+{
+  int i;
+  int j;
+  grub_size_t rowskip;
+  grub_uint8_t *dstptr;
+  grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
+  grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  /* Get the start address.  */
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          *dstptr++ = fill0;
+          *dstptr++ = fill1;
+        }
+
+      /* Advance the dest pointer to the right location on the next line.  */
+      dstptr += rowskip;
+    }
+}
+
+/* Optimized filler for index color.  It is assumed that color
+   is already mapped to destination format.  */
+void
+grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst,
+			   grub_video_color_t color, int x, int y,
+			   int width, int height)
+{
+  int i;
+  int j;
+  grub_size_t rowskip;
+  grub_uint8_t *dstptr;
+  grub_uint8_t fill = (grub_uint8_t)color & 0xFF;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  /* Get the start address.  */
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        *dstptr++ = fill;
+
+      /* Advance the dest pointer to the right location on the next line.  */
+      dstptr += rowskip;
+    }
+}
diff --git a/video/fb/fbutil.c b/video/fb/fbutil.c
new file mode 100644
index 0000000..511beaa
--- /dev/null
+++ b/video/fb/fbutil.c
@@ -0,0 +1,178 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* SPECIAL NOTES!
+
+   Please note following when reading the code below:
+
+   - In this driver we assume that every memory can be accessed by same memory
+     bus.  If there are different address spaces do not use this code as a base
+     code for other archs.
+
+   - Every function in this code assumes that bounds checking has been done in
+     previous phase and they are opted out in here.  */
+
+#include <grub/fbutil.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+grub_uint8_t *
+grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
+              unsigned int x, unsigned int y)
+{
+  grub_uint8_t *ptr = 0;
+
+  switch (source->mode_info->bpp)
+    {
+    case 32:
+      ptr = source->data + y * source->mode_info->pitch + x * 4;
+      break;
+
+    case 24:
+      ptr = source->data + y * source->mode_info->pitch + x * 3;
+      break;
+
+    case 16:
+    case 15:
+      ptr = source->data + y * source->mode_info->pitch + x * 2;
+      break;
+
+    case 8:
+      ptr = source->data + y * source->mode_info->pitch + x;
+      break;
+
+    case 1:
+      /* For 1-bit bitmaps, addressing needs to be done at the bit level
+         and it doesn't make sense, in general, to ask for a pointer
+         to a particular pixel's data.  */
+      break;
+    }
+
+  return ptr;
+}
+
+grub_video_color_t
+get_pixel (struct grub_video_fbblit_info *source,
+           unsigned int x, unsigned int y)
+{
+  grub_video_color_t color = 0;
+
+  switch (source->mode_info->bpp)
+    {
+    case 32:
+      color = *(grub_uint32_t *)grub_video_fb_get_video_ptr (source, x, y);
+      break;
+
+    case 24:
+      {
+        grub_uint8_t *ptr;
+        ptr = grub_video_fb_get_video_ptr (source, x, y);
+        color = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16);
+      }
+      break;
+
+    case 16:
+    case 15:
+      color = *(grub_uint16_t *)grub_video_fb_get_video_ptr (source, x, y);
+      break;
+
+    case 8:
+      color = *(grub_uint8_t *)grub_video_fb_get_video_ptr (source, x, y);
+      break;
+
+    case 1:
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+        {
+          int bit_index = y * source->mode_info->width + x;
+          grub_uint8_t *ptr = source->data + bit_index / 8;
+          int bit_pos = 7 - bit_index % 8;
+          color = (*ptr >> bit_pos) & 0x01;
+        }
+      break;
+
+    default:
+      break;
+    }
+
+  return color;
+}
+
+void
+set_pixel (struct grub_video_fbblit_info *source,
+           unsigned int x, unsigned int y, grub_video_color_t color)
+{
+  switch (source->mode_info->bpp)
+    {
+    case 32:
+      {
+        grub_uint32_t *ptr;
+
+        ptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (source, x, y);
+
+        *ptr = color;
+      }
+      break;
+
+    case 24:
+      {
+        grub_uint8_t *ptr;
+        grub_uint8_t *colorptr = (grub_uint8_t *)&color;
+
+        ptr = grub_video_fb_get_video_ptr (source, x, y);
+
+        ptr[0] = colorptr[0];
+        ptr[1] = colorptr[1];
+        ptr[2] = colorptr[2];
+      }
+      break;
+
+    case 16:
+    case 15:
+      {
+        grub_uint16_t *ptr;
+
+        ptr = (grub_uint16_t *)grub_video_fb_get_video_ptr (source, x, y);
+
+        *ptr = (grub_uint16_t) (color & 0xFFFF);
+      }
+      break;
+
+    case 8:
+      {
+        grub_uint8_t *ptr;
+
+        ptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (source, x, y);
+
+        *ptr = (grub_uint8_t) (color & 0xFF);
+      }
+      break;
+
+    case 1:
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+        {
+          int bit_index = y * source->mode_info->width + x;
+          grub_uint8_t *ptr = source->data + bit_index / 8;
+          int bit_pos = 7 - bit_index % 8;
+          *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
+        }
+      break;
+
+    default:
+      break;
+    }
+}
diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c
new file mode 100644
index 0000000..5f2917d
--- /dev/null
+++ b/video/fb/video_fb.c
@@ -0,0 +1,1184 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/video.h>
+#include <grub/video_fb.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/fbblit.h>
+#include <grub/fbfill.h>
+#include <grub/fbutil.h>
+#include <grub/bitmap.h>
+
+static struct grub_video_fbrender_target *render_target;
+struct grub_video_palette_data *palette;
+static unsigned int palette_size;
+
+/* Specify "standard" VGA palette, some video cards may
+   need this and this will also be used when using RGB modes.  */
+struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS] =
+  {
+    // {R, G, B, A}
+    {0x00, 0x00, 0x00, 0xFF}, // 0 = black
+    {0x00, 0x00, 0xA8, 0xFF}, // 1 = blue
+    {0x00, 0xA8, 0x00, 0xFF}, // 2 = green
+    {0x00, 0xA8, 0xA8, 0xFF}, // 3 = cyan
+    {0xA8, 0x00, 0x00, 0xFF}, // 4 = red
+    {0xA8, 0x00, 0xA8, 0xFF}, // 5 = magenta
+    {0xA8, 0x54, 0x00, 0xFF}, // 6 = brown
+    {0xA8, 0xA8, 0xA8, 0xFF}, // 7 = light gray
+
+    {0x54, 0x54, 0x54, 0xFF}, // 8 = dark gray
+    {0x54, 0x54, 0xFE, 0xFF}, // 9 = bright blue
+    {0x54, 0xFE, 0x54, 0xFF}, // 10 = bright green
+    {0x54, 0xFE, 0xFE, 0xFF}, // 11 = bright cyan
+    {0xFE, 0x54, 0x54, 0xFF}, // 12 = bright red
+    {0xFE, 0x54, 0xFE, 0xFF}, // 13 = bright magenta
+    {0xFE, 0xFE, 0x54, 0xFF}, // 14 = yellow
+    {0xFE, 0xFE, 0xFE, 0xFF}  // 15 = white
+  };
+
+grub_err_t
+grub_video_fb_init (void)
+{
+  grub_free (palette);
+  render_target = 0;
+  palette = 0;
+  palette_size = 0;
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_fini (void)
+{
+  grub_free (palette);
+  render_target = 0;
+  palette = 0;
+  palette_size = 0;
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_info (struct grub_video_mode_info *mode_info)
+{
+  /* Copy mode info from active render target.  */
+  grub_memcpy (mode_info, &render_target->mode_info,
+               sizeof (struct grub_video_mode_info));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_palette (unsigned int start, unsigned int count,
+			   struct grub_video_palette_data *palette_data)
+{
+  unsigned int i;
+
+  /* Assume that we know everything from index color palette.  */
+  for (i = 0; (i < count) && ((i + start) < palette_size); i++)
+    palette_data[i] = palette[start + i];
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_set_palette (unsigned int start, unsigned int count,
+			   struct grub_video_palette_data *palette_data)
+{
+  unsigned i;
+  if (start + count > palette_size)
+    {
+      palette_size = start + count;
+      palette = grub_realloc (palette, sizeof (palette[0]) * palette_size);
+      if (!palette)
+	{
+	  grub_video_fb_fini ();
+	  return grub_errno;
+	}
+    }
+  for (i = 0; (i < count) && ((i + start) < palette_size); i++)
+    palette[start + i] = palette_data[i];
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_set_viewport (unsigned int x, unsigned int y,
+			    unsigned int width, unsigned int height)
+{
+  /* Make sure viewport is withing screen dimensions.  If viewport was set
+     to be out of the region, mark its size as zero.  */
+  if (x > render_target->mode_info.width)
+    {
+      x = 0;
+      width = 0;
+    }
+
+  if (y > render_target->mode_info.height)
+    {
+      y = 0;
+      height = 0;
+    }
+
+  if (x + width > render_target->mode_info.width)
+    width = render_target->mode_info.width - x;
+
+  if (y + height > render_target->mode_info.height)
+    height = render_target->mode_info.height - y;
+
+  render_target->viewport.x = x;
+  render_target->viewport.y = y;
+  render_target->viewport.width = width;
+  render_target->viewport.height = height;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_viewport (unsigned int *x, unsigned int *y,
+			    unsigned int *width, unsigned int *height)
+{
+  if (x) *x = render_target->viewport.x;
+  if (y) *y = render_target->viewport.y;
+  if (width) *width = render_target->viewport.width;
+  if (height) *height = render_target->viewport.height;
+
+  return GRUB_ERR_NONE;
+}
+
+/* Maps color name to target optimized color format.  */
+grub_video_color_t
+grub_video_fb_map_color (grub_uint32_t color_name)
+{
+  /* TODO: implement color theme mapping code.  */
+
+  if (color_name < palette_size)
+    {
+      if ((render_target->mode_info.mode_type
+           & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+        return color_name;
+      else
+        {
+          grub_video_color_t color;
+
+          color = grub_video_fb_map_rgb (palette[color_name].r,
+					 palette[color_name].g,
+					 palette[color_name].b);
+
+          return color;
+        }
+    }
+
+  return 0;
+}
+
+/* Maps RGB to target optimized color format.  */
+grub_video_color_t
+grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green,
+		       grub_uint8_t blue)
+{
+  if ((render_target->mode_info.mode_type
+       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+    {
+      int minindex = 0;
+      int delta = 0;
+      int tmp;
+      int val;
+      unsigned i;
+
+      /* Find best matching color.  */
+      for (i = 0; i < palette_size; i++)
+        {
+          val = palette[i].r - red;
+          tmp = val * val;
+          val = palette[i].g - green;
+          tmp += val * val;
+          val = palette[i].b - blue;
+          tmp += val * val;
+
+          if (i == 0)
+            delta = tmp;
+
+          if (tmp < delta)
+            {
+              delta = tmp;
+              minindex = i;
+              if (tmp == 0)
+                break;
+            }
+        }
+
+      return minindex;
+    }
+  else if ((render_target->mode_info.mode_type
+            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+    {
+       if (red == render_target->mode_info.fg_red
+           && green == render_target->mode_info.fg_green
+           && blue == render_target->mode_info.fg_blue)
+         return 1;
+       else
+         return 0;
+    }
+  else
+    {
+      grub_uint32_t value;
+      grub_uint8_t alpha = 255; /* Opaque color.  */
+
+      red >>= 8 - render_target->mode_info.red_mask_size;
+      green >>= 8 - render_target->mode_info.green_mask_size;
+      blue >>= 8 - render_target->mode_info.blue_mask_size;
+      alpha >>= 8 - render_target->mode_info.reserved_mask_size;
+
+      value = red << render_target->mode_info.red_field_pos;
+      value |= green << render_target->mode_info.green_field_pos;
+      value |= blue << render_target->mode_info.blue_field_pos;
+      value |= alpha << render_target->mode_info.reserved_field_pos;
+
+      return value;
+    }
+
+}
+
+/* Maps RGBA to target optimized color format.  */
+grub_video_color_t
+grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
+			grub_uint8_t blue, grub_uint8_t alpha)
+{
+  if ((render_target->mode_info.mode_type
+       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+    /* No alpha available in index color modes, just use
+       same value as in only RGB modes.  */
+    return grub_video_fb_map_rgb (red, green, blue);
+  else if ((render_target->mode_info.mode_type
+            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+    {
+      if (red == render_target->mode_info.fg_red
+          && green == render_target->mode_info.fg_green
+          && blue == render_target->mode_info.fg_blue
+          && alpha == render_target->mode_info.fg_alpha)
+        return 1;
+      else
+        return 0;
+    }
+  else
+    {
+      grub_uint32_t value;
+
+      red >>= 8 - render_target->mode_info.red_mask_size;
+      green >>= 8 - render_target->mode_info.green_mask_size;
+      blue >>= 8 - render_target->mode_info.blue_mask_size;
+      alpha >>= 8 - render_target->mode_info.reserved_mask_size;
+
+      value = red << render_target->mode_info.red_field_pos;
+      value |= green << render_target->mode_info.green_field_pos;
+      value |= blue << render_target->mode_info.blue_field_pos;
+      value |= alpha << render_target->mode_info.reserved_field_pos;
+
+      return value;
+    }
+}
+
+/* Splits target optimized format to components.  */
+grub_err_t
+grub_video_fb_unmap_color (grub_video_color_t color,
+			   grub_uint8_t *red, grub_uint8_t *green,
+			   grub_uint8_t *blue, grub_uint8_t *alpha)
+{
+  struct grub_video_fbblit_info target_info;
+
+  target_info.mode_info = &render_target->mode_info;
+  target_info.data = render_target->data;
+
+  grub_video_fb_unmap_color_int (&target_info, color, red, green, blue, alpha);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Splits color in source format to components.  */
+void
+grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
+			       grub_video_color_t color,
+			       grub_uint8_t *red, grub_uint8_t *green,
+			       grub_uint8_t *blue, grub_uint8_t *alpha)
+{
+  struct grub_video_mode_info *mode_info;
+  mode_info = source->mode_info;
+
+  if ((mode_info->mode_type
+       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+    {
+      /* If we have an out-of-bounds color, return transparent black.  */
+      if (color > 255)
+        {
+          *red = 0;
+          *green = 0;
+          *blue = 0;
+          *alpha = 0;
+          return;
+        }
+
+      *red = palette[color].r;
+      *green = palette[color].g;
+      *blue = palette[color].b;
+      *alpha = palette[color].a;
+      return;
+    }
+  else if ((mode_info->mode_type
+            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+    {
+      if (color & 1)
+        {
+          *red = mode_info->fg_red;
+          *green = mode_info->fg_green;
+          *blue = mode_info->fg_blue;
+          *alpha = mode_info->fg_alpha;
+        }
+      else
+        {
+          *red = mode_info->bg_red;
+          *green = mode_info->bg_green;
+          *blue = mode_info->bg_blue;
+          *alpha = mode_info->bg_alpha;
+        }
+    }
+  else
+    {
+      grub_uint32_t tmp;
+
+      /* Get red component.  */
+      tmp = color >> mode_info->red_field_pos;
+      tmp &= (1 << mode_info->red_mask_size) - 1;
+      tmp <<= 8 - mode_info->red_mask_size;
+      tmp |= (1 << (8 - mode_info->red_mask_size)) - 1;
+      *red = tmp & 0xFF;
+
+      /* Get green component.  */
+      tmp = color >> mode_info->green_field_pos;
+      tmp &= (1 << mode_info->green_mask_size) - 1;
+      tmp <<= 8 - mode_info->green_mask_size;
+      tmp |= (1 << (8 - mode_info->green_mask_size)) - 1;
+      *green = tmp & 0xFF;
+
+      /* Get blue component.  */
+      tmp = color >> mode_info->blue_field_pos;
+      tmp &= (1 << mode_info->blue_mask_size) - 1;
+      tmp <<= 8 - mode_info->blue_mask_size;
+      tmp |= (1 << (8 - mode_info->blue_mask_size)) - 1;
+      *blue = tmp & 0xFF;
+
+      /* Get alpha component.  */
+      if (source->mode_info->reserved_mask_size > 0)
+        {
+          tmp = color >> mode_info->reserved_field_pos;
+          tmp &= (1 << mode_info->reserved_mask_size) - 1;
+          tmp <<= 8 - mode_info->reserved_mask_size;
+          tmp |= (1 << (8 - mode_info->reserved_mask_size)) - 1;
+        }
+      else
+        /* If there is no alpha component, assume it opaque.  */
+        tmp = 255;
+
+      *alpha = tmp & 0xFF;
+    }
+}
+
+grub_err_t
+grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
+			 unsigned int width, unsigned int height)
+{
+  struct grub_video_fbblit_info target;
+
+  /* Make sure there is something to do.  */
+  if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
+    return GRUB_ERR_NONE;
+  if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
+    return GRUB_ERR_NONE;
+
+  /* Do not allow drawing out of viewport.  */
+  if (x < 0)
+    {
+      width += x;
+      x = 0;
+    }
+  if (y < 0)
+    {
+      height += y;
+      y = 0;
+    }
+
+  if ((x + width) > render_target->viewport.width)
+    width = render_target->viewport.width - x;
+  if ((y + height) > render_target->viewport.height)
+    height = render_target->viewport.height - y;
+
+  /* Add viewport offset.  */
+  x += render_target->viewport.x;
+  y += render_target->viewport.y;
+
+  /* Use fbblit_info to encapsulate rendering.  */
+  target.mode_info = &render_target->mode_info;
+  target.data = render_target->data;
+
+  /* Try to figure out more optimized version.  Note that color is already
+     mapped to target format so we can make assumptions based on that.  */
+  if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+    {
+      grub_video_fbfill_direct32 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+    {
+      grub_video_fbfill_direct32 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+    {
+      grub_video_fbfill_direct24 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
+    {
+      grub_video_fbfill_direct16 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_565)
+    {
+      grub_video_fbfill_direct16 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+    {
+      grub_video_fbfill_direct8 (&target, color, x, y,
+				       width, height);
+      return GRUB_ERR_NONE;
+    }
+
+  /* No optimized version found, use default (slow) filler.  */
+  grub_video_fbfill (&target, color, x, y, width, height);
+
+  return GRUB_ERR_NONE;
+}
+
+/* NOTE: This function assumes that given coordinates are within bounds of
+   handled data.  */
+static void
+common_blitter (struct grub_video_fbblit_info *target,
+                struct grub_video_fbblit_info *source,
+                enum grub_video_blit_operators oper, int x, int y,
+                unsigned int width, unsigned int height,
+                int offset_x, int offset_y)
+{
+  if (oper == GRUB_VIDEO_BLIT_REPLACE)
+    {
+      /* Try to figure out more optimized version for replace operator.  */
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+	{
+	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+	    {
+	      grub_video_fbblit_replace_directN (target, source,
+						       x, y, width, height,
+						       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+	    {
+	      grub_video_fbblit_replace_BGRX8888_RGBX8888 (target, source,
+								 x, y, width, height,
+								 offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+	    {
+	      grub_video_fbblit_replace_BGR888_RGBX8888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	    {
+	      grub_video_fbblit_replace_RGB888_RGBX8888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+	    {
+	      grub_video_fbblit_replace_index_RGBX8888 (target, source,
+							      x, y, width, height,
+							      offset_x, offset_y);
+	      return;
+	    }
+	}
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	{
+	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+	    {
+	      grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+	    {
+	      grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+	    {
+	      grub_video_fbblit_replace_BGR888_RGB888 (target, source,
+							     x, y, width, height,
+							     offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	    {
+	      grub_video_fbblit_replace_directN (target, source,
+						       x, y, width, height,
+						       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+	    {
+	      grub_video_fbblit_replace_index_RGB888 (target, source,
+							    x, y, width, height,
+							    offset_x, offset_y);
+	      return;
+	    }
+	}
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+	{
+	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+	    {
+	      grub_video_fbblit_replace_directN (target, source,
+						       x, y, width, height,
+						       offset_x, offset_y);
+	      return;
+	    }
+	}
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+	{
+	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+	    {
+	      grub_video_fbblit_replace_directN (target, source,
+						       x, y, width, height,
+						       offset_x, offset_y);
+	      return;
+	    }
+	}
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+	{
+	  if (target->mode_info->bpp == 32)
+	    {
+	      grub_video_fbblit_replace_32bit_1bit (target, source,
+						    x, y, width, height,
+						    offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->bpp == 24)
+	    {
+	      grub_video_fbblit_replace_24bit_1bit (target, source,
+						    x, y, width, height,
+						    offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->bpp == 16)
+	    {
+	      grub_video_fbblit_replace_16bit_1bit (target, source,
+						    x, y, width, height,
+						    offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->bpp == 8)
+	    {
+	      grub_video_fbblit_replace_8bit_1bit (target, source,
+						   x, y, width, height,
+						   offset_x, offset_y);
+	      return;
+	    }
+	}
+
+      /* No optimized replace operator found, use default (slow) blitter.  */
+      grub_video_fbblit_replace (target, source, x, y, width, height,
+				       offset_x, offset_y);
+    }
+  else
+    {
+      /* Try to figure out more optimized blend operator.  */
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+	{
+	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+	    {
+	      grub_video_fbblit_blend_BGRA8888_RGBA8888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+	    {
+	      grub_video_fbblit_blend_RGBA8888_RGBA8888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+	    {
+	      grub_video_fbblit_blend_BGR888_RGBA8888 (target, source,
+							     x, y, width, height,
+							     offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	    {
+	      grub_video_fbblit_blend_RGB888_RGBA8888 (target, source,
+							     x, y, width, height,
+							     offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+	    {
+	      grub_video_fbblit_blend_index_RGBA8888 (target, source,
+							    x, y, width, height,
+							    offset_x, offset_y);
+	      return;
+	    }
+	}
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	{
+	  /* Note: There is really no alpha information here, so blend is
+	     changed to replace.  */
+
+	  if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+	    {
+	      grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+	    {
+	      grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
+							       x, y, width, height,
+							       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+	    {
+	      grub_video_fbblit_replace_BGR888_RGB888 (target, source,
+							     x, y, width, height,
+							     offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	    {
+	      grub_video_fbblit_replace_directN (target, source,
+						       x, y, width, height,
+						       offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+	    {
+	      grub_video_fbblit_replace_index_RGB888 (target, source,
+							    x, y, width, height,
+							    offset_x, offset_y);
+	      return;
+	    }
+	}
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+	{
+	  if (target->mode_info->blit_format
+	      == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888
+	      || target->mode_info->blit_format
+	      == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+	    {
+	      grub_video_fbblit_blend_XXXA8888_1bit (target, source,
+						     x, y, width, height,
+						     offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format
+		   == GRUB_VIDEO_BLIT_FORMAT_BGR_888
+		   || target->mode_info->blit_format
+		   == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+	    {
+	      grub_video_fbblit_blend_XXX888_1bit (target, source,
+						   x, y, width, height,
+						   offset_x, offset_y);
+	      return;
+	    }
+	  else if (target->mode_info->blit_format
+		   == GRUB_VIDEO_BLIT_FORMAT_BGR_565
+		   || target->mode_info->blit_format
+		   == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
+	    {
+	      grub_video_fbblit_blend_XXX565_1bit (target, source,
+						   x, y, width, height,
+						   offset_x, offset_y);
+	      return;
+	    }
+
+	}
+
+
+      /* No optimized blend operation found, use default (slow) blitter.  */
+      grub_video_fbblit_blend (target, source, x, y, width, height,
+				     offset_x, offset_y);
+    }
+}
+
+grub_err_t
+grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap,
+			   enum grub_video_blit_operators oper, int x, int y,
+			   int offset_x, int offset_y,
+			   unsigned int width, unsigned int height)
+{
+  struct grub_video_fbblit_info source;
+  struct grub_video_fbblit_info target;
+
+  /* Make sure there is something to do.  */
+  if ((width == 0) || (height == 0))
+    return GRUB_ERR_NONE;
+  if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
+    return GRUB_ERR_NONE;
+  if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
+    return GRUB_ERR_NONE;
+  if ((x + (int)bitmap->mode_info.width) < 0)
+    return GRUB_ERR_NONE;
+  if ((y + (int)bitmap->mode_info.height) < 0)
+    return GRUB_ERR_NONE;
+  if ((offset_x >= (int)bitmap->mode_info.width)
+      || (offset_x + (int)width < 0))
+    return GRUB_ERR_NONE;
+  if ((offset_y >= (int)bitmap->mode_info.height)
+      || (offset_y + (int)height < 0))
+    return GRUB_ERR_NONE;
+
+  /* If we have negative coordinates, optimize drawing to minimum.  */
+  if (offset_x < 0)
+    {
+      width += offset_x;
+      x -= offset_x;
+      offset_x = 0;
+    }
+
+  if (offset_y < 0)
+    {
+      height += offset_y;
+      y -= offset_y;
+      offset_y = 0;
+    }
+
+  if (x < 0)
+    {
+      width += x;
+      offset_x -= x;
+      x = 0;
+    }
+
+  if (y < 0)
+    {
+      height += y;
+      offset_y -= y;
+      y = 0;
+    }
+
+  /* Do not allow drawing out of viewport.  */
+  if ((x + width) > render_target->viewport.width)
+    width = render_target->viewport.width - x;
+  if ((y + height) > render_target->viewport.height)
+    height = render_target->viewport.height - y;
+
+  if ((offset_x + width) > bitmap->mode_info.width)
+    width = bitmap->mode_info.width - offset_x;
+  if ((offset_y + height) > bitmap->mode_info.height)
+    height = bitmap->mode_info.height - offset_y;
+
+  /* Limit drawing to source render target dimensions.  */
+  if (width > bitmap->mode_info.width)
+    width = bitmap->mode_info.width;
+
+  if (height > bitmap->mode_info.height)
+    height = bitmap->mode_info.height;
+
+  /* Add viewport offset.  */
+  x += render_target->viewport.x;
+  y += render_target->viewport.y;
+
+  /* Use fbblit_info to encapsulate rendering.  */
+  source.mode_info = &bitmap->mode_info;
+  source.data = bitmap->data;
+  target.mode_info = &render_target->mode_info;
+  target.data = render_target->data;
+
+  /* Do actual blitting.  */
+  common_blitter (&target, &source, oper, x, y, width, height,
+                  offset_x, offset_y);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source,
+                                   enum grub_video_blit_operators oper,
+                                   int x, int y, int offset_x, int offset_y,
+                                   unsigned int width, unsigned int height)
+{
+  struct grub_video_fbblit_info source_info;
+  struct grub_video_fbblit_info target_info;
+
+  /* Make sure there is something to do.  */
+  if ((width == 0) || (height == 0))
+    return GRUB_ERR_NONE;
+  if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
+    return GRUB_ERR_NONE;
+  if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
+    return GRUB_ERR_NONE;
+  if ((x + (int)source->mode_info.width) < 0)
+    return GRUB_ERR_NONE;
+  if ((y + (int)source->mode_info.height) < 0)
+    return GRUB_ERR_NONE;
+  if ((offset_x >= (int)source->mode_info.width)
+      || (offset_x + (int)width < 0))
+    return GRUB_ERR_NONE;
+  if ((offset_y >= (int)source->mode_info.height)
+      || (offset_y + (int)height < 0))
+    return GRUB_ERR_NONE;
+
+  /* If we have negative coordinates, optimize drawing to minimum.  */
+  if (offset_x < 0)
+    {
+      width += offset_x;
+      x -= offset_x;
+      offset_x = 0;
+    }
+
+  if (offset_y < 0)
+    {
+      height += offset_y;
+      y -= offset_y;
+      offset_y = 0;
+    }
+
+  if (x < 0)
+    {
+      width += x;
+      offset_x -= x;
+      x = 0;
+    }
+
+  if (y < 0)
+    {
+      height += y;
+      offset_y -= y;
+      y = 0;
+    }
+
+  /* Do not allow drawing out of viewport.  */
+  if ((x + width) > render_target->viewport.width)
+    width = render_target->viewport.width - x;
+  if ((y + height) > render_target->viewport.height)
+    height = render_target->viewport.height - y;
+
+  if ((offset_x + width) > source->mode_info.width)
+    width = source->mode_info.width - offset_x;
+  if ((offset_y + height) > source->mode_info.height)
+    height = source->mode_info.height - offset_y;
+
+  /* Limit drawing to source render target dimensions.  */
+  if (width > source->mode_info.width)
+    width = source->mode_info.width;
+
+  if (height > source->mode_info.height)
+    height = source->mode_info.height;
+
+  /* Add viewport offset.  */
+  x += render_target->viewport.x;
+  y += render_target->viewport.y;
+
+  /* Use fbblit_info to encapsulate rendering.  */
+  source_info.mode_info = &source->mode_info;
+  source_info.data = source->data;
+  target_info.mode_info = &render_target->mode_info;
+  target_info.data = render_target->data;
+
+  /* Do actual blitting.  */
+  common_blitter (&target_info, &source_info, oper, x, y, width, height,
+                  offset_x, offset_y);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
+{
+  int width;
+  int height;
+  int src_x;
+  int src_y;
+  int dst_x;
+  int dst_y;
+
+  /* 1. Check if we have something to do.  */
+  if ((dx == 0) && (dy == 0))
+    return GRUB_ERR_NONE;
+
+  width = render_target->viewport.width - grub_abs (dx);
+  height = render_target->viewport.height - grub_abs (dy);
+
+  if (dx < 0)
+    {
+      src_x = render_target->viewport.x - dx;
+      dst_x = render_target->viewport.x;
+    }
+  else
+    {
+      src_x = render_target->viewport.x;
+      dst_x = render_target->viewport.x + dx;
+    }
+
+  if (dy < 0)
+    {
+      src_y = render_target->viewport.y - dy;
+      dst_y = render_target->viewport.y;
+    }
+  else
+    {
+      src_y = render_target->viewport.y;
+      dst_y = render_target->viewport.y + dy;
+    }
+
+  /* 2. Check if there is need to copy data.  */
+  if ((grub_abs (dx) < render_target->viewport.width)
+       && (grub_abs (dy) < render_target->viewport.height))
+    {
+      /* 3. Move data in render target.  */
+      struct grub_video_fbblit_info target;
+      grub_uint8_t *src;
+      grub_uint8_t *dst;
+      int j;
+
+      target.mode_info = &render_target->mode_info;
+      target.data = render_target->data;
+
+      /* Check vertical direction of the move.  */
+      if (dy <= 0)
+	/* 3a. Move data upwards.  */
+	for (j = 0; j < height; j++)
+	  {
+	    dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j);
+	    src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j);
+	    grub_memmove (dst, src,
+			  width * target.mode_info->bytes_per_pixel);
+	  }
+      else
+	/* 3b. Move data downwards.  */
+	for (j = (height - 1); j >= 0; j--)
+	  {
+	    dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j);
+	    src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j);
+	    grub_memmove (dst, src,
+			  width * target.mode_info->bytes_per_pixel);
+	  }
+    }
+
+  /* 4. Fill empty space with specified color.  In this implementation
+     there might be colliding areas but at the moment there is no need
+     to optimize this.  */
+
+  /* 4a. Fill top & bottom parts.  */
+  if (dy > 0)
+    grub_video_fb_fill_rect (color, 0, 0, render_target->viewport.width, dy);
+  else if (dy < 0)
+    {
+      if (render_target->viewport.height < grub_abs (dy))
+        dy = -render_target->viewport.height;
+
+      grub_video_fb_fill_rect (color, 0, render_target->viewport.height + dy,
+                                render_target->viewport.width, -dy);
+    }
+
+  /* 4b. Fill left & right parts.  */
+  if (dx > 0)
+    grub_video_fb_fill_rect (color, 0, 0,
+                              dx, render_target->viewport.height);
+  else if (dx < 0)
+    {
+      if (render_target->viewport.width < grub_abs (dx))
+        dx = -render_target->viewport.width;
+
+      grub_video_fb_fill_rect (color, render_target->viewport.width + dx, 0,
+                                -dx, render_target->viewport.height);
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+
+grub_err_t
+grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
+				    unsigned int width, unsigned int height,
+				    unsigned int mode_type __attribute__ ((unused)))
+{
+  struct grub_video_fbrender_target *target;
+  unsigned int size;
+
+  /* Validate arguments.  */
+  if ((! result)
+      || (width == 0)
+      || (height == 0))
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "invalid argument given.");
+
+  /* Allocate memory for render target.  */
+  target = grub_malloc (sizeof (struct grub_video_fbrender_target));
+  if (! target)
+    return grub_errno;
+
+  /* TODO: Implement other types too.
+     Currently only 32bit render targets are supported.  */
+
+  /* Mark render target as allocated.  */
+  target->is_allocated = 1;
+
+  /* Maximize viewport.  */
+  target->viewport.x = 0;
+  target->viewport.y = 0;
+  target->viewport.width = width;
+  target->viewport.height = height;
+
+  /* Setup render target format.  */
+  target->mode_info.width = width;
+  target->mode_info.height = height;
+  target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB
+                                | GRUB_VIDEO_MODE_TYPE_ALPHA;
+  target->mode_info.bpp = 32;
+  target->mode_info.bytes_per_pixel = 4;
+  target->mode_info.pitch = target->mode_info.bytes_per_pixel * width;
+  target->mode_info.number_of_colors = palette_size; /* Emulated palette.  */
+  target->mode_info.red_mask_size = 8;
+  target->mode_info.red_field_pos = 0;
+  target->mode_info.green_mask_size = 8;
+  target->mode_info.green_field_pos = 8;
+  target->mode_info.blue_mask_size = 8;
+  target->mode_info.blue_field_pos = 16;
+  target->mode_info.reserved_mask_size = 8;
+  target->mode_info.reserved_field_pos = 24;
+
+  target->mode_info.blit_format = grub_video_get_blit_format (&target->mode_info);
+
+  /* Calculate size needed for the data.  */
+  size = (width * target->mode_info.bytes_per_pixel) * height;
+
+  target->data = grub_malloc (size);
+  if (! target->data)
+    {
+      grub_free (target);
+      return grub_errno;
+    }
+
+  /* Clear render target with black and maximum transparency.  */
+  grub_memset (target->data, 0, size);
+
+  /* TODO: Add render target to render target list.  */
+
+  /* Save result to caller.  */
+  *result = target;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_target **result,
+						 const struct grub_video_mode_info *mode_info,
+						 void *ptr)
+{
+  struct grub_video_fbrender_target *target;
+  unsigned y;
+
+  /* Allocate memory for render target.  */
+  target = grub_malloc (sizeof (struct grub_video_fbrender_target));
+  if (! target)
+    return grub_errno;
+
+  /* Mark framebuffer memory as non allocated.  */
+  target->is_allocated = 0;
+  target->data = ptr;
+
+  grub_memcpy (&(target->mode_info), mode_info, sizeof (target->mode_info));
+
+  /* Reset viewport to match new mode.  */
+  target->viewport.x = 0;
+  target->viewport.y = 0;
+  target->viewport.width = mode_info->width;
+  target->viewport.height = mode_info->height;
+
+  /* Clear render target with black and maximum transparency.  */
+  for (y = 0; y < mode_info->height; y++)
+    grub_memset (target->data + mode_info->pitch * y, 0,
+		 mode_info->bytes_per_pixel * mode_info->width);
+
+  /* Save result to caller.  */
+  *result = target;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target)
+{
+  /* If there is no target, then just return without error.  */
+  if (! target)
+    return GRUB_ERR_NONE;
+
+  /* TODO: Delist render target from render target list.  */
+
+  /* If this is software render target, free it's memory.  */
+  if (target->is_allocated)
+    grub_free (target->data);
+
+  /* Free render target.  */
+  grub_free (target);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target)
+{
+  if (! target->data)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "invalid render target given.");
+
+  render_target = target;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target)
+{
+  *target = render_target;
+
+  return GRUB_ERR_NONE;
+}
diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c
new file mode 100644
index 0000000..a285b26
--- /dev/null
+++ b/video/i386/pc/vbe.c
@@ -0,0 +1,592 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define grub_video_render_target grub_video_fbrender_target
+
+#include <grub/err.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/vga.h>
+#include <grub/machine/vbe.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/video.h>
+
+static int vbe_detected = -1;
+
+static struct grub_vbe_info_block controller_info;
+static struct grub_vbe_mode_info_block active_vbe_mode_info;
+
+static struct
+{
+  struct grub_video_mode_info mode_info;
+  struct grub_video_render_target *render_target;
+
+  unsigned int bytes_per_scan_line;
+  unsigned int bytes_per_pixel;
+  grub_uint32_t active_vbe_mode;
+  grub_uint8_t *ptr;
+  int index_color_mode;
+} framebuffer;
+
+static grub_uint32_t initial_vbe_mode;
+static grub_uint16_t *vbe_mode_list;
+
+static void *
+real2pm (grub_vbe_farptr_t ptr)
+{
+  return (void *) ((((unsigned long) ptr & 0xFFFF0000) >> 12UL)
+                   + ((unsigned long) ptr & 0x0000FFFF));
+}
+
+grub_err_t
+grub_vbe_probe (struct grub_vbe_info_block *info_block)
+{
+  struct grub_vbe_info_block *vbe_ib;
+  grub_vbe_status_t status;
+
+  /* Clear caller's controller info block.  */
+  if (info_block)
+    grub_memset (info_block, 0, sizeof (*info_block));
+
+  /* Do not probe more than one time, if not necessary.  */
+  if (vbe_detected == -1 || info_block)
+    {
+      /* Clear old copy of controller info block.  */
+      grub_memset (&controller_info, 0, sizeof (controller_info));
+
+      /* Mark VESA BIOS extension as undetected.  */
+      vbe_detected = 0;
+
+      /* Use low memory scratch area as temporary storage
+         for VESA BIOS call.  */
+      vbe_ib = (struct grub_vbe_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+
+      /* Prepare info block.  */
+      grub_memset (vbe_ib, 0, sizeof (*vbe_ib));
+
+      vbe_ib->signature[0] = 'V';
+      vbe_ib->signature[1] = 'B';
+      vbe_ib->signature[2] = 'E';
+      vbe_ib->signature[3] = '2';
+
+      /* Try to get controller info block.  */
+      status = grub_vbe_bios_get_controller_info (vbe_ib);
+      if (status == GRUB_VBE_STATUS_OK)
+        {
+          /* Copy it for later usage.  */
+          grub_memcpy (&controller_info, vbe_ib, sizeof (controller_info));
+
+          /* Mark VESA BIOS extension as detected.  */
+          vbe_detected = 1;
+        }
+    }
+
+  if (! vbe_detected)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "VESA BIOS Extension not found");
+
+  /* Make copy of controller info block to caller.  */
+  if (info_block)
+    grub_memcpy (info_block, &controller_info, sizeof (*info_block));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_vbe_set_video_mode (grub_uint32_t vbe_mode,
+			 struct grub_vbe_mode_info_block *vbe_mode_info)
+{
+  grub_vbe_status_t status;
+  grub_uint32_t old_vbe_mode;
+  struct grub_vbe_mode_info_block new_vbe_mode_info;
+  grub_err_t err;
+
+  /* Make sure that VBE is supported.  */
+  grub_vbe_probe (0);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Try to get mode info.  */
+  grub_vbe_get_video_mode_info (vbe_mode, &new_vbe_mode_info);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* For all VESA BIOS modes, force linear frame buffer.  */
+  if (vbe_mode >= 0x100)
+    {
+      /* We only want linear frame buffer modes.  */
+      vbe_mode |= 1 << 14;
+
+      /* Determine frame buffer pixel format.  */
+      switch (new_vbe_mode_info.memory_model)
+        {
+        case GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL:
+          framebuffer.index_color_mode = 1;
+          break;
+
+        case GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR:
+          framebuffer.index_color_mode = 0;
+          break;
+
+        default:
+          return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                             "unsupported pixel format 0x%x",
+                             new_vbe_mode_info.memory_model);
+        }
+    }
+
+  /* Get current mode.  */
+  grub_vbe_get_video_mode (&old_vbe_mode);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Try to set video mode.  */
+  status = grub_vbe_bios_set_mode (vbe_mode, 0);
+  if (status != GRUB_VBE_STATUS_OK)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", vbe_mode);
+
+  /* Save information for later usage.  */
+  framebuffer.active_vbe_mode = vbe_mode;
+  grub_memcpy (&active_vbe_mode_info, &new_vbe_mode_info, sizeof (active_vbe_mode_info));
+
+  if (vbe_mode < 0x100)
+    {
+      /* If this is not a VESA mode, guess address.  */
+      framebuffer.ptr = (grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR;
+      framebuffer.index_color_mode = 1;
+    }
+  else
+    {
+      framebuffer.ptr = (grub_uint8_t *) new_vbe_mode_info.phys_base_addr;
+
+      if (controller_info.version >= 0x300)
+        framebuffer.bytes_per_scan_line = new_vbe_mode_info.lin_bytes_per_scan_line;
+      else
+        framebuffer.bytes_per_scan_line = new_vbe_mode_info.bytes_per_scan_line;
+    }
+
+  /* Check whether mode is text mode or graphics mode.  */
+  if (new_vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_TEXT)
+    {
+      /* Text mode.  */
+
+      /* No special action needed for text mode as it is not supported for
+         graphical support.  */
+    }
+  else
+    {
+      /* Graphics mode.  */
+
+      /* Calculate bytes_per_pixel value.  */
+      switch(new_vbe_mode_info.bits_per_pixel)
+	{
+	case 32: framebuffer.bytes_per_pixel = 4; break;
+	case 24: framebuffer.bytes_per_pixel = 3; break;
+	case 16: framebuffer.bytes_per_pixel = 2; break;
+	case 15: framebuffer.bytes_per_pixel = 2; break;
+	case 8: framebuffer.bytes_per_pixel = 1; break;
+	default:
+	  grub_vbe_bios_set_mode (old_vbe_mode, 0);
+	  return grub_error (GRUB_ERR_BAD_DEVICE,
+			     "cannot set VBE mode %x",
+			     vbe_mode);
+	  break;
+	}
+
+      /* If video mode is in indexed color, setup default VGA palette.  */
+      if (framebuffer.index_color_mode)
+	{
+	  struct grub_vbe_palette_data *palette
+	    = (struct grub_vbe_palette_data *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+	  unsigned i;
+
+	  /* Make sure that the BIOS can reach the palette.  */
+	  for (i = 0; i < GRUB_VIDEO_FBSTD_NUMCOLORS; i++)
+	    {
+	      palette[i].red = grub_video_fbstd_colors[i].r;
+	      palette[i].green = grub_video_fbstd_colors[i].g;
+	      palette[i].blue = grub_video_fbstd_colors[i].b;
+	      palette[i].alignment = 0;
+	    }
+
+	  status = grub_vbe_bios_set_palette_data (GRUB_VIDEO_FBSTD_NUMCOLORS,
+						   0, palette);
+
+	  /* Just ignore the status.  */
+	  err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+					   grub_video_fbstd_colors);
+	  if (err)
+	    return err;
+
+	}
+    }
+
+  /* Copy mode info for caller.  */
+  if (vbe_mode_info)
+    grub_memcpy (vbe_mode_info, &new_vbe_mode_info, sizeof (*vbe_mode_info));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_vbe_get_video_mode (grub_uint32_t *mode)
+{
+  grub_vbe_status_t status;
+
+  /* Make sure that VBE is supported.  */
+  grub_vbe_probe (0);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Try to query current mode from VESA BIOS.  */
+  status = grub_vbe_bios_get_mode (mode);
+  if (status != GRUB_VBE_STATUS_OK)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current VBE mode");
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_vbe_get_video_mode_info (grub_uint32_t mode,
+                              struct grub_vbe_mode_info_block *mode_info)
+{
+  struct grub_vbe_mode_info_block *mi_tmp
+    = (struct grub_vbe_mode_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+  grub_vbe_status_t status;
+
+  /* Make sure that VBE is supported.  */
+  grub_vbe_probe (0);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* If mode is not VESA mode, skip mode info query.  */
+  if (mode >= 0x100)
+    {
+      /* Try to get mode info from VESA BIOS.  */
+      status = grub_vbe_bios_get_mode_info (mode, mi_tmp);
+      if (status != GRUB_VBE_STATUS_OK)
+        return grub_error (GRUB_ERR_BAD_DEVICE,
+                           "cannot get information on the mode %x", mode);
+
+      /* Make copy of mode info block.  */
+      grub_memcpy (mode_info, mi_tmp, sizeof (*mode_info));
+    }
+  else
+    /* Just clear mode info block if it isn't a VESA mode.  */
+    grub_memset (mode_info, 0, sizeof (*mode_info));
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_vbe_init (void)
+{
+  grub_uint16_t *rm_vbe_mode_list;
+  grub_uint16_t *p;
+  grub_size_t vbe_mode_list_size;
+  struct grub_vbe_info_block info_block;
+
+  /* Check if there is adapter present.
+
+     Firmware note: There has been a report that some cards store video mode
+     list in temporary memory.  So we must first use vbe probe to get
+     refreshed information to receive valid pointers and data, and then
+     copy this information to somewhere safe.  */
+  grub_vbe_probe (&info_block);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Copy modelist to local memory.  */
+  p = rm_vbe_mode_list = real2pm (info_block.video_mode_ptr);
+  while(*p++ != 0xFFFF)
+    ;
+
+  vbe_mode_list_size = (grub_addr_t) p - (grub_addr_t) rm_vbe_mode_list;
+  vbe_mode_list = grub_malloc (vbe_mode_list_size);
+  if (! vbe_mode_list)
+    return grub_errno;
+  grub_memcpy (vbe_mode_list, rm_vbe_mode_list, vbe_mode_list_size);
+
+  /* Adapter could be found, figure out initial video mode.  */
+  grub_vbe_get_video_mode (&initial_vbe_mode);
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      /* Free allocated resources.  */
+      grub_free (vbe_mode_list);
+      vbe_mode_list = NULL;
+
+      return grub_errno;
+    }
+
+  /* Reset frame buffer.  */
+  grub_memset (&framebuffer, 0, sizeof(framebuffer));
+
+  return grub_video_fb_init ();
+}
+
+static grub_err_t
+grub_video_vbe_fini (void)
+{
+  grub_vbe_status_t status;
+
+  /* Restore old video mode.  */
+  status = grub_vbe_bios_set_mode (initial_vbe_mode, 0);
+  if (status != GRUB_VBE_STATUS_OK)
+    /* TODO: Decide, is this something we want to do.  */
+    return grub_errno;
+
+  /* TODO: Free any resources allocated by driver.  */
+  grub_free (vbe_mode_list);
+  vbe_mode_list = NULL;
+
+  /* TODO: destroy render targets.  */
+
+  return grub_video_fb_fini ();
+}
+
+static grub_err_t
+grub_video_vbe_setup (unsigned int width, unsigned int height,
+                      unsigned int mode_type)
+{
+  grub_uint16_t *p;
+  struct grub_vbe_mode_info_block vbe_mode_info;
+  struct grub_vbe_mode_info_block best_vbe_mode_info;
+  grub_uint32_t best_vbe_mode = 0;
+  int depth;
+
+  /* Decode depth from mode_type.  If it is zero, then autodetect.  */
+  depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
+          >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
+
+  /* Walk thru mode list and try to find matching mode.  */
+  for (p = vbe_mode_list; *p != 0xFFFF; p++)
+    {
+      grub_uint32_t vbe_mode = *p;
+
+      grub_vbe_get_video_mode_info (vbe_mode, &vbe_mode_info);
+      if (grub_errno != GRUB_ERR_NONE)
+        {
+          /* Could not retrieve mode info, retreat.  */
+          grub_errno = GRUB_ERR_NONE;
+          break;
+        }
+
+      if ((vbe_mode_info.mode_attributes & 0x001) == 0)
+        /* If not available, skip it.  */
+        continue;
+
+      if ((vbe_mode_info.mode_attributes & 0x002) == 0)
+        /* Not enough information.  */
+        continue;
+
+      if ((vbe_mode_info.mode_attributes & 0x008) == 0)
+        /* Monochrome is unusable.  */
+        continue;
+
+      if ((vbe_mode_info.mode_attributes & 0x080) == 0)
+        /* We support only linear frame buffer modes.  */
+        continue;
+
+      if ((vbe_mode_info.mode_attributes & 0x010) == 0)
+        /* We allow only graphical modes.  */
+        continue;
+
+      if ((vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL)
+          && (vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR))
+        /* Not compatible memory model.  */
+        continue;
+
+      if ((vbe_mode_info.x_resolution != width)
+          || (vbe_mode_info.y_resolution != height))
+        /* Non matching resolution.  */
+        continue;
+
+      /* Check if user requested RGB or index color mode.  */
+      if ((mode_type & GRUB_VIDEO_MODE_TYPE_COLOR_MASK) != 0)
+        {
+          if (((mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+              && (vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL))
+            /* Requested only index color modes.  */
+            continue;
+
+          if (((mode_type & GRUB_VIDEO_MODE_TYPE_RGB) != 0)
+              && (vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR))
+            /* Requested only RGB modes.  */
+            continue;
+        }
+
+      /* If there is a request for specific depth, ignore others.  */
+      if ((depth != 0) && (vbe_mode_info.bits_per_pixel != depth))
+        continue;
+
+      /* Select mode with most number of bits per pixel.  */
+      if (best_vbe_mode != 0)
+        if (vbe_mode_info.bits_per_pixel < best_vbe_mode_info.bits_per_pixel)
+          continue;
+
+      /* Save so far best mode information for later use.  */
+      best_vbe_mode = vbe_mode;
+      grub_memcpy (&best_vbe_mode_info, &vbe_mode_info, sizeof (vbe_mode_info));
+    }
+
+  /* Try to initialize best mode found.  */
+  if (best_vbe_mode != 0)
+    {
+      grub_err_t err;
+      /* If this fails, then we have mode selection heuristics problem,
+         or adapter failure.  */
+      /* grub_vbe_set_video_mode already sets active_vbe_mode_info. */
+      grub_vbe_set_video_mode (best_vbe_mode, NULL);
+      if (grub_errno != GRUB_ERR_NONE)
+        return grub_errno;
+
+      /* Fill mode info details.  */
+      framebuffer.mode_info.width = active_vbe_mode_info.x_resolution;
+      framebuffer.mode_info.height = active_vbe_mode_info.y_resolution;
+
+      if (framebuffer.index_color_mode)
+        framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+      else
+        framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
+
+      framebuffer.mode_info.bpp = active_vbe_mode_info.bits_per_pixel;
+      framebuffer.mode_info.bytes_per_pixel = framebuffer.bytes_per_pixel;
+      framebuffer.mode_info.pitch = framebuffer.bytes_per_scan_line;
+      framebuffer.mode_info.number_of_colors = 256; /* TODO: fix me.  */
+      framebuffer.mode_info.red_mask_size = active_vbe_mode_info.red_mask_size;
+      framebuffer.mode_info.red_field_pos = active_vbe_mode_info.red_field_position;
+      framebuffer.mode_info.green_mask_size = active_vbe_mode_info.green_mask_size;
+      framebuffer.mode_info.green_field_pos = active_vbe_mode_info.green_field_position;
+      framebuffer.mode_info.blue_mask_size = active_vbe_mode_info.blue_mask_size;
+      framebuffer.mode_info.blue_field_pos = active_vbe_mode_info.blue_field_position;
+      framebuffer.mode_info.reserved_mask_size = active_vbe_mode_info.rsvd_mask_size;
+      framebuffer.mode_info.reserved_field_pos = active_vbe_mode_info.rsvd_field_position;
+
+      framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info);
+
+      err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
+
+      if (err)
+	return err;
+
+      err = grub_video_fb_set_active_render_target (framebuffer.render_target);
+
+      if (err)
+	return err;
+
+      /* Copy default palette to initialize emulated palette.  */
+      err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+				       grub_video_fbstd_colors);
+      return err;
+    }
+
+  /* Couldn't found matching mode.  */
+  return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found.");
+}
+
+static grub_err_t
+grub_video_vbe_set_palette (unsigned int start, unsigned int count,
+                            struct grub_video_palette_data *palette_data)
+{
+  if (framebuffer.index_color_mode)
+    {
+      /* TODO: Implement setting indexed color mode palette to hardware.  */
+      //status = grub_vbe_bios_set_palette_data (sizeof (vga_colors)
+      //                                         / sizeof (struct grub_vbe_palette_data),
+      //                                         0,
+      //                                         palette);
+
+    }
+
+  /* Then set color to emulated palette.  */
+
+  return grub_video_fb_set_palette (start, count, palette_data);
+}
+
+static grub_err_t
+grub_video_vbe_swap_buffers (void)
+{
+  /* TODO: Implement buffer swapping.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_vbe_set_active_render_target (struct grub_video_render_target *target)
+{
+  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
+      target = framebuffer.render_target;
+
+  return grub_video_fb_set_active_render_target (target);
+}
+
+static grub_err_t
+grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info,
+				  void **framebuf)
+{
+  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
+  *framebuf = (char *) framebuffer.ptr;
+
+  grub_free (vbe_mode_list);
+  vbe_mode_list = NULL;
+
+  grub_video_fb_fini ();
+
+  return GRUB_ERR_NONE;
+}
+
+
+static struct grub_video_adapter grub_video_vbe_adapter =
+  {
+    .name = "VESA BIOS Extension Video Driver",
+
+    .init = grub_video_vbe_init,
+    .fini = grub_video_vbe_fini,
+    .setup = grub_video_vbe_setup,
+    .get_info = grub_video_fb_get_info,
+    .get_info_and_fini = grub_video_vbe_get_info_and_fini,
+    .set_palette = grub_video_vbe_set_palette,
+    .get_palette = grub_video_fb_get_palette,
+    .set_viewport = grub_video_fb_set_viewport,
+    .get_viewport = grub_video_fb_get_viewport,
+    .map_color = grub_video_fb_map_color,
+    .map_rgb = grub_video_fb_map_rgb,
+    .map_rgba = grub_video_fb_map_rgba,
+    .unmap_color = grub_video_fb_unmap_color,
+    .fill_rect = grub_video_fb_fill_rect,
+    .blit_bitmap = grub_video_fb_blit_bitmap,
+    .blit_render_target = grub_video_fb_blit_render_target,
+    .scroll = grub_video_fb_scroll,
+    .swap_buffers = grub_video_vbe_swap_buffers,
+    .create_render_target = grub_video_fb_create_render_target,
+    .delete_render_target = grub_video_fb_delete_render_target,
+    .set_active_render_target = grub_video_vbe_set_active_render_target,
+    .get_active_render_target = grub_video_fb_get_active_render_target,
+
+    .next = 0
+  };
+
+GRUB_MOD_INIT(video_i386_pc_vbe)
+{
+  grub_video_register (&grub_video_vbe_adapter);
+}
+
+GRUB_MOD_FINI(video_i386_pc_vbe)
+{
+  grub_video_unregister (&grub_video_vbe_adapter);
+}
diff --git a/video/readers/jpeg.c b/video/readers/jpeg.c
new file mode 100644
index 0000000..460a528
--- /dev/null
+++ b/video/readers/jpeg.c
@@ -0,0 +1,746 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/bitmap.h>
+#include <grub/types.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/bufio.h>
+
+/* Uncomment following define to enable JPEG debug.  */
+//#define JPEG_DEBUG
+
+#define JPEG_ESC_CHAR		0xFF
+
+#define JPEG_SAMPLING_1x1	0x11
+
+#define JPEG_MARKER_SOI		0xd8
+#define JPEG_MARKER_EOI		0xd9
+#define JPEG_MARKER_DHT		0xc4
+#define JPEG_MARKER_DQT		0xdb
+#define JPEG_MARKER_SOF0	0xc0
+#define JPEG_MARKER_SOS		0xda
+
+#define SHIFT_BITS		8
+#define CONST(x)		((int) ((x) * (1L << SHIFT_BITS) + 0.5))
+
+#define JPEG_UNIT_SIZE		8
+
+static const grub_uint8_t jpeg_zigzag_order[64] = {
+  0, 1, 8, 16, 9, 2, 3, 10,
+  17, 24, 32, 25, 18, 11, 4, 5,
+  12, 19, 26, 33, 40, 48, 41, 34,
+  27, 20, 13, 6, 7, 14, 21, 28,
+  35, 42, 49, 56, 57, 50, 43, 36,
+  29, 22, 15, 23, 30, 37, 44, 51,
+  58, 59, 52, 45, 38, 31, 39, 46,
+  53, 60, 61, 54, 47, 55, 62, 63
+};
+
+typedef int jpeg_data_unit_t[64];
+
+struct grub_jpeg_data
+{
+  grub_file_t file;
+  struct grub_video_bitmap **bitmap;
+
+  int image_width;
+  int image_height;
+
+  grub_uint8_t *huff_value[4];
+  int huff_offset[4][16];
+  int huff_maxval[4][16];
+
+  grub_uint8_t quan_table[2][64];
+  int comp_index[3][3];
+
+  jpeg_data_unit_t ydu[4];
+  jpeg_data_unit_t crdu;
+  jpeg_data_unit_t cbdu;
+
+  int vs, hs;
+
+  int dc_value[3];
+
+  int bit_mask, bit_save;
+};
+
+static grub_uint8_t
+grub_jpeg_get_byte (struct grub_jpeg_data *data)
+{
+  grub_uint8_t r;
+
+  r = 0;
+  grub_file_read (data->file, &r, 1);
+
+  return r;
+}
+
+static grub_uint16_t
+grub_jpeg_get_word (struct grub_jpeg_data *data)
+{
+  grub_uint16_t r;
+
+  r = 0;
+  grub_file_read (data->file, &r, sizeof (grub_uint16_t));
+
+  return grub_be_to_cpu16 (r);
+}
+
+static int
+grub_jpeg_get_bit (struct grub_jpeg_data *data)
+{
+  int ret;
+
+  if (data->bit_mask == 0)
+    {
+      data->bit_save = grub_jpeg_get_byte (data);
+      if (data->bit_save == JPEG_ESC_CHAR)
+	{
+	  if (grub_jpeg_get_byte (data) != 0)
+	    {
+	      grub_error (GRUB_ERR_BAD_FILE_TYPE,
+			  "jpeg: invalid 0xFF in data stream");
+	      return 0;
+	    }
+	}
+      data->bit_mask = 0x80;
+    }
+
+  ret = ((data->bit_save & data->bit_mask) != 0);
+  data->bit_mask >>= 1;
+  return ret;
+}
+
+static int
+grub_jpeg_get_number (struct grub_jpeg_data *data, int num)
+{
+  int value, i, msb;
+
+  if (num == 0)
+    return 0;
+
+  msb = value = grub_jpeg_get_bit (data);
+  for (i = 1; i < num; i++)
+    value = (value << 1) + (grub_jpeg_get_bit (data) != 0);
+  if (!msb)
+    value += 1 - (1 << num);
+
+  return value;
+}
+
+static int
+grub_jpeg_get_huff_code (struct grub_jpeg_data *data, int id)
+{
+  int code, i;
+
+  code = 0;
+  for (i = 0; i < 16; i++)
+    {
+      code <<= 1;
+      if (grub_jpeg_get_bit (data))
+	code++;
+      if (code < data->huff_maxval[id][i])
+	return data->huff_value[id][code + data->huff_offset[id][i]];
+    }
+  grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: huffman decode fails");
+  return 0;
+}
+
+static grub_err_t
+grub_jpeg_decode_huff_table (struct grub_jpeg_data *data)
+{
+  int id, ac, i, n, base, ofs;
+  grub_uint32_t next_marker;
+  grub_uint8_t count[16];
+
+  next_marker = data->file->offset;
+  next_marker += grub_jpeg_get_word (data);
+
+  id = grub_jpeg_get_byte (data);
+  ac = (id >> 4);
+  id &= 0xF;
+  if (id > 1)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		       "jpeg: too many huffman tables");
+
+  if (grub_file_read (data->file, &count, sizeof (count)) !=
+      sizeof (count))
+    return grub_errno;
+
+  n = 0;
+  for (i = 0; i < 16; i++)
+    n += count[i];
+
+  id += ac * 2;
+  data->huff_value[id] = grub_malloc (n);
+  if (grub_errno)
+    return grub_errno;
+
+  if (grub_file_read (data->file, data->huff_value[id], n) != n)
+    return grub_errno;
+
+  base = 0;
+  ofs = 0;
+  for (i = 0; i < 16; i++)
+    {
+      base += count[i];
+      ofs += count[i];
+
+      data->huff_maxval[id][i] = base;
+      data->huff_offset[id][i] = ofs - base;
+
+      base <<= 1;
+    }
+
+  if (data->file->offset != next_marker)
+    grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in huffman table");
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_jpeg_decode_quan_table (struct grub_jpeg_data *data)
+{
+  int id;
+  grub_uint32_t next_marker;
+
+  next_marker = data->file->offset;
+  next_marker += grub_jpeg_get_word (data);
+
+  id = grub_jpeg_get_byte (data);
+  if (id >= 0x10)		/* Upper 4-bit is precision.  */
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		       "jpeg: only 8-bit precision is supported");
+
+  if (id > 1)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		       "jpeg: too many quantization tables");
+
+  if (grub_file_read (data->file, &data->quan_table[id], 64) != 64)
+    return grub_errno;
+
+  if (data->file->offset != next_marker)
+    grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		"jpeg: extra byte in quantization table");
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_jpeg_decode_sof (struct grub_jpeg_data *data)
+{
+  int i, cc;
+  grub_uint32_t next_marker;
+
+  next_marker = data->file->offset;
+  next_marker += grub_jpeg_get_word (data);
+
+  if (grub_jpeg_get_byte (data) != 8)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		       "jpeg: only 8-bit precision is supported");
+
+  data->image_height = grub_jpeg_get_word (data);
+  data->image_width = grub_jpeg_get_word (data);
+
+  if ((!data->image_height) || (!data->image_width))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid image size");
+
+  cc = grub_jpeg_get_byte (data);
+  if (cc != 3)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		       "jpeg: component count must be 3");
+
+  for (i = 0; i < cc; i++)
+    {
+      int id, ss;
+
+      id = grub_jpeg_get_byte (data) - 1;
+      if ((id < 0) || (id >= 3))
+	return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
+
+      ss = grub_jpeg_get_byte (data);	/* Sampling factor.  */
+      if (!id)
+	{
+	  data->vs = ss & 0xF;	/* Vertical sampling.  */
+	  data->hs = ss >> 4;	/* Horizontal sampling.  */
+	  if ((data->vs > 2) || (data->hs > 2))
+	    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+			       "jpeg: sampling method not supported");
+	}
+      else if (ss != JPEG_SAMPLING_1x1)
+	return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+			   "jpeg: sampling method not supported");
+      data->comp_index[id][0] = grub_jpeg_get_byte (data);
+    }
+
+  if (data->file->offset != next_marker)
+    grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sof");
+
+  return grub_errno;
+}
+
+static void
+grub_jpeg_idct_transform (jpeg_data_unit_t du)
+{
+  int *pd;
+  int i;
+  int t0, t1, t2, t3, t4, t5, t6, t7;
+  int v0, v1, v2, v3, v4;
+
+  pd = du;
+  for (i = 0; i < JPEG_UNIT_SIZE; i++, pd++)
+    {
+      if ((pd[JPEG_UNIT_SIZE * 1] | pd[JPEG_UNIT_SIZE * 2] |
+	   pd[JPEG_UNIT_SIZE * 3] | pd[JPEG_UNIT_SIZE * 4] |
+	   pd[JPEG_UNIT_SIZE * 5] | pd[JPEG_UNIT_SIZE * 6] |
+	   pd[JPEG_UNIT_SIZE * 7]) == 0)
+	{
+	  pd[JPEG_UNIT_SIZE * 0] <<= SHIFT_BITS;
+
+	  pd[JPEG_UNIT_SIZE * 1] = pd[JPEG_UNIT_SIZE * 2]
+	    = pd[JPEG_UNIT_SIZE * 3] = pd[JPEG_UNIT_SIZE * 4]
+	    = pd[JPEG_UNIT_SIZE * 5] = pd[JPEG_UNIT_SIZE * 6]
+	    = pd[JPEG_UNIT_SIZE * 7] = pd[JPEG_UNIT_SIZE * 0];
+
+	  continue;
+	}
+
+      t0 = pd[JPEG_UNIT_SIZE * 0];
+      t1 = pd[JPEG_UNIT_SIZE * 2];
+      t2 = pd[JPEG_UNIT_SIZE * 4];
+      t3 = pd[JPEG_UNIT_SIZE * 6];
+
+      v4 = (t1 + t3) * CONST (0.541196100);
+
+      v0 = ((t0 + t2) << SHIFT_BITS);
+      v1 = ((t0 - t2) << SHIFT_BITS);
+      v2 = v4 - t3 * CONST (1.847759065);
+      v3 = v4 + t1 * CONST (0.765366865);
+
+      t0 = v0 + v3;
+      t3 = v0 - v3;
+      t1 = v1 + v2;
+      t2 = v1 - v2;
+
+      t4 = pd[JPEG_UNIT_SIZE * 7];
+      t5 = pd[JPEG_UNIT_SIZE * 5];
+      t6 = pd[JPEG_UNIT_SIZE * 3];
+      t7 = pd[JPEG_UNIT_SIZE * 1];
+
+      v0 = t4 + t7;
+      v1 = t5 + t6;
+      v2 = t4 + t6;
+      v3 = t5 + t7;
+
+      v4 = (v2 + v3) * CONST (1.175875602);
+
+      v0 *= CONST (0.899976223);
+      v1 *= CONST (2.562915447);
+      v2 = v2 * CONST (1.961570560) - v4;
+      v3 = v3 * CONST (0.390180644) - v4;
+
+      t4 = t4 * CONST (0.298631336) - v0 - v2;
+      t5 = t5 * CONST (2.053119869) - v1 - v3;
+      t6 = t6 * CONST (3.072711026) - v1 - v2;
+      t7 = t7 * CONST (1.501321110) - v0 - v3;
+
+      pd[JPEG_UNIT_SIZE * 0] = t0 + t7;
+      pd[JPEG_UNIT_SIZE * 7] = t0 - t7;
+      pd[JPEG_UNIT_SIZE * 1] = t1 + t6;
+      pd[JPEG_UNIT_SIZE * 6] = t1 - t6;
+      pd[JPEG_UNIT_SIZE * 2] = t2 + t5;
+      pd[JPEG_UNIT_SIZE * 5] = t2 - t5;
+      pd[JPEG_UNIT_SIZE * 3] = t3 + t4;
+      pd[JPEG_UNIT_SIZE * 4] = t3 - t4;
+    }
+
+  pd = du;
+  for (i = 0; i < JPEG_UNIT_SIZE; i++, pd += JPEG_UNIT_SIZE)
+    {
+      if ((pd[1] | pd[2] | pd[3] | pd[4] | pd[5] | pd[6] | pd[7]) == 0)
+	{
+	  pd[0] >>= (SHIFT_BITS + 3);
+	  pd[1] = pd[2] = pd[3] = pd[4] = pd[5] = pd[6] = pd[7] = pd[0];
+	  continue;
+	}
+
+      v4 = (pd[2] + pd[6]) * CONST (0.541196100);
+
+      v0 = (pd[0] + pd[4]) << SHIFT_BITS;
+      v1 = (pd[0] - pd[4]) << SHIFT_BITS;
+      v2 = v4 - pd[6] * CONST (1.847759065);
+      v3 = v4 + pd[2] * CONST (0.765366865);
+
+      t0 = v0 + v3;
+      t3 = v0 - v3;
+      t1 = v1 + v2;
+      t2 = v1 - v2;
+
+      t4 = pd[7];
+      t5 = pd[5];
+      t6 = pd[3];
+      t7 = pd[1];
+
+      v0 = t4 + t7;
+      v1 = t5 + t6;
+      v2 = t4 + t6;
+      v3 = t5 + t7;
+
+      v4 = (v2 + v3) * CONST (1.175875602);
+
+      v0 *= CONST (0.899976223);
+      v1 *= CONST (2.562915447);
+      v2 = v2 * CONST (1.961570560) - v4;
+      v3 = v3 * CONST (0.390180644) - v4;
+
+      t4 = t4 * CONST (0.298631336) - v0 - v2;
+      t5 = t5 * CONST (2.053119869) - v1 - v3;
+      t6 = t6 * CONST (3.072711026) - v1 - v2;
+      t7 = t7 * CONST (1.501321110) - v0 - v3;
+
+      pd[0] = (t0 + t7) >> (SHIFT_BITS * 2 + 3);
+      pd[7] = (t0 - t7) >> (SHIFT_BITS * 2 + 3);
+      pd[1] = (t1 + t6) >> (SHIFT_BITS * 2 + 3);
+      pd[6] = (t1 - t6) >> (SHIFT_BITS * 2 + 3);
+      pd[2] = (t2 + t5) >> (SHIFT_BITS * 2 + 3);
+      pd[5] = (t2 - t5) >> (SHIFT_BITS * 2 + 3);
+      pd[3] = (t3 + t4) >> (SHIFT_BITS * 2 + 3);
+      pd[4] = (t3 - t4) >> (SHIFT_BITS * 2 + 3);
+    }
+
+  for (i = 0; i < JPEG_UNIT_SIZE * JPEG_UNIT_SIZE; i++)
+    {
+      du[i] += 128;
+
+      if (du[i] < 0)
+	du[i] = 0;
+      if (du[i] > 255)
+	du[i] = 255;
+    }
+}
+
+static void
+grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
+{
+  int pos, h1, h2, qt;
+
+  grub_memset (du, 0, sizeof (jpeg_data_unit_t));
+
+  qt = data->comp_index[id][0];
+  h1 = data->comp_index[id][1];
+  h2 = data->comp_index[id][2];
+
+  data->dc_value[id] +=
+    grub_jpeg_get_number (data, grub_jpeg_get_huff_code (data, h1));
+
+  du[0] = data->dc_value[id] * (int) data->quan_table[qt][0];
+  pos = 1;
+  while (pos < 64)
+    {
+      int num, val;
+
+      num = grub_jpeg_get_huff_code (data, h2);
+      if (!num)
+	break;
+
+      val = grub_jpeg_get_number (data, num & 0xF);
+      num >>= 4;
+      pos += num;
+      du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos];
+      pos++;
+    }
+
+  grub_jpeg_idct_transform (du);
+}
+
+static void
+grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb)
+{
+  int dd;
+
+  cr -= 128;
+  cb -= 128;
+
+  /* Red  */
+  dd = yy + ((cr * CONST (1.402)) >> SHIFT_BITS);
+  if (dd < 0)
+    dd = 0;
+  if (dd > 255)
+    dd = 255;
+  *(rgb++) = dd;
+
+  /* Green  */
+  dd = yy - ((cb * CONST (0.34414) + cr * CONST (0.71414)) >> SHIFT_BITS);
+  if (dd < 0)
+    dd = 0;
+  if (dd > 255)
+    dd = 255;
+  *(rgb++) = dd;
+
+  /* Blue  */
+  dd = yy + ((cb * CONST (1.772)) >> SHIFT_BITS);
+  if (dd < 0)
+    dd = 0;
+  if (dd > 255)
+    dd = 255;
+  *(rgb++) = dd;
+}
+
+static grub_err_t
+grub_jpeg_decode_sos (struct grub_jpeg_data *data)
+{
+  int i, cc, r1, c1, nr1, nc1, vb, hb;
+  grub_uint8_t *ptr1;
+  grub_uint32_t data_offset;
+
+  data_offset = data->file->offset;
+  data_offset += grub_jpeg_get_word (data);
+
+  cc = grub_jpeg_get_byte (data);
+
+  if (cc != 3)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		       "jpeg: component count must be 3");
+
+  for (i = 0; i < cc; i++)
+    {
+      int id, ht;
+
+      id = grub_jpeg_get_byte (data) - 1;
+      if ((id < 0) || (id >= 3))
+	return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
+
+      ht = grub_jpeg_get_byte (data);
+      data->comp_index[id][1] = (ht >> 4);
+      data->comp_index[id][2] = (ht & 0xF) + 2;
+    }
+
+  grub_jpeg_get_byte (data);	/* Skip 3 unused bytes.  */
+  grub_jpeg_get_word (data);
+
+  if (data->file->offset != data_offset)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos");
+
+  if (grub_video_bitmap_create (data->bitmap, data->image_width,
+				data->image_height,
+				GRUB_VIDEO_BLIT_FORMAT_RGB_888))
+    return grub_errno;
+
+  data->bit_mask = 0x0;
+
+  vb = data->vs * 8;
+  hb = data->hs * 8;
+  nr1 = (data->image_height + vb - 1) / vb;
+  nc1 = (data->image_width + hb - 1) / hb;
+
+  ptr1 = (*data->bitmap)->data;
+  for (r1 = 0; r1 < nr1;
+       r1++, ptr1 += (vb * data->image_width - hb * nc1) * 3)
+    for (c1 = 0; c1 < nc1; c1++, ptr1 += hb * 3)
+      {
+	int r2, c2, nr2, nc2;
+	grub_uint8_t *ptr2;
+
+	for (r2 = 0; r2 < data->vs; r2++)
+	  for (c2 = 0; c2 < data->hs; c2++)
+	    grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]);
+
+	grub_jpeg_decode_du (data, 1, data->cbdu);
+	grub_jpeg_decode_du (data, 2, data->crdu);
+
+	if (grub_errno)
+	  return grub_errno;
+
+	nr2 = (r1 == nr1 - 1) ? (data->image_height - r1 * vb) : vb;
+	nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb;
+
+	ptr2 = ptr1;
+	for (r2 = 0; r2 < nr2; r2++, ptr2 += (data->image_width - nc2) * 3)
+	  for (c2 = 0; c2 < nc2; c2++, ptr2 += 3)
+	    {
+	      int i0, yy, cr, cb;
+
+	      i0 = (r2 / data->vs) * 8 + (c2 / data->hs);
+	      cr = data->crdu[i0];
+	      cb = data->cbdu[i0];
+	      yy =
+		data->ydu[(r2 / 8) * 2 + (c2 / 8)][(r2 % 8) * 8 + (c2 % 8)];
+
+	      grub_jpeg_ycrcb_to_rgb (yy, cr, cb, ptr2);
+	    }
+      }
+
+  return grub_errno;
+}
+
+static grub_uint8_t
+grub_jpeg_get_marker (struct grub_jpeg_data *data)
+{
+  grub_uint8_t r;
+
+  r = grub_jpeg_get_byte (data);
+
+  if (r != JPEG_ESC_CHAR)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid maker");
+      return 0;
+    }
+
+  return grub_jpeg_get_byte (data);
+}
+
+static grub_err_t
+grub_jpeg_decode_jpeg (struct grub_jpeg_data *data)
+{
+  if (grub_jpeg_get_marker (data) != JPEG_MARKER_SOI)	/* Start Of Image.  */
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid jpeg file");
+
+  while (grub_errno == 0)
+    {
+      grub_uint8_t marker;
+
+      marker = grub_jpeg_get_marker (data);
+      if (grub_errno)
+	break;
+
+#ifdef JPEG_DEBUG
+      grub_printf ("jpeg marker: %x\n", marker);
+#endif
+
+      switch (marker)
+	{
+	case JPEG_MARKER_DHT:	/* Define Huffman Table.  */
+	  grub_jpeg_decode_huff_table (data);
+	  break;
+	case JPEG_MARKER_DQT:	/* Define Quantization Table.  */
+	  grub_jpeg_decode_quan_table (data);
+	  break;
+	case JPEG_MARKER_SOF0:	/* Start Of Frame 0.  */
+	  grub_jpeg_decode_sof (data);
+	  break;
+	case JPEG_MARKER_SOS:	/* Start Of Scan.  */
+	  grub_jpeg_decode_sos (data);
+	  break;
+	case JPEG_MARKER_EOI:	/* End Of Image.  */
+	  return grub_errno;
+	default:		/* Skip unrecognized marker.  */
+	  {
+	    grub_uint16_t sz;
+
+	    sz = grub_jpeg_get_word (data);
+	    if (grub_errno)
+	      return (grub_errno);
+	    grub_file_seek (data->file, data->file->offset + sz - 2);
+	  }
+	}
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_video_reader_jpeg (struct grub_video_bitmap **bitmap,
+			const char *filename)
+{
+  grub_file_t file;
+  struct grub_jpeg_data *data;
+
+  file = grub_buffile_open (filename, 0);
+  if (!file)
+    return grub_errno;
+
+  data = grub_zalloc (sizeof (*data));
+  if (data != NULL)
+    {
+      int i;
+
+      data->file = file;
+      data->bitmap = bitmap;
+      grub_jpeg_decode_jpeg (data);
+
+      for (i = 0; i < 4; i++)
+	if (data->huff_value[i])
+	  grub_free (data->huff_value[i]);
+
+      grub_free (data);
+    }
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_video_bitmap_destroy (*bitmap);
+      *bitmap = 0;
+    }
+
+  grub_file_close (file);
+  return grub_errno;
+}
+
+#if defined(JPEG_DEBUG)
+static grub_err_t
+grub_cmd_jpegtest (struct grub_arg_list *state __attribute__ ((unused)),
+		   int argc, char **args)
+{
+  struct grub_video_bitmap *bitmap = 0;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  grub_video_reader_jpeg (&bitmap, args[0]);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  grub_video_bitmap_destroy (bitmap);
+
+  return GRUB_ERR_NONE;
+}
+#endif
+
+static struct grub_video_bitmap_reader jpg_reader = {
+  .extension = ".jpg",
+  .reader = grub_video_reader_jpeg,
+  .next = 0
+};
+
+static struct grub_video_bitmap_reader jpeg_reader = {
+  .extension = ".jpeg",
+  .reader = grub_video_reader_jpeg,
+  .next = 0
+};
+
+GRUB_MOD_INIT (video_reader_jpeg)
+{
+  grub_video_bitmap_reader_register (&jpg_reader);
+  grub_video_bitmap_reader_register (&jpeg_reader);
+#if defined(JPEG_DEBUG)
+  grub_register_command ("jpegtest", grub_cmd_jpegtest,
+			 GRUB_COMMAND_FLAG_BOTH, "jpegtest FILE",
+			 "Tests loading of JPEG bitmap.", 0);
+#endif
+}
+
+GRUB_MOD_FINI (video_reader_jpeg)
+{
+#if defined(JPEG_DEBUG)
+  grub_unregister_command ("jpegtest");
+#endif
+  grub_video_bitmap_reader_unregister (&jpeg_reader);
+  grub_video_bitmap_reader_unregister (&jpg_reader);
+}
diff --git a/video/readers/png.c b/video/readers/png.c
new file mode 100644
index 0000000..c2008ae
--- /dev/null
+++ b/video/readers/png.c
@@ -0,0 +1,909 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/bitmap.h>
+#include <grub/types.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/bufio.h>
+
+/* Uncomment following define to enable PNG debug.  */
+//#define PNG_DEBUG
+
+#define PNG_COLOR_MASK_PALETTE	1
+#define PNG_COLOR_MASK_COLOR	2
+#define PNG_COLOR_MASK_ALPHA	4
+
+#define PNG_COLOR_TYPE_GRAY	0
+#define PNG_COLOR_TYPE_PALETTE	(PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
+#define PNG_COLOR_TYPE_RGB	(PNG_COLOR_MASK_COLOR)
+#define PNG_COLOR_TYPE_RGBA	(PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
+#define PNG_COLOR_TYPE_GRAYA	(PNG_COLOR_MASK_ALPHA)
+
+#define PNG_COMPRESSION_BASE	0
+
+#define PNG_INTERLACE_NONE	0
+#define PNG_INTERLACE_ADAM7	1
+
+#define PNG_FILTER_TYPE_BASE	0
+
+#define PNG_FILTER_VALUE_NONE	0
+#define PNG_FILTER_VALUE_SUB	1
+#define PNG_FILTER_VALUE_UP	2
+#define PNG_FILTER_VALUE_AVG	3
+#define PNG_FILTER_VALUE_PAETH	4
+#define PNG_FILTER_VALUE_LAST	5
+
+#define PNG_CHUNK_IHDR		0x49484452
+#define PNG_CHUNK_IDAT		0x49444154
+#define PNG_CHUNK_IEND		0x49454e44
+
+#define Z_DEFLATED		8
+#define Z_FLAG_DICT		32
+
+#define INFLATE_STORED		0
+#define INFLATE_FIXED		1
+#define INFLATE_DYNAMIC		2
+
+#define WSIZE			0x8000
+
+#define DEFLATE_HCLEN_BASE	4
+#define DEFLATE_HCLEN_MAX	19
+#define DEFLATE_HLIT_BASE	257
+#define DEFLATE_HLIT_MAX	288
+#define DEFLATE_HDIST_BASE	1
+#define DEFLATE_HDIST_MAX	30
+
+#define DEFLATE_HUFF_LEN	16
+
+struct huff_table
+{
+  int *values, *maxval, *offset;
+  int num_values, max_length;
+};
+
+struct grub_png_data
+{
+  grub_file_t file;
+  struct grub_video_bitmap **bitmap;
+
+  int bit_count, bit_save;
+
+  grub_uint32_t next_offset;
+
+  int image_width, image_height, bpp, is_16bit, raw_bytes;
+  grub_uint8_t *image_data;
+
+  int inside_idat, idat_remain;
+
+  int code_values[DEFLATE_HLIT_MAX];
+  int code_maxval[DEFLATE_HUFF_LEN];
+  int code_offset[DEFLATE_HUFF_LEN];
+
+  int dist_values[DEFLATE_HDIST_MAX];
+  int dist_maxval[DEFLATE_HUFF_LEN];
+  int dist_offset[DEFLATE_HUFF_LEN];
+
+  struct huff_table code_table;
+  struct huff_table dist_table;
+
+  grub_uint8_t slide[WSIZE];
+  int wp;
+
+  grub_uint8_t *cur_rgb;
+
+  int cur_column, cur_filter, first_line;
+};
+
+static grub_uint32_t
+grub_png_get_dword (struct grub_png_data *data)
+{
+  grub_uint32_t r;
+
+  r = 0;
+  grub_file_read (data->file, &r, sizeof (grub_uint32_t));
+
+  return grub_be_to_cpu32 (r);
+}
+
+static grub_uint8_t
+grub_png_get_byte (struct grub_png_data *data)
+{
+  grub_uint8_t r;
+
+  if ((data->inside_idat) && (data->idat_remain == 0))
+    {
+      grub_uint32_t len, type;
+
+      do
+	{
+          /* Skip crc checksum.  */
+	  grub_png_get_dword (data);
+
+          if (data->file->offset != data->next_offset)
+            {
+              grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                          "png: chunk size error");
+              return 0;
+            }
+
+	  len = grub_png_get_dword (data);
+	  type = grub_png_get_dword (data);
+	  if (type != PNG_CHUNK_IDAT)
+	    {
+	      grub_error (GRUB_ERR_BAD_FILE_TYPE,
+			  "png: unexpected end of data");
+	      return 0;
+	    }
+
+          data->next_offset = data->file->offset + len + 4;
+	}
+      while (len == 0);
+      data->idat_remain = len;
+    }
+
+  r = 0;
+  grub_file_read (data->file, &r, 1);
+
+  if (data->inside_idat)
+    data->idat_remain--;
+
+  return r;
+}
+
+static int
+grub_png_get_bits (struct grub_png_data *data, int num)
+{
+  int code, shift;
+
+  if (data->bit_count == 0)
+    {
+      data->bit_save = grub_png_get_byte (data);
+      data->bit_count = 8;
+    }
+
+  code = 0;
+  shift = 0;
+  while (grub_errno == 0)
+    {
+      int n;
+
+      n = data->bit_count;
+      if (n > num)
+	n = num;
+
+      code += (int) (data->bit_save & ((1 << n) - 1)) << shift;
+      num -= n;
+      if (!num)
+	{
+	  data->bit_count -= n;
+	  data->bit_save >>= n;
+	  break;
+	}
+
+      shift += n;
+
+      data->bit_save = grub_png_get_byte (data);
+      data->bit_count = 8;
+    }
+
+  return code;
+}
+
+static grub_err_t
+grub_png_decode_image_header (struct grub_png_data *data)
+{
+  int color_type;
+  int color_bits;
+
+  data->image_width = grub_png_get_dword (data);
+  data->image_height = grub_png_get_dword (data);
+
+  if ((!data->image_height) || (!data->image_width))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size");
+
+  color_bits = grub_png_get_byte (data);
+  if ((color_bits != 8) && (color_bits != 16))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                       "png: bit depth must be 8 or 16");
+  data->is_16bit = (color_bits == 16);
+
+  color_type = grub_png_get_byte (data);
+  if (color_type == PNG_COLOR_TYPE_RGB)
+    {
+      if (grub_video_bitmap_create (data->bitmap, data->image_width,
+				    data->image_height,
+				    GRUB_VIDEO_BLIT_FORMAT_RGB_888))
+	return grub_errno;
+      data->bpp = 3;
+    }
+  else if (color_type == PNG_COLOR_TYPE_RGBA)
+    {
+      if (grub_video_bitmap_create (data->bitmap, data->image_width,
+				    data->image_height,
+				    GRUB_VIDEO_BLIT_FORMAT_RGBA_8888))
+	return grub_errno;
+      data->bpp = 4;
+    }
+  else
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		       "png: color type not supported");
+
+  if (data->is_16bit)
+    {
+      data->bpp <<= 1;
+
+      data->image_data = grub_malloc (data->image_height *
+                                      data->image_width *  data->bpp);
+      if (grub_errno)
+        return grub_errno;
+
+      data->cur_rgb = data->image_data;
+    }
+  else
+    {
+      data->image_data = 0;
+      data->cur_rgb = (*data->bitmap)->data;
+    }
+
+  data->raw_bytes = data->image_height * (data->image_width + 1) * data->bpp;
+
+  data->cur_column = 0;
+  data->first_line = 1;
+
+  if (grub_png_get_byte (data) != PNG_COMPRESSION_BASE)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		       "png: compression method not supported");
+
+  if (grub_png_get_byte (data) != PNG_FILTER_TYPE_BASE)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		       "png: filter method not supported");
+
+  if (grub_png_get_byte (data) != PNG_INTERLACE_NONE)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		       "png: interlace method not supported");
+
+  /* Skip crc checksum.  */
+  grub_png_get_dword (data);
+
+  return grub_errno;
+}
+
+/* Order of the bit length code lengths.  */
+static const grub_uint8_t bitorder[] = {
+  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
+};
+
+/* Copy lengths for literal codes 257..285.  */
+static const int cplens[] = {
+  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
+};
+
+/* Extra bits for literal codes 257..285.  */
+static const grub_uint8_t cplext[] = {
+  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+  3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99
+};				/* 99==invalid  */
+
+/* Copy offsets for distance codes 0..29.  */
+static const int cpdist[] = {
+  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+  8193, 12289, 16385, 24577
+};
+
+/* Extra bits for distance codes.  */
+static const grub_uint8_t cpdext[] = {
+  0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+  7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+  12, 12, 13, 13
+};
+
+static void
+grub_png_init_huff_table (struct huff_table *ht, int cur_maxlen,
+			  int *cur_values, int *cur_maxval, int *cur_offset)
+{
+  ht->values = cur_values;
+  ht->maxval = cur_maxval;
+  ht->offset = cur_offset;
+  ht->num_values = 0;
+  ht->max_length = cur_maxlen;
+  grub_memset (cur_maxval, 0, sizeof (int) * cur_maxlen);
+}
+
+static void
+grub_png_insert_huff_item (struct huff_table *ht, int code, int len)
+{
+  int i, n;
+
+  if (len == 0)
+    return;
+
+  if (len > ht->max_length)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid code length");
+      return;
+    }
+
+  n = 0;
+  for (i = len; i < ht->max_length; i++)
+    n += ht->maxval[i];
+
+  for (i = 0; i < n; i++)
+    ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1];
+
+  ht->values[ht->num_values - n] = code;
+  ht->num_values++;
+  ht->maxval[len - 1]++;
+}
+
+static void
+grub_png_build_huff_table (struct huff_table *ht)
+{
+  int base, ofs, i;
+
+  base = 0;
+  ofs = 0;
+  for (i = 0; i < ht->max_length; i++)
+    {
+      base += ht->maxval[i];
+      ofs += ht->maxval[i];
+
+      ht->maxval[i] = base;
+      ht->offset[i] = ofs - base;
+
+      base <<= 1;
+    }
+}
+
+static int
+grub_png_get_huff_code (struct grub_png_data *data, struct huff_table *ht)
+{
+  int code, i;
+
+  code = 0;
+  for (i = 0; i < ht->max_length; i++)
+    {
+      code = (code << 1) + grub_png_get_bits (data, 1);
+      if (code < ht->maxval[i])
+	return ht->values[code + ht->offset[i]];
+    }
+  return 0;
+}
+
+static grub_err_t
+grub_png_init_fixed_block (struct grub_png_data *data)
+{
+  int i;
+
+  grub_png_init_huff_table (&data->code_table, DEFLATE_HUFF_LEN,
+			    data->code_values, data->code_maxval,
+			    data->code_offset);
+
+  for (i = 0; i < 144; i++)
+    grub_png_insert_huff_item (&data->code_table, i, 8);
+
+  for (; i < 256; i++)
+    grub_png_insert_huff_item (&data->code_table, i, 9);
+
+  for (; i < 280; i++)
+    grub_png_insert_huff_item (&data->code_table, i, 7);
+
+  for (; i < DEFLATE_HLIT_MAX; i++)
+    grub_png_insert_huff_item (&data->code_table, i, 8);
+
+  grub_png_build_huff_table (&data->code_table);
+
+  grub_png_init_huff_table (&data->dist_table, DEFLATE_HUFF_LEN,
+			    data->dist_values, data->dist_maxval,
+			    data->dist_offset);
+
+  for (i = 0; i < DEFLATE_HDIST_MAX; i++)
+    grub_png_insert_huff_item (&data->dist_table, i, 5);
+
+  grub_png_build_huff_table (&data->dist_table);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_png_init_dynamic_block (struct grub_png_data *data)
+{
+  int nl, nd, nb, i, prev;
+  struct huff_table cl;
+  int cl_values[sizeof (bitorder)];
+  int cl_maxval[8];
+  int cl_offset[8];
+  grub_uint8_t lens[DEFLATE_HCLEN_MAX];
+
+  nl = DEFLATE_HLIT_BASE + grub_png_get_bits (data, 5);
+  nd = DEFLATE_HDIST_BASE + grub_png_get_bits (data, 5);
+  nb = DEFLATE_HCLEN_BASE + grub_png_get_bits (data, 4);
+
+  if ((nl > DEFLATE_HLIT_MAX) || (nd > DEFLATE_HDIST_MAX) ||
+      (nb > DEFLATE_HCLEN_MAX))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: too much data");
+
+  grub_png_init_huff_table (&cl, 8, cl_values, cl_maxval, cl_offset);
+
+  for (i = 0; i < nb; i++)
+    lens[bitorder[i]] = grub_png_get_bits (data, 3);
+
+  for (; i < DEFLATE_HCLEN_MAX; i++)
+    lens[bitorder[i]] = 0;
+
+  for (i = 0; i < DEFLATE_HCLEN_MAX; i++)
+    grub_png_insert_huff_item (&cl, i, lens[i]);
+
+  grub_png_build_huff_table (&cl);
+
+  grub_png_init_huff_table (&data->code_table, DEFLATE_HUFF_LEN,
+			    data->code_values, data->code_maxval,
+			    data->code_offset);
+
+  grub_png_init_huff_table (&data->dist_table, DEFLATE_HUFF_LEN,
+			    data->dist_values, data->dist_maxval,
+			    data->dist_offset);
+
+  prev = 0;
+  for (i = 0; i < nl + nd; i++)
+    {
+      int n, code;
+      struct huff_table *ht;
+
+      if (grub_errno)
+	return grub_errno;
+
+      if (i < nl)
+	{
+	  ht = &data->code_table;
+	  code = i;
+	}
+      else
+	{
+	  ht = &data->dist_table;
+	  code = i - nl;
+	}
+
+      n = grub_png_get_huff_code (data, &cl);
+      if (n < 16)
+	{
+	  grub_png_insert_huff_item (ht, code, n);
+	  prev = n;
+	}
+      else if (n == 16)
+	{
+	  int c;
+
+	  c = 3 + grub_png_get_bits (data, 2);
+	  while (c > 0)
+	    {
+	      grub_png_insert_huff_item (ht, code++, prev);
+	      i++;
+	      c--;
+	    }
+	  i--;
+	}
+      else if (n == 17)
+	i += 3 + grub_png_get_bits (data, 3) - 1;
+      else
+	i += 11 + grub_png_get_bits (data, 7) - 1;
+    }
+
+  grub_png_build_huff_table (&data->code_table);
+  grub_png_build_huff_table (&data->dist_table);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_png_output_byte (struct grub_png_data *data, grub_uint8_t n)
+{
+  int row_bytes;
+
+  if (--data->raw_bytes < 0)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "image size overflown");
+
+  if (data->cur_column == 0)
+    {
+      if (n >= PNG_FILTER_VALUE_LAST)
+	return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid filter value");
+
+      data->cur_filter = n;
+    }
+  else
+    *(data->cur_rgb++) = n;
+
+  data->cur_column++;
+  row_bytes = data->image_width * data->bpp;
+  if (data->cur_column == row_bytes + 1)
+    {
+      grub_uint8_t *blank_line = NULL;
+      grub_uint8_t *cur = data->cur_rgb - row_bytes;
+      grub_uint8_t *left = cur;
+      grub_uint8_t *up;
+
+      if (data->first_line)
+	{
+	  blank_line = grub_zalloc (row_bytes);
+	  if (blank_line == NULL)
+	    return grub_errno;
+
+	  up = blank_line;
+	}
+      else
+	up = cur - row_bytes;
+
+      switch (data->cur_filter)
+	{
+	case PNG_FILTER_VALUE_SUB:
+	  {
+	    int i;
+
+	    cur += data->bpp;
+	    for (i = data->bpp; i < row_bytes; i++, cur++, left++)
+	      *cur += *left;
+
+	    break;
+	  }
+	case PNG_FILTER_VALUE_UP:
+	  {
+	    int i;
+
+	    for (i = 0; i < row_bytes; i++, cur++, up++)
+	      *cur += *up;
+
+	    break;
+	  }
+	case PNG_FILTER_VALUE_AVG:
+	  {
+	    int i;
+
+	    for (i = 0; i < data->bpp; i++, cur++, up++)
+	      *cur += *up >> 1;
+
+	    for (; i < row_bytes; i++, cur++, up++, left++)
+	      *cur += ((int) *up + (int) *left) >> 1;
+
+	    break;
+	  }
+	case PNG_FILTER_VALUE_PAETH:
+	  {
+	    int i;
+	    grub_uint8_t *upper_left = up;
+
+	    for (i = 0; i < data->bpp; i++, cur++, up++)
+	      *cur += *up;
+
+	    for (; i < row_bytes; i++, cur++, up++, left++, upper_left++)
+	      {
+		int a, b, c, pa, pb, pc;
+
+                a = *left;
+                b = *up;
+                c = *upper_left;
+
+                pa = b - c;
+                pb = a - c;
+                pc = pa + pb;
+
+                if (pa < 0)
+                  pa = -pa;
+
+                if (pb < 0)
+                  pb = -pb;
+
+                if (pc < 0)
+                  pc = -pc;
+
+                *cur += ((pa <= pb) && (pa <= pc)) ? a : (pb <= pc) ? b : c;
+	      }
+	  }
+	}
+
+      if (blank_line)
+	grub_free (blank_line);
+
+      data->cur_column = 0;
+      data->first_line = 0;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_png_read_dynamic_block (struct grub_png_data *data)
+{
+  while (grub_errno == 0)
+    {
+      int n;
+
+      n = grub_png_get_huff_code (data, &data->code_table);
+      if (n < 256)
+	{
+	  data->slide[data->wp] = n;
+	  grub_png_output_byte (data, n);
+
+	  data->wp++;
+	  if (data->wp >= WSIZE)
+	    data->wp = 0;
+	}
+      else if (n == 256)
+	break;
+      else
+	{
+	  int len, dist, pos;
+
+	  n -= 257;
+	  len = cplens[n];
+	  if (cplext[n])
+	    len += grub_png_get_bits (data, cplext[n]);
+
+	  n = grub_png_get_huff_code (data, &data->dist_table);
+	  dist = cpdist[n];
+	  if (cpdext[n])
+	    dist += grub_png_get_bits (data, cpdext[n]);
+
+	  pos = data->wp - dist;
+	  if (pos < 0)
+	    pos += WSIZE;
+
+	  while (len > 0)
+	    {
+	      data->slide[data->wp] = data->slide[pos];
+	      grub_png_output_byte (data, data->slide[data->wp]);
+
+	      data->wp++;
+	      if (data->wp >= WSIZE)
+		data->wp = 0;
+
+	      pos++;
+	      if (pos >= WSIZE)
+		pos = 0;
+
+	      len--;
+	    }
+	}
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_png_decode_image_data (struct grub_png_data *data)
+{
+  grub_uint8_t cmf, flg;
+  int final;
+
+  cmf = grub_png_get_byte (data);
+  flg = grub_png_get_byte (data);
+
+  if ((cmf & 0xF) != Z_DEFLATED)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		       "png: only support deflate compression method");
+
+  if (flg & Z_FLAG_DICT)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+		       "png: dictionary not supported");
+
+  do
+    {
+      int block_type;
+
+      final = grub_png_get_bits (data, 1);
+      block_type = grub_png_get_bits (data, 2);
+
+      switch (block_type)
+	{
+	case INFLATE_STORED:
+	  {
+	    grub_uint16_t i, len;
+
+	    data->bit_count = 0;
+	    len = grub_png_get_byte (data);
+	    len += ((grub_uint16_t) grub_png_get_byte (data)) << 8;
+
+            /* Skip NLEN field.  */
+	    grub_png_get_byte (data);
+	    grub_png_get_byte (data);
+
+	    for (i = 0; i < len; i++)
+	      grub_png_output_byte (data, grub_png_get_byte (data));
+
+	    break;
+	  }
+
+	case INFLATE_FIXED:
+          grub_png_init_fixed_block (data);
+	  grub_png_read_dynamic_block (data);
+	  break;
+
+	case INFLATE_DYNAMIC:
+	  grub_png_init_dynamic_block (data);
+	  grub_png_read_dynamic_block (data);
+	  break;
+
+	default:
+	  return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+			     "png: unknown block type");
+	}
+    }
+  while ((!final) && (grub_errno == 0));
+
+  /* Skip adler checksum.  */
+  grub_png_get_dword (data);
+
+  /* Skip crc checksum.  */
+  grub_png_get_dword (data);
+
+  return grub_errno;
+}
+
+static const grub_uint8_t png_magic[8] =
+  { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0x0a };
+
+static void
+grub_png_convert_image (struct grub_png_data *data)
+{
+  int i;
+  grub_uint8_t *d1, *d2;
+
+  d1 = (*data->bitmap)->data;
+  d2 = data->image_data + 1;
+
+  /* Only copy the upper 8 bit.  */
+  for (i = 0; i < (data->image_width * data->image_height * data->bpp >> 1);
+       i++, d1++, d2+=2)
+    *d1 = *d2;
+}
+
+static grub_err_t
+grub_png_decode_png (struct grub_png_data *data)
+{
+  grub_uint8_t magic[8];
+
+  if (grub_file_read (data->file, &magic[0], 8) != 8)
+    return grub_errno;
+
+  if (grub_memcmp (magic, png_magic, sizeof (png_magic)))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: not a png file");
+
+  while (1)
+    {
+      grub_uint32_t len, type;
+
+      len = grub_png_get_dword (data);
+      type = grub_png_get_dword (data);
+      data->next_offset = data->file->offset + len + 4;
+
+      switch (type)
+	{
+	case PNG_CHUNK_IHDR:
+	  grub_png_decode_image_header (data);
+	  break;
+
+	case PNG_CHUNK_IDAT:
+	  data->inside_idat = 1;
+	  data->idat_remain = len;
+	  data->bit_count = 0;
+
+	  grub_png_decode_image_data (data);
+
+	  data->inside_idat = 0;
+	  break;
+
+	case PNG_CHUNK_IEND:
+          if (data->is_16bit)
+            grub_png_convert_image (data);
+
+	  return grub_errno;
+
+	default:
+	  grub_file_seek (data->file, data->file->offset + len + 4);
+	}
+
+      if (grub_errno)
+        break;
+
+      if (data->file->offset != data->next_offset)
+        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                           "png: chunk size error");
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_video_reader_png (struct grub_video_bitmap **bitmap,
+		       const char *filename)
+{
+  grub_file_t file;
+  struct grub_png_data *data;
+
+  file = grub_buffile_open (filename, 0);
+  if (!file)
+    return grub_errno;
+
+  data = grub_zalloc (sizeof (*data));
+  if (data != NULL)
+    {
+      data->file = file;
+      data->bitmap = bitmap;
+
+      grub_png_decode_png (data);
+
+      grub_free (data->image_data);
+      grub_free (data);
+    }
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_video_bitmap_destroy (*bitmap);
+      *bitmap = 0;
+    }
+
+  grub_file_close (file);
+  return grub_errno;
+}
+
+#if defined(PNG_DEBUG)
+static grub_err_t
+grub_cmd_pngtest (struct grub_arg_list *state __attribute__ ((unused)),
+		  int argc, char **args)
+{
+  struct grub_video_bitmap *bitmap = 0;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  grub_video_reader_png (&bitmap, args[0]);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  grub_video_bitmap_destroy (bitmap);
+
+  return GRUB_ERR_NONE;
+}
+#endif
+
+static struct grub_video_bitmap_reader png_reader = {
+  .extension = ".png",
+  .reader = grub_video_reader_png,
+  .next = 0
+};
+
+GRUB_MOD_INIT (video_reader_png)
+{
+  grub_video_bitmap_reader_register (&png_reader);
+#if defined(PNG_DEBUG)
+  grub_register_command ("pngtest", grub_cmd_pngtest,
+			 GRUB_COMMAND_FLAG_BOTH, "pngtest FILE",
+			 "Tests loading of PNG bitmap.", 0);
+#endif
+}
+
+GRUB_MOD_FINI (video_reader_png)
+{
+#if defined(PNG_DEBUG)
+  grub_unregister_command ("pngtest");
+#endif
+  grub_video_bitmap_reader_unregister (&png_reader);
+}
diff --git a/video/readers/tga.c b/video/readers/tga.c
new file mode 100644
index 0000000..d0ca277
--- /dev/null
+++ b/video/readers/tga.c
@@ -0,0 +1,494 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/bitmap.h>
+#include <grub/types.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/bufio.h>
+
+/* Uncomment following define to enable TGA debug.  */
+//#define TGA_DEBUG
+
+#if defined(TGA_DEBUG)
+#define dump_int_field(x) grub_printf( #x " = %d (0x%04x)\n", x, x);
+#endif
+
+enum
+{
+  GRUB_TGA_IMAGE_TYPE_NONE = 0,
+  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR = 1,
+  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR = 2,
+  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE = 3,
+  GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR = 9,
+  GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR = 10,
+  GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE = 11,
+};
+
+enum
+{
+  GRUB_TGA_COLOR_MAP_TYPE_NONE = 0,
+  GRUB_TGA_COLOR_MAP_TYPE_INCLUDED = 1
+};
+
+enum
+{
+  GRUB_TGA_IMAGE_ORIGIN_RIGHT = 0x10,
+  GRUB_TGA_IMAGE_ORIGIN_TOP   = 0x20
+};
+
+struct grub_tga_header
+{
+  grub_uint8_t id_length;
+  grub_uint8_t color_map_type;
+  grub_uint8_t image_type;
+
+  /* Color Map Specification.  */
+  grub_uint16_t color_map_first_index;
+  grub_uint16_t color_map_length;
+  grub_uint8_t color_map_bpp;
+
+  /* Image Specification.  */
+  grub_uint16_t image_x_origin;
+  grub_uint16_t image_y_origin;
+  grub_uint16_t image_width;
+  grub_uint16_t image_height;
+  grub_uint8_t image_bpp;
+  grub_uint8_t image_descriptor;
+} __attribute__ ((packed));
+
+static grub_err_t
+tga_load_truecolor_rle_R8G8B8 (struct grub_video_bitmap *bitmap,
+                               struct grub_tga_header *header,
+                               grub_file_t file)
+{
+  unsigned int x;
+  unsigned int y;
+  grub_uint8_t type;
+  grub_uint8_t *ptr;
+  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
+  grub_uint8_t bytes_per_pixel;
+
+  bytes_per_pixel = header->image_bpp / 8;
+
+  for (y = 0; y < header->image_height; y++)
+    {
+      ptr = bitmap->data;
+      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
+        ptr += y * bitmap->mode_info.pitch;
+      else
+        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
+
+      for (x = 0; x < header->image_width;)
+        {
+          if (grub_file_read (file, &type, sizeof (type)) != sizeof(type))
+            return grub_errno;
+
+          if (type & 0x80)
+            {
+              /* RLE-encoded packet.  */
+              type &= 0x7f;
+              type++;
+
+              if (grub_file_read (file, &tmp[0], bytes_per_pixel)
+                  != bytes_per_pixel)
+                return grub_errno;
+
+              while (type)
+                {
+                  if (x < header->image_width)
+                    {
+                      ptr[0] = tmp[2];
+                      ptr[1] = tmp[1];
+                      ptr[2] = tmp[0];
+                      ptr += 3;
+                    }
+
+                  type--;
+                  x++;
+                }
+            }
+          else
+            {
+              /* RAW-encoded packet.  */
+              type++;
+
+              while (type)
+                {
+                  if (grub_file_read (file, &tmp[0], bytes_per_pixel)
+                      != bytes_per_pixel)
+                    return grub_errno;
+
+                  if (x < header->image_width)
+                    {
+                      ptr[0] = tmp[2];
+                      ptr[1] = tmp[1];
+                      ptr[2] = tmp[0];
+                      ptr += 3;
+                    }
+
+                  type--;
+                  x++;
+                }
+            }
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+tga_load_truecolor_rle_R8G8B8A8 (struct grub_video_bitmap *bitmap,
+                                 struct grub_tga_header *header,
+                                 grub_file_t file)
+{
+  unsigned int x;
+  unsigned int y;
+  grub_uint8_t type;
+  grub_uint8_t *ptr;
+  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
+  grub_uint8_t bytes_per_pixel;
+
+  bytes_per_pixel = header->image_bpp / 8;
+
+  for (y = 0; y < header->image_height; y++)
+    {
+      ptr = bitmap->data;
+      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
+        ptr += y * bitmap->mode_info.pitch;
+      else
+        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
+
+      for (x = 0; x < header->image_width;)
+        {
+          if (grub_file_read (file, &type, sizeof (type)) != sizeof(type))
+            return grub_errno;
+
+          if (type & 0x80)
+            {
+              /* RLE-encoded packet.  */
+              type &= 0x7f;
+              type++;
+
+              if (grub_file_read (file, &tmp[0], bytes_per_pixel)
+                  != bytes_per_pixel)
+                return grub_errno;
+
+              while (type)
+                {
+                  if (x < header->image_width)
+                    {
+                      ptr[0] = tmp[2];
+                      ptr[1] = tmp[1];
+                      ptr[2] = tmp[0];
+                      ptr[3] = tmp[3];
+                      ptr += 4;
+                    }
+
+                  type--;
+                  x++;
+                }
+            }
+          else
+            {
+              /* RAW-encoded packet.  */
+              type++;
+
+              while (type)
+                {
+                  if (grub_file_read (file, &tmp[0], bytes_per_pixel)
+                      != bytes_per_pixel)
+                    return grub_errno;
+
+                  if (x < header->image_width)
+                    {
+                      ptr[0] = tmp[2];
+                      ptr[1] = tmp[1];
+                      ptr[2] = tmp[0];
+                      ptr[3] = tmp[3];
+                      ptr += 4;
+                    }
+
+                  type--;
+                  x++;
+                }
+            }
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+tga_load_truecolor_R8G8B8 (struct grub_video_bitmap *bitmap,
+                           struct grub_tga_header *header,
+                           grub_file_t file)
+{
+  unsigned int x;
+  unsigned int y;
+  grub_uint8_t *ptr;
+  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
+  grub_uint8_t bytes_per_pixel;
+
+  bytes_per_pixel = header->image_bpp / 8;
+
+  for (y = 0; y < header->image_height; y++)
+    {
+      ptr = bitmap->data;
+      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
+        ptr += y * bitmap->mode_info.pitch;
+      else
+        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
+
+      for (x = 0; x < header->image_width; x++)
+        {
+          if (grub_file_read (file, &tmp[0], bytes_per_pixel)
+              != bytes_per_pixel)
+            return grub_errno;
+
+          ptr[0] = tmp[2];
+          ptr[1] = tmp[1];
+          ptr[2] = tmp[0];
+
+          ptr += 3;
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+tga_load_truecolor_R8G8B8A8 (struct grub_video_bitmap *bitmap,
+                             struct grub_tga_header *header,
+                             grub_file_t file)
+{
+  unsigned int x;
+  unsigned int y;
+  grub_uint8_t *ptr;
+  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
+  grub_uint8_t bytes_per_pixel;
+
+  bytes_per_pixel = header->image_bpp / 8;
+
+  for (y = 0; y < header->image_height; y++)
+    {
+      ptr = bitmap->data;
+      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
+        ptr += y * bitmap->mode_info.pitch;
+      else
+        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
+
+      for (x = 0; x < header->image_width; x++)
+        {
+          if (grub_file_read (file, &tmp[0], bytes_per_pixel)
+              != bytes_per_pixel)
+            return grub_errno;
+
+          ptr[0] = tmp[2];
+          ptr[1] = tmp[1];
+          ptr[2] = tmp[0];
+          ptr[3] = tmp[3];
+
+          ptr += 4;
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_reader_tga (struct grub_video_bitmap **bitmap,
+                       const char *filename)
+{
+  grub_file_t file;
+  grub_ssize_t pos;
+  struct grub_tga_header header;
+  int has_alpha;
+
+  file = grub_buffile_open (filename, 0);
+  if (! file)
+    return grub_errno;
+
+  /* TGA Specification states that we SHOULD start by reading
+     ID from end of file, but we really don't care about that as we are
+     not going to support developer area & extensions at this point.  */
+
+  /* Read TGA header from beginning of file.  */
+  if (grub_file_read (file, &header, sizeof (header))
+      != sizeof (header))
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+  /* Skip ID field.  */
+  pos = grub_file_tell (file);
+  pos += header.id_length;
+  grub_file_seek (file, pos);
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+#if defined(TGA_DEBUG)
+  grub_printf("tga: header\n");
+  dump_int_field(header.id_length);
+  dump_int_field(header.color_map_type);
+  dump_int_field(header.image_type);
+  dump_int_field(header.color_map_first_index);
+  dump_int_field(header.color_map_length);
+  dump_int_field(header.color_map_bpp);
+  dump_int_field(header.image_x_origin);
+  dump_int_field(header.image_y_origin);
+  dump_int_field(header.image_width);
+  dump_int_field(header.image_height);
+  dump_int_field(header.image_bpp);
+  dump_int_field(header.image_descriptor);
+#endif
+
+  /* Check that bitmap encoding is supported.  */
+  switch (header.image_type)
+    {
+      case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
+      case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
+        break;
+
+      default:
+        grub_file_close (file);
+        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                           "Unsupported bitmap format (unknown encoding).");
+    }
+
+  /* Check that bitmap depth is supported.  */
+  switch (header.image_bpp)
+    {
+      case 24:
+        has_alpha = 0;
+        break;
+
+      case 32:
+        has_alpha = 1;
+        break;
+
+      default:
+        grub_file_close (file);
+        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                           "Unsupported bitmap format (bpp=%d).",
+                           header.image_bpp);
+    }
+
+  /* Allocate bitmap.  If there is alpha information store it too.  */
+  if (has_alpha)
+    {
+      grub_video_bitmap_create (bitmap, header.image_width,
+                                header.image_height,
+                                GRUB_VIDEO_BLIT_FORMAT_RGBA_8888);
+      if (grub_errno != GRUB_ERR_NONE)
+        {
+          grub_file_close (file);
+          return grub_errno;
+        }
+
+      /* Load bitmap data.  */
+      switch (header.image_type)
+        {
+          case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
+            tga_load_truecolor_R8G8B8A8 (*bitmap, &header, file);
+            break;
+
+          case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
+            tga_load_truecolor_rle_R8G8B8A8 (*bitmap, &header, file);
+            break;
+        }
+    }
+  else
+    {
+      grub_video_bitmap_create (bitmap, header.image_width,
+                                header.image_height,
+                                GRUB_VIDEO_BLIT_FORMAT_RGB_888);
+      if (grub_errno != GRUB_ERR_NONE)
+        {
+          grub_file_close (file);
+          return grub_errno;
+        }
+
+      /* Load bitmap data.  */
+      switch (header.image_type)
+        {
+          case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
+            tga_load_truecolor_R8G8B8 (*bitmap, &header, file);
+            break;
+
+          case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
+            tga_load_truecolor_rle_R8G8B8 (*bitmap, &header, file);
+            break;
+        }
+    }
+
+  /* If there was a loading problem, destroy bitmap.  */
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_video_bitmap_destroy (*bitmap);
+      *bitmap = 0;
+    }
+
+  grub_file_close (file);
+  return grub_errno;
+}
+
+#if defined(TGA_DEBUG)
+static grub_err_t
+grub_cmd_tgatest (struct grub_arg_list *state __attribute__ ((unused)),
+                  int argc, char **args)
+{
+  struct grub_video_bitmap *bitmap = 0;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  grub_video_reader_tga (&bitmap, args[0]);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  grub_video_bitmap_destroy (bitmap);
+
+  return GRUB_ERR_NONE;
+}
+#endif
+
+static struct grub_video_bitmap_reader tga_reader = {
+  .extension = ".tga",
+  .reader = grub_video_reader_tga,
+  .next = 0
+};
+
+GRUB_MOD_INIT(video_reader_tga)
+{
+  grub_video_bitmap_reader_register (&tga_reader);
+#if defined(TGA_DEBUG)
+  grub_register_command ("tgatest", grub_cmd_tgatest, GRUB_COMMAND_FLAG_BOTH,
+                         "tgatest FILE", "Tests loading of TGA bitmap.", 0);
+#endif
+}
+
+GRUB_MOD_FINI(video_reader_tga)
+{
+#if defined(TGA_DEBUG)
+  grub_unregister_command ("tgatest");
+#endif
+  grub_video_bitmap_reader_unregister (&tga_reader);
+}
diff --git a/video/video.c b/video/video.c
new file mode 100644
index 0000000..c1d66bd
--- /dev/null
+++ b/video/video.c
@@ -0,0 +1,723 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/video.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+/* The list of video adapters registered to system.  */
+static grub_video_adapter_t grub_video_adapter_list;
+
+/* Active video adapter.  */
+static grub_video_adapter_t grub_video_adapter_active;
+
+/* Register video driver.  */
+void
+grub_video_register (grub_video_adapter_t adapter)
+{
+  adapter->next = grub_video_adapter_list;
+  grub_video_adapter_list = adapter;
+}
+
+/* Unregister video driver.  */
+void
+grub_video_unregister (grub_video_adapter_t adapter)
+{
+  grub_video_adapter_t *p, q;
+
+  for (p = &grub_video_adapter_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == adapter)
+      {
+        *p = q->next;
+        break;
+      }
+}
+
+/* Iterate thru all registered video drivers.  */
+void
+grub_video_iterate (int (*hook) (grub_video_adapter_t adapter))
+{
+  grub_video_adapter_t p;
+
+  for (p = grub_video_adapter_list; p; p = p->next)
+    if (hook (p))
+      break;
+}
+
+/* Restore back to initial mode (where applicable).  */
+grub_err_t
+grub_video_restore (void)
+{
+  if (grub_video_adapter_active)
+    {
+      grub_video_adapter_active->fini ();
+      if (grub_errno != GRUB_ERR_NONE)
+        return grub_errno;
+
+      grub_video_adapter_active = 0;
+    }
+  return GRUB_ERR_NONE;
+}
+
+/* Get information about active video mode.  */
+grub_err_t
+grub_video_get_info (struct grub_video_mode_info *mode_info)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  /* If mode_info is NULL just report that video adapter is active.  */
+  if (! mode_info)
+    {
+      grub_errno = GRUB_ERR_NONE;
+      return grub_errno;
+    }
+
+  return grub_video_adapter_active->get_info (mode_info);
+}
+
+/* Get information about active video mode.  */
+grub_err_t
+grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info,
+			      void **framebuffer)
+{
+  grub_err_t err;
+
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  err = grub_video_adapter_active->get_info_and_fini (mode_info, framebuffer);
+  if (err)
+    return err;
+
+  grub_video_adapter_active = 0;
+  return GRUB_ERR_NONE;
+}
+
+/* Determine optimized blitting formation for specified video mode info.  */
+enum grub_video_blit_format
+grub_video_get_blit_format (struct grub_video_mode_info *mode_info)
+{
+  /* Check if we have any known 32 bit modes.  */
+  if (mode_info->bpp == 32)
+    {
+      if ((mode_info->red_mask_size == 8)
+	  && (mode_info->red_field_pos == 16)
+	  && (mode_info->green_mask_size == 8)
+	  && (mode_info->green_field_pos == 8)
+	  && (mode_info->blue_mask_size == 8)
+	  && (mode_info->blue_field_pos == 0))
+	{
+	  return GRUB_VIDEO_BLIT_FORMAT_BGRA_8888;
+	}
+      else if ((mode_info->red_mask_size == 8)
+	       && (mode_info->red_field_pos == 0)
+	       && (mode_info->green_mask_size == 8)
+	       && (mode_info->green_field_pos == 8)
+	       && (mode_info->blue_mask_size == 8)
+	       && (mode_info->blue_field_pos == 16))
+	{
+	  return GRUB_VIDEO_BLIT_FORMAT_RGBA_8888;
+	}
+    }
+  /* Check if we have any known 24 bit modes.  */
+  else if (mode_info->bpp == 24)
+    {
+      if ((mode_info->red_mask_size == 8)
+	  && (mode_info->red_field_pos == 16)
+	  && (mode_info->green_mask_size == 8)
+	  && (mode_info->green_field_pos == 8)
+	  && (mode_info->blue_mask_size == 8)
+	  && (mode_info->blue_field_pos == 0))
+	{
+	  return GRUB_VIDEO_BLIT_FORMAT_BGR_888;
+	}
+      else if ((mode_info->red_mask_size == 8)
+	       && (mode_info->red_field_pos == 0)
+	       && (mode_info->green_mask_size == 8)
+	       && (mode_info->green_field_pos == 8)
+	       && (mode_info->blue_mask_size == 8)
+	       && (mode_info->blue_field_pos == 16))
+	{
+	  return GRUB_VIDEO_BLIT_FORMAT_RGB_888;
+	}
+    }
+  /* Check if we have any known 16 bit modes.  */
+  else if (mode_info->bpp == 16)
+    {
+      if ((mode_info->red_mask_size == 5)
+	  && (mode_info->red_field_pos == 11)
+	  && (mode_info->green_mask_size == 6)
+	  && (mode_info->green_field_pos == 5)
+	  && (mode_info->blue_mask_size == 5)
+	  && (mode_info->blue_field_pos == 0))
+	{
+	  return GRUB_VIDEO_BLIT_FORMAT_BGR_565;
+	}
+      else if ((mode_info->red_mask_size == 5)
+	       && (mode_info->red_field_pos == 0)
+	       && (mode_info->green_mask_size == 6)
+	       && (mode_info->green_field_pos == 5)
+	       && (mode_info->blue_mask_size == 5)
+	       && (mode_info->blue_field_pos == 11))
+	{
+	  return GRUB_VIDEO_BLIT_FORMAT_RGB_565;
+	}
+    }
+  else if (mode_info->bpp == 1)
+    return GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED;
+
+  /* Backup route.  Unknown format.  */
+
+  /* If there are more than 8 bits per color, assume RGB(A) mode.  */
+  if (mode_info->bpp > 8)
+    {
+      if (mode_info->reserved_mask_size > 0)
+	{
+	  return GRUB_VIDEO_BLIT_FORMAT_RGBA;
+	}
+      else
+	{
+	  return GRUB_VIDEO_BLIT_FORMAT_RGB;
+	}
+    }
+
+  /* Assume as indexcolor mode.  */
+  return GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR;
+}
+
+/* Set new indexed color palette entries.  */
+grub_err_t
+grub_video_set_palette (unsigned int start, unsigned int count,
+                        struct grub_video_palette_data *palette_data)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->set_palette (start, count, palette_data);
+}
+
+/* Get indexed color palette entries.  */
+grub_err_t
+grub_video_get_palette (unsigned int start, unsigned int count,
+                        struct grub_video_palette_data *palette_data)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->get_palette (start, count, palette_data);
+}
+
+/* Set viewport dimensions.  */
+grub_err_t
+grub_video_set_viewport (unsigned int x, unsigned int y,
+                         unsigned int width, unsigned int height)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->set_viewport (x, y, width, height);
+}
+
+/* Get viewport dimensions.  */
+grub_err_t
+grub_video_get_viewport (unsigned int *x, unsigned int *y,
+                         unsigned int *width, unsigned int *height)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->get_viewport (x, y, width, height);
+}
+
+/* Map color name to adapter specific color.  */
+grub_video_color_t
+grub_video_map_color (grub_uint32_t color_name)
+{
+  if (! grub_video_adapter_active)
+    return 0;
+
+  return grub_video_adapter_active->map_color (color_name);
+}
+
+/* Map RGB value to adapter specific color.  */
+grub_video_color_t
+grub_video_map_rgb (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue)
+{
+  if (! grub_video_adapter_active)
+    return 0;
+
+  return grub_video_adapter_active->map_rgb (red, green, blue);
+}
+
+/* Map RGBA value to adapter specific color.  */
+grub_video_color_t
+grub_video_map_rgba (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue,
+                     grub_uint8_t alpha)
+{
+  if (! grub_video_adapter_active)
+    return 0;
+
+  return grub_video_adapter_active->map_rgba (red, green, blue, alpha);
+}
+
+/* Unmap video color back to RGBA components.  */
+grub_err_t
+grub_video_unmap_color (grub_video_color_t color, grub_uint8_t *red,
+                        grub_uint8_t *green, grub_uint8_t *blue,
+                        grub_uint8_t *alpha)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->unmap_color (color,
+                                                 red,
+                                                 green,
+                                                 blue,
+                                                 alpha);
+}
+
+/* Fill rectangle using specified color.  */
+grub_err_t
+grub_video_fill_rect (grub_video_color_t color, int x, int y,
+                      unsigned int width, unsigned int height)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->fill_rect (color, x, y, width, height);
+}
+
+/* Blit bitmap to screen.  */
+grub_err_t
+grub_video_blit_bitmap (struct grub_video_bitmap *bitmap,
+                        enum grub_video_blit_operators oper,
+                        int x, int y, int offset_x, int offset_y,
+                        unsigned int width, unsigned int height)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->blit_bitmap (bitmap, oper, x, y,
+                                                 offset_x, offset_y,
+                                                 width, height);
+}
+
+/* Blit render target to active render target.  */
+grub_err_t
+grub_video_blit_render_target (struct grub_video_render_target *target,
+                               enum grub_video_blit_operators oper,
+                               int x, int y, int offset_x, int offset_y,
+                               unsigned int width, unsigned int height)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->blit_render_target (target, oper, x, y,
+                                                        offset_x, offset_y,
+                                                        width, height);
+}
+
+/* Scroll viewport and fill new areas with specified color.  */
+grub_err_t
+grub_video_scroll (grub_video_color_t color, int dx, int dy)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->scroll (color, dx, dy);
+}
+
+/* Swap buffers (swap active render target).  */
+grub_err_t
+grub_video_swap_buffers (void)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->swap_buffers ();
+}
+
+/* Create new render target.  */
+grub_err_t
+grub_video_create_render_target (struct grub_video_render_target **result,
+                                 unsigned int width, unsigned int height,
+                                 unsigned int mode_type)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->create_render_target (result,
+                                                          width, height,
+                                                          mode_type);
+}
+
+/* Delete render target.  */
+grub_err_t
+grub_video_delete_render_target (struct grub_video_render_target *target)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->delete_render_target (target);
+}
+
+/* Set active render target.  */
+grub_err_t
+grub_video_set_active_render_target (struct grub_video_render_target *target)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->set_active_render_target (target);
+}
+
+/* Get active render target.  */
+grub_err_t
+grub_video_get_active_render_target (struct grub_video_render_target **target)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
+
+  return grub_video_adapter_active->get_active_render_target (target);
+}
+
+grub_err_t
+grub_video_set_mode (const char *modestring,
+		     int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p,
+						   struct grub_video_mode_info *mode_info))
+{
+  char *tmp;
+  char *next_mode;
+  char *current_mode;
+  char *param;
+  char *value;
+  char *modevar;
+  int width = -1;
+  int height = -1;
+  int depth = -1;
+  int flags = 0;
+
+  /* Take copy of env.var. as we don't want to modify that.  */
+  modevar = grub_strdup (modestring);
+
+  /* Initialize next mode.  */
+  next_mode = modevar;
+
+  if (! modevar)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		       "couldn't allocate space for local modevar copy");
+
+  if (grub_memcmp (next_mode, "keep", sizeof ("keep")) == 0
+      || grub_memcmp (next_mode, "keep,", sizeof ("keep,") - 1) == 0
+      || grub_memcmp (next_mode, "keep;", sizeof ("keep;") - 1) == 0)
+    {
+      struct grub_video_mode_info mode_info;
+      int suitable = 1;
+      grub_err_t err;
+
+      grub_memset (&mode_info, 0, sizeof (mode_info));
+
+      if (grub_video_adapter_active)
+	{
+	  err = grub_video_get_info (&mode_info);
+	  if (err)
+	    {
+	      suitable = 0;
+	      grub_errno = GRUB_ERR_NONE;
+	    }
+	}
+      else
+	mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_PURE_TEXT;
+
+      if (suitable && hook)
+	suitable = hook (grub_video_adapter_active, &mode_info);
+      if (suitable)
+	{
+	  grub_free (modevar);
+	  return GRUB_ERR_NONE;
+	}
+      next_mode += sizeof ("keep") - 1;
+      if (! *next_mode)
+	{
+	  grub_free (modevar);
+
+	  return grub_error (GRUB_ERR_BAD_ARGUMENT,
+			     "No suitable mode found.");
+	}
+
+      /* Skip separator. */
+      next_mode++;
+    }
+
+  /* De-activate last set video adapter.  */
+  if (grub_video_adapter_active)
+    {
+      /* Finalize adapter.  */
+      grub_video_adapter_active->fini ();
+      if (grub_errno != GRUB_ERR_NONE)
+	grub_errno = GRUB_ERR_NONE;
+
+      /* Mark active adapter as not set.  */
+      grub_video_adapter_active = 0;
+    }
+
+  /* Loop until all modes has been tested out.  */
+  while (next_mode != NULL)
+    {
+      /* Use last next_mode as current mode.  */
+      tmp = next_mode;
+
+      /* Reset video mode settings.  */
+      width = -1;
+      height = -1;
+      depth = -1;
+      flags = 0;
+
+      /* Save position of next mode and separate modes.  */
+      for (; *next_mode; next_mode++)
+	if (*next_mode == ',' || *next_mode == ';')
+	  break;
+      if (*next_mode)
+	{
+	  *next_mode = 0;
+	  next_mode++;
+	}
+      else
+	next_mode = 0;
+
+      /* Skip whitespace.  */
+      while (grub_isspace (*tmp))
+	tmp++;
+
+      /* Initialize token holders.  */
+      current_mode = tmp;
+      param = tmp;
+      value = NULL;
+
+      /* XXX: we assume that we're in pure text mode if
+	 no video mode is initialized. Is it always true? */
+      if (grub_strcmp (param, "text") == 0)
+	{
+	  struct grub_video_mode_info mode_info;
+
+	  grub_memset (&mode_info, 0, sizeof (mode_info));
+	  mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_PURE_TEXT;
+
+	  if (! hook || hook (0, &mode_info))
+	    {
+	      /* Valid mode found from adapter, and it has been activated.
+		 Specify it as active adapter.  */
+	      grub_video_adapter_active = NULL;
+
+	      /* Free memory.  */
+	      grub_free (modevar);
+
+	      return GRUB_ERR_NONE;
+	    }
+	}
+
+      /* Parse <width>x<height>[x<depth>]*/
+
+      /* Find width value.  */
+      value = param;
+      param = grub_strchr(param, 'x');
+      if (param == NULL)
+	{
+	  grub_err_t rc;
+
+	  /* First setup error message.  */
+	  rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
+			   "Invalid mode: %s\n",
+			   current_mode);
+
+	  /* Free memory before returning.  */
+	  grub_free (modevar);
+
+	  return rc;
+	}
+
+      *param = 0;
+      param++;
+
+      width = grub_strtoul (value, 0, 0);
+      if (grub_errno != GRUB_ERR_NONE)
+	{
+	  grub_err_t rc;
+
+	  /* First setup error message.  */
+	  rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
+			   "Invalid mode: %s\n",
+			   current_mode);
+
+	  /* Free memory before returning.  */
+	  grub_free (modevar);
+
+	  return rc;
+	}
+
+      /* Find height value.  */
+      value = param;
+      param = grub_strchr(param, 'x');
+      if (param == NULL)
+	{
+	  height = grub_strtoul (value, 0, 0);
+	  if (grub_errno != GRUB_ERR_NONE)
+	    {
+	      grub_err_t rc;
+
+	      /* First setup error message.  */
+	      rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
+			       "Invalid mode: %s\n",
+			       current_mode);
+
+	      /* Free memory before returning.  */
+	      grub_free (modevar);
+
+	      return rc;
+	    }
+	}
+      else
+	{
+	  /* We have optional color depth value.  */
+	  *param = 0;
+	  param++;
+
+	  height = grub_strtoul (value, 0, 0);
+	  if (grub_errno != GRUB_ERR_NONE)
+	    {
+	      grub_err_t rc;
+
+	      /* First setup error message.  */
+	      rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
+			       "Invalid mode: %s\n",
+			       current_mode);
+
+	      /* Free memory before returning.  */
+	      grub_free (modevar);
+
+	      return rc;
+	    }
+
+	  /* Convert color depth value.  */
+	  value = param;
+	  depth = grub_strtoul (value, 0, 0);
+	  if (grub_errno != GRUB_ERR_NONE)
+	    {
+	      grub_err_t rc;
+
+	      /* First setup error message.  */
+	      rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
+			       "Invalid mode: %s\n",
+			       current_mode);
+
+	      /* Free memory before returning.  */
+	      grub_free (modevar);
+
+	      return rc;
+	    }
+	}
+
+      /* Try out video mode.  */
+
+      /* If we have 8 or less bits, then assume that it is indexed color mode.  */
+      if ((depth <= 8) && (depth != -1))
+	flags |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+
+      /* We have more than 8 bits, then assume that it is RGB color mode.  */
+      if (depth > 8)
+	flags |= GRUB_VIDEO_MODE_TYPE_RGB;
+
+      /* If user requested specific depth, forward that information to driver.  */
+      if (depth != -1)
+	flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
+	  & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
+
+      /* Try to initialize requested mode.  Ignore any errors.  */
+      grub_video_adapter_t p;
+
+      /* Loop thru all possible video adapter trying to find requested mode.  */
+      for (p = grub_video_adapter_list; p; p = p->next)
+	{
+	  grub_err_t err;
+	  struct grub_video_mode_info mode_info;
+
+	  grub_memset (&mode_info, 0, sizeof (mode_info));
+
+	  /* Try to initialize adapter, if it fails, skip to next adapter.  */
+	  err = p->init ();
+	  if (err != GRUB_ERR_NONE)
+	    {
+	      grub_errno = GRUB_ERR_NONE;
+	      continue;
+	    }
+
+	  /* Try to initialize video mode.  */
+	  err = p->setup (width, height, flags);
+	  if (err != GRUB_ERR_NONE)
+	    {
+	      p->fini ();
+	      grub_errno = GRUB_ERR_NONE;
+	      continue;
+	    }
+
+	  err = p->get_info (&mode_info);
+	  if (err != GRUB_ERR_NONE)
+	    {
+	      p->fini ();
+	      grub_errno = GRUB_ERR_NONE;
+	      continue;
+	    }
+
+	  if (hook && ! hook (p, &mode_info))
+	    {
+	      p->fini ();
+	      grub_errno = GRUB_ERR_NONE;
+	      continue;
+	    }
+
+	  /* Valid mode found from adapter, and it has been activated.
+	     Specify it as active adapter.  */
+	  grub_video_adapter_active = p;
+
+	  /* Free memory.  */
+	  grub_free (modevar);
+
+	  return GRUB_ERR_NONE;
+	}
+
+    }
+
+  /* Free memory.  */
+  grub_free (modevar);
+
+  return grub_error (GRUB_ERR_BAD_ARGUMENT,
+		     "No suitable mode found.");
+}
+
+/* Initialize Video API module.  */
+GRUB_MOD_INIT(video_video)
+{
+}
+
+/* Finalize Video API module.  */
+GRUB_MOD_FINI(video_video)
+{
+}