direct-io.hg

changeset 4366:fedff27be9eb

bitkeeper revision 1.1236.1.149 (42492762NRUXAIqtzpmd2lX5HSPVog)

Added the mbootpack tool, which packages multiboot boot files and
disguises them as a linux bzImage. Useful for booting Xen using
pxelinux, or another linux-only bootloader.

Signed-off-by: Tim Deegan <Tim.Deegan@cl.cam.ac.uk>
author tjd21@arcadians.cl.cam.ac.uk
date Tue Mar 29 10:01:06 2005 +0000 (2005-03-29)
parents 5dda4da58939
children 7d66265be1c5
files .rootkeys BitKeeper/etc/logging_ok tools/misc/Makefile tools/misc/mbootpack/GPL tools/misc/mbootpack/Makefile tools/misc/mbootpack/README tools/misc/mbootpack/bin2c.c tools/misc/mbootpack/bootsect.S tools/misc/mbootpack/buildimage.c tools/misc/mbootpack/mb_header.h tools/misc/mbootpack/mb_info.h tools/misc/mbootpack/mbootpack.c tools/misc/mbootpack/mbootpack.h tools/misc/mbootpack/setup.S
line diff
     1.1 --- a/.rootkeys	Tue Mar 29 08:06:06 2005 +0000
     1.2 +++ b/.rootkeys	Tue Mar 29 10:01:06 2005 +0000
     1.3 @@ -696,6 +696,17 @@ 41a216cayFe2FQroFuzvNPw1AvNiqQ tools/lib
     1.4  41a216ca7mgVSnCBHPCLkGOIqPS1CQ tools/libxutil/util.h
     1.5  3f776bd2Xd-dUcPKlPN2vG89VGtfvQ tools/misc/Makefile
     1.6  40ab2cfawIw8tsYo0dQKtp83h4qfTQ tools/misc/fakei386xen
     1.7 +4249273cDOw6_uLUPvvUwWU1ZrJxnQ tools/misc/mbootpack/GPL
     1.8 +4249273cSmj2h8Fj3UpTg0g-k6CLsA tools/misc/mbootpack/Makefile
     1.9 +4249273c8gKIttF1QPiczvGo5AEOeA tools/misc/mbootpack/README
    1.10 +4249273c4N4PAkvt3trNlto4h76k8A tools/misc/mbootpack/bin2c.c
    1.11 +4249273cISg5nhW1Pt7OJ0jFu343ig tools/misc/mbootpack/bootsect.S
    1.12 +4249273cUiz8CgLqnG7XYFa8x5-MoQ tools/misc/mbootpack/buildimage.c
    1.13 +4249273c_gZ2yI_h-ci66E1Y5oSEPA tools/misc/mbootpack/mb_header.h
    1.14 +4249273cWnlW0-lOIYua1bkKirn6vA tools/misc/mbootpack/mb_info.h
    1.15 +4249273cA8LI3IMaSuhLOjykuMeQJA tools/misc/mbootpack/mbootpack.c
    1.16 +4249273cVTgyv2HYd-mC29IDaz0-mg tools/misc/mbootpack/mbootpack.h
    1.17 +4249273cLXQbRWFp_v-FqcyOm0sYtg tools/misc/mbootpack/setup.S
    1.18  3f6dc136ZKOjd8PIqLbFBl_v-rnkGg tools/misc/miniterm/Makefile
    1.19  3f6dc140C8tAeBfroAF24VrmCS4v_w tools/misc/miniterm/README
    1.20  3f6dc142IHaf6XIcAYGmhV9nNSIHFQ tools/misc/miniterm/miniterm.c
     2.1 --- a/BitKeeper/etc/logging_ok	Tue Mar 29 08:06:06 2005 +0000
     2.2 +++ b/BitKeeper/etc/logging_ok	Tue Mar 29 10:01:06 2005 +0000
     2.3 @@ -81,6 +81,7 @@ smh22@uridium.cl.cam.ac.uk
     2.4  sos22@donkeykong.cl.cam.ac.uk
     2.5  sos22@douglas.cl.cam.ac.uk
     2.6  sos22@labyrinth.cl.cam.ac.uk
     2.7 +tjd21@arcadians.cl.cam.ac.uk
     2.8  tlh20@elite.cl.cam.ac.uk
     2.9  tlh20@labyrinth.cl.cam.ac.uk
    2.10  tw275@labyrinth.cl.cam.ac.uk
     3.1 --- a/tools/misc/Makefile	Tue Mar 29 08:06:06 2005 +0000
     3.2 +++ b/tools/misc/Makefile	Tue Mar 29 10:01:06 2005 +0000
     3.3 @@ -21,6 +21,7 @@ INSTALL_SBIN = netfix xm xend xensv xenp
     3.4  all: build
     3.5  build: $(TARGETS)
     3.6  	$(MAKE) -C miniterm
     3.7 +	$(MAKE) -C mbootpack
     3.8  
     3.9  install: build
    3.10  	[ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin
    3.11 @@ -29,10 +30,13 @@ install: build
    3.12  	$(INSTALL_PROG) $(INSTALL_SBIN) $(DESTDIR)/usr/sbin
    3.13  #       No sense in installing miniterm on the Xen box.
    3.14  #	$(MAKE) -C miniterm install
    3.15 +#       Likewise mbootpack
    3.16 +#	$(MAKE) -C mbootpack install
    3.17  
    3.18  clean:
    3.19  	$(RM) *.o $(TARGETS) *~
    3.20  	$(MAKE) -C miniterm clean
    3.21 +	$(MAKE) -C mbootpack clean
    3.22  
    3.23  %.o: %.c $(HDRS) Makefile
    3.24  	$(CC) -c $(CFLAGS) -o $@ $<
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/misc/mbootpack/GPL	Tue Mar 29 10:01:06 2005 +0000
     4.3 @@ -0,0 +1,340 @@
     4.4 +		    GNU GENERAL PUBLIC LICENSE
     4.5 +		       Version 2, June 1991
     4.6 +
     4.7 + Copyright (C) 1989, 1991 Free Software Foundation, Inc.
     4.8 +                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     4.9 + Everyone is permitted to copy and distribute verbatim copies
    4.10 + of this license document, but changing it is not allowed.
    4.11 +
    4.12 +			    Preamble
    4.13 +
    4.14 +  The licenses for most software are designed to take away your
    4.15 +freedom to share and change it.  By contrast, the GNU General Public
    4.16 +License is intended to guarantee your freedom to share and change free
    4.17 +software--to make sure the software is free for all its users.  This
    4.18 +General Public License applies to most of the Free Software
    4.19 +Foundation's software and to any other program whose authors commit to
    4.20 +using it.  (Some other Free Software Foundation software is covered by
    4.21 +the GNU Library General Public License instead.)  You can apply it to
    4.22 +your programs, too.
    4.23 +
    4.24 +  When we speak of free software, we are referring to freedom, not
    4.25 +price.  Our General Public Licenses are designed to make sure that you
    4.26 +have the freedom to distribute copies of free software (and charge for
    4.27 +this service if you wish), that you receive source code or can get it
    4.28 +if you want it, that you can change the software or use pieces of it
    4.29 +in new free programs; and that you know you can do these things.
    4.30 +
    4.31 +  To protect your rights, we need to make restrictions that forbid
    4.32 +anyone to deny you these rights or to ask you to surrender the rights.
    4.33 +These restrictions translate to certain responsibilities for you if you
    4.34 +distribute copies of the software, or if you modify it.
    4.35 +
    4.36 +  For example, if you distribute copies of such a program, whether
    4.37 +gratis or for a fee, you must give the recipients all the rights that
    4.38 +you have.  You must make sure that they, too, receive or can get the
    4.39 +source code.  And you must show them these terms so they know their
    4.40 +rights.
    4.41 +
    4.42 +  We protect your rights with two steps: (1) copyright the software, and
    4.43 +(2) offer you this license which gives you legal permission to copy,
    4.44 +distribute and/or modify the software.
    4.45 +
    4.46 +  Also, for each author's protection and ours, we want to make certain
    4.47 +that everyone understands that there is no warranty for this free
    4.48 +software.  If the software is modified by someone else and passed on, we
    4.49 +want its recipients to know that what they have is not the original, so
    4.50 +that any problems introduced by others will not reflect on the original
    4.51 +authors' reputations.
    4.52 +
    4.53 +  Finally, any free program is threatened constantly by software
    4.54 +patents.  We wish to avoid the danger that redistributors of a free
    4.55 +program will individually obtain patent licenses, in effect making the
    4.56 +program proprietary.  To prevent this, we have made it clear that any
    4.57 +patent must be licensed for everyone's free use or not licensed at all.
    4.58 +
    4.59 +  The precise terms and conditions for copying, distribution and
    4.60 +modification follow.
    4.61 +
    4.62 +		    GNU GENERAL PUBLIC LICENSE
    4.63 +   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
    4.64 +
    4.65 +  0. This License applies to any program or other work which contains
    4.66 +a notice placed by the copyright holder saying it may be distributed
    4.67 +under the terms of this General Public License.  The "Program", below,
    4.68 +refers to any such program or work, and a "work based on the Program"
    4.69 +means either the Program or any derivative work under copyright law:
    4.70 +that is to say, a work containing the Program or a portion of it,
    4.71 +either verbatim or with modifications and/or translated into another
    4.72 +language.  (Hereinafter, translation is included without limitation in
    4.73 +the term "modification".)  Each licensee is addressed as "you".
    4.74 +
    4.75 +Activities other than copying, distribution and modification are not
    4.76 +covered by this License; they are outside its scope.  The act of
    4.77 +running the Program is not restricted, and the output from the Program
    4.78 +is covered only if its contents constitute a work based on the
    4.79 +Program (independent of having been made by running the Program).
    4.80 +Whether that is true depends on what the Program does.
    4.81 +
    4.82 +  1. You may copy and distribute verbatim copies of the Program's
    4.83 +source code as you receive it, in any medium, provided that you
    4.84 +conspicuously and appropriately publish on each copy an appropriate
    4.85 +copyright notice and disclaimer of warranty; keep intact all the
    4.86 +notices that refer to this License and to the absence of any warranty;
    4.87 +and give any other recipients of the Program a copy of this License
    4.88 +along with the Program.
    4.89 +
    4.90 +You may charge a fee for the physical act of transferring a copy, and
    4.91 +you may at your option offer warranty protection in exchange for a fee.
    4.92 +
    4.93 +  2. You may modify your copy or copies of the Program or any portion
    4.94 +of it, thus forming a work based on the Program, and copy and
    4.95 +distribute such modifications or work under the terms of Section 1
    4.96 +above, provided that you also meet all of these conditions:
    4.97 +
    4.98 +    a) You must cause the modified files to carry prominent notices
    4.99 +    stating that you changed the files and the date of any change.
   4.100 +
   4.101 +    b) You must cause any work that you distribute or publish, that in
   4.102 +    whole or in part contains or is derived from the Program or any
   4.103 +    part thereof, to be licensed as a whole at no charge to all third
   4.104 +    parties under the terms of this License.
   4.105 +
   4.106 +    c) If the modified program normally reads commands interactively
   4.107 +    when run, you must cause it, when started running for such
   4.108 +    interactive use in the most ordinary way, to print or display an
   4.109 +    announcement including an appropriate copyright notice and a
   4.110 +    notice that there is no warranty (or else, saying that you provide
   4.111 +    a warranty) and that users may redistribute the program under
   4.112 +    these conditions, and telling the user how to view a copy of this
   4.113 +    License.  (Exception: if the Program itself is interactive but
   4.114 +    does not normally print such an announcement, your work based on
   4.115 +    the Program is not required to print an announcement.)
   4.116 +
   4.117 +These requirements apply to the modified work as a whole.  If
   4.118 +identifiable sections of that work are not derived from the Program,
   4.119 +and can be reasonably considered independent and separate works in
   4.120 +themselves, then this License, and its terms, do not apply to those
   4.121 +sections when you distribute them as separate works.  But when you
   4.122 +distribute the same sections as part of a whole which is a work based
   4.123 +on the Program, the distribution of the whole must be on the terms of
   4.124 +this License, whose permissions for other licensees extend to the
   4.125 +entire whole, and thus to each and every part regardless of who wrote it.
   4.126 +
   4.127 +Thus, it is not the intent of this section to claim rights or contest
   4.128 +your rights to work written entirely by you; rather, the intent is to
   4.129 +exercise the right to control the distribution of derivative or
   4.130 +collective works based on the Program.
   4.131 +
   4.132 +In addition, mere aggregation of another work not based on the Program
   4.133 +with the Program (or with a work based on the Program) on a volume of
   4.134 +a storage or distribution medium does not bring the other work under
   4.135 +the scope of this License.
   4.136 +
   4.137 +  3. You may copy and distribute the Program (or a work based on it,
   4.138 +under Section 2) in object code or executable form under the terms of
   4.139 +Sections 1 and 2 above provided that you also do one of the following:
   4.140 +
   4.141 +    a) Accompany it with the complete corresponding machine-readable
   4.142 +    source code, which must be distributed under the terms of Sections
   4.143 +    1 and 2 above on a medium customarily used for software interchange; or,
   4.144 +
   4.145 +    b) Accompany it with a written offer, valid for at least three
   4.146 +    years, to give any third party, for a charge no more than your
   4.147 +    cost of physically performing source distribution, a complete
   4.148 +    machine-readable copy of the corresponding source code, to be
   4.149 +    distributed under the terms of Sections 1 and 2 above on a medium
   4.150 +    customarily used for software interchange; or,
   4.151 +
   4.152 +    c) Accompany it with the information you received as to the offer
   4.153 +    to distribute corresponding source code.  (This alternative is
   4.154 +    allowed only for noncommercial distribution and only if you
   4.155 +    received the program in object code or executable form with such
   4.156 +    an offer, in accord with Subsection b above.)
   4.157 +
   4.158 +The source code for a work means the preferred form of the work for
   4.159 +making modifications to it.  For an executable work, complete source
   4.160 +code means all the source code for all modules it contains, plus any
   4.161 +associated interface definition files, plus the scripts used to
   4.162 +control compilation and installation of the executable.  However, as a
   4.163 +special exception, the source code distributed need not include
   4.164 +anything that is normally distributed (in either source or binary
   4.165 +form) with the major components (compiler, kernel, and so on) of the
   4.166 +operating system on which the executable runs, unless that component
   4.167 +itself accompanies the executable.
   4.168 +
   4.169 +If distribution of executable or object code is made by offering
   4.170 +access to copy from a designated place, then offering equivalent
   4.171 +access to copy the source code from the same place counts as
   4.172 +distribution of the source code, even though third parties are not
   4.173 +compelled to copy the source along with the object code.
   4.174 +
   4.175 +  4. You may not copy, modify, sublicense, or distribute the Program
   4.176 +except as expressly provided under this License.  Any attempt
   4.177 +otherwise to copy, modify, sublicense or distribute the Program is
   4.178 +void, and will automatically terminate your rights under this License.
   4.179 +However, parties who have received copies, or rights, from you under
   4.180 +this License will not have their licenses terminated so long as such
   4.181 +parties remain in full compliance.
   4.182 +
   4.183 +  5. You are not required to accept this License, since you have not
   4.184 +signed it.  However, nothing else grants you permission to modify or
   4.185 +distribute the Program or its derivative works.  These actions are
   4.186 +prohibited by law if you do not accept this License.  Therefore, by
   4.187 +modifying or distributing the Program (or any work based on the
   4.188 +Program), you indicate your acceptance of this License to do so, and
   4.189 +all its terms and conditions for copying, distributing or modifying
   4.190 +the Program or works based on it.
   4.191 +
   4.192 +  6. Each time you redistribute the Program (or any work based on the
   4.193 +Program), the recipient automatically receives a license from the
   4.194 +original licensor to copy, distribute or modify the Program subject to
   4.195 +these terms and conditions.  You may not impose any further
   4.196 +restrictions on the recipients' exercise of the rights granted herein.
   4.197 +You are not responsible for enforcing compliance by third parties to
   4.198 +this License.
   4.199 +
   4.200 +  7. If, as a consequence of a court judgment or allegation of patent
   4.201 +infringement or for any other reason (not limited to patent issues),
   4.202 +conditions are imposed on you (whether by court order, agreement or
   4.203 +otherwise) that contradict the conditions of this License, they do not
   4.204 +excuse you from the conditions of this License.  If you cannot
   4.205 +distribute so as to satisfy simultaneously your obligations under this
   4.206 +License and any other pertinent obligations, then as a consequence you
   4.207 +may not distribute the Program at all.  For example, if a patent
   4.208 +license would not permit royalty-free redistribution of the Program by
   4.209 +all those who receive copies directly or indirectly through you, then
   4.210 +the only way you could satisfy both it and this License would be to
   4.211 +refrain entirely from distribution of the Program.
   4.212 +
   4.213 +If any portion of this section is held invalid or unenforceable under
   4.214 +any particular circumstance, the balance of the section is intended to
   4.215 +apply and the section as a whole is intended to apply in other
   4.216 +circumstances.
   4.217 +
   4.218 +It is not the purpose of this section to induce you to infringe any
   4.219 +patents or other property right claims or to contest validity of any
   4.220 +such claims; this section has the sole purpose of protecting the
   4.221 +integrity of the free software distribution system, which is
   4.222 +implemented by public license practices.  Many people have made
   4.223 +generous contributions to the wide range of software distributed
   4.224 +through that system in reliance on consistent application of that
   4.225 +system; it is up to the author/donor to decide if he or she is willing
   4.226 +to distribute software through any other system and a licensee cannot
   4.227 +impose that choice.
   4.228 +
   4.229 +This section is intended to make thoroughly clear what is believed to
   4.230 +be a consequence of the rest of this License.
   4.231 +
   4.232 +  8. If the distribution and/or use of the Program is restricted in
   4.233 +certain countries either by patents or by copyrighted interfaces, the
   4.234 +original copyright holder who places the Program under this License
   4.235 +may add an explicit geographical distribution limitation excluding
   4.236 +those countries, so that distribution is permitted only in or among
   4.237 +countries not thus excluded.  In such case, this License incorporates
   4.238 +the limitation as if written in the body of this License.
   4.239 +
   4.240 +  9. The Free Software Foundation may publish revised and/or new versions
   4.241 +of the General Public License from time to time.  Such new versions will
   4.242 +be similar in spirit to the present version, but may differ in detail to
   4.243 +address new problems or concerns.
   4.244 +
   4.245 +Each version is given a distinguishing version number.  If the Program
   4.246 +specifies a version number of this License which applies to it and "any
   4.247 +later version", you have the option of following the terms and conditions
   4.248 +either of that version or of any later version published by the Free
   4.249 +Software Foundation.  If the Program does not specify a version number of
   4.250 +this License, you may choose any version ever published by the Free Software
   4.251 +Foundation.
   4.252 +
   4.253 +  10. If you wish to incorporate parts of the Program into other free
   4.254 +programs whose distribution conditions are different, write to the author
   4.255 +to ask for permission.  For software which is copyrighted by the Free
   4.256 +Software Foundation, write to the Free Software Foundation; we sometimes
   4.257 +make exceptions for this.  Our decision will be guided by the two goals
   4.258 +of preserving the free status of all derivatives of our free software and
   4.259 +of promoting the sharing and reuse of software generally.
   4.260 +
   4.261 +			    NO WARRANTY
   4.262 +
   4.263 +  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
   4.264 +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
   4.265 +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
   4.266 +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
   4.267 +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   4.268 +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
   4.269 +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
   4.270 +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
   4.271 +REPAIR OR CORRECTION.
   4.272 +
   4.273 +  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
   4.274 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
   4.275 +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
   4.276 +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
   4.277 +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
   4.278 +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
   4.279 +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
   4.280 +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
   4.281 +POSSIBILITY OF SUCH DAMAGES.
   4.282 +
   4.283 +		     END OF TERMS AND CONDITIONS
   4.284 +
   4.285 +	    How to Apply These Terms to Your New Programs
   4.286 +
   4.287 +  If you develop a new program, and you want it to be of the greatest
   4.288 +possible use to the public, the best way to achieve this is to make it
   4.289 +free software which everyone can redistribute and change under these terms.
   4.290 +
   4.291 +  To do so, attach the following notices to the program.  It is safest
   4.292 +to attach them to the start of each source file to most effectively
   4.293 +convey the exclusion of warranty; and each file should have at least
   4.294 +the "copyright" line and a pointer to where the full notice is found.
   4.295 +
   4.296 +    <one line to give the program's name and a brief idea of what it does.>
   4.297 +    Copyright (C) <year>  <name of author>
   4.298 +
   4.299 +    This program is free software; you can redistribute it and/or modify
   4.300 +    it under the terms of the GNU General Public License as published by
   4.301 +    the Free Software Foundation; either version 2 of the License, or
   4.302 +    (at your option) any later version.
   4.303 +
   4.304 +    This program is distributed in the hope that it will be useful,
   4.305 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   4.306 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   4.307 +    GNU General Public License for more details.
   4.308 +
   4.309 +    You should have received a copy of the GNU General Public License
   4.310 +    along with this program; if not, write to the Free Software
   4.311 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   4.312 +
   4.313 +
   4.314 +Also add information on how to contact you by electronic and paper mail.
   4.315 +
   4.316 +If the program is interactive, make it output a short notice like this
   4.317 +when it starts in an interactive mode:
   4.318 +
   4.319 +    Gnomovision version 69, Copyright (C) year name of author
   4.320 +    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
   4.321 +    This is free software, and you are welcome to redistribute it
   4.322 +    under certain conditions; type `show c' for details.
   4.323 +
   4.324 +The hypothetical commands `show w' and `show c' should show the appropriate
   4.325 +parts of the General Public License.  Of course, the commands you use may
   4.326 +be called something other than `show w' and `show c'; they could even be
   4.327 +mouse-clicks or menu items--whatever suits your program.
   4.328 +
   4.329 +You should also get your employer (if you work as a programmer) or your
   4.330 +school, if any, to sign a "copyright disclaimer" for the program, if
   4.331 +necessary.  Here is a sample; alter the names:
   4.332 +
   4.333 +  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
   4.334 +  `Gnomovision' (which makes passes at compilers) written by James Hacker.
   4.335 +
   4.336 +  <signature of Ty Coon>, 1 April 1989
   4.337 +  Ty Coon, President of Vice
   4.338 +
   4.339 +This General Public License does not permit incorporating your program into
   4.340 +proprietary programs.  If your program is a subroutine library, you may
   4.341 +consider it more useful to permit linking proprietary applications with the
   4.342 +library.  If this is what you want to do, use the GNU Library General
   4.343 +Public License instead of this License.
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/misc/mbootpack/Makefile	Tue Mar 29 10:01:06 2005 +0000
     5.3 @@ -0,0 +1,97 @@
     5.4 +#
     5.5 +#  Makefile for mbootpack
     5.6 +#
     5.7 +INSTALL		= install
     5.8 +INSTALL_PROG	= $(INSTALL) -m0755
     5.9 +INSTALL_DIR	= $(INSTALL) -d -m0755
    5.10 +
    5.11 +XEN_ROOT=../../..
    5.12 +include $(XEN_ROOT)/tools/Rules.mk
    5.13 +
    5.14 +CFLAGS   += -Wall -Werror -O3 
    5.15 +
    5.16 +INCLUDES += -I $(XEN_XC)
    5.17 +INCLUDES += -I $(XEN_LIBXC)
    5.18 +CFLAGS   += $(INCLUDES)
    5.19 +
    5.20 +HDRS     = $(wildcard *.h)
    5.21 +
    5.22 +TARGETS  = mbootpack
    5.23 +
    5.24 +INSTALL_BIN  = mbootpack
    5.25 +INSTALL_SBIN =
    5.26 +
    5.27 +all: build
    5.28 +build: $(TARGETS)
    5.29 +
    5.30 +install: build
    5.31 +	$(INSTALL_PROG) $(INSTALL_BIN) $(DESTDIR)/usr/bin
    5.32 +
    5.33 +#
    5.34 +#  What object files need building for the program
    5.35 +#
    5.36 +
    5.37 +OBJS	:= mbootpack.o buildimage.o
    5.38 +DEPS	:= mbootpack.d buildimage.d
    5.39 +
    5.40 +# 
    5.41 +#  Tools etc.
    5.42 +#
    5.43 +
    5.44 +RM 	:= rm -f
    5.45 +GDB	:= gdb
    5.46 +INCS	:= -I. -I-
    5.47 +DEFS	:= 
    5.48 +LDFLAGS	:= 
    5.49 +CC	:= gcc
    5.50 +CFLAGS 	:= -W -Wall -Wpointer-arith -Wcast-qual -Wno-unused -Wno-format
    5.51 +CFLAGS	+= -Wmissing-prototypes
    5.52 +#CFLAGS	+= -pipe -g -O0 -Wcast-align
    5.53 +CFLAGS	+= -pipe -O3 
    5.54 +
    5.55 +#
    5.56 +#  Rules
    5.57 +#
    5.58 +
    5.59 +mbootpack: $(OBJS)
    5.60 +	$(CC) -o $@ $(filter-out %.a, $^) $(LDFLAGS)
    5.61 +
    5.62 +clean: FRC
    5.63 +	$(RM) mbootpack *.o *.d bootsect setup bzimage_header.c bin2c
    5.64 +
    5.65 +bootsect: bootsect.S
    5.66 +	$(CC) $(CFLAGS) $(INCS) $(DEFS) -D__MB_ASM -c bootsect.S -o bootsect.o
    5.67 +	$(LD) -m elf_i386 -Ttext 0x0 -s --oformat binary bootsect.o -o $@
    5.68 +
    5.69 +setup: setup.S
    5.70 +	$(CC) $(CFLAGS) $(INCS) $(DEFS) -D__MB_ASM -c setup.S -o setup.o
    5.71 +	$(LD) -m elf_i386 -Ttext 0x0 -s --oformat binary setup.o -o $@
    5.72 +
    5.73 +bin2c: bin2c.o 
    5.74 +	$(CC) -o $@ $^ 
    5.75 +
    5.76 +bzimage_header.c: bootsect setup bin2c
    5.77 +	./bin2c -n 8 -b1 -a bzimage_bootsect bootsect > bzimage_header.c
    5.78 +	./bin2c -n 8 -b1 -a bzimage_setup setup >> bzimage_header.c
    5.79 +
    5.80 +buildimage.c buildimage.d: bzimage_header.c
    5.81 +
    5.82 +%.o: %.S
    5.83 +	$(CC) $(CFLAGS) $(INCS) $(DEFS) -c $< -o $@
    5.84 +
    5.85 +%.o: %.c
    5.86 +	$(CC) $(CFLAGS) $(INCS) $(DEFS) -c $< -o $@
    5.87 +
    5.88 +%.d: %.c
    5.89 +	$(CC) $(CFLAGS) $(INCS) $(DEFS) -M $< > $@
    5.90 +
    5.91 +FRC: 
    5.92 +.PHONY:: all FRC clean gdb
    5.93 +.PRECIOUS: $(OBJS) $(OBJS:.o=.c) $(DEPS)
    5.94 +.SUFFIXES: 
    5.95 +
    5.96 +-include $(DEPS)
    5.97 +
    5.98 +#
    5.99 +#  EOF
   5.100 +#
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/misc/mbootpack/README	Tue Mar 29 10:01:06 2005 +0000
     6.3 @@ -0,0 +1,77 @@
     6.4 +
     6.5 +mbootpack
     6.6 +---------
     6.7 +
     6.8 +This is a utility to take a multiboot kernel and modules and repackage
     6.9 +them in a form that a standard linux bootloader will be able to load them.
    6.10 +It statically allocates memory addresses based on a 'standard' PC memory 
    6.11 +layout, and then saves the image of the loaded system, along with an 
    6.12 +almost-standard linux bzImage header which takes care of the start-of-day 
    6.13 +requirements of a multiboot kernel (setting up 32-bit protected mode, etc.)
    6.14 +
    6.15 +Example invocation, to package a xen VMM and xenlinux guest and initrd:
    6.16 +
    6.17 +   mbootpack -o bzImage -m ./xenlinux -m ./initrd.img ./xen-image
    6.18 +
    6.19 +You can now boot the 'bzImage' file using your favourite linux bootloader.
    6.20 +
    6.21 +The kernel command line will be provided at boot time by the bootloader
    6.22 +(you can specify a kernel command-line using the '-c' flag, but it will
    6.23 +be overridden at boot time unledd the bootloder provides an entirely
    6.24 +empty command line).  If you wan to override the command line for the
    6.25 +first module (i.e. domain 0 kernel in Xen) at boot time, append ' -- '
    6.26 +and the module commadn line to the bootloader command line, e.g.:
    6.27 +
    6.28 +  boot: bzImage com1=9600,8n1 console=com1 dom0_mem=49152 -- root=/dev/sda3 ro console=ttyS0,9600n8 
    6.29 +
    6.30 +Everything before the '--' is passed to the kernel (xen) as its command
    6.31 +line; everything after is passed to the first module (xenlinux).
    6.32 +
    6.33 +This is ALPHA code: there are execution paths which have *not* been
    6.34 +tested, though it works for loading the Xen hypervisor using GrUB, LILO
    6.35 +or SYSLINUX.  Bug reports and patches are very welcome.
    6.36 +
    6.37 +Possible features for future versions (all look possible, if there's any 
    6.38 +demand for them):
    6.39 +
    6.40 +    - support for kernels that load below 1MB
    6.41 +    - zImage-style compressed images
    6.42 +    - sane error messgaes for insane load addresses
    6.43 +    - support for the MULTIBOOT_VIDEO_MODE bit
    6.44 +    - proper support for passing E820h memory-maps from bzImage
    6.45 +
    6.46 +
    6.47 +Tim Deegan <tjd21@cl.cam.ac.uk>, March 2005
    6.48 +
    6.49 +
    6.50 +
    6.51 +License and attributions
    6.52 +------------------------
    6.53 +
    6.54 +The bzImage header block was originally taken from the Linux kernel.
    6.55 +http://www.kernel.org/
    6.56 +
    6.57 +Some parts of the Multiboot loader code are based on GNU GRUB.
    6.58 +mb_info.h and mb_header.h are taken from GNU GRUB.
    6.59 +http://www.gnu.org/software/grub/
    6.60 +
    6.61 +Bin2C was written by Nicolas Doualot; I tidied it a bit for a clean compile.
    6.62 +http://slubman.celeonet.fr/program.php?style=Default&project=bin2c
    6.63 +
    6.64 +All other code is copyright (C) 2003-2005  Tim Deegan (tjd21@cl.cam.ac.uk)
    6.65 +
    6.66 +mbootpack is distributed under the GNU General Public License: see "GPL"
    6.67 +
    6.68 +This program is free software; you can redistribute it and/or modify
    6.69 +it under the terms of the GNU General Public License as published by
    6.70 +the Free Software Foundation; either version 2 of the License, or
    6.71 +(at your option) any later version.
    6.72 +
    6.73 +This program is distributed in the hope that it will be useful,
    6.74 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.75 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.76 +GNU General Public License for more details.
    6.77 +
    6.78 +You should have received a copy of the GNU General Public License
    6.79 +along with this program; if not, write to the Free Software
    6.80 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/misc/mbootpack/bin2c.c	Tue Mar 29 10:01:06 2005 +0000
     7.3 @@ -0,0 +1,356 @@
     7.4 +/***************************************************************************************
     7.5 +   Project informations:
     7.6 +      Project:    bin2c
     7.7 +      Version:    1.00
     7.8 +      Plateforme: PC
     7.9 +      Copyright:  DNDD.INC
    7.10 +      Date:       28/03/2004
    7.11 +
    7.12 +   File informations:
    7.13 +      Name:       bin2c.c
    7.14 +      Description:Convert any file to a C array
    7.15 +
    7.16 +   Author informations:
    7.17 +      Author:     DOUALOT Nicolas
    7.18 +      E-Mail:     slubman@laposte.net
    7.19 +      site:       http://membres.lycos.fr/slubman/gp32
    7.20 +***************************************************************************************/
    7.21 +
    7.22 +
    7.23 +#include <stdio.h>				/*perror */
    7.24 +#include <sys/mman.h>			/*PROT_READ,MAP_xxx */
    7.25 +#include <fcntl.h>				/*O_RDONLY */
    7.26 +#include <sys/stat.h>			/*stat */
    7.27 +#include <stdlib.h>				/*atoi */
    7.28 +#include <string.h>				/*strcmp */
    7.29 +#include <ctype.h>				/*toupper */
    7.30 +
    7.31 +#define VERSION "1.10"
    7.32 +
    7.33 +
    7.34 +static void help(void)
    7.35 +{
    7.36 +	fprintf(stdout, "\nbin2c v"VERSION"\n");
    7.37 +	fprintf(stdout, "Slubman DevSoft (c)2003-2004 slubman.dndd@laposte.net \n\n");
    7.38 +
    7.39 +	fprintf(stdout, "Usage: bin2c [flags] <infile>\n\n");
    7.40 +
    7.41 +	//fprintf(stdout, "\t-quiet      :\tdon't output standard messages\n");
    7.42 +	//fprintf(stdout, "\t-slash      :\tappend backslash at end of line\n");
    7.43 +	fprintf(stdout, "\t-n <count>  :\tnumber of items per line\n");
    7.44 +	fprintf(stdout, "\t-b1         :\tgenerate unsigned char array\n");
    7.45 +	fprintf(stdout, "\t-b2         :\tgenerate unsigned short  array\n");
    7.46 +	fprintf(stdout, "\t-b4         :\tgenerate unsigned long array\n");
    7.47 +	fprintf(stdout, "\t-a <name>   :\tgenerate an array with given name\n");
    7.48 +	fprintf(stdout, "\t-ss <nr>    :\tskip number of bytes at begin of inputfile\n");
    7.49 +	fprintf(stdout, "\t-se <nr>    :\tskip number of bytes at end of inputfile\n");
    7.50 +	fprintf(stdout, "\t-lb <nr>    :\tinsert an additionally linebreak every nr line\n");
    7.51 +	fprintf(stdout, "\t-h          :\tproduce an header\n");
    7.52 +	fprintf(stdout, "\tinfile      :\tname of infile\n");
    7.53 +	fprintf(stdout, "\toutfile     :\tname of outfile (use \"-\" for stdout)\n\n");
    7.54 +
    7.55 +	fprintf(stdout, " \tconverts binary file to C array data\n");
    7.56 +}
    7.57 +
    7.58 +static void UnknownFlag(char *flag)
    7.59 +{
    7.60 +	fprintf(stderr, "Error: unknown flag %s\n", flag);
    7.61 +	help();
    7.62 +	exit(EXIT_FAILURE);
    7.63 +}
    7.64 +
    7.65 +static void WriteHeader(FILE * outFile, char *oFileName, char *iFileName)
    7.66 +{
    7.67 +	// File Header
    7.68 +	fprintf(outFile, "/***************************************************************************************\n");
    7.69 +	fprintf(outFile, "*   File Name:\n");
    7.70 +	fprintf(outFile, "*      Name:       %s\n", oFileName);
    7.71 +	fprintf(outFile, "*      From:       %s\n", iFileName);
    7.72 +	fprintf(outFile, "*      Created by :bin2c v"VERSION"\n*\n");
    7.73 +	fprintf(outFile, "*   bin2c v"VERSION":\n");
    7.74 +	fprintf(outFile, "*      Author:     DOUALOT Nicolas\n");
    7.75 +	fprintf(outFile, "*      E-Mail:     slubman.dndd@laposte.net\n");
    7.76 +	fprintf(outFile, "*      site:       http://www.slubman.linux-fan.com/\n");
    7.77 +	fprintf(outFile, "***************************************************************************************/\n\n");
    7.78 +}
    7.79 +
    7.80 +int main(int argc, char *argv[])
    7.81 +{
    7.82 +	FILE *inFile = stdin, *outFile = stdout;
    7.83 +	int a, i, nbLine = 0;
    7.84 +	unsigned char *memory;
    7.85 +	struct stat st;
    7.86 +
    7.87 +	// Options
    7.88 +	char arrayName[255] = "array";	// Array name
    7.89 +	char *iFileName = NULL;		// File to convert
    7.90 +	char *oFileName = NULL;		// File to write
    7.91 +	int bpd = 1;				// Array item length
    7.92 +	int lb = 0;					// Array blank line each lb line(s)
    7.93 +	int nbCol = 15;					// Nuber of items per line
    7.94 +	int SkeepStart = 0;			// Number of byte to skip at file begining
    7.95 +	int SkeepEnd = 0;			// Number of byte to skip at file end
    7.96 +	int header = 0;				// Produce an header
    7.97 +
    7.98 +	// Is there the good number of arguments
    7.99 +	if (argc < 2)
   7.100 +	{
   7.101 +		help();
   7.102 +		return 0;
   7.103 +	}
   7.104 +
   7.105 +	// On récupère les arguments (Ready for more options)
   7.106 +	for (a = 1; a < argc; a++)
   7.107 +	{
   7.108 +		// An option
   7.109 +		if (argv[a][0] == '-')
   7.110 +		{
   7.111 +			// Wich flag is it ?
   7.112 +			switch (argv[a][1])
   7.113 +			{
   7.114 +					// Writting on stdout
   7.115 +				case 0:
   7.116 +					printf("%s\n", argv[a]);
   7.117 +					outFile = stdout;
   7.118 +					break;
   7.119 +
   7.120 +					// ArrayName flag
   7.121 +				case 'a':
   7.122 +					strcpy(arrayName, argv[++a]);
   7.123 +					break;
   7.124 +
   7.125 +					// Data type
   7.126 +				case 'b':
   7.127 +					switch (argv[a][2])
   7.128 +					{
   7.129 +						case '1':
   7.130 +							bpd = 1;
   7.131 +							break;
   7.132 +
   7.133 +						case '2':
   7.134 +							bpd = 2;
   7.135 +							break;
   7.136 +
   7.137 +						case '4':
   7.138 +							bpd = 4;
   7.139 +							break;
   7.140 +
   7.141 +						default:
   7.142 +							UnknownFlag(argv[a]);
   7.143 +					}
   7.144 +					break;
   7.145 +
   7.146 +					// Produce an header
   7.147 +				case 'h':
   7.148 +					header = 1;
   7.149 +					break;
   7.150 +
   7.151 +					// New line each n line
   7.152 +				case 'l':
   7.153 +					switch (argv[a][2])
   7.154 +					{
   7.155 +						case 'b':
   7.156 +							lb = atoi(argv[++a]);
   7.157 +							break;
   7.158 +
   7.159 +						default:
   7.160 +							UnknownFlag(argv[a]);
   7.161 +					}
   7.162 +
   7.163 +					// Number of bit per line
   7.164 +				case 'n':
   7.165 +					nbCol = atoi(argv[++a]);
   7.166 +					break;
   7.167 +
   7.168 +					// Skip bytes
   7.169 +				case 's':
   7.170 +					switch (argv[a][2])
   7.171 +					{
   7.172 +							// Beginig of file
   7.173 +						case 's':
   7.174 +							SkeepStart = atoi(argv[++a]);
   7.175 +							break;
   7.176 +
   7.177 +							// End of file
   7.178 +						case 'e':
   7.179 +							SkeepEnd = atoi(argv[++a]);
   7.180 +							break;
   7.181 +
   7.182 +							// Flag inconnu
   7.183 +						default:
   7.184 +							UnknownFlag(argv[a]);
   7.185 +					}
   7.186 +
   7.187 +					// Flag inconnu
   7.188 +				default:
   7.189 +					UnknownFlag(argv[a]);
   7.190 +			}
   7.191 +		}
   7.192 +		// A filename
   7.193 +		else
   7.194 +		{
   7.195 +			if (iFileName == NULL)
   7.196 +			{
   7.197 +				iFileName = argv[a];
   7.198 +				if ((inFile = fopen(iFileName, "rb")) == NULL)
   7.199 +				{
   7.200 +					fprintf(stderr, "Error: can't open %s\n", iFileName);
   7.201 +					exit(EXIT_FAILURE);
   7.202 +				}
   7.203 +			}
   7.204 +			else
   7.205 +			{
   7.206 +				if (oFileName == NULL)
   7.207 +				{
   7.208 +					oFileName = argv[a];
   7.209 +					if ((outFile = fopen(oFileName, "wb")) == NULL)
   7.210 +					{
   7.211 +						fprintf(stderr, "Error: can't open %s\n", oFileName);
   7.212 +						exit(EXIT_FAILURE);
   7.213 +					}
   7.214 +				}
   7.215 +				else
   7.216 +				{
   7.217 +					fprintf(stderr, "Error: Too many filesnames given!\n");
   7.218 +					help();
   7.219 +					exit(EXIT_FAILURE);
   7.220 +				}
   7.221 +			}
   7.222 +		}
   7.223 +	}
   7.224 +
   7.225 +	if (!iFileName)
   7.226 +		exit(EXIT_FAILURE);
   7.227 +
   7.228 +	// Get file informations
   7.229 +	if (stat(iFileName, &st) != 0)
   7.230 +	{
   7.231 +		fprintf(stderr, "Error: when scanning file %s\n", argv[1]);
   7.232 +		exit(EXIT_FAILURE);
   7.233 +	}
   7.234 +
   7.235 +	// Allocating memory
   7.236 +	if (!(memory = malloc(st.st_size + 3)))
   7.237 +	{
   7.238 +		memset(memory, 0, st.st_size + 3);
   7.239 +		fprintf(stderr, "Error: not enought memory\n");
   7.240 +		exit(EXIT_FAILURE);
   7.241 +	}
   7.242 +
   7.243 +	// Reading the file
   7.244 +	if (fread(memory, 1, st.st_size, inFile) != (size_t)st.st_size)
   7.245 +	{
   7.246 +		fprintf(stderr, "Error: when reading file %s\n", argv[1]);
   7.247 +		fclose(inFile);
   7.248 +		exit(EXIT_FAILURE);
   7.249 +	}
   7.250 +	fclose(inFile);
   7.251 +
   7.252 +	// Must produce an header
   7.253 +	if (header)
   7.254 +	{
   7.255 +		unsigned int i;
   7.256 +		char hFileName[256], *def = NULL;
   7.257 +		FILE *hFile = stdout;
   7.258 +
   7.259 +		if (oFileName)
   7.260 +		{
   7.261 +			strcpy(hFileName, oFileName);
   7.262 +			hFileName[strlen(hFileName) - 1] = 'h';
   7.263 +			hFile = fopen(hFileName, "wt");
   7.264 +		}
   7.265 +
   7.266 +		WriteHeader(hFile, hFileName, iFileName);
   7.267 +
   7.268 +		// Replace all '.' by '_'
   7.269 +		for (i = 0; i < strlen(hFileName); i++)
   7.270 +			if (hFileName[i] == '.')
   7.271 +				hFileName[i] = '_';
   7.272 +			else
   7.273 +				hFileName[i] = toupper(hFileName[i]);
   7.274 +
   7.275 +		// the #ifdef at the begining
   7.276 +		def = strrchr(hFileName, '/');
   7.277 +		def = def ? def + 1 : hFileName;
   7.278 +		fprintf(hFile, "#ifndef __%s__\n#define __%s__\n\n", def, def);
   7.279 +
   7.280 +		// Define array size
   7.281 +		fprintf(hFile, "#define _%s_size_ %u\n\n", arrayName, (unsigned int) (st.st_size - SkeepStart - SkeepEnd) / bpd);
   7.282 +
   7.283 +		// Begin the array
   7.284 +		fprintf(hFile, "extern unsigned ");
   7.285 +		fprintf(hFile, "%s ", bpd == 1 ? "char" : bpd == 2 ? "short" : "long");
   7.286 +		fprintf(hFile, "%s[", arrayName);
   7.287 +		fprintf(hFile, "%u];\n\n", (unsigned int) (st.st_size - SkeepStart - SkeepEnd) / bpd);
   7.288 +
   7.289 +		// the #endif at the end
   7.290 +		fprintf(hFile, "#endif\n\n");
   7.291 +
   7.292 +		if (oFileName)
   7.293 +			fclose(hFile);
   7.294 +	}
   7.295 +
   7.296 +	WriteHeader(outFile, oFileName, iFileName);
   7.297 +
   7.298 +	// Define array size
   7.299 +	if (!header)
   7.300 +		fprintf(outFile, "#define _%s_size_ %u\n\n", arrayName, (unsigned int) (st.st_size - SkeepStart - SkeepEnd) / bpd);
   7.301 +
   7.302 +	// Begin the array
   7.303 +	fprintf(outFile, "unsigned ");
   7.304 +	fprintf(outFile, "%s ", bpd == 1 ? "char" : bpd == 2 ? "short" : "long");
   7.305 +	fprintf(outFile, "%s[", arrayName);
   7.306 +	fprintf(outFile, "%u] = {\n\t", (unsigned int) (st.st_size - SkeepStart - SkeepEnd) / bpd);
   7.307 +
   7.308 +	// Writing file elements
   7.309 +	for (i = 0; i < (st.st_size - SkeepEnd - SkeepStart) / bpd; /*i+=bpd */ i++)
   7.310 +	{
   7.311 +		// We write an item of bpd byte(s)
   7.312 +		switch (bpd)
   7.313 +		{
   7.314 +			case 1:
   7.315 +				fprintf(outFile, "0x%02x", *(unsigned char *) &memory[SkeepStart + i]);
   7.316 +				break;
   7.317 +
   7.318 +			case 2:
   7.319 +				fprintf(outFile, "0x%04x", *(unsigned short *) &memory[SkeepStart + i]);
   7.320 +				break;
   7.321 +
   7.322 +			case 4:
   7.323 +				fprintf(outFile, "0x%08lx", *(unsigned long *) &memory[SkeepStart + i]);
   7.324 +				break;
   7.325 +		}
   7.326 +
   7.327 +		// Must put a coma ?
   7.328 +		if (i != st.st_size - 1)
   7.329 +			fprintf(outFile, ",");
   7.330 +
   7.331 +		// End of a line ?
   7.332 +		if (i && !((i + 1) % nbCol))
   7.333 +		{
   7.334 +			// -lb option
   7.335 +			if (lb && !((++nbLine) % lb))
   7.336 +				fprintf(outFile, "\n");
   7.337 +			fprintf(outFile, "\n\t");
   7.338 +		}
   7.339 +		// Add a space
   7.340 +		else
   7.341 +			fprintf(outFile, " ");
   7.342 +	}
   7.343 +
   7.344 +	// The last line as nbCol elements
   7.345 +	if (((st.st_size - SkeepStart - SkeepEnd) / bpd) % nbCol)
   7.346 +		fprintf(outFile, "\n");
   7.347 +
   7.348 +	// Close the array
   7.349 +	fprintf(outFile, "};\n");
   7.350 +
   7.351 +	// CLose the output file
   7.352 +	if (outFile != stdout)
   7.353 +		fclose(outFile);
   7.354 +
   7.355 +	// Free allocated memory
   7.356 +	free(memory);
   7.357 +
   7.358 +	exit(EXIT_SUCCESS);
   7.359 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tools/misc/mbootpack/bootsect.S	Tue Mar 29 10:01:06 2005 +0000
     8.3 @@ -0,0 +1,136 @@
     8.4 +/*
     8.5 + *  bootsect.S
     8.6 + *
     8.7 + *  This is bootsect.S from the linux 2.6.9 sources,
     8.8 + *  with minor changes for mbootpack.
     8.9 + *
    8.10 + *  
    8.11 + *  This program is free software; you can redistribute it and/or
    8.12 + *  modify it under the terms of the GNU General Public License as
    8.13 + *  published by the Free Software Foundation; either version 2 of the
    8.14 + *  License, or (at your option) any later version.
    8.15 + *
    8.16 + *  This program is distributed in the hope that it will be useful,
    8.17 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.18 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.19 + *  General Public License for more details.
    8.20 + *
    8.21 + *  You should have received a copy of the GNU General Public License
    8.22 + *  along with this program; if not, write to the Free Software
    8.23 + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
    8.24 + *  02111-1307, USA.
    8.25 + *
    8.26 + * $Id: bootsect.S,v 1.2 2005/03/23 10:39:11 tjd21 Exp $
    8.27 + *
    8.28 + */
    8.29 +	
    8.30 +#include "mbootpack.h"
    8.31 +		
    8.32 +/*
    8.33 + *	bootsect.S		Copyright (C) 1991, 1992 Linus Torvalds
    8.34 + *
    8.35 + *	modified by Drew Eckhardt
    8.36 + *	modified by Bruce Evans (bde)
    8.37 + *	modified by Chris Noe (May 1999) (as86 -> gas)
    8.38 + *	gutted by H. Peter Anvin (Jan 2003)
    8.39 + *
    8.40 + * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
    8.41 + * addresses must be multiplied by 16 to obtain their respective linear
    8.42 + * addresses. To avoid confusion, linear addresses are written using leading
    8.43 + * hex while segment addresses are written as segment:offset.
    8.44 + *
    8.45 + */
    8.46 + 
    8.47 +/* #include <asm/boot.h> */
    8.48 +/* Definitions we should have got from there */	
    8.49 +#define DEF_INITSEG     0x9000
    8.50 +#define DEF_SYSSEG      0x1000
    8.51 +#define DEF_SETUPSEG    0x9020
    8.52 +#define DEF_SYSSIZE     0x7F00
    8.53 +#define NORMAL_VGA      0xffff
    8.54 +#define EXTENDED_VGA    0xfffe
    8.55 +#define ASK_VGA         0xfffd
    8.56 +
    8.57 +
    8.58 +/* SETUPSECTS	= 4 */			/* default nr of setup-sectors */
    8.59 +BOOTSEG		= 0x07C0		/* original address of boot-sector */
    8.60 +INITSEG		= DEF_INITSEG		/* we move boot here - out of the way */
    8.61 +SETUPSEG	= DEF_SETUPSEG		/* setup starts here */
    8.62 +SYSSEG		= DEF_SYSSEG		/* system loaded at 0x10000 (65536) */
    8.63 +SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
    8.64 +					/* to be loaded */
    8.65 +ROOT_DEV	= 0 			/* ROOT_DEV is now written by "build" */
    8.66 +SWAP_DEV	= 0			/* SWAP_DEV is now written by "build" */
    8.67 +
    8.68 +#ifndef SVGA_MODE
    8.69 +/* #define SVGA_MODE ASK_VGA */
    8.70 +#define SVGA_MODE NORMAL_VGA
    8.71 +#endif
    8.72 +
    8.73 +#ifndef RAMDISK
    8.74 +#define RAMDISK 0
    8.75 +#endif
    8.76 +
    8.77 +#ifndef ROOT_RDONLY
    8.78 +#define ROOT_RDONLY 1
    8.79 +#endif
    8.80 +
    8.81 +.code16
    8.82 +.text
    8.83 +
    8.84 +.global _start
    8.85 +_start:
    8.86 +
    8.87 +	# Normalize the start address
    8.88 +	jmpl	$BOOTSEG, $start2
    8.89 +
    8.90 +start2:
    8.91 +	movw	%cs, %ax
    8.92 +	movw	%ax, %ds
    8.93 +	movw	%ax, %es
    8.94 +	movw	%ax, %ss
    8.95 +	movw	$0x7c00, %sp
    8.96 +	sti
    8.97 +	cld
    8.98 +
    8.99 +	movw	$bugger_off_msg, %si
   8.100 +
   8.101 +msg_loop:
   8.102 +	lodsb
   8.103 +	andb	%al, %al
   8.104 +	jz	die
   8.105 +	movb	$0xe, %ah
   8.106 +	movw	$7, %bx
   8.107 +	int	$0x10
   8.108 +	jmp	msg_loop
   8.109 +
   8.110 +die:
   8.111 +	# Allow the user to press a key, then reboot
   8.112 +	xorw	%ax, %ax
   8.113 +	int	$0x16
   8.114 +	int	$0x19
   8.115 +
   8.116 +	# int 0x19 should never return.  In case it does anyway,
   8.117 +	# invoke the BIOS reset code...
   8.118 +	ljmp	$0xf000,$0xfff0
   8.119 +
   8.120 +
   8.121 +bugger_off_msg:
   8.122 +	.ascii	"Direct booting from floppy is no longer supported.\r\n"
   8.123 +	.ascii	"Please use a boot loader program instead.\r\n"
   8.124 +	.ascii	"\n"
   8.125 +	.ascii	"Remove disk and press any key to reboot . . .\r\n"
   8.126 +	.byte	0
   8.127 +	
   8.128 +
   8.129 +	# Kernel attributes; used by setupbegtext
   8.130 +
   8.131 +	.org 497
   8.132 +setup_sects:	.byte SETUPSECTS
   8.133 +root_flags:	.word ROOT_RDONLY
   8.134 +syssize:	.word SYSSIZE
   8.135 +swap_dev:	.word SWAP_DEV
   8.136 +ram_size:	.word RAMDISK
   8.137 +vid_mode:	.word SVGA_MODE
   8.138 +root_dev:	.word ROOT_DEV
   8.139 +boot_flag:	.word 0xAA55
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/misc/mbootpack/buildimage.c	Tue Mar 29 10:01:06 2005 +0000
     9.3 @@ -0,0 +1,174 @@
     9.4 +/*
     9.5 + *  buildimage.c
     9.6 + *
     9.7 + *  Takes the memory image of a loaded kernel and modules and repackages 
     9.8 + *  it as a linux bzImage
     9.9 + *
    9.10 + *  Copyright (C) 2003-2004  Tim Deegan (tjd21@cl.cam.ac.uk)
    9.11 + * 
    9.12 + *  This program is free software; you can redistribute it and/or
    9.13 + *  modify it under the terms of the GNU General Public License as
    9.14 + *  published by the Free Software Foundation; either version 2 of the
    9.15 + *  License, or (at your option) any later version.
    9.16 + *
    9.17 + *  This program is distributed in the hope that it will be useful,
    9.18 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.19 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    9.20 + *  General Public License for more details.
    9.21 + *
    9.22 + *  You should have received a copy of the GNU General Public License
    9.23 + *  along with this program; if not, write to the Free Software
    9.24 + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
    9.25 + *  02111-1307, USA.
    9.26 + *
    9.27 + * $Id: buildimage.c,v 1.2 2005/03/23 10:39:19 tjd21 Exp $
    9.28 + *
    9.29 + */
    9.30 +
    9.31 +
    9.32 +
    9.33 +#include <assert.h>
    9.34 +#include <stdio.h>
    9.35 +#include <stdlib.h>
    9.36 +#include <errno.h>
    9.37 +#include <string.h>
    9.38 +#include <getopt.h>
    9.39 +#include <elf.h>
    9.40 +#include <unistd.h>
    9.41 +#include <sys/types.h>
    9.42 +#include <sys/stat.h>
    9.43 +#include <sys/mman.h>
    9.44 +#include <asm/page.h>
    9.45 +
    9.46 +#include "mbootpack.h"
    9.47 +#include "mb_header.h"
    9.48 +
    9.49 +/*  We will build an image that a bzImage-capable bootloader will load like 
    9.50 + *  this:
    9.51 + * 
    9.52 + *  ==============   (0)
    9.53 + *  (BIOS memory)
    9.54 + *  --------------
    9.55 + *  (Bootloader)
    9.56 + *  --------------
    9.57 + *  bzImage startup code
    9.58 + *  MBI, command-lines, module info
    9.59 + *  ==============   (0xa0000)
    9.60 + *  (memory hole)
    9.61 + *  ==============   (0x100000)
    9.62 + *  Kernel and modules
    9.63 + *  ==============
    9.64 + * 
    9.65 + *  The bzImage startup code is mostly taken straight from the linux kernel
    9.66 + *  (see bootsect.S, startup.S).  It does the usual unpleasant start-of-day
    9.67 + *  tasks to get to 32-bit protected mode, then sets registers appropriately 
    9.68 + *  and jumps to the kernel's entry address.
    9.69 + *  
    9.70 + *  It also does some relocation to make sure the MBI is where we expect it, 
    9.71 + *  and parses the linux command line.
    9.72 + */
    9.73 +
    9.74 +#define BZ_SETUP_OFFSET    (512 * (1 + SETUPSECTS)) 
    9.75 +#define BZ_ENTRY_OFFSET    0x30
    9.76 +#define BZ_MBI_OFFSET      0x34
    9.77 +/* These *MUST* fit the offsets of entry_address and mbi_address in setup.S */
    9.78 +
    9.79 +/* Bring in the bzImage boot sector and setup code */
    9.80 +#include "bzimage_header.c"
    9.81 +
    9.82 +address_t place_mbi(long int size) 
    9.83 +/* Find space at the top of *low* memory for the MBI and associated red tape */
    9.84 +{
    9.85 +    address_t start;
    9.86 +    start = 0xa000 - size;
    9.87 +    if (start < 0x9000 + sizeof(bzimage_bootsect) + sizeof(bzimage_setup)) {
    9.88 +        printf("Fatal: command-lines too long: need %i, have %i bytes\n",
    9.89 +               size, 
    9.90 +               0x1000 - (sizeof(bzimage_bootsect) + sizeof(bzimage_setup)));
    9.91 +        exit(1);        
    9.92 +    }
    9.93 +    if (!quiet) {
    9.94 +        printf("Placed MBI and strings (%p+%p)\n", 
    9.95 +               start, size);
    9.96 +    }
    9.97 +    return start;
    9.98 +}
    9.99 +
   9.100 +void make_bzImage(section_t *sections, 
   9.101 +                  address_t entry, 
   9.102 +                  address_t mbi,
   9.103 +                  FILE *fp)
   9.104 +/* Rework this list of sections into a bzImage and write it out to fp */
   9.105 +{
   9.106 +    int i;
   9.107 +    size_t offset;
   9.108 +    section_t *s;
   9.109 +
   9.110 +    /* Patch the kernel and mbi addresses into the setup code */
   9.111 +    *(address_t *)(bzimage_setup + BZ_ENTRY_OFFSET) = entry;
   9.112 +    *(address_t *)(bzimage_setup + BZ_MBI_OFFSET) = mbi;
   9.113 +    if (!quiet) printf("Kernel entry is %p, MBI is %p.\n", entry, mbi);
   9.114 +
   9.115 +    /* Write out header and trampoline */
   9.116 +    if (fseek(fp, 0, SEEK_SET) < 0) {
   9.117 +        printf("Fatal: error seeking in output file: %s\n", 
   9.118 +               strerror(errno));
   9.119 +        exit(1);
   9.120 +    }
   9.121 +    if (fwrite(bzimage_bootsect, sizeof(bzimage_bootsect), 1, fp) != 1) {
   9.122 +        printf("Fatal: error writing to output file: %s\n", 
   9.123 +               strerror(errno));
   9.124 +        exit(1);
   9.125 +    }
   9.126 +    if (fwrite(bzimage_setup, sizeof(bzimage_setup), 1, fp) != 1) {
   9.127 +        printf("Fatal: error writing to output file: %s\n", 
   9.128 +               strerror(errno));
   9.129 +        exit(1);
   9.130 +    }
   9.131 +
   9.132 +    if (!quiet) printf("Wrote bzImage header: %i + %i bytes.\n", 
   9.133 +                       sizeof(bzimage_bootsect), sizeof(bzimage_setup));
   9.134 +
   9.135 +    /* Sorted list of sections below 1MB: write them out */
   9.136 +    for (s = sections, i = 0; s; s = s->next) {
   9.137 +        if (s->start >= HIGHMEM_START) continue;
   9.138 +        offset = (s->start - 0x9000);
   9.139 +        if (fseek(fp, offset, SEEK_SET) < 0) {
   9.140 +            printf("Fatal: error seeking in output file: %s\n", 
   9.141 +                   strerror(errno));
   9.142 +            exit(1);
   9.143 +        }
   9.144 +        if (fwrite(s->buffer, s->size, 1, fp) != 1) {
   9.145 +            printf("Fatal: error writing to output file: %s\n", 
   9.146 +                   strerror(errno));
   9.147 +            exit(1);
   9.148 +        }
   9.149 +        i++;
   9.150 +    }
   9.151 +
   9.152 +    if (!quiet) printf("Wrote %i low-memory sections.\n", i);
   9.153 +
   9.154 +    /* Sorted list of sections higher than 1MB: write them out */
   9.155 +    for (s = sections, i = 0; s; s = s->next) {
   9.156 +        if (s->start < HIGHMEM_START) continue;
   9.157 +        offset = (s->start - HIGHMEM_START) + BZ_SETUP_OFFSET;
   9.158 +        if (fseek(fp, offset, SEEK_SET) < 0) {
   9.159 +            printf("Fatal: error seeking in output file: %s\n", 
   9.160 +                   strerror(errno));
   9.161 +            exit(1);
   9.162 +        }
   9.163 +        if (fwrite(s->buffer, s->size, 1, fp) != 1) {
   9.164 +            printf("Fatal: error writing to output file: %s\n", 
   9.165 +                   strerror(errno));
   9.166 +            exit(1);
   9.167 +        }
   9.168 +        i++;
   9.169 +    }
   9.170 +    
   9.171 +    if (!quiet) printf("Wrote %i high-memory sections.\n", i);
   9.172 +}
   9.173 +
   9.174 +
   9.175 +/*
   9.176 + *  EOF(buildimage.c)
   9.177 + */
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/misc/mbootpack/mb_header.h	Tue Mar 29 10:01:06 2005 +0000
    10.3 @@ -0,0 +1,90 @@
    10.4 +/*
    10.5 + *  GRUB  --  GRand Unified Bootloader
    10.6 + *  Copyright (C) 2000   Free Software Foundation, Inc.
    10.7 + *
    10.8 + *  This program is free software; you can redistribute it and/or modify
    10.9 + *  it under the terms of the GNU General Public License as published by
   10.10 + *  the Free Software Foundation; either version 2 of the License, or
   10.11 + *  (at your option) any later version.
   10.12 + *
   10.13 + *  This program is distributed in the hope that it will be useful,
   10.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.16 + *  GNU General Public License for more details.
   10.17 + *
   10.18 + *  You should have received a copy of the GNU General Public License
   10.19 + *  along with this program; if not, write to the Free Software
   10.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   10.21 + */
   10.22 +
   10.23 +/*
   10.24 + *  MultiBoot Header description
   10.25 + */
   10.26 +
   10.27 +struct multiboot_header
   10.28 +{
   10.29 +  /* Must be MULTIBOOT_MAGIC - see below.  */
   10.30 +  unsigned magic;
   10.31 +  
   10.32 +  /* Feature flags - see below.  */
   10.33 +  unsigned flags;
   10.34 +  
   10.35 +  /*
   10.36 +   * Checksum
   10.37 +   *
   10.38 +   * The above fields plus this one must equal 0 mod 2^32.
   10.39 +   */
   10.40 +  unsigned checksum;
   10.41 +  
   10.42 +  /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set.  */
   10.43 +  unsigned header_addr;
   10.44 +  unsigned load_addr;
   10.45 +  unsigned load_end_addr;
   10.46 +  unsigned bss_end_addr;
   10.47 +  unsigned entry_addr;
   10.48 +
   10.49 +  /* These are only valid if MULTIBOOT_VIDEO_MODE is set.  */
   10.50 +  unsigned mode_type;
   10.51 +  unsigned width;
   10.52 +  unsigned height;
   10.53 +  unsigned depth;
   10.54 +};
   10.55 +
   10.56 +/*
   10.57 + * The entire multiboot_header must be contained
   10.58 + * within the first MULTIBOOT_SEARCH bytes of the kernel image.
   10.59 + */
   10.60 +#define MULTIBOOT_SEARCH		8192
   10.61 +#define MULTIBOOT_FOUND(addr, len) \
   10.62 +  (! ((addr) & 0x3) \
   10.63 +   && (len) >= 12 \
   10.64 +   && *((int *) (addr)) == MULTIBOOT_MAGIC \
   10.65 +   && ! (*((unsigned *) (addr)) + *((unsigned *) (addr + 4)) \
   10.66 +	 + *((unsigned *) (addr + 8))) \
   10.67 +   && (! (MULTIBOOT_AOUT_KLUDGE & *((int *) (addr + 4))) || (len) >= 32) \
   10.68 +   && (! (MULTIBOOT_VIDEO_MODE & *((int *) (addr + 4))) || (len) >= 48))
   10.69 +
   10.70 +/* Magic value identifying the multiboot_header.  */
   10.71 +#define MULTIBOOT_MAGIC			0x1BADB002
   10.72 +
   10.73 +/*
   10.74 + * Features flags for 'flags'.
   10.75 + * If a boot loader sees a flag in MULTIBOOT_MUSTKNOW set
   10.76 + * and it doesn't understand it, it must fail.
   10.77 + */
   10.78 +#define MULTIBOOT_MUSTKNOW		0x0000FFFF
   10.79 +
   10.80 +/* currently unsupported flags...  this is a kind of version number.  */
   10.81 +#define MULTIBOOT_UNSUPPORTED		0x0000FFF8
   10.82 +
   10.83 +/* Align all boot modules on i386 page (4KB) boundaries.  */
   10.84 +#define MULTIBOOT_PAGE_ALIGN		0x00000001
   10.85 +
   10.86 +/* Must pass memory information to OS.  */
   10.87 +#define MULTIBOOT_MEMORY_INFO		0x00000002
   10.88 +
   10.89 +/* Must pass video information to OS.  */
   10.90 +#define MULTIBOOT_VIDEO_MODE		0x00000004
   10.91 +
   10.92 +/* This flag indicates the use of the address fields in the header.  */
   10.93 +#define MULTIBOOT_AOUT_KLUDGE		0x00010000
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/misc/mbootpack/mb_info.h	Tue Mar 29 10:01:06 2005 +0000
    11.3 @@ -0,0 +1,217 @@
    11.4 +/*
    11.5 + *  GRUB  --  GRand Unified Bootloader
    11.6 + *  Copyright (C) 2000  Free Software Foundation, Inc.
    11.7 + *
    11.8 + *  This program is free software; you can redistribute it and/or modify
    11.9 + *  it under the terms of the GNU General Public License as published by
   11.10 + *  the Free Software Foundation; either version 2 of the License, or
   11.11 + *  (at your option) any later version.
   11.12 + *
   11.13 + *  This program is distributed in the hope that it will be useful,
   11.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.16 + *  GNU General Public License for more details.
   11.17 + *
   11.18 + *  You should have received a copy of the GNU General Public License
   11.19 + *  along with this program; if not, write to the Free Software
   11.20 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   11.21 + */
   11.22 +
   11.23 +/*
   11.24 + *  The structure type "mod_list" is used by the "multiboot_info" structure.
   11.25 + */
   11.26 +
   11.27 +struct mod_list
   11.28 +{
   11.29 +  /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
   11.30 +  unsigned long mod_start;
   11.31 +  unsigned long mod_end;
   11.32 +  
   11.33 +  /* Module command line */
   11.34 +  unsigned long cmdline;
   11.35 +  
   11.36 +  /* padding to take it to 16 bytes (must be zero) */
   11.37 +  unsigned long pad;
   11.38 +};
   11.39 +
   11.40 +
   11.41 +/*
   11.42 + *  INT-15, AX=E820 style "AddressRangeDescriptor"
   11.43 + *  ...with a "size" parameter on the front which is the structure size - 4,
   11.44 + *  pointing to the next one, up until the full buffer length of the memory
   11.45 + *  map has been reached.
   11.46 + */
   11.47 +
   11.48 +struct AddrRangeDesc
   11.49 +{
   11.50 +  unsigned long size;
   11.51 +  unsigned long long BaseAddr;
   11.52 +  unsigned long long Length;
   11.53 +  unsigned long Type;
   11.54 +  
   11.55 +  /* unspecified optional padding... */
   11.56 +};
   11.57 +
   11.58 +/* usable memory "Type", all others are reserved.  */
   11.59 +#define MB_ARD_MEMORY		1
   11.60 +
   11.61 +
   11.62 +/* Drive Info structure.  */
   11.63 +struct drive_info
   11.64 +{
   11.65 +  /* The size of this structure.  */
   11.66 +  unsigned long size;
   11.67 +
   11.68 +  /* The BIOS drive number.  */
   11.69 +  unsigned char drive_number;
   11.70 +
   11.71 +  /* The access mode (see below).  */
   11.72 +  unsigned char drive_mode;
   11.73 +
   11.74 +  /* The BIOS geometry.  */
   11.75 +  unsigned short drive_cylinders;
   11.76 +  unsigned char drive_heads;
   11.77 +  unsigned char drive_sectors;
   11.78 +
   11.79 +  /* The array of I/O ports used for the drive.  */
   11.80 +  unsigned short drive_ports[0];
   11.81 +};
   11.82 +
   11.83 +/* Drive Mode.  */
   11.84 +#define MB_DI_CHS_MODE		0
   11.85 +#define MB_DI_LBA_MODE		1
   11.86 +
   11.87 +
   11.88 +/* APM BIOS info.  */
   11.89 +struct apm_info
   11.90 +{
   11.91 +  unsigned short version;
   11.92 +  unsigned short cseg;
   11.93 +  unsigned long offset;
   11.94 +  unsigned short cseg_16;
   11.95 +  unsigned short dseg_16;
   11.96 +  unsigned short cseg_len;
   11.97 +  unsigned short cseg_16_len;
   11.98 +  unsigned short dseg_16_len;
   11.99 +};
  11.100 +
  11.101 +
  11.102 +/*
  11.103 + *  MultiBoot Info description
  11.104 + *
  11.105 + *  This is the struct passed to the boot image.  This is done by placing
  11.106 + *  its address in the EAX register.
  11.107 + */
  11.108 +
  11.109 +struct multiboot_info
  11.110 +{
  11.111 +  /* MultiBoot info version number */
  11.112 +  unsigned long flags;
  11.113 +  
  11.114 +  /* Available memory from BIOS */
  11.115 +  unsigned long mem_lower;
  11.116 +  unsigned long mem_upper;
  11.117 +  
  11.118 +  /* "root" partition */
  11.119 +  unsigned long boot_device;
  11.120 +  
  11.121 +  /* Kernel command line */
  11.122 +  unsigned long cmdline;
  11.123 +  
  11.124 +  /* Boot-Module list */
  11.125 +  unsigned long mods_count;
  11.126 +  unsigned long mods_addr;
  11.127 +  
  11.128 +  union
  11.129 +  {
  11.130 +    struct
  11.131 +    {
  11.132 +      /* (a.out) Kernel symbol table info */
  11.133 +      unsigned long tabsize;
  11.134 +      unsigned long strsize;
  11.135 +      unsigned long addr;
  11.136 +      unsigned long pad;
  11.137 +    }
  11.138 +    a;
  11.139 +    
  11.140 +    struct
  11.141 +    {
  11.142 +      /* (ELF) Kernel section header table */
  11.143 +      unsigned long num;
  11.144 +      unsigned long size;
  11.145 +      unsigned long addr;
  11.146 +      unsigned long shndx;
  11.147 +    }
  11.148 +    e;
  11.149 +  }
  11.150 +  syms;
  11.151 +  
  11.152 +  /* Memory Mapping buffer */
  11.153 +  unsigned long mmap_length;
  11.154 +  unsigned long mmap_addr;
  11.155 +  
  11.156 +  /* Drive Info buffer */
  11.157 +  unsigned long drives_length;
  11.158 +  unsigned long drives_addr;
  11.159 +  
  11.160 +  /* ROM configuration table */
  11.161 +  unsigned long config_table;
  11.162 +  
  11.163 +  /* Boot Loader Name */
  11.164 +  unsigned long boot_loader_name;
  11.165 +
  11.166 +  /* APM table */
  11.167 +  unsigned long apm_table;
  11.168 +
  11.169 +  /* Video */
  11.170 +  unsigned long vbe_control_info;
  11.171 +  unsigned long vbe_mode_info;
  11.172 +  unsigned short vbe_mode;
  11.173 +  unsigned short vbe_interface_seg;
  11.174 +  unsigned short vbe_interface_off;
  11.175 +  unsigned short vbe_interface_len;
  11.176 +};
  11.177 +
  11.178 +/*
  11.179 + *  Flags to be set in the 'flags' parameter above
  11.180 + */
  11.181 +
  11.182 +/* is there basic lower/upper memory information? */
  11.183 +#define MB_INFO_MEMORY			0x00000001
  11.184 +/* is there a boot device set? */
  11.185 +#define MB_INFO_BOOTDEV			0x00000002
  11.186 +/* is the command-line defined? */
  11.187 +#define MB_INFO_CMDLINE			0x00000004
  11.188 +/* are there modules to do something with? */
  11.189 +#define MB_INFO_MODS			0x00000008
  11.190 +
  11.191 +/* These next two are mutually exclusive */
  11.192 +
  11.193 +/* is there a symbol table loaded? */
  11.194 +#define MB_INFO_AOUT_SYMS		0x00000010
  11.195 +/* is there an ELF section header table? */
  11.196 +#define MB_INFO_ELF_SHDR		0x00000020
  11.197 +
  11.198 +/* is there a full memory map? */
  11.199 +#define MB_INFO_MEM_MAP			0x00000040
  11.200 +
  11.201 +/* Is there drive info?  */
  11.202 +#define MB_INFO_DRIVE_INFO		0x00000080
  11.203 +
  11.204 +/* Is there a config table?  */
  11.205 +#define MB_INFO_CONFIG_TABLE		0x00000100
  11.206 +
  11.207 +/* Is there a boot loader name?  */
  11.208 +#define MB_INFO_BOOT_LOADER_NAME	0x00000200
  11.209 +
  11.210 +/* Is there a APM table?  */
  11.211 +#define MB_INFO_APM_TABLE		0x00000400
  11.212 +
  11.213 +/* Is there video information?  */
  11.214 +#define MB_INFO_VIDEO_INFO		0x00000800
  11.215 +
  11.216 +/*
  11.217 + *  The following value must be present in the EAX register.
  11.218 + */
  11.219 +
  11.220 +#define MULTIBOOT_VALID			0x2BADB002
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/tools/misc/mbootpack/mbootpack.c	Tue Mar 29 10:01:06 2005 +0000
    12.3 @@ -0,0 +1,703 @@
    12.4 +/*
    12.5 + *  mbootpack.c
    12.6 + *
    12.7 + *  Takes a multiboot image, command-line and modules, and repackages
    12.8 + *  them as if they were a linux kernel.   Only supports a subset of 
    12.9 + *  the multiboot info page options (enough to boot the Xen hypervisor).
   12.10 + *
   12.11 + *  Copyright (C) 2003-2004  Tim Deegan (tjd21@cl.cam.ac.uk)
   12.12 + * 
   12.13 + *  Parts based on GNU GRUB, Copyright (C) 2000  Free Software Foundation, Inc
   12.14 + *
   12.15 + *  This program is free software; you can redistribute it and/or
   12.16 + *  modify it under the terms of the GNU General Public License as
   12.17 + *  published by the Free Software Foundation; either version 2 of the
   12.18 + *  License, or (at your option) any later version.
   12.19 + *
   12.20 + *  This program is distributed in the hope that it will be useful,
   12.21 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.22 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12.23 + *  General Public License for more details.
   12.24 + *
   12.25 + *  You should have received a copy of the GNU General Public License
   12.26 + *  along with this program; if not, write to the Free Software
   12.27 + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   12.28 + *  02111-1307, USA.
   12.29 + *
   12.30 + * $Id: mbootpack.c,v 1.3 2005/03/23 10:38:36 tjd21 Exp tjd21 $
   12.31 + *
   12.32 + */
   12.33 +
   12.34 +#define _GNU_SOURCE
   12.35 +#include "mbootpack.h"
   12.36 +
   12.37 +#include <assert.h>
   12.38 +#include <stdio.h>
   12.39 +#include <stdlib.h>
   12.40 +#include <errno.h>
   12.41 +#include <string.h>
   12.42 +#include <getopt.h>
   12.43 +#include <elf.h>
   12.44 +#include <unistd.h>
   12.45 +#include <sys/types.h>
   12.46 +#include <sys/stat.h>
   12.47 +#include <sys/mman.h>
   12.48 +#include <asm/page.h>
   12.49 +
   12.50 +/* From GNU GRUB */
   12.51 +#include "mb_header.h"
   12.52 +#include "mb_info.h"
   12.53 +
   12.54 +
   12.55 +/*
   12.56 + *  The plan: Marshal up the multiboot modules and strings as if we 
   12.57 + *  were loading them into memory on a fresh ix86 PC.  Attach 
   12.58 + *  a linux bzImage header to the front, which sets up the machine
   12.59 + *  appropriately and then jumps to the kernel entry address.
   12.60 + * 
   12.61 + *  The memory map will be made up roughly like so:
   12.62 + *
   12.63 + *  =============
   12.64 + *  multiboot information (mbi) struct
   12.65 + *  -------
   12.66 + *  kernel command line
   12.67 + *  -------
   12.68 + *  bootloader name
   12.69 + *  -------
   12.70 + *  module command lines
   12.71 + *  -------
   12.72 + *  module information structs
   12.73 + *  =============
   12.74 + *   (memory hole)
   12.75 + *  =============
   12.76 + *  kernel
   12.77 + *  -------------
   12.78 + *  module 1
   12.79 + *  -------------
   12.80 + *  module 2
   12.81 + *  -------------
   12.82 + *      .
   12.83 + *      .
   12.84 + *      .
   12.85 + *
   12.86 + *  ==============
   12.87 + * 
   12.88 + * 
   12.89 + *  For allocation of memory we assume that the target machine has 'low'
   12.90 + *  memory from 0 to 640K and 'high' memory starting at 1M.  We allocate
   12.91 + *  the kernel first, wherever it wants to be.  After that, sections
   12.92 + *  are added at the next available aligned address, always in the order
   12.93 + *  given above, and skipping the memory hole at 640K.  Allocated sections 
   12.94 + *  are stored in a linked list of buffers.
   12.95 + * 
   12.96 + *  Re-packaging as a bzImage file happens in buildimage.c
   12.97 + *  
   12.98 + */
   12.99 +
  12.100 +/* Version */
  12.101 +static const char version_string[] = "mbootpack " MBOOTPACK_VERSION_STRING;
  12.102 +
  12.103 +/* Flags */
  12.104 +int quiet = 0;
  12.105 +
  12.106 +/* How much of the start of a kernel we read looking for headers.  
  12.107 + * Must be >= MULTIBOOT_SEARCH */
  12.108 +#define HEADERBUF_SIZE MULTIBOOT_SEARCH
  12.109 +
  12.110 +
  12.111 +/* Linked list of loaded sections, and a pointer to the next 
  12.112 + * available space (i.e. just above the highest allocation so far). */
  12.113 +static section_t *sections = NULL;
  12.114 +static section_t *last_section = NULL;
  12.115 +static address_t next_free_space = 0; 
  12.116 +
  12.117 +static void usage(void)
  12.118 +/* If we don't understand the command-line options */ 
  12.119 +{
  12.120 +    printf(
  12.121 +"Usage: mbpack [OPTIONS] kernel-image\n\n"
  12.122 +"  -h --help                       Print this text.\n"
  12.123 +"  -q --quiet                      Only output errors and warnings.\n"
  12.124 +"  -o --output=filename            Output to filename (default \"bzImage\").\n"
  12.125 +"  -M --multiboot-output           Produce a multiboot kernel, not a bzImage\n"
  12.126 +"                                  (sets default output file to \"mbImage\").\n"
  12.127 +"  -c --command-line=STRING        Set the kernel command line (DEPRECATED!).\n"
  12.128 +"  -m --module=\"MOD arg1 arg2...\"  Load module MOD with arguments \"arg1...\"\n"
  12.129 +"                                  (can be used multiple times).\n"
  12.130 +"\n");
  12.131 +    exit(1);
  12.132 +}
  12.133 +
  12.134 +
  12.135 +static void place_kernel_section(address_t start, long int size)
  12.136 +/* Place the kernel in memory, checking for the memory hole. */
  12.137 +{
  12.138 +    if (start >= MEM_HOLE_END) {
  12.139 +        /* Above the memory hole: easy */
  12.140 +        next_free_space = MAX(next_free_space, start + size);
  12.141 +        if (!quiet) {
  12.142 +            printf("Placed kernel section (%p+%p)\n", start, size);
  12.143 +        }
  12.144 +        return;
  12.145 +    }
  12.146 +    
  12.147 +    if (start >= MEM_HOLE_START) {
  12.148 +        /* In the memory hole.  Not so good */
  12.149 +        printf("Fatal: kernel load address (%p) is in the memory hole.\n",
  12.150 +               start);
  12.151 +        exit(1);
  12.152 +    }
  12.153 +    
  12.154 +    if (start + size > MEM_HOLE_START) {
  12.155 +        /* Too big for low memory */
  12.156 +        printf("Fatal: kernel (%p+%p) runs into the memory hole.\n",
  12.157 +               start, size);
  12.158 +        exit(1);
  12.159 +    }	
  12.160 +    
  12.161 +    /* Kernel loads below the memory hole */
  12.162 +    next_free_space = MAX(next_free_space, start + size);
  12.163 +
  12.164 +    if (!quiet) {
  12.165 +        printf("Placed kernel section (%p+%p)\n", start, size);
  12.166 +    }
  12.167 +}
  12.168 +
  12.169 +
  12.170 +static address_t place_section(long int size, int align)
  12.171 +/* Find the next available place for this section.  
  12.172 + * "align" must be a power of 2 */
  12.173 +{
  12.174 +    address_t start;
  12.175 +    assert(next_free_space != 0);
  12.176 +    assert(((~align + 1) & align) == align);
  12.177 +
  12.178 +    start = ROUNDUP_P2(next_free_space, align);
  12.179 +
  12.180 +    /* Check that we don't hit the memory hole */
  12.181 +    if (start < MEM_HOLE_END && (start + size) > MEM_HOLE_START) 
  12.182 +        start = ROUNDUP_P2(MEM_HOLE_END, align);
  12.183 +
  12.184 +    next_free_space = start + size;
  12.185 +
  12.186 +    if (!quiet) {
  12.187 +        printf("Placed section (%p+%p), align=%p\n", 
  12.188 +               start, size, align);
  12.189 +    }
  12.190 +    return start;
  12.191 +}
  12.192 +
  12.193 +
  12.194 +
  12.195 +
  12.196 +static address_t load_kernel(const char *filename)
  12.197 +/* Load an elf32/multiboot kernel from this file 
  12.198 + * Returns the entry address for the kernel. */
  12.199 +{
  12.200 +    unsigned int i;
  12.201 +    address_t start;
  12.202 +    size_t len;
  12.203 +    long int size, loadsize;
  12.204 +    FILE *fp;    
  12.205 +    char *buffer;
  12.206 +    section_t *sec, *s;
  12.207 +    Elf32_Ehdr *ehdr;
  12.208 +    Elf32_Phdr *phdr;
  12.209 +    struct multiboot_header *mbh;
  12.210 +    struct stat sb;
  12.211 +
  12.212 +    static char headerbuf[HEADERBUF_SIZE];
  12.213 +
  12.214 +    /* Stat and open the file */
  12.215 +    if (stat(filename, &sb) != 0) {
  12.216 +        printf("Fatal: cannot stat %s: %s\n", filename, strerror(errno));
  12.217 +        exit(1);
  12.218 +    }
  12.219 +    if ((fp = fopen(filename, "r")) == NULL) {
  12.220 +        printf("Fatal: cannot open %s: %s\n", filename, strerror(errno));
  12.221 +        exit(1);
  12.222 +    }
  12.223 +    
  12.224 +    /* Load the first 8k of the file */
  12.225 +    if (fseek(fp, 0, SEEK_SET) < 0) {
  12.226 +        printf("Fatal: seek error in %s: %s\n", filename, strerror(errno));
  12.227 +        exit(1);
  12.228 +    }
  12.229 +    if ((len = fread(headerbuf, 1, HEADERBUF_SIZE, fp))
  12.230 +        < HEADERBUF_SIZE)
  12.231 +    {
  12.232 +        if (feof(fp))   /* Short file */
  12.233 +        {
  12.234 +            if (len < 12) {
  12.235 +                printf("Fatal: %s is too short to be a multiboot file.", 
  12.236 +                       filename);
  12.237 +                exit(1);
  12.238 +            }
  12.239 +        } else {
  12.240 +            printf("Fatal: read error in %s: %s\n", filename, strerror(errno));
  12.241 +            exit(1);
  12.242 +        }
  12.243 +    }
  12.244 +
  12.245 +    /* Sanity-check: is this file compressed? */
  12.246 +    if ((headerbuf[0] == '\037' && 
  12.247 +         (headerbuf[1] == '\235' /* .Z */ ||
  12.248 +          headerbuf[1] == '\213' /* .gz */)) ||
  12.249 +        (headerbuf[0] == 'B' && headerbuf[1] == 'Z') /* .bz[2] */) {
  12.250 +        printf("Warning: %s looks like a compressed file.\n"
  12.251 +               "         You should uncompress it first!\n", filename);
  12.252 +    }
  12.253 +    
  12.254 +    /* Now look for a multiboot header */
  12.255 +    for (i = 0; i <= MIN(len - 12, MULTIBOOT_SEARCH - 12); i += 4)
  12.256 +    {
  12.257 +        mbh = (struct multiboot_header *)(headerbuf + i);
  12.258 +        if (mbh->magic != MULTIBOOT_MAGIC 
  12.259 +            || ((mbh->magic+mbh->flags+mbh->checksum) & 0xffffffff))
  12.260 +        {
  12.261 +            /* Not a multiboot header */
  12.262 +            continue;
  12.263 +        }
  12.264 +        if (mbh->flags & MULTIBOOT_UNSUPPORTED) {
  12.265 +            /* Requires options we don't support */
  12.266 +            printf("Fatal: found a multiboot header, but it "
  12.267 +                    "requires multiboot options that I\n"
  12.268 +                    "don't understand.  Sorry.\n");
  12.269 +            exit(1);
  12.270 +        } 
  12.271 +        if (mbh->flags & MULTIBOOT_VIDEO_MODE) { 
  12.272 +            /* Asked for screen mode information */
  12.273 +            /* XXX carry on regardless */
  12.274 +            printf("Warning: found a multiboot header which asks "
  12.275 +                   "for screen mode information.\n"
  12.276 +                   "         This kernel will NOT be given valid"
  12.277 +                   "screen mode information at boot time.\n");
  12.278 +        }
  12.279 +        /* This kernel will do: place and load it */
  12.280 +
  12.281 +        if (mbh->flags & MULTIBOOT_AOUT_KLUDGE) {
  12.282 +
  12.283 +            /* Load using the offsets in the multiboot header */
  12.284 +            if(!quiet) 
  12.285 +                printf("Loading %s using multiboot header.\n", filename);
  12.286 +
  12.287 +            /* How much is there? */
  12.288 +            start = mbh->load_addr;            
  12.289 +            if (mbh->load_end_addr != 0) 
  12.290 +                loadsize = mbh->load_end_addr - mbh->load_addr;
  12.291 +            else 
  12.292 +                loadsize = sb.st_size;
  12.293 +            
  12.294 +            /* How much memory will it take up? */ 
  12.295 +            if (mbh->bss_end_addr != 0)
  12.296 +                size = mbh->bss_end_addr - mbh->load_addr;
  12.297 +            else
  12.298 +                size = loadsize;
  12.299 +            
  12.300 +            if (loadsize > size) {
  12.301 +                printf("Fatal: can't load %i bytes of kernel into %i bytes " 
  12.302 +                       "of memory.\n", loadsize, size);
  12.303 +                exit(1);
  12.304 +            }
  12.305 +
  12.306 +            /* Does it fit where it wants to be? */
  12.307 +            place_kernel_section(start, size);            
  12.308 +            
  12.309 +            /* Load the kernel */
  12.310 +            if ((buffer = malloc(size)) == NULL) {
  12.311 +                printf("Fatal: malloc() for kernel load failed: %s\n",
  12.312 +                       strerror(errno));
  12.313 +                exit(1);
  12.314 +            }
  12.315 +            if ((fread(buffer, loadsize, 1, fp)) != 1) { 
  12.316 +                printf("Fatal: cannot read %s: %s\n", 
  12.317 +                       filename, strerror(errno));
  12.318 +                exit(1);
  12.319 +            }
  12.320 +            fclose(fp);
  12.321 +            
  12.322 +            /* Clear the kernel BSS */
  12.323 +            memset(buffer + loadsize, 0, size - loadsize);
  12.324 +
  12.325 +            /* Start off the linked list of sections */
  12.326 +            if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL) {
  12.327 +                printf("Fatal: malloc() for section_t failed: %s\n",
  12.328 +                       strerror(errno));
  12.329 +                exit(1);
  12.330 +            }
  12.331 +            sec->buffer = buffer;
  12.332 +            sec->start = start;
  12.333 +            sec->size = size;
  12.334 +            sec->next = NULL;
  12.335 +            sec->prev = NULL;
  12.336 +            sections = sec;
  12.337 +            last_section = sec;
  12.338 +            
  12.339 +            /* Done. */
  12.340 +            if (!quiet) printf("Loaded kernel from %s\n", filename);
  12.341 +            return mbh->entry_addr;
  12.342 +            
  12.343 +        } else {
  12.344 +
  12.345 +            /* Now look for an ELF32 header */    
  12.346 +            ehdr = (Elf32_Ehdr *)headerbuf;
  12.347 +            if (*(unsigned long *)ehdr != 0x464c457f 
  12.348 +                || ehdr->e_ident[EI_DATA] != ELFDATA2LSB
  12.349 +                || ehdr->e_ident[EI_CLASS] != ELFCLASS32
  12.350 +                || ehdr->e_machine != EM_386)
  12.351 +            {
  12.352 +                printf("Fatal: kernel has neither ELF32/x86 nor multiboot load"
  12.353 +                       " headers.\n");
  12.354 +                exit(1);
  12.355 +            }
  12.356 +            if (ehdr->e_phoff + ehdr->e_phnum*sizeof(*phdr) > HEADERBUF_SIZE) {
  12.357 +                /* Don't expect this will happen with sane kernels */
  12.358 +                printf("Fatal: too much ELF for me.  Try increasing "
  12.359 +                       "HEADERBUF_SIZE in mbootpack.\n");
  12.360 +                exit(1);
  12.361 +            }
  12.362 +            if (ehdr->e_phoff + ehdr->e_phnum*sizeof (*phdr) > len) {
  12.363 +                printf("Fatal: malformed ELF header overruns EOF.\n");
  12.364 +                exit(1);
  12.365 +            }
  12.366 +            if (ehdr->e_phnum <= 0) {
  12.367 +                printf("Fatal: ELF kernel has no program headers.\n");
  12.368 +                exit(1);
  12.369 +            }
  12.370 +
  12.371 +            if(!quiet) 
  12.372 +                printf("Loading %s using ELF header.\n", filename);
  12.373 +
  12.374 +            if (ehdr->e_type != ET_EXEC 
  12.375 +                || ehdr->e_version != EV_CURRENT
  12.376 +                || ehdr->e_phentsize != sizeof (Elf32_Phdr)) {
  12.377 +                printf("Warning: funny-looking ELF header.\n");
  12.378 +            }
  12.379 +            phdr = (Elf32_Phdr *)(headerbuf + ehdr->e_phoff);
  12.380 +
  12.381 +            /* Obey the program headers to load the kernel */
  12.382 +            for(i = 0; i < ehdr->e_phnum; i++) {
  12.383 +
  12.384 +                start = phdr[i].p_paddr;
  12.385 +                size = phdr[i].p_memsz;
  12.386 +                if (phdr[i].p_type != PT_LOAD) 
  12.387 +                    loadsize = 0;
  12.388 +                else 
  12.389 +                    loadsize = MIN((long int)phdr[i].p_filesz, size);
  12.390 +
  12.391 +                if ((buffer = malloc(size)) == NULL) {
  12.392 +                    printf("Fatal: malloc() for kernel load failed: %s\n",
  12.393 +                           strerror(errno));
  12.394 +                    exit(1);
  12.395 +                }
  12.396 +
  12.397 +                /* Place the section where it wants to be */
  12.398 +                place_kernel_section(start, size);            
  12.399 +
  12.400 +                /* Load section from file */ 
  12.401 +                if (loadsize > 0) {
  12.402 +                    if (fseek(fp, phdr[i].p_offset, SEEK_SET) != 0) {
  12.403 +                        printf("Fatal: seek failed in %s\n",
  12.404 +                                strerror(errno));
  12.405 +                        exit(1);
  12.406 +                    }
  12.407 +                    if ((fread(buffer, loadsize, 1, fp)) != 1) { 
  12.408 +                        printf("Fatal: cannot read %s: %s\n", 
  12.409 +                               filename, strerror(errno));
  12.410 +                        exit(1);
  12.411 +                    }
  12.412 +                }
  12.413 +
  12.414 +                /* Clear the rest of the buffer */
  12.415 +                memset(buffer + loadsize, 0, size - loadsize);
  12.416 +
  12.417 +                /* Add this section to the list (keeping it ordered) */
  12.418 +                if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL) {
  12.419 +                    printf("Fatal: malloc() for section_t failed: %s\n",
  12.420 +                           strerror(errno));
  12.421 +                    exit(1);
  12.422 +                }
  12.423 +                sec->buffer = buffer;
  12.424 +                sec->start = start;
  12.425 +                sec->size = size;
  12.426 +
  12.427 +                for(s = sections; s; s = s->next) {
  12.428 +                    if (s->start > start) {
  12.429 +                        sec->next = s;
  12.430 +                        if (s->prev == NULL) {
  12.431 +                            /* sec becomes the new first item */
  12.432 +                            s->prev = sec;
  12.433 +                            sections = sec;
  12.434 +                        } else {
  12.435 +                            /* sec goes between s->prev and s */
  12.436 +                            sec->prev = s->prev;
  12.437 +                            sec->prev->next = sec;
  12.438 +                            s->prev = sec;
  12.439 +                        }
  12.440 +                        break;
  12.441 +                    }
  12.442 +                }
  12.443 +                if (s == NULL) {
  12.444 +                    /* sec becomes the new last item */
  12.445 +                    sec->next = NULL;
  12.446 +                    sec->prev = last_section;
  12.447 +                    if (last_section) {
  12.448 +                        last_section->next = sec;
  12.449 +                    } else {
  12.450 +                        sections = sec;
  12.451 +                    }
  12.452 +                    last_section = sec;
  12.453 +                }
  12.454 +            }
  12.455 +         
  12.456 +            /* Done! */
  12.457 +            if (!quiet) printf("Loaded kernel from %s\n", filename);
  12.458 +            return ehdr->e_entry;
  12.459 +        }
  12.460 +
  12.461 +    }
  12.462 +
  12.463 +    /* This is not a multiboot kernel */
  12.464 +    printf("Fatal: %s is not a multiboot kernel.\n", filename);
  12.465 +    exit(1);
  12.466 +}
  12.467 +
  12.468 +
  12.469 +
  12.470 +
  12.471 +int main(int argc, char **argv) 
  12.472 +{
  12.473 +    char *buffer, *imagename, *command_line, *p;
  12.474 +    char *mod_filename, *mod_command_line, *mod_clp;
  12.475 +    char *out_filename;
  12.476 +    section_t *sec;
  12.477 +    FILE *fp;
  12.478 +    struct stat sb;
  12.479 +    struct multiboot_info *mbi;
  12.480 +    struct mod_list *modp;
  12.481 +    address_t start, kernel_entry;
  12.482 +    long int size, mod_command_line_space, command_line_len;
  12.483 +    int modules, opt, mbi_reloc_offset, make_multiboot;
  12.484 +
  12.485 +    static const char short_options[] = "hc:m:o:qM";
  12.486 +    static const struct option options[] = {
  12.487 +        { "help",		0, 0, 'h' },
  12.488 +        { "command-line",	1, 0, 'c' },
  12.489 +        { "append",	       	1, 0, 'c' },
  12.490 +        { "module",		1, 0, 'm' },
  12.491 +        { "output",		1, 0, 'o' },
  12.492 +        { "quiet",		0, 0, 'q' },
  12.493 +        { 0, 		       	0, 0, 0 },
  12.494 +    };
  12.495 +
  12.496 +    /* Parse the command line */
  12.497 +    out_filename = NULL;
  12.498 +    command_line = "";
  12.499 +    command_line_len = 0;
  12.500 +    modules = 0;
  12.501 +    mod_command_line_space = 0;
  12.502 +    while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1)
  12.503 +    {
  12.504 +        switch(opt) {
  12.505 +        case 'c':
  12.506 +            command_line = optarg;
  12.507 +            break;
  12.508 +        case 'm':
  12.509 +            modules++;
  12.510 +            mod_command_line_space += strlen(optarg) + 1;
  12.511 +            break;
  12.512 +        case 'o':
  12.513 +            out_filename = optarg;
  12.514 +            break;
  12.515 +        case 'q':
  12.516 +            quiet = 1;
  12.517 +            break;
  12.518 +        case 'h':
  12.519 +        case '?':
  12.520 +        default:
  12.521 +            usage();
  12.522 +        }
  12.523 +    }
  12.524 +    imagename = argv[optind];
  12.525 +    if (!imagename || strlen(imagename) == 0) usage();
  12.526 +    command_line_len = strlen(command_line) + strlen(imagename) + 2;
  12.527 +    /* Leave space to overwritethe command-line at boot time */
  12.528 +    command_line_len = MAX(command_line_len, CMD_LINE_SPACE); 
  12.529 +    if (!out_filename) out_filename = "bzImage";
  12.530 +
  12.531 +    /* Place and load the kernel */
  12.532 +    kernel_entry = load_kernel(imagename);
  12.533 +    assert(sections != NULL);
  12.534 +    assert(last_section != NULL);
  12.535 +    assert(next_free_space != 0);
  12.536 +    
  12.537 +    /* Next section is all the metadata between kernel and modules */
  12.538 +    size = ((((sizeof (struct multiboot_info)
  12.539 +               + command_line_len
  12.540 +               + strlen(version_string) + 1
  12.541 +               + mod_command_line_space) 
  12.542 +              + 3 ) & ~3)
  12.543 +            + modules * sizeof (struct mod_list));
  12.544 +    /* Locate this section after the setup sectors, in *low* memory */
  12.545 +    start = place_mbi(size);
  12.546 +
  12.547 +    if ((buffer = malloc(size)) == NULL) {
  12.548 +        printf("Fatal: malloc() for boot metadata failed: %s\n",
  12.549 +               strerror(errno));
  12.550 +        exit(1);
  12.551 +    }
  12.552 +
  12.553 +    if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL) {
  12.554 +        printf("Fatal: malloc() for section_t failed: %s\n",
  12.555 +               strerror(errno));
  12.556 +        exit(1);
  12.557 +    }
  12.558 +    sec->buffer = buffer;
  12.559 +    sec->start = start;
  12.560 +    sec->size = size;
  12.561 +    sec->next = NULL;
  12.562 +    sec->prev = last_section;
  12.563 +    last_section->next = sec;
  12.564 +    last_section = sec;
  12.565 +
  12.566 +    /* Multiboot info struct */
  12.567 +    mbi = (struct multiboot_info *)buffer;
  12.568 +    memset(buffer, 0, sizeof (struct multiboot_info));
  12.569 +    mbi_reloc_offset = start - (address_t)buffer;
  12.570 +    
  12.571 +    /* Command line */
  12.572 +    p = (char *)(mbi + 1);
  12.573 +    sprintf(p, "%s %s", imagename, command_line);
  12.574 +    mbi->cmdline = ((address_t)p) + mbi_reloc_offset;
  12.575 +    p += command_line_len;
  12.576 +
  12.577 +    /* Bootloader ID */
  12.578 +    sprintf(p, version_string);
  12.579 +    mbi->boot_loader_name = ((address_t)p) + mbi_reloc_offset;
  12.580 +    p += strlen(version_string) + 1;
  12.581 +
  12.582 +    /* Next is space for the module command lines */
  12.583 +    mod_clp = p;
  12.584 +
  12.585 +    /* Last come the module info structs */
  12.586 +    modp = (struct mod_list *)
  12.587 +        ((((address_t)p + mod_command_line_space) + 3) & ~3);
  12.588 +    mbi->mods_count = modules;
  12.589 +    mbi->mods_addr = ((address_t)modp) + mbi_reloc_offset;
  12.590 +
  12.591 +    /* Memory information will be added at boot time, by setup.S 
  12.592 +     * or trampoline.S. */
  12.593 +    mbi->flags = MB_INFO_CMDLINE | MB_INFO_BOOT_LOADER_NAME;
  12.594 +
  12.595 +
  12.596 +    /* Load the modules */
  12.597 +    if (modules) {
  12.598 +        mbi->flags |= MB_INFO_MODS;
  12.599 +                
  12.600 +        /* Go back and parse the module command lines */
  12.601 +        optind = opterr = 1;
  12.602 +        while((opt = getopt_long(argc, argv, 
  12.603 +                                 short_options, options, 0)) != -1)
  12.604 +        {
  12.605 +            if (opt != 'm') continue;
  12.606 +
  12.607 +            /* Split module filename from command line */
  12.608 +            mod_command_line = mod_filename = optarg;
  12.609 +            if ((p = strchr(mod_filename, ' ')) != NULL) {
  12.610 +                /* See as I discard the 'const' modifier */
  12.611 +                *p = '\0';
  12.612 +            }
  12.613 +
  12.614 +            /* Find space for it */
  12.615 +            if (stat(mod_filename, &sb) != 0) {
  12.616 +                printf("Fatal: cannot stat %s: %s\n",
  12.617 +                       mod_filename, strerror(errno));
  12.618 +                exit(1);
  12.619 +            }
  12.620 +            size = sb.st_size;
  12.621 +            start = place_section(size, X86_PAGE_SIZE);
  12.622 +            /* XXX should be place_section(size, 4) if the MBH hasn't got
  12.623 +             * XXX MULTIBOOT_PAGE_ALIGN set, but that breaks Xen */
  12.624 +
  12.625 +            /* Load it */ 
  12.626 +            if ((buffer = malloc(sb.st_size)) == NULL) {
  12.627 +                printf("Fatal: malloc failed for module load: %s\n",
  12.628 +                       strerror(errno));
  12.629 +                exit(1);
  12.630 +            }
  12.631 +            if ((fp = fopen(mod_filename, "r")) == NULL) {
  12.632 +                printf("Fatal: cannot open %s: %s\n",
  12.633 +                       mod_filename, strerror(errno));
  12.634 +                exit(1);
  12.635 +            }
  12.636 +            if ((fread(buffer, sb.st_size, 1, fp)) != 1) { 
  12.637 +                printf("Fatal: cannot read %s: %s\n",
  12.638 +                       mod_filename, strerror(errno));
  12.639 +                exit(1);
  12.640 +            }
  12.641 +            fclose(fp);
  12.642 +            
  12.643 +            /* Sanity-check: is this file compressed? */
  12.644 +            if ((buffer[0] == '\037' && 
  12.645 +                 (buffer[1] == '\235' /* .Z */ ||
  12.646 +                  buffer[1] == '\213' /* .gz */)) ||
  12.647 +                (buffer[0] == 'B' && buffer[1] == 'Z') /* .bz[2] */) {
  12.648 +                printf("Warning: %s looks like a compressed file.\n",
  12.649 +                       mod_filename);
  12.650 +            }
  12.651 +
  12.652 +            if (!quiet) printf("Loaded module from %s\n", mod_filename);
  12.653 +
  12.654 +            /* Restore the command line to its former glory */
  12.655 +            if (p != NULL) *p = ' ';
  12.656 +
  12.657 +            /* Fill in the module info struct */
  12.658 +            modp->mod_start = start;
  12.659 +            modp->mod_end = start + size;
  12.660 +            modp->cmdline = (address_t)mod_clp + mbi_reloc_offset;
  12.661 +            modp->pad = 0;
  12.662 +            modp++;
  12.663 +
  12.664 +            /* Store the module command line */
  12.665 +            sprintf(mod_clp, "%s", mod_command_line);
  12.666 +            mod_clp += strlen(mod_clp) + 1;
  12.667 +
  12.668 +            /* Add the section to the list */
  12.669 +            if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL) {
  12.670 +                printf("Fatal: malloc() for section_t failed: %s\n",
  12.671 +                       strerror(errno));
  12.672 +                exit(1);
  12.673 +            }
  12.674 +            sec->buffer = buffer;
  12.675 +            sec->start = start;
  12.676 +            sec->size = size;
  12.677 +            sec->next = NULL;
  12.678 +            sec->prev = last_section;
  12.679 +            last_section->next = sec;
  12.680 +            last_section = sec;
  12.681 +
  12.682 +        }
  12.683 +		
  12.684 +    }
  12.685 +    
  12.686 +    /* Everything is placed and loaded.  Now we package it all up 
  12.687 +     * as a bzImage */
  12.688 +    if ((fp = fopen(out_filename, "w")) == NULL) {
  12.689 +        printf("Fatal: cannot open %s: %s\n", out_filename, strerror(errno));
  12.690 +        exit(1);
  12.691 +    }
  12.692 +    make_bzImage(sections, 
  12.693 +                 kernel_entry, 
  12.694 +                 ((address_t)mbi) + mbi_reloc_offset,
  12.695 +                 fp);
  12.696 +    fclose(fp);
  12.697 +
  12.698 +    /* Success! */
  12.699 +    if(!quiet) printf("Finished.\n");
  12.700 +    return 0;
  12.701 +}
  12.702 +
  12.703 +/*
  12.704 + *  EOF (mbootpack.c)
  12.705 + */
  12.706 +
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/misc/mbootpack/mbootpack.h	Tue Mar 29 10:01:06 2005 +0000
    13.3 @@ -0,0 +1,91 @@
    13.4 +/*
    13.5 + *  mbootpack.h
    13.6 + *
    13.7 + *  Common definitions for mbootpack
    13.8 + * 
    13.9 + *  Copyright (C) 2003-2004  Tim Deegan (tjd21@cl.cam.ac.uk)
   13.10 + * 
   13.11 + *  This program is free software; you can redistribute it and/or
   13.12 + *  modify it under the terms of the GNU General Public License as
   13.13 + *  published by the Free Software Foundation; either version 2 of the
   13.14 + *  License, or (at your option) any later version.
   13.15 + *
   13.16 + *  This program is distributed in the hope that it will be useful,
   13.17 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.18 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13.19 + *  General Public License for more details.
   13.20 + *
   13.21 + *  You should have received a copy of the GNU General Public License
   13.22 + *  along with this program; if not, write to the Free Software
   13.23 + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   13.24 + *  02111-1307, USA.
   13.25 + *
   13.26 + * $Id: mbootpack.h,v 1.2 2005/03/23 10:38:37 tjd21 Exp $
   13.27 + *
   13.28 + */
   13.29 +
   13.30 +#ifndef __MBOOTPACK__H__
   13.31 +#define __MBOOTPACK__H__
   13.32 +
   13.33 +#ifndef __MB_ASM
   13.34 +
   13.35 +#undef NDEBUG
   13.36 +#include <stdio.h>
   13.37 +
   13.38 +/* Flags */
   13.39 +extern int quiet;
   13.40 +
   13.41 +/* Types */
   13.42 +typedef unsigned long address_t;
   13.43 +
   13.44 +typedef struct section_t {
   13.45 +    char *buffer;
   13.46 +    address_t start;
   13.47 +    long int size;
   13.48 +    struct section_t *prev;
   13.49 +    struct section_t *next;
   13.50 +} section_t;
   13.51 +
   13.52 +/* buildimage.c */
   13.53 +extern void make_bzImage(section_t *sections, 
   13.54 +                         address_t entry, 
   13.55 +                         address_t mbi, 
   13.56 +                         FILE *fp);
   13.57 +
   13.58 +address_t place_mbi(long int size);
   13.59 +
   13.60 +
   13.61 +/* trampoline.S */
   13.62 +extern unsigned char mb_trampoline[];
   13.63 +extern unsigned char mb_trampoline_end[];
   13.64 +extern volatile address_t mb_mbi_address, mb_entry_address;
   13.65 +
   13.66 +/* Macros */
   13.67 +#define MIN(_x,_y) (((_x)<=(_y))?(_x):(_y))
   13.68 +#define MAX(_x,_y) (((_x)<=(_y))?(_y):(_x))
   13.69 +#define ROUNDUP_P2(_x, _a) (((_x)+((_a)-1))&(~((_a)-1)))
   13.70 +
   13.71 +#endif
   13.72 +
   13.73 +/* x86 memory: such fun */
   13.74 +#define MEM_HOLE_START  0xa0000
   13.75 +#define MEM_HOLE_END    0x100000
   13.76 +#define HIGHMEM_START   MEM_HOLE_END
   13.77 +#define X86_PAGE_SIZE   0x1000
   13.78 +
   13.79 +/* How much command line we'll take from the bootloader. */
   13.80 +#define CMD_LINE_SPACE  0x300
   13.81 +
   13.82 +/* Number of 512-byte sectors to load in low memory (max 7) */
   13.83 +#define SETUPSECTS	7
   13.84 +
   13.85 +
   13.86 +/* Who are we? */
   13.87 +#define MBOOTPACK_VERSION_STRING "v0.2 (alpha)"
   13.88 +
   13.89 +#endif /* __MBOOTPACK__H__ */
   13.90 +
   13.91 +/*
   13.92 + *  EOF (mbootpack.h)
   13.93 + */
   13.94 +
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/misc/mbootpack/setup.S	Tue Mar 29 10:01:06 2005 +0000
    14.3 @@ -0,0 +1,1064 @@
    14.4 +/*
    14.5 + *  bootsect.S
    14.6 + *
    14.7 + *  This is setup.S from the linux 2.6.9 source code,
    14.8 + *  with heavy cuts and changes for mbootpack
    14.9 + *  November 2004 Tim Deegan <tjd21@cl.cam.ac.uk>
   14.10 + *
   14.11 + *  
   14.12 + *  This program is free software; you can redistribute it and/or
   14.13 + *  modify it under the terms of the GNU General Public License as
   14.14 + *  published by the Free Software Foundation; either version 2 of the
   14.15 + *  License, or (at your option) any later version.
   14.16 + *
   14.17 + *  This program is distributed in the hope that it will be useful,
   14.18 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.19 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14.20 + *  General Public License for more details.
   14.21 + *
   14.22 + *  You should have received a copy of the GNU General Public License
   14.23 + *  along with this program; if not, write to the Free Software
   14.24 + *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   14.25 + *  02111-1307, USA.
   14.26 + *
   14.27 + * $Id: setup.S,v 1.4 2005/03/23 10:39:03 tjd21 Exp $
   14.28 + *
   14.29 + */
   14.30 +	
   14.31 +#include "mbootpack.h"
   14.32 +		
   14.33 +/*
   14.34 + *	setup.S		Copyright (C) 1991, 1992 Linus Torvalds
   14.35 + *
   14.36 + * setup.s is responsible for getting the system data from the BIOS,
   14.37 + * and putting them into the appropriate places in system memory.
   14.38 + * both setup.s and system has been loaded by the bootblock.
   14.39 + *
   14.40 + * This code asks the bios for memory/disk/other parameters, and
   14.41 + * puts them in a "safe" place: 0x90000-0x901FF, ie where the
   14.42 + * boot-block used to be. It is then up to the protected mode
   14.43 + * system to read them from there before the area is overwritten
   14.44 + * for buffer-blocks.
   14.45 + *
   14.46 + * Move PS/2 aux init code to psaux.c
   14.47 + * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
   14.48 + *
   14.49 + * some changes and additional features by Christoph Niemann,
   14.50 + * March 1993/June 1994 (Christoph.Niemann@linux.org)
   14.51 + *
   14.52 + * add APM BIOS checking by Stephen Rothwell, May 1994
   14.53 + * (sfr@canb.auug.org.au)
   14.54 + *
   14.55 + * High load stuff, initrd support and position independency
   14.56 + * by Hans Lermen & Werner Almesberger, February 1996
   14.57 + * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
   14.58 + *
   14.59 + * Video handling moved to video.S by Martin Mares, March 1996
   14.60 + * <mj@k332.feld.cvut.cz>
   14.61 + *
   14.62 + * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
   14.63 + * parsons) to avoid loadlin confusion, July 1997
   14.64 + *
   14.65 + * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
   14.66 + * <stiker@northlink.com>
   14.67 + *
   14.68 + * Fix to work around buggy BIOSes which dont use carry bit correctly
   14.69 + * and/or report extended memory in CX/DX for e801h memory size detection 
   14.70 + * call.  As a result the kernel got wrong figures.  The int15/e801h docs
   14.71 + * from Ralf Brown interrupt list seem to indicate AX/BX should be used
   14.72 + * anyway.  So to avoid breaking many machines (presumably there was a reason
   14.73 + * to orginally use CX/DX instead of AX/BX), we do a kludge to see
   14.74 + * if CX/DX have been changed in the e801 call and if so use AX/BX .
   14.75 + * Michael Miller, April 2001 <michaelm@mjmm.org>
   14.76 + *
   14.77 + * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes
   14.78 + * by Robert Schwebel, December 2001 <robert@schwebel.de>
   14.79 + */
   14.80 +
   14.81 +/*
   14.82 +#include <linux/config.h>
   14.83 +#include <asm/segment.h>
   14.84 +#include <linux/version.h>
   14.85 +#include <linux/compile.h>
   14.86 +#include <asm/boot.h>
   14.87 +#include <asm/e820.h>
   14.88 +#include <asm/page.h>
   14.89 +*/
   14.90 +
   14.91 +/* Definitions that should have come from these includes */
   14.92 +#define DEF_INITSEG     0x9000
   14.93 +#define DEF_SYSSEG      0x1000
   14.94 +#define DEF_SETUPSEG    0x9020
   14.95 +#define DEF_SYSSIZE     0x7F00
   14.96 +#define NORMAL_VGA      0xffff
   14.97 +#define EXTENDED_VGA    0xfffe
   14.98 +#define ASK_VGA         0xfffd
   14.99 +#define GDT_ENTRY_BOOT_CS	2
  14.100 +#define __BOOT_CS		(GDT_ENTRY_BOOT_CS * 8)
  14.101 +#define GDT_ENTRY_BOOT_DS	(GDT_ENTRY_BOOT_CS + 1)
  14.102 +#define __BOOT_DS		(GDT_ENTRY_BOOT_DS * 8)
  14.103 +#define __PAGE_OFFSET           (0xC0000000)
  14.104 +#define E820MAP 0x2d0           /* our map */
  14.105 +#define E820MAX 32              /* number of entries in E820MAP */
  14.106 +#define E820NR  0x1e8           /* # entries in E820MAP */
  14.107 +#define E820_RAM        1
  14.108 +#define E820_RESERVED   2
  14.109 +#define E820_ACPI       3 /* usable as RAM once ACPI tables have been read */
  14.110 +#define E820_NVS        4
  14.111 +#define __BIG_KERNEL__
  14.112 +	
  14.113 +		
  14.114 +/* Signature words to ensure LILO loaded us right */
  14.115 +#define SIG1	0xAA55
  14.116 +#define SIG2	0x5A5A
  14.117 +	
  14.118 +INITSEG  = DEF_INITSEG		# 0x9000, we move boot here, out of the way
  14.119 +SYSSEG   = DEF_SYSSEG		# 0x1000, system loaded at 0x10000 (65536).
  14.120 +SETUPSEG = DEF_SETUPSEG		# 0x9020, this is the current segment
  14.121 +				# ... and the former contents of CS
  14.122 +
  14.123 +DELTA_INITSEG = SETUPSEG - INITSEG	# 0x0020
  14.124 +
  14.125 +.code16
  14.126 +.globl _start, begtext, begdata, begbss, endtext, enddata, endbss
  14.127 +
  14.128 +.text
  14.129 +begtext:
  14.130 +.data
  14.131 +begdata:
  14.132 +.bss
  14.133 +begbss:
  14.134 +.text
  14.135 +
  14.136 +_start:
  14.137 +start:
  14.138 +	jmp	trampoline
  14.139 +
  14.140 +# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
  14.141 +
  14.142 +		.ascii	"HdrS"		# header signature
  14.143 +		.word	0x0203		# header version number (>= 0x0105)
  14.144 +					# or else old loadlin-1.5 will fail)
  14.145 +realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
  14.146 +start_sys_seg:	.word	SYSSEG
  14.147 +		.word	kernel_version	# pointing to kernel version string
  14.148 +					# above section of header is compatible
  14.149 +					# with loadlin-1.5 (header v1.5). Don't
  14.150 +					# change it.
  14.151 +
  14.152 +type_of_loader:	.byte	0		# = 0, old one (LILO, Loadlin,
  14.153 +					#      Bootlin, SYSLX, bootsect...)
  14.154 +					# See Documentation/i386/boot.txt for
  14.155 +					# assigned ids
  14.156 +	
  14.157 +# flags, unused bits must be zero (RFU) bit within loadflags
  14.158 +loadflags:
  14.159 +LOADED_HIGH	= 1			# If set, the kernel is loaded high
  14.160 +CAN_USE_HEAP	= 0x80			# If set, the loader also has set
  14.161 +					# heap_end_ptr to tell how much
  14.162 +					# space behind setup.S can be used for
  14.163 +					# heap purposes.
  14.164 +					# Only the loader knows what is free
  14.165 +#ifndef __BIG_KERNEL__
  14.166 +		.byte	0
  14.167 +#else
  14.168 +		.byte	LOADED_HIGH
  14.169 +#endif
  14.170 +
  14.171 +setup_move_size: .word  0x8000		# size to move, when setup is not
  14.172 +					# loaded at 0x90000. We will move setup 
  14.173 +					# to 0x90000 then just before jumping
  14.174 +					# into the kernel. However, only the
  14.175 +					# loader knows how much data behind
  14.176 +					# us also needs to be loaded.
  14.177 +
  14.178 +/* N.B. these next addresses are entirely ignored by this code -- it
  14.179 + * assumes it was loaded with the 32bit code at 0x100000, and doesn't 
  14.180 + * touch the ramdisk. */
  14.181 +code32_start:				# here loaders can put a different
  14.182 +					# start address for 32-bit code.
  14.183 +#ifndef __BIG_KERNEL__
  14.184 +		.long	0x1000		#   0x1000 = default for zImage
  14.185 +#else
  14.186 +		.long	0x100000	# 0x100000 = default for big kernel
  14.187 +#endif
  14.188 +
  14.189 +ramdisk_image:	.long	0		# address of loaded ramdisk image
  14.190 +					# Here the loader puts the 32-bit
  14.191 +					# address where it loaded the image.
  14.192 +					# This only will be read by the kernel.
  14.193 +
  14.194 +ramdisk_size:	.long	0		# its size in bytes
  14.195 +
  14.196 +bootsect_kludge:
  14.197 +		.long	0		# obsolete
  14.198 +
  14.199 +heap_end_ptr:	.word	modelist+1024	# (Header version 0x0201 or later)
  14.200 +					# space from here (exclusive) down to
  14.201 +					# end of setup code can be used by setup
  14.202 +					# for local heap purposes.
  14.203 +
  14.204 +pad1:		.word	0
  14.205 +cmd_line_ptr:	.long 0			# (Header version 0x0202 or later)
  14.206 +					# If nonzero, a 32-bit pointer
  14.207 +					# to the kernel command line.
  14.208 +					# The command line should be
  14.209 +					# located between the start of
  14.210 +					# setup and the end of low
  14.211 +					# memory (0xa0000), or it may
  14.212 +					# get overwritten before it
  14.213 +					# gets read.  If this field is
  14.214 +					# used, there is no longer
  14.215 +					# anything magical about the
  14.216 +					# 0x90000 segment; the setup
  14.217 +					# can be located anywhere in
  14.218 +					# low memory 0x10000 or higher.
  14.219 +
  14.220 +ramdisk_max:	.long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
  14.221 +					# (Header version 0x0203 or later)
  14.222 +					# The highest safe address for
  14.223 +					# the contents of an initrd
  14.224 +
  14.225 +/* Add more known locations: the image builder will overwrite
  14.226 + * these with the entry point and MBI location for the multiboot kernel.
  14.227 + * These offsets *must* match the definitions in buildimage.c  */
  14.228 +
  14.229 +entry_address:	.long 0		# This will be offset 0x30 (0x230 from b'sect)
  14.230 +mbi_address:	.long 0		# This will be offset 0x34
  14.231 +
  14.232 +/* Storage space for the size of memory */
  14.233 +highmem_size:	.long 0
  14.234 +		
  14.235 +trampoline:	call	start_of_setup
  14.236 +		.space	1024
  14.237 +# End of setup header #####################################################
  14.238 +
  14.239 +start_of_setup:
  14.240 +# Bootlin depends on this being done early
  14.241 +	movw	$0x01500, %ax
  14.242 +	movb	$0x81, %dl
  14.243 +	int	$0x13
  14.244 +
  14.245 +#ifdef SAFE_RESET_DISK_CONTROLLER
  14.246 +# Reset the disk controller.
  14.247 +	movw	$0x0000, %ax
  14.248 +	movb	$0x80, %dl
  14.249 +	int	$0x13
  14.250 +#endif
  14.251 +
  14.252 +# Set %ds = %cs, we know that SETUPSEG = %cs at this point
  14.253 +	movw	%cs, %ax		# aka SETUPSEG
  14.254 +	movw	%ax, %ds
  14.255 +	
  14.256 +# Check signature at end of setup	
  14.257 +	cmpw	$SIG1, setup_sig1
  14.258 +	jne	bad_sig
  14.259 +
  14.260 +	cmpw	$SIG2, setup_sig2
  14.261 +	jne	bad_sig
  14.262 +
  14.263 +	jmp	good_sig1
  14.264 +
  14.265 +# Routine to print asciiz string at ds:si
  14.266 +prtstr:
  14.267 +	lodsb
  14.268 +	andb	%al, %al
  14.269 +	jz	fin
  14.270 +
  14.271 +	call	prtchr
  14.272 +	jmp	prtstr
  14.273 +
  14.274 +fin:	ret
  14.275 +
  14.276 +# Space printing
  14.277 +prtsp2:	call	prtspc		# Print double space
  14.278 +prtspc:	movb	$0x20, %al	# Print single space (note: fall-thru)
  14.279 +
  14.280 +# Part of above routine, this one just prints ascii al
  14.281 +prtchr:	pushw	%ax
  14.282 +	pushw	%cx
  14.283 +	movw	$7,%bx
  14.284 +	movw	$0x01, %cx
  14.285 +	movb	$0x0e, %ah
  14.286 +	int	$0x10
  14.287 +	popw	%cx
  14.288 +	popw	%ax
  14.289 +	ret
  14.290 +
  14.291 +beep:	movb	$0x07, %al
  14.292 +	jmp	prtchr
  14.293 +	
  14.294 +no_sig_mess: .string	"No setup signature found ..."
  14.295 +
  14.296 +good_sig1:
  14.297 +	jmp	good_sig
  14.298 +
  14.299 +# We now have to find the rest of the setup code/data
  14.300 +bad_sig:
  14.301 +	movw	%cs, %ax			# SETUPSEG
  14.302 +	subw	$DELTA_INITSEG, %ax		# INITSEG
  14.303 +	movw	%ax, %ds
  14.304 +	xorb	%bh, %bh
  14.305 +	movb	(497), %bl			# get setup sect from bootsect
  14.306 +	subw	$4, %bx				# LILO loads 4 sectors of setup
  14.307 +	shlw	$8, %bx				# convert to words (1sect=2^8 words)
  14.308 +	movw	%bx, %cx
  14.309 +	shrw	$3, %bx				# convert to segment
  14.310 +	addw	$SYSSEG, %bx
  14.311 +	movw	%bx, %cs:start_sys_seg
  14.312 +# Move rest of setup code/data to here
  14.313 +	movw	$2048, %di			# four sectors loaded by LILO
  14.314 +	subw	%si, %si
  14.315 +	pushw	%cs
  14.316 +	popw	%es
  14.317 +	movw	$SYSSEG, %ax
  14.318 +	movw	%ax, %ds
  14.319 +	rep
  14.320 +	movsw
  14.321 +	movw	%cs, %ax			# aka SETUPSEG
  14.322 +	movw	%ax, %ds
  14.323 +	cmpw	$SIG1, setup_sig1
  14.324 +	jne	no_sig
  14.325 +
  14.326 +	cmpw	$SIG2, setup_sig2
  14.327 +	jne	no_sig
  14.328 +
  14.329 +	jmp	good_sig
  14.330 +
  14.331 +no_sig:
  14.332 +	lea	no_sig_mess, %si
  14.333 +	call	prtstr
  14.334 +
  14.335 +no_sig_loop:
  14.336 +	hlt
  14.337 +	jmp	no_sig_loop
  14.338 +
  14.339 +mb_hello_mess1:
  14.340 +	.string	"mboot"
  14.341 +	
  14.342 +good_sig:
  14.343 +	lea	mb_hello_mess1, %si
  14.344 +	call	prtstr
  14.345 +
  14.346 +	movw	%cs, %ax			# aka SETUPSEG
  14.347 +	subw	$DELTA_INITSEG, %ax 		# aka INITSEG
  14.348 +	movw	%ax, %ds
  14.349 +# Check if an old loader tries to load a big-kernel
  14.350 +	testb	$LOADED_HIGH, %cs:loadflags	# Do we have a big kernel?
  14.351 +	jz	loader_ok			# No, no danger for old loaders.
  14.352 +
  14.353 +	cmpb	$0, %cs:type_of_loader 		# Do we have a loader that
  14.354 +						# can deal with us?
  14.355 +	jnz	loader_ok			# Yes, continue.
  14.356 +
  14.357 +	pushw	%cs				# No, we have an old loader,
  14.358 +	popw	%ds				# die. 
  14.359 +	lea	loader_panic_mess, %si
  14.360 +	call	prtstr
  14.361 +
  14.362 +	jmp	no_sig_loop
  14.363 +
  14.364 +loader_panic_mess: .string "Wrong loader, giving up..."
  14.365 +
  14.366 +loader_ok:
  14.367 +	
  14.368 +# Get memory size (extended mem, kB)
  14.369 +
  14.370 +/* We'll be storing this in highmem_size, to be copied to the mbi */
  14.371 +
  14.372 +# Try three different memory detection schemes.  First, try
  14.373 +# e820h, which lets us assemble a memory map, then try e801h,
  14.374 +# which returns a 32-bit memory size, and finally 88h, which
  14.375 +# returns 0-64m
  14.376 +
  14.377 +	xorl	%edx, %edx
  14.378 +	xorl	%eax, %eax
  14.379 +	movl	%eax, (0x1e0)
  14.380 +	movl	%eax, highmem_size
  14.381 +	movb	%al, (E820NR)
  14.382 +	
  14.383 +# method E820H:
  14.384 +# the memory map from hell.  e820h returns memory classified into
  14.385 +# a whole bunch of different types, and allows memory holes and
  14.386 +# everything.  We scan through this memory map and build a list
  14.387 +# of the first 32 memory areas, which we return at [E820MAP].
  14.388 +# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
  14.389 +
  14.390 +#define SMAP  0x534d4150
  14.391 +
  14.392 +meme820:
  14.393 +	xorl	%ebx, %ebx			# continuation counter
  14.394 +	movw	$E820MAP, %di			# point into the whitelist
  14.395 +						# so we can have the bios
  14.396 +						# directly write into it.
  14.397 +
  14.398 +jmpe820:
  14.399 +	movl	$0x0000e820, %eax		# e820, upper word zeroed
  14.400 +	movl	$SMAP, %edx			# ascii 'SMAP'
  14.401 +	movl	$20, %ecx			# size of the e820rec
  14.402 +	pushw	%ds				# data record.
  14.403 +	popw	%es
  14.404 +	int	$0x15				# make the call
  14.405 +	jc	bail820				# fall to e801 if it fails
  14.406 +
  14.407 +	cmpl	$SMAP, %eax			# check the return is `SMAP'
  14.408 +	jne	bail820				# fall to e801 if it fails
  14.409 +
  14.410 +#	cmpl	$1, 16(%di)			# is this usable memory?
  14.411 +#	jne	again820
  14.412 +
  14.413 +	# If this is usable memory, we save it by simply advancing %di by
  14.414 +	# sizeof(e820rec).
  14.415 +	#
  14.416 +good820:
  14.417 +	movb	(E820NR), %al			# up to 32 entries
  14.418 +	cmpb	$E820MAX, %al
  14.419 +	jnl	bail820
  14.420 +
  14.421 +	incb	(E820NR)
  14.422 +	movw	%di, %ax
  14.423 +	addw	$20, %ax
  14.424 +	movw	%ax, %di
  14.425 +again820:
  14.426 +	cmpl	$0, %ebx			# check to see if
  14.427 +	jne	jmpe820				# %ebx is set to EOF	
  14.428 +
  14.429 +/* Multiboot spec says high mem should be the address of the first
  14.430 + * upper memory hole, minus 1 MB */
  14.431 +	xorl	%ebx, %ebx
  14.432 +	xorl	%ecx, %ecx
  14.433 +	xorl	%edx, %edx
  14.434 +	movw	$E820MAP, %di			# Start at the beginning
  14.435 +calc_highmem_loop:
  14.436 +	cmpl	$1, 16(%di)			# is it usable memory?
  14.437 +	jnz	calc_highmem_next
  14.438 +	cmpl	$0, 4(%di)			# is base < 4GB?
  14.439 +	jnz	calc_highmem_next
  14.440 +	cmpl	$0x100000, 0(%di)		# is base <= 1MB?
  14.441 +	jg	calc_highmem_next
  14.442 +	movl	8(%di), %ecx			# Calculate base+length
  14.443 +	shrl	$10, %ecx			# in kilobytes
  14.444 +	movl	12(%di), %edx
  14.445 +	shll	$22, %edx
  14.446 +	orl	%edx, %ecx
  14.447 +	movl	0(%di), %edx
  14.448 +	shrl	$10, %edx
  14.449 +	addl	%edx, %ecx
  14.450 +	subl	$1024, %ecx			# - 1 MB
  14.451 +	cmpl	%cs:highmem_size, %ecx
  14.452 +	jl	calc_highmem_next
  14.453 +	movl	%ecx, %cs:highmem_size
  14.454 +calc_highmem_next:
  14.455 +	add	$1, %bl
  14.456 +	add	$20, %di
  14.457 +	cmp	%bl, (E820NR)
  14.458 +	je	calc_highmem_done
  14.459 +	jmp	calc_highmem_loop
  14.460 +calc_highmem_done:
  14.461 +			
  14.462 +bail820:
  14.463 +
  14.464 +# method E801H:
  14.465 +# memory size is in 1k chunksizes, to avoid confusing loadlin.
  14.466 +
  14.467 +meme801:
  14.468 +	stc					# fix to work around buggy
  14.469 +	xorw	%cx,%cx				# BIOSes which dont clear/set
  14.470 +	xorw	%dx,%dx				# carry on pass/error of
  14.471 +						# e801h memory size call
  14.472 +						# or merely pass cx,dx though
  14.473 +						# without changing them.
  14.474 +	movw	$0xe801, %ax
  14.475 +	int	$0x15
  14.476 +	jc	mem88
  14.477 +
  14.478 +	cmpw	$0x0, %cx			# Kludge to handle BIOSes
  14.479 +	jne	e801usecxdx			# which report their extended
  14.480 +	cmpw	$0x0, %dx			# memory in AX/BX rather than
  14.481 +	jne	e801usecxdx			# CX/DX.  The spec I have read
  14.482 +	movw	%ax, %cx			# seems to indicate AX/BX 
  14.483 +	movw	%bx, %dx			# are more reasonable anyway...
  14.484 +
  14.485 +e801usecxdx:
  14.486 +	andl	$0xffff, %edx			# clear sign extend
  14.487 +	shll	$6, %edx			# and go from 64k to 1k chunks
  14.488 +	andl	$0xffff, %ecx			# clear sign extend
  14.489 +	addl	%ecx, %edx
  14.490 +
  14.491 +	cmpl	%cs:highmem_size, %edx		# store extended mem size
  14.492 +	jl	mem88				# if it's bigger than
  14.493 +	movl	%edx, %cs:highmem_size		# what we already have
  14.494 +	
  14.495 +# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
  14.496 +# 64mb, depending on the bios) in ax.
  14.497 +mem88:
  14.498 +	movb	$0x88, %ah
  14.499 +	int	$0x15
  14.500 +
  14.501 +	andl	$0xffff, %eax			# clear sign extend
  14.502 +	cmpl	%cs:highmem_size, %eax		# store extended mem size
  14.503 +	jl	have_memsize			# if it's bigger than
  14.504 +	movl	%eax, %cs:highmem_size		# what we already have
  14.505 +
  14.506 +have_memsize:
  14.507 +	
  14.508 +/* Culled: HDD probes, APM, speedstep */
  14.509 +
  14.510 +# Now we want to move to protected mode ...
  14.511 +	cmpw	$0, %cs:realmode_swtch
  14.512 +	jz	rmodeswtch_normal
  14.513 +
  14.514 +	lcall	*%cs:realmode_swtch
  14.515 +
  14.516 +	jmp	rmodeswtch_end
  14.517 +
  14.518 +rmodeswtch_normal:
  14.519 +        pushw	%cs
  14.520 +	call	default_switch
  14.521 +
  14.522 +rmodeswtch_end:
  14.523 +
  14.524 +/* Culled: code to take the 32bit entry address from the loader */
  14.525 +/* Culled: code to relocate non-bzImage kernels */
  14.526 +	
  14.527 +	# then we load the segment descriptors
  14.528 +	movw	%cs, %ax			# aka SETUPSEG
  14.529 +	movw	%ax, %ds
  14.530 +		
  14.531 +# Check whether we need to be downward compatible with version <=201
  14.532 +	cmpl	$0, cmd_line_ptr
  14.533 +	jne	end_move_self		# loader uses version >=202 features
  14.534 +	cmpb	$0x20, type_of_loader
  14.535 +	je	end_move_self		# bootsect loader, we know of it
  14.536 +
  14.537 +# Boot loader doesnt support boot protocol version 2.02.
  14.538 +# If we have our code not at 0x90000, we need to move it there now.
  14.539 +# We also then need to move the params behind it (commandline)
  14.540 +# Because we would overwrite the code on the current IP, we move
  14.541 +# it in two steps, jumping high after the first one.
  14.542 +	movw	%cs, %ax
  14.543 +	cmpw	$SETUPSEG, %ax
  14.544 +	je	end_move_self
  14.545 +
  14.546 +	cli					# make sure we really have
  14.547 +						# interrupts disabled !
  14.548 +						# because after this the stack
  14.549 +						# should not be used
  14.550 +	subw	$DELTA_INITSEG, %ax		# aka INITSEG
  14.551 +	movw	%ss, %dx
  14.552 +	cmpw	%ax, %dx
  14.553 +	jb	move_self_1
  14.554 +
  14.555 +	addw	$INITSEG, %dx
  14.556 +	subw	%ax, %dx			# this will go into %ss after
  14.557 +						# the move
  14.558 +move_self_1:
  14.559 +	movw	%ax, %ds
  14.560 +	movw	$INITSEG, %ax			# real INITSEG
  14.561 +	movw	%ax, %es
  14.562 +	movw	%cs:setup_move_size, %cx
  14.563 +	std					# we have to move up, so we use
  14.564 +						# direction down because the
  14.565 +						# areas may overlap
  14.566 +	movw	%cx, %di
  14.567 +	decw	%di
  14.568 +	movw	%di, %si
  14.569 +	subw	$move_self_here+0x200, %cx
  14.570 +	rep
  14.571 +	movsb
  14.572 +	ljmp	$SETUPSEG, $move_self_here
  14.573 +
  14.574 +move_self_here:
  14.575 +	movw	$move_self_here+0x200, %cx
  14.576 +	rep
  14.577 +	movsb
  14.578 +	movw	$SETUPSEG, %ax
  14.579 +	movw	%ax, %ds
  14.580 +	movw	%dx, %ss
  14.581 +end_move_self:					# now we are at the right place
  14.582 +
  14.583 +#
  14.584 +# Enable A20.  This is at the very best an annoying procedure.
  14.585 +# A20 code ported from SYSLINUX 1.52-1.63 by H. Peter Anvin.
  14.586 +# AMD Elan bug fix by Robert Schwebel.
  14.587 +#
  14.588 +
  14.589 +#if defined(CONFIG_X86_ELAN)
  14.590 +	movb $0x02, %al			# alternate A20 gate
  14.591 +	outb %al, $0x92			# this works on SC410/SC520
  14.592 +a20_elan_wait:
  14.593 +	call a20_test
  14.594 +	jz a20_elan_wait
  14.595 +	jmp a20_done
  14.596 +#endif
  14.597 +
  14.598 +
  14.599 +A20_TEST_LOOPS		=  32		# Iterations per wait
  14.600 +A20_ENABLE_LOOPS	= 255		# Total loops to try		
  14.601 +
  14.602 +
  14.603 +#ifndef CONFIG_X86_VOYAGER
  14.604 +a20_try_loop:
  14.605 +
  14.606 +	# First, see if we are on a system with no A20 gate.
  14.607 +a20_none:
  14.608 +	call	a20_test
  14.609 +	jnz	a20_done
  14.610 +
  14.611 +	# Next, try the BIOS (INT 0x15, AX=0x2401)
  14.612 +a20_bios:
  14.613 +	movw	$0x2401, %ax
  14.614 +	pushfl					# Be paranoid about flags
  14.615 +	int	$0x15
  14.616 +	popfl
  14.617 +
  14.618 +	call	a20_test
  14.619 +	jnz	a20_done
  14.620 +
  14.621 +	# Try enabling A20 through the keyboard controller
  14.622 +#endif /* CONFIG_X86_VOYAGER */
  14.623 +a20_kbc:
  14.624 +	call	empty_8042
  14.625 +
  14.626 +#ifndef CONFIG_X86_VOYAGER
  14.627 +	call	a20_test			# Just in case the BIOS worked
  14.628 +	jnz	a20_done			# but had a delayed reaction.
  14.629 +#endif
  14.630 +
  14.631 +	movb	$0xD1, %al			# command write
  14.632 +	outb	%al, $0x64
  14.633 +	call	empty_8042
  14.634 +
  14.635 +	movb	$0xDF, %al			# A20 on
  14.636 +	outb	%al, $0x60
  14.637 +	call	empty_8042
  14.638 +
  14.639 +#ifndef CONFIG_X86_VOYAGER
  14.640 +	# Wait until a20 really *is* enabled; it can take a fair amount of
  14.641 +	# time on certain systems; Toshiba Tecras are known to have this
  14.642 +	# problem.
  14.643 +a20_kbc_wait:
  14.644 +	xorw	%cx, %cx
  14.645 +a20_kbc_wait_loop:
  14.646 +	call	a20_test
  14.647 +	jnz	a20_done
  14.648 +	loop	a20_kbc_wait_loop
  14.649 +
  14.650 +	# Final attempt: use "configuration port A"
  14.651 +a20_fast:
  14.652 +	inb	$0x92, %al			# Configuration Port A
  14.653 +	orb	$0x02, %al			# "fast A20" version
  14.654 +	andb	$0xFE, %al			# don't accidentally reset
  14.655 +	outb	%al, $0x92
  14.656 +
  14.657 +	# Wait for configuration port A to take effect
  14.658 +a20_fast_wait:
  14.659 +	xorw	%cx, %cx
  14.660 +a20_fast_wait_loop:
  14.661 +	call	a20_test
  14.662 +	jnz	a20_done
  14.663 +	loop	a20_fast_wait_loop
  14.664 +
  14.665 +	# A20 is still not responding.  Try frobbing it again.
  14.666 +	# 
  14.667 +	decb	(a20_tries)
  14.668 +	jnz	a20_try_loop
  14.669 +	
  14.670 +	movw	$a20_err_msg, %si
  14.671 +	call	prtstr
  14.672 +
  14.673 +a20_die:
  14.674 +	hlt
  14.675 +	jmp	a20_die
  14.676 +
  14.677 +a20_tries:
  14.678 +	.byte	A20_ENABLE_LOOPS
  14.679 +
  14.680 +a20_err_msg:
  14.681 +	.ascii	"linux: fatal error: A20 gate not responding!"
  14.682 +	.byte	13, 10, 0
  14.683 +
  14.684 +	# If we get here, all is good
  14.685 +a20_done:
  14.686 +
  14.687 +
  14.688 +#endif /* CONFIG_X86_VOYAGER */
  14.689 +
  14.690 +/* Another print, to show protected mode and A20 are OK */
  14.691 +
  14.692 +	jmp	mb_hello_mess2_end
  14.693 +mb_hello_mess2:
  14.694 +	.string "pack "	
  14.695 +mb_hello_mess2_end:	
  14.696 +	lea	mb_hello_mess2, %si
  14.697 +	call	prtstr
  14.698 +	
  14.699 +# set up gdt and idt
  14.700 +/*	lidt	idt_48				# load idt with 0,0 */
  14.701 +/* Multiboot kernels must set up their own IDT:	leave this for now, 
  14.702 + * so we can print diagnostics */
  14.703 +	
  14.704 +	xorl	%eax, %eax			# Compute gdt_base
  14.705 +	movw	%ds, %ax			# (Convert %ds:gdt to a linear ptr)
  14.706 +	shll	$4, %eax
  14.707 +	addl	$gdt, %eax
  14.708 +	movl	%eax, (gdt_48+2)
  14.709 +	lgdt	gdt_48				# load gdt with whatever is
  14.710 +						# appropriate
  14.711 +	
  14.712 +# make sure any possible coprocessor is properly reset..
  14.713 +	xorw	%ax, %ax
  14.714 +	outb	%al, $0xf0
  14.715 +	call	delay
  14.716 +
  14.717 +	outb	%al, $0xf1
  14.718 +	call	delay
  14.719 +
  14.720 +	
  14.721 +# well, that went ok, I hope. Now we mask all interrupts - the rest
  14.722 +# is done in init_IRQ().
  14.723 +	movb	$0xFF, %al			# mask all interrupts for now
  14.724 +	outb	%al, $0xA1
  14.725 +	call	delay
  14.726 +	
  14.727 +	movb	$0xFB, %al			# mask all irq's but irq2 which
  14.728 +	outb	%al, $0x21			# is cascaded
  14.729 +
  14.730 +# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
  14.731 +# need no steenking BIOS anyway (except for the initial loading :-).
  14.732 +# The BIOS-routine wants lots of unnecessary data, and it's less
  14.733 +# "interesting" anyway. This is how REAL programmers do it.
  14.734 +
  14.735 +/* Tailor the jump below so the target is the 32bit trampoline code */
  14.736 +
  14.737 +	xorl	%eax, %eax			# Calculate
  14.738 +	movw    %cs, %ax			# the linear
  14.739 +        shll    $4, %eax			# address of
  14.740 +        addl    $trampoline32, %eax		# %cs:trampoline32
  14.741 +	movl	%eax, %cs:code32		# Stick it into the jmpi
  14.742 +
  14.743 +	/* Load a 32-bit pointer to the entry address into %ecx */
  14.744 +	xorl	%ecx, %ecx			# Calculate
  14.745 +	movw    %cs, %cx			# the linear
  14.746 +        shll    $4, %ecx			# address of
  14.747 +        addl    $entry_address, %ecx		# %cs:entry_address
  14.748 +
  14.749 +# Well, now's the time to actually move into protected mode.
  14.750 +
  14.751 +	lea	mb_ready_mess, %si
  14.752 +	call	prtstr
  14.753 +	
  14.754 +/* May as well load this IDT now */
  14.755 +	lidt	idt_48
  14.756 +
  14.757 +	xorl	%eax, %eax
  14.758 +	movw	$1, %ax				# protected mode (PE) bit
  14.759 +	lmsw	%ax				# This is it!
  14.760 +	jmp	flush_instr
  14.761 +flush_instr:	
  14.762 +	
  14.763 +	/* Set up segment registers */
  14.764 +	movw	$__BOOT_DS, %dx
  14.765 +	movw	%dx, %ds
  14.766 +	movw	%dx, %es
  14.767 +	movw	%dx, %fs
  14.768 +	movw	%dx, %gs
  14.769 +	movw	%dx, %ss
  14.770 +
  14.771 +	/* Trampoline expects this in %eax */
  14.772 +	movl	%ecx, %eax
  14.773 +	
  14.774 +	/* Jump to the 32-bit trampoline */
  14.775 +
  14.776 +# NOTE: For high loaded big kernels we need a
  14.777 +#	jmpi    0x100000,__BOOT_CS
  14.778 +#
  14.779 +#	but we yet haven't reloaded the CS register, so the default size 
  14.780 +#	of the target offset still is 16 bit.
  14.781 +#       However, using an operand prefix (0x66), the CPU will properly
  14.782 +#	take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
  14.783 +#	Manual, Mixing 16-bit and 32-bit code, page 16-6)
  14.784 +
  14.785 +	.byte 0x66, 0xea			# prefix + jmpi-opcode
  14.786 +code32:	.long	0x1000				# will be set to trampoline32
  14.787 +						# by code above.
  14.788 +	.word	__BOOT_CS
  14.789 +
  14.790 +# Here's a bunch of information about your current kernel..
  14.791 +
  14.792 +kernel_version:	 .string "mbootpack changeling bzImage"
  14.793 +mb_ready_mess:	
  14.794 +		.ascii MBOOTPACK_VERSION_STRING
  14.795 +		.ascii "\r\n"
  14.796 +		.byte 0
  14.797 +
  14.798 +# This is the default real mode switch routine.
  14.799 +# to be called just before protected mode transition
  14.800 +default_switch:
  14.801 +	cli					# no interrupts allowed !
  14.802 +	movb	$0x80, %al			# disable NMI for bootup
  14.803 +						# sequence
  14.804 +	outb	%al, $0x70
  14.805 +	lret
  14.806 +
  14.807 +
  14.808 +#ifndef CONFIG_X86_VOYAGER
  14.809 +# This routine tests whether or not A20 is enabled.  If so, it
  14.810 +# exits with zf = 0.
  14.811 +#
  14.812 +# The memory address used, 0x200, is the int $0x80 vector, which
  14.813 +# should be safe.
  14.814 +
  14.815 +A20_TEST_ADDR = 4*0x80
  14.816 +
  14.817 +a20_test:
  14.818 +	pushw	%cx
  14.819 +	pushw	%ax
  14.820 +	xorw	%cx, %cx
  14.821 +	movw	%cx, %fs			# Low memory
  14.822 +	decw	%cx
  14.823 +	movw	%cx, %gs			# High memory area
  14.824 +	movw	$A20_TEST_LOOPS, %cx
  14.825 +	movw	%fs:(A20_TEST_ADDR), %ax
  14.826 +	pushw	%ax
  14.827 +a20_test_wait:
  14.828 +	incw	%ax
  14.829 +	movw	%ax, %fs:(A20_TEST_ADDR)
  14.830 +	call	delay				# Serialize and make delay constant
  14.831 +	cmpw	%gs:(A20_TEST_ADDR+0x10), %ax
  14.832 +	loope	a20_test_wait
  14.833 +
  14.834 +	popw	%fs:(A20_TEST_ADDR)
  14.835 +	popw	%ax
  14.836 +	popw	%cx
  14.837 +	ret	
  14.838 +
  14.839 +#endif /* CONFIG_X86_VOYAGER */
  14.840 +
  14.841 +# This routine checks that the keyboard command queue is empty
  14.842 +# (after emptying the output buffers)
  14.843 +#
  14.844 +# Some machines have delusions that the keyboard buffer is always full
  14.845 +# with no keyboard attached...
  14.846 +#
  14.847 +# If there is no keyboard controller, we will usually get 0xff
  14.848 +# to all the reads.  With each IO taking a microsecond and
  14.849 +# a timeout of 100,000 iterations, this can take about half a
  14.850 +# second ("delay" == outb to port 0x80). That should be ok,
  14.851 +# and should also be plenty of time for a real keyboard controller
  14.852 +# to empty.
  14.853 +#
  14.854 +
  14.855 +empty_8042:
  14.856 +	pushl	%ecx
  14.857 +	movl	$100000, %ecx
  14.858 +
  14.859 +empty_8042_loop:
  14.860 +	decl	%ecx
  14.861 +	jz	empty_8042_end_loop
  14.862 +
  14.863 +	call	delay
  14.864 +
  14.865 +	inb	$0x64, %al			# 8042 status port
  14.866 +	testb	$1, %al				# output buffer?
  14.867 +	jz	no_output
  14.868 +
  14.869 +	call	delay
  14.870 +	inb	$0x60, %al			# read it
  14.871 +	jmp	empty_8042_loop
  14.872 +
  14.873 +no_output:
  14.874 +	testb	$2, %al				# is input buffer full?
  14.875 +	jnz	empty_8042_loop			# yes - loop
  14.876 +empty_8042_end_loop:
  14.877 +	popl	%ecx
  14.878 +	ret
  14.879 +
  14.880 +# Read the cmos clock. Return the seconds in al
  14.881 +gettime:
  14.882 +	pushw	%cx
  14.883 +	movb	$0x02, %ah
  14.884 +	int	$0x1a
  14.885 +	movb	%dh, %al			# %dh contains the seconds
  14.886 +	andb	$0x0f, %al
  14.887 +	movb	%dh, %ah
  14.888 +	movb	$0x04, %cl
  14.889 +	shrb	%cl, %ah
  14.890 +	aad
  14.891 +	popw	%cx
  14.892 +	ret
  14.893 +
  14.894 +# Delay is needed after doing I/O
  14.895 +delay:
  14.896 +	outb	%al,$0x80
  14.897 +	ret
  14.898 +
  14.899 +# Descriptor tables
  14.900 +#
  14.901 +# NOTE: The intel manual says gdt should be sixteen bytes aligned for
  14.902 +# efficiency reasons.  However, there are machines which are known not
  14.903 +# to boot with misaligned GDTs, so alter this at your peril!  If you alter
  14.904 +# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two
  14.905 +# empty GDT entries (one for NULL and one reserved).
  14.906 +#
  14.907 +# NOTE:	On some CPUs, the GDT must be 8 byte aligned.  This is
  14.908 +# true for the Voyager Quad CPU card which will not boot without
  14.909 +# This directive.  16 byte aligment is recommended by intel.
  14.910 +#
  14.911 +
  14.912 +
  14.913 +/* The boot-time code segment is set at the jmpi above */
  14.914 +/* Dont change this without checking everything still matches  */
  14.915 +
  14.916 +	.align 16
  14.917 +gdt:
  14.918 +	.fill GDT_ENTRY_BOOT_CS,8,0
  14.919 +
  14.920 +	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
  14.921 +	.word	0				# base address = 0
  14.922 +	.word	0x9A00				# code read/exec
  14.923 +	.word	0x00CF				# granularity = 4096, 386
  14.924 +						#  (+5th nibble of limit)
  14.925 +
  14.926 +	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
  14.927 +	.word	0				# base address = 0
  14.928 +	.word	0x9200				# data read/write
  14.929 +	.word	0x00CF				# granularity = 4096, 386
  14.930 +						#  (+5th nibble of limit)
  14.931 +gdt_end:
  14.932 +	.align	4
  14.933 +	
  14.934 +	.word	0				# alignment byte
  14.935 +idt_48:
  14.936 +	.word	0				# idt limit = 0
  14.937 +	.word	0, 0				# idt base = 0L
  14.938 +
  14.939 +	.word	0				# alignment byte
  14.940 +gdt_48:
  14.941 +	.word	gdt_end - gdt - 1		# gdt limit
  14.942 +	.word	0, 0				# gdt base (filled in later)
  14.943 +
  14.944 +# Include video setup & detection code
  14.945 +
  14.946 +/* #include "video.S" */
  14.947 +
  14.948 +.code32
  14.949 +trampoline32:
  14.950 +	/* Here, %eax = 32-bit pointer to entry_address */
  14.951 +
  14.952 +	/* Check if the bootloader gave us a (non-empty) command line */
  14.953 +	movl	-8(%eax), %ebx			# cmd_line_ptr
  14.954 +	cmpl	$0, %ebx
  14.955 +	je	no_cmd_line
  14.956 +	cmpb	$0, 0(%ebx)
  14.957 +	je	no_cmd_line
  14.958 +
  14.959 +	/* Find the MBI command line */
  14.960 +	movl    %eax, %ecx			# &entry_address
  14.961 +	addl	$(begtext-entry_address), %ecx	# --> start of setup
  14.962 +	subl    $0x9200, %ecx			# --> reloc offset
  14.963 +	movl	%ecx, %esi			# (copy offset)
  14.964 +	movl	%ecx, %ebx			# (copy offset)
  14.965 +	addl	4(%eax), %ecx			# --> current addr of MBI
  14.966 +	addl	16(%ecx), %ebx			# --> cur. addr of MB cmdline
  14.967 +
  14.968 +	/* Overwrite the built-in MBI kernel command line */
  14.969 +	movl	-8(%eax), %ecx
  14.970 +	movl	$0, %edi
  14.971 +
  14.972 +	/* Give the kernel a 'self' word, that linux doesn't get */
  14.973 +	movw	$0x202E, 0(%ebx)			# '. '
  14.974 +	addl	$0x2, %ebx
  14.975 +	
  14.976 +cmd_line_copy:	
  14.977 +	movb	(%ecx, %edi), %dl
  14.978 +	movb	%dl, (%ebx, %edi)
  14.979 +	inc	%edi
  14.980 +	cmp	$CMD_LINE_SPACE-3, %edi 
  14.981 +	je	cmd_line_copy_end
  14.982 +
  14.983 +	cmpb	$0x0, %dl
  14.984 +	jne	cmd_line_copy
  14.985 +cmd_line_copy_end:
  14.986 +	movb	$0x0, (%ebx, %edi)
  14.987 +	subl	$0x2, %ebx
  14.988 +	
  14.989 +	/* Look for '--' in the kernel command line */
  14.990 +cmd_line_scan:
  14.991 +	inc	%ebx
  14.992 +	cmpb	$0x0, 0(%ebx)
  14.993 +	je	no_cmd_line
  14.994 +	cmpl	$0x202D2D20, 0(%ebx)		# ' -- '
  14.995 +	jne	cmd_line_scan
  14.996 +
  14.997 +	/* Found it: terminate kernel's command line */
  14.998 +	movb	$0x0, 0(%ebx)
  14.999 +	inc	%ebx
 14.1000 +	/* Relocate address to where it will be moved to */
 14.1001 +	subl	%esi, %ebx
 14.1002 +	
 14.1003 +	/* Is there a module 0? */
 14.1004 +	movl	%esi, %ecx			# Reloc offset
 14.1005 +	addl	4(%eax), %ecx			# --> current addr of MBI
 14.1006 +	cmpl	$0x0, 20(%ecx)			# (check module count)
 14.1007 +	je	no_cmd_line
 14.1008 +	/* Overwrite module 0's command line */
 14.1009 +	movl	%esi, %edx			# Reloc offset
 14.1010 +	addl	24(%ecx), %edx			# --> cur. add. of Module 0
 14.1011 +	movl	%ebx, 8(%edx)			# --> blat mod. 0's cmdline
 14.1012 +no_cmd_line:
 14.1013 +
 14.1014 +
 14.1015 +	/* Relocate the MBI from after the setup code to its proper home
 14.1016 +	 * between the MBI pointer and 0xa000 */
 14.1017 +	movl    %eax, %ecx			# &entry_address
 14.1018 +	addl	$(begtext-entry_address), %ecx	# --> start of setup
 14.1019 +	subl    $0x9200, %ecx			# --> reloc offset
 14.1020 +	addl	4(%eax), %ecx			# --> current addr of MBI
 14.1021 +	
 14.1022 +	movl	$0xa000, %ebx			# End of MBI
 14.1023 +	subl	4(%eax), %ebx			# --> size of MBI
 14.1024 +	movl	%ebx, %edi
 14.1025 +	
 14.1026 +	movl	4(%eax), %ebx	                # Destination of MBI
 14.1027 +	
 14.1028 +mbi_copy:
 14.1029 +	dec	%edi
 14.1030 +	movb	(%ecx, %edi), %dl
 14.1031 +	movb	%dl, (%ebx, %edi)
 14.1032 +	cmp	$0x0, %edi
 14.1033 +	jne	mbi_copy	
 14.1034 +	
 14.1035 +	/* Copy memory size into MBI structure */
 14.1036 +	movl	4(%eax), %ebx	                # MBI pointer
 14.1037 +	movl	8(%eax), %ecx			# highmem_size
 14.1038 +	movl	%ecx, 8(%ebx)			# --> mbi.mem_upper
 14.1039 +	movl	$0x280, %ecx
 14.1040 +	movl	%ecx, 4(%ebx)			# --> mbi.mem_lower
 14.1041 +	/* Set the MB_INFO_MEMORY bit */
 14.1042 +	orl	$1, 0(%ebx)
 14.1043 +
 14.1044 +	/* Recover the MBI pointer into %ebx */
 14.1045 +	movl	4(%eax), %ebx	                # MBI pointer
 14.1046 +	/* Extract the load address into %ecx */
 14.1047 +	movl	0(%eax), %ecx
 14.1048 +	/* Let the kernel know we're a multiboot loader */
 14.1049 +	movl	$0x2BADB002, %eax
 14.1050 +	/* Jump to the kernel address supplied */
 14.1051 +	jmp	*%ecx
 14.1052 +
 14.1053 +# Setup signature -- must be last
 14.1054 +setup_sig1:	.word	SIG1
 14.1055 +setup_sig2:	.word	SIG2
 14.1056 +
 14.1057 +# After this point, there is some free space which is used by the video mode
 14.1058 +# handling code to store the temporary mode table (not used by the kernel).
 14.1059 +
 14.1060 +modelist:
 14.1061 +
 14.1062 +.text
 14.1063 +endtext:
 14.1064 +.data
 14.1065 +enddata:
 14.1066 +.bss
 14.1067 +endbss: