mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
Remove obsolete tool 'mbootpack'. SYSLINUX now supports Multiboot format.
Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
6794b71355
commit
6f007b178f
14 files changed
-3341
No files matched your search
@@ -3,7 +3,6 @@ CONFIG_HVM := y
|
||||
CONFIG_MIGRATE := y
|
||||
CONFIG_XCUTILS := y
|
||||
CONFIG_IOEMU := y
|
||||
CONFIG_MBOOTPACK := y
|
||||
|
||||
CFLAGS += -m32 -march=i686
|
||||
LDFLAGS += -m32
|
||||
|
||||
@@ -3,7 +3,6 @@ CONFIG_HVM := y
|
||||
CONFIG_MIGRATE := y
|
||||
CONFIG_XCUTILS := y
|
||||
CONFIG_IOEMU := y
|
||||
CONFIG_MBOOTPACK := y
|
||||
|
||||
CFLAGS += -m64
|
||||
LDFLAGS += -m64
|
||||
|
||||
@@ -20,9 +20,6 @@ all: build
|
||||
.PHONY: build
|
||||
build: $(TARGETS)
|
||||
$(MAKE) -C miniterm
|
||||
ifeq ($(CONFIG_MBOOTPACK),y)
|
||||
$(MAKE) -C mbootpack
|
||||
endif
|
||||
$(MAKE) -C lomount
|
||||
|
||||
.PHONY: install
|
||||
@@ -34,14 +31,11 @@ install: build
|
||||
$(MAKE) -C lomount install
|
||||
# No sense in installing miniterm on the Xen box.
|
||||
# $(MAKE) -C miniterm install
|
||||
# Likewise mbootpack
|
||||
# $(MAKE) -C mbootpack install
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) *.o $(TARGETS) *~
|
||||
$(MAKE) -C miniterm clean
|
||||
$(MAKE) -C mbootpack clean
|
||||
$(MAKE) -C lomount clean
|
||||
|
||||
%.o: %.c $(HDRS) Makefile
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@@ -1,64 +0,0 @@
|
||||
#
|
||||
# Makefile for mbootpack
|
||||
#
|
||||
XEN_ROOT=../../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
.PHONY: all
|
||||
all: build
|
||||
|
||||
.PHONY: build
|
||||
build: mbootpack
|
||||
|
||||
.PHONY: install
|
||||
install: build
|
||||
$(INSTALL_PROG) mbootpack $(DESTDIR)/usr/bin
|
||||
|
||||
# Tools etc.
|
||||
RM := rm -f
|
||||
INCS := -I. -I-
|
||||
DEFS :=
|
||||
|
||||
# What object files need building for the program
|
||||
OBJS := mbootpack.o buildimage.o
|
||||
|
||||
# Get gcc to generate the dependencies for us.
|
||||
DEPFLAGS = -Wp,-MD,.$(@F).d
|
||||
DEPS = .*.d
|
||||
|
||||
mbootpack: $(OBJS)
|
||||
$(HOSTCC) $(HOSTCFLAGS) -o $@ $(filter-out %.a, $^)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) mbootpack *.o $(DEPS) bootsect setup bzimage_header.c bin2c
|
||||
|
||||
bootsect: bootsect.S
|
||||
$(CC) -m32 $(INCS) $(DEFS) -D__MB_ASM -c bootsect.S -o bootsect.o
|
||||
$(LD) -m elf_i386 -Ttext 0x0 -s --oformat binary bootsect.o -o $@
|
||||
|
||||
setup: setup.S
|
||||
$(CC) -m32 $(INCS) $(DEFS) -D__MB_ASM -c setup.S -o setup.o
|
||||
$(LD) -m elf_i386 -Ttext 0x0 -s --oformat binary setup.o -o $@
|
||||
|
||||
bin2c: bin2c.o
|
||||
$(HOSTCC) $(HOSTCFLAGS) -o $@ $^
|
||||
|
||||
bzimage_header.c: bootsect setup bin2c
|
||||
./bin2c -n 8 -b1 -a bzimage_bootsect bootsect > bzimage_header.c
|
||||
./bin2c -n 8 -b1 -a bzimage_setup setup >> bzimage_header.c
|
||||
|
||||
buildimage.c: bzimage_header.c
|
||||
@
|
||||
|
||||
%.o: %.c
|
||||
$(HOSTCC) $(DEPFLAGS) $(HOSTCFLAGS) $(INCS) $(DEFS) -c $< -o $@
|
||||
|
||||
.PRECIOUS: $(OBJS) $(OBJS:.o=.c) $(DEPS)
|
||||
.SUFFIXES:
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
#
|
||||
# EOF
|
||||
#
|
||||
@@ -1,77 +0,0 @@
|
||||
|
||||
mbootpack
|
||||
---------
|
||||
|
||||
This is a utility to take a multiboot kernel and modules and repackage
|
||||
them in a form that a standard linux bootloader will be able to load them.
|
||||
It statically allocates memory addresses based on a 'standard' PC memory
|
||||
layout, and then saves the image of the loaded system, along with an
|
||||
almost-standard linux bzImage header which takes care of the start-of-day
|
||||
requirements of a multiboot kernel (setting up 32-bit protected mode, etc.)
|
||||
|
||||
Example invocation, to package a xen VMM and xenlinux guest and initrd:
|
||||
|
||||
mbootpack -o bzImage -m ./xenlinux -m ./initrd.img ./xen-image
|
||||
|
||||
You can now boot the 'bzImage' file using your favourite linux bootloader.
|
||||
|
||||
The kernel command line will be provided at boot time by the bootloader
|
||||
(you can specify a kernel command-line using the '-c' flag, but it will
|
||||
be overridden at boot time unledd the bootloder provides an entirely
|
||||
empty command line). If you wan to override the command line for the
|
||||
first module (i.e. domain 0 kernel in Xen) at boot time, append ' -- '
|
||||
and the module commadn line to the bootloader command line, e.g.:
|
||||
|
||||
boot: bzImage com1=9600,8n1 console=com1 dom0_mem=49152 -- root=/dev/sda3 ro console=ttyS0,9600n8
|
||||
|
||||
Everything before the '--' is passed to the kernel (xen) as its command
|
||||
line; everything after is passed to the first module (xenlinux).
|
||||
|
||||
This is ALPHA code: there are execution paths which have *not* been
|
||||
tested, though it works for loading the Xen hypervisor using GrUB, LILO
|
||||
or SYSLINUX. Bug reports and patches are very welcome.
|
||||
|
||||
Possible features for future versions (all look possible, if there's any
|
||||
demand for them):
|
||||
|
||||
- support for kernels that load below 1MB
|
||||
- zImage-style compressed images
|
||||
- sane error messgaes for insane load addresses
|
||||
- support for the MULTIBOOT_VIDEO_MODE bit
|
||||
- proper support for passing E820h memory-maps from bzImage
|
||||
|
||||
|
||||
Tim Deegan <tjd21@cl.cam.ac.uk>, March 2005
|
||||
|
||||
|
||||
|
||||
License and attributions
|
||||
------------------------
|
||||
|
||||
The bzImage header block was originally taken from the Linux kernel.
|
||||
http://www.kernel.org/
|
||||
|
||||
Some parts of the Multiboot loader code are based on GNU GRUB.
|
||||
mb_info.h and mb_header.h are taken from GNU GRUB.
|
||||
http://www.gnu.org/software/grub/
|
||||
|
||||
Bin2C was written by Nicolas Doualot; I tidied it a bit for a clean compile.
|
||||
http://slubman.celeonet.fr/program.php?style=Default&project=bin2c
|
||||
|
||||
All other code is copyright (C) 2003-2005 Tim Deegan (tjd21@cl.cam.ac.uk)
|
||||
|
||||
mbootpack is distributed under the GNU General Public License: see "GPL"
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
@@ -1,356 +0,0 @@
|
||||
/***************************************************************************************
|
||||
Project informations:
|
||||
Project: bin2c
|
||||
Version: 1.00
|
||||
Plateforme: PC
|
||||
Copyright: DNDD.INC
|
||||
Date: 28/03/2004
|
||||
|
||||
File informations:
|
||||
Name: bin2c.c
|
||||
Description:Convert any file to a C array
|
||||
|
||||
Author informations:
|
||||
Author: DOUALOT Nicolas
|
||||
E-Mail: slubman@laposte.net
|
||||
site: http://membres.lycos.fr/slubman/gp32
|
||||
***************************************************************************************/
|
||||
|
||||
|
||||
#include <stdio.h> /*perror */
|
||||
#include <sys/mman.h> /*PROT_READ,MAP_xxx */
|
||||
#include <fcntl.h> /*O_RDONLY */
|
||||
#include <sys/stat.h> /*stat */
|
||||
#include <stdlib.h> /*atoi */
|
||||
#include <string.h> /*strcmp */
|
||||
#include <ctype.h> /*toupper */
|
||||
|
||||
#define VERSION "1.10"
|
||||
|
||||
|
||||
static void help(void)
|
||||
{
|
||||
fprintf(stdout, "\nbin2c v"VERSION"\n");
|
||||
fprintf(stdout, "Slubman DevSoft (c)2003-2004 slubman.dndd@laposte.net \n\n");
|
||||
|
||||
fprintf(stdout, "Usage: bin2c [flags] <infile>\n\n");
|
||||
|
||||
//fprintf(stdout, "\t-quiet :\tdon't output standard messages\n");
|
||||
//fprintf(stdout, "\t-slash :\tappend backslash at end of line\n");
|
||||
fprintf(stdout, "\t-n <count> :\tnumber of items per line\n");
|
||||
fprintf(stdout, "\t-b1 :\tgenerate unsigned char array\n");
|
||||
fprintf(stdout, "\t-b2 :\tgenerate unsigned short array\n");
|
||||
fprintf(stdout, "\t-b4 :\tgenerate unsigned long array\n");
|
||||
fprintf(stdout, "\t-a <name> :\tgenerate an array with given name\n");
|
||||
fprintf(stdout, "\t-ss <nr> :\tskip number of bytes at begin of inputfile\n");
|
||||
fprintf(stdout, "\t-se <nr> :\tskip number of bytes at end of inputfile\n");
|
||||
fprintf(stdout, "\t-lb <nr> :\tinsert an additionally linebreak every nr line\n");
|
||||
fprintf(stdout, "\t-h :\tproduce an header\n");
|
||||
fprintf(stdout, "\tinfile :\tname of infile\n");
|
||||
fprintf(stdout, "\toutfile :\tname of outfile (use \"-\" for stdout)\n\n");
|
||||
|
||||
fprintf(stdout, " \tconverts binary file to C array data\n");
|
||||
}
|
||||
|
||||
static void UnknownFlag(char *flag)
|
||||
{
|
||||
fprintf(stderr, "Error: unknown flag %s\n", flag);
|
||||
help();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void WriteHeader(FILE * outFile, char *oFileName, char *iFileName)
|
||||
{
|
||||
// File Header
|
||||
fprintf(outFile, "/***************************************************************************************\n");
|
||||
fprintf(outFile, "* File Name:\n");
|
||||
fprintf(outFile, "* Name: %s\n", oFileName);
|
||||
fprintf(outFile, "* From: %s\n", iFileName);
|
||||
fprintf(outFile, "* Created by :bin2c v"VERSION"\n*\n");
|
||||
fprintf(outFile, "* bin2c v"VERSION":\n");
|
||||
fprintf(outFile, "* Author: DOUALOT Nicolas\n");
|
||||
fprintf(outFile, "* E-Mail: slubman.dndd@laposte.net\n");
|
||||
fprintf(outFile, "* site: http://www.slubman.linux-fan.com/\n");
|
||||
fprintf(outFile, "***************************************************************************************/\n\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *inFile = stdin, *outFile = stdout;
|
||||
int a, i, nbLine = 0;
|
||||
unsigned char *memory;
|
||||
struct stat st;
|
||||
|
||||
// Options
|
||||
char arrayName[255] = "array"; // Array name
|
||||
char *iFileName = NULL; // File to convert
|
||||
char *oFileName = NULL; // File to write
|
||||
int bpd = 1; // Array item length
|
||||
int lb = 0; // Array blank line each lb line(s)
|
||||
int nbCol = 15; // Nuber of items per line
|
||||
int SkeepStart = 0; // Number of byte to skip at file begining
|
||||
int SkeepEnd = 0; // Number of byte to skip at file end
|
||||
int header = 0; // Produce an header
|
||||
|
||||
// Is there the good number of arguments
|
||||
if (argc < 2)
|
||||
{
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// On récupère les arguments (Ready for more options)
|
||||
for (a = 1; a < argc; a++)
|
||||
{
|
||||
// An option
|
||||
if (argv[a][0] == '-')
|
||||
{
|
||||
// Wich flag is it ?
|
||||
switch (argv[a][1])
|
||||
{
|
||||
// Writting on stdout
|
||||
case 0:
|
||||
printf("%s\n", argv[a]);
|
||||
outFile = stdout;
|
||||
break;
|
||||
|
||||
// ArrayName flag
|
||||
case 'a':
|
||||
strcpy(arrayName, argv[++a]);
|
||||
break;
|
||||
|
||||
// Data type
|
||||
case 'b':
|
||||
switch (argv[a][2])
|
||||
{
|
||||
case '1':
|
||||
bpd = 1;
|
||||
break;
|
||||
|
||||
case '2':
|
||||
bpd = 2;
|
||||
break;
|
||||
|
||||
case '4':
|
||||
bpd = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
UnknownFlag(argv[a]);
|
||||
}
|
||||
break;
|
||||
|
||||
// Produce an header
|
||||
case 'h':
|
||||
header = 1;
|
||||
break;
|
||||
|
||||
// New line each n line
|
||||
case 'l':
|
||||
switch (argv[a][2])
|
||||
{
|
||||
case 'b':
|
||||
lb = atoi(argv[++a]);
|
||||
break;
|
||||
|
||||
default:
|
||||
UnknownFlag(argv[a]);
|
||||
}
|
||||
|
||||
// Number of bit per line
|
||||
case 'n':
|
||||
nbCol = atoi(argv[++a]);
|
||||
break;
|
||||
|
||||
// Skip bytes
|
||||
case 's':
|
||||
switch (argv[a][2])
|
||||
{
|
||||
// Beginig of file
|
||||
case 's':
|
||||
SkeepStart = atoi(argv[++a]);
|
||||
break;
|
||||
|
||||
// End of file
|
||||
case 'e':
|
||||
SkeepEnd = atoi(argv[++a]);
|
||||
break;
|
||||
|
||||
// Flag inconnu
|
||||
default:
|
||||
UnknownFlag(argv[a]);
|
||||
}
|
||||
|
||||
// Flag inconnu
|
||||
default:
|
||||
UnknownFlag(argv[a]);
|
||||
}
|
||||
}
|
||||
// A filename
|
||||
else
|
||||
{
|
||||
if (iFileName == NULL)
|
||||
{
|
||||
iFileName = argv[a];
|
||||
if ((inFile = fopen(iFileName, "rb")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: can't open %s\n", iFileName);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (oFileName == NULL)
|
||||
{
|
||||
oFileName = argv[a];
|
||||
if ((outFile = fopen(oFileName, "wb")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: can't open %s\n", oFileName);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Error: Too many filesnames given!\n");
|
||||
help();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!iFileName)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
// Get file informations
|
||||
if (stat(iFileName, &st) != 0)
|
||||
{
|
||||
fprintf(stderr, "Error: when scanning file %s\n", argv[1]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Allocating memory
|
||||
if (!(memory = malloc(st.st_size + 3)))
|
||||
{
|
||||
memset(memory, 0, st.st_size + 3);
|
||||
fprintf(stderr, "Error: not enought memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Reading the file
|
||||
if (fread(memory, 1, st.st_size, inFile) != (size_t)st.st_size)
|
||||
{
|
||||
fprintf(stderr, "Error: when reading file %s\n", argv[1]);
|
||||
fclose(inFile);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fclose(inFile);
|
||||
|
||||
// Must produce an header
|
||||
if (header)
|
||||
{
|
||||
unsigned int i;
|
||||
char hFileName[256], *def = NULL;
|
||||
FILE *hFile = stdout;
|
||||
|
||||
if (oFileName)
|
||||
{
|
||||
strcpy(hFileName, oFileName);
|
||||
hFileName[strlen(hFileName) - 1] = 'h';
|
||||
hFile = fopen(hFileName, "wt");
|
||||
}
|
||||
|
||||
WriteHeader(hFile, hFileName, iFileName);
|
||||
|
||||
// Replace all '.' by '_'
|
||||
for (i = 0; i < strlen(hFileName); i++)
|
||||
if (hFileName[i] == '.')
|
||||
hFileName[i] = '_';
|
||||
else
|
||||
hFileName[i] = toupper(hFileName[i]);
|
||||
|
||||
// the #ifdef at the begining
|
||||
def = strrchr(hFileName, '/');
|
||||
def = def ? def + 1 : hFileName;
|
||||
fprintf(hFile, "#ifndef __%s__\n#define __%s__\n\n", def, def);
|
||||
|
||||
// Define array size
|
||||
fprintf(hFile, "#define _%s_size_ %u\n\n", arrayName, (unsigned int) (st.st_size - SkeepStart - SkeepEnd) / bpd);
|
||||
|
||||
// Begin the array
|
||||
fprintf(hFile, "extern unsigned ");
|
||||
fprintf(hFile, "%s ", bpd == 1 ? "char" : bpd == 2 ? "short" : "long");
|
||||
fprintf(hFile, "%s[", arrayName);
|
||||
fprintf(hFile, "%u];\n\n", (unsigned int) (st.st_size - SkeepStart - SkeepEnd) / bpd);
|
||||
|
||||
// the #endif at the end
|
||||
fprintf(hFile, "#endif\n\n");
|
||||
|
||||
if (oFileName)
|
||||
fclose(hFile);
|
||||
}
|
||||
|
||||
WriteHeader(outFile, oFileName, iFileName);
|
||||
|
||||
// Define array size
|
||||
if (!header)
|
||||
fprintf(outFile, "#define _%s_size_ %u\n\n", arrayName, (unsigned int) (st.st_size - SkeepStart - SkeepEnd) / bpd);
|
||||
|
||||
// Begin the array
|
||||
fprintf(outFile, "unsigned ");
|
||||
fprintf(outFile, "%s ", bpd == 1 ? "char" : bpd == 2 ? "short" : "long");
|
||||
fprintf(outFile, "%s[", arrayName);
|
||||
fprintf(outFile, "%u] = {\n\t", (unsigned int) (st.st_size - SkeepStart - SkeepEnd) / bpd);
|
||||
|
||||
// Writing file elements
|
||||
for (i = 0; i < (st.st_size - SkeepEnd - SkeepStart) / bpd; /*i+=bpd */ i++)
|
||||
{
|
||||
// We write an item of bpd byte(s)
|
||||
switch (bpd)
|
||||
{
|
||||
case 1:
|
||||
fprintf(outFile, "0x%02x", *(unsigned char *) &memory[SkeepStart + i]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
fprintf(outFile, "0x%04x", *(unsigned short *) &memory[SkeepStart + i]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
fprintf(outFile, "0x%08lx", *(unsigned long *) &memory[SkeepStart + i]);
|
||||
break;
|
||||
}
|
||||
|
||||
// Must put a coma ?
|
||||
if (i != st.st_size - 1)
|
||||
fprintf(outFile, ",");
|
||||
|
||||
// End of a line ?
|
||||
if (i && !((i + 1) % nbCol))
|
||||
{
|
||||
// -lb option
|
||||
if (lb && !((++nbLine) % lb))
|
||||
fprintf(outFile, "\n");
|
||||
fprintf(outFile, "\n\t");
|
||||
}
|
||||
// Add a space
|
||||
else
|
||||
fprintf(outFile, " ");
|
||||
}
|
||||
|
||||
// The last line as nbCol elements
|
||||
if (((st.st_size - SkeepStart - SkeepEnd) / bpd) % nbCol)
|
||||
fprintf(outFile, "\n");
|
||||
|
||||
// Close the array
|
||||
fprintf(outFile, "};\n");
|
||||
|
||||
// CLose the output file
|
||||
if (outFile != stdout)
|
||||
fclose(outFile);
|
||||
|
||||
// Free allocated memory
|
||||
free(memory);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* bootsect.S
|
||||
*
|
||||
* This is bootsect.S from the linux 2.6.9 sources,
|
||||
* with minor changes for mbootpack.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* $Id: bootsect.S,v 1.2 2005/03/23 10:39:11 tjd21 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mbootpack.h"
|
||||
|
||||
/*
|
||||
* bootsect.S Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*
|
||||
* modified by Drew Eckhardt
|
||||
* modified by Bruce Evans (bde)
|
||||
* modified by Chris Noe (May 1999) (as86 -> gas)
|
||||
* gutted by H. Peter Anvin (Jan 2003)
|
||||
*
|
||||
* BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment
|
||||
* addresses must be multiplied by 16 to obtain their respective linear
|
||||
* addresses. To avoid confusion, linear addresses are written using leading
|
||||
* hex while segment addresses are written as segment:offset.
|
||||
*
|
||||
*/
|
||||
|
||||
/* #include <asm/boot.h> */
|
||||
/* Definitions we should have got from there */
|
||||
#define DEF_INITSEG 0x9000
|
||||
#define DEF_SYSSEG 0x1000
|
||||
#define DEF_SETUPSEG 0x9020
|
||||
#define DEF_SYSSIZE 0x7F00
|
||||
#define NORMAL_VGA 0xffff
|
||||
#define EXTENDED_VGA 0xfffe
|
||||
#define ASK_VGA 0xfffd
|
||||
|
||||
|
||||
/* SETUPSECTS = 4 */ /* default nr of setup-sectors */
|
||||
BOOTSEG = 0x07C0 /* original address of boot-sector */
|
||||
INITSEG = DEF_INITSEG /* we move boot here - out of the way */
|
||||
SETUPSEG = DEF_SETUPSEG /* setup starts here */
|
||||
SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */
|
||||
SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */
|
||||
/* to be loaded */
|
||||
ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */
|
||||
SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */
|
||||
|
||||
#ifndef SVGA_MODE
|
||||
/* #define SVGA_MODE ASK_VGA */
|
||||
#define SVGA_MODE NORMAL_VGA
|
||||
#endif
|
||||
|
||||
#ifndef RAMDISK
|
||||
#define RAMDISK 0
|
||||
#endif
|
||||
|
||||
#ifndef ROOT_RDONLY
|
||||
#define ROOT_RDONLY 1
|
||||
#endif
|
||||
|
||||
.code16
|
||||
.text
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
# Normalize the start address
|
||||
jmpl $BOOTSEG, $start2
|
||||
|
||||
start2:
|
||||
movw %cs, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
movw $0x7c00, %sp
|
||||
sti
|
||||
cld
|
||||
|
||||
movw $bugger_off_msg, %si
|
||||
|
||||
msg_loop:
|
||||
lodsb
|
||||
andb %al, %al
|
||||
jz die
|
||||
movb $0xe, %ah
|
||||
movw $7, %bx
|
||||
int $0x10
|
||||
jmp msg_loop
|
||||
|
||||
die:
|
||||
# Allow the user to press a key, then reboot
|
||||
xorw %ax, %ax
|
||||
int $0x16
|
||||
int $0x19
|
||||
|
||||
# int 0x19 should never return. In case it does anyway,
|
||||
# invoke the BIOS reset code...
|
||||
ljmp $0xf000,$0xfff0
|
||||
|
||||
|
||||
bugger_off_msg:
|
||||
.ascii "Direct booting from floppy is no longer supported.\r\n"
|
||||
.ascii "Please use a boot loader program instead.\r\n"
|
||||
.ascii "\n"
|
||||
.ascii "Remove disk and press any key to reboot . . .\r\n"
|
||||
.byte 0
|
||||
|
||||
|
||||
# Kernel attributes; used by setupbegtext
|
||||
|
||||
.org 497
|
||||
setup_sects: .byte SETUPSECTS
|
||||
root_flags: .word ROOT_RDONLY
|
||||
syssize: .word SYSSIZE
|
||||
swap_dev: .word SWAP_DEV
|
||||
ram_size: .word RAMDISK
|
||||
vid_mode: .word SVGA_MODE
|
||||
root_dev: .word ROOT_DEV
|
||||
boot_flag: .word 0xAA55
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* buildimage.c
|
||||
*
|
||||
* Takes the memory image of a loaded kernel and modules and repackages
|
||||
* it as a linux bzImage
|
||||
*
|
||||
* Copyright (C) 2003-2004 Tim Deegan (tjd21@cl.cam.ac.uk)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* $Id: buildimage.c,v 1.2 2005/03/23 10:39:19 tjd21 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <elf.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#include "mbootpack.h"
|
||||
#include "mb_header.h"
|
||||
|
||||
|
||||
/* We will build an image that a bzImage-capable bootloader will load like
|
||||
* this:
|
||||
*
|
||||
* ============== (0)
|
||||
* (BIOS memory)
|
||||
* --------------
|
||||
* (Bootloader)
|
||||
* --------------
|
||||
* bzImage startup code
|
||||
* MBI, command-lines, module info
|
||||
* ============== (0xa0000)
|
||||
* (memory hole)
|
||||
* ============== (0x100000)
|
||||
* Kernel and modules
|
||||
* ==============
|
||||
*
|
||||
* The bzImage startup code is mostly taken straight from the linux kernel
|
||||
* (see bootsect.S, startup.S). It does the usual unpleasant start-of-day
|
||||
* tasks to get to 32-bit protected mode, then sets registers appropriately
|
||||
* and jumps to the kernel's entry address.
|
||||
*
|
||||
* It also does some relocation to make sure the MBI is where we expect it,
|
||||
* and parses the linux command line.
|
||||
*/
|
||||
|
||||
#define BZ_SETUP_OFFSET (512 * (1 + SETUPSECTS))
|
||||
#define BZ_ENTRY_OFFSET 0x30
|
||||
#define BZ_MBI_OFFSET 0x34
|
||||
/* These *MUST* fit the offsets of entry_address and mbi_address in setup.S */
|
||||
|
||||
/* Bring in the bzImage boot sector and setup code */
|
||||
#include "bzimage_header.c"
|
||||
|
||||
#define _p(x) ((void *)(unsigned long)(x))
|
||||
|
||||
address_t place_mbi(long int size)
|
||||
/* Find space at the top of *low* memory for the MBI and associated red tape */
|
||||
{
|
||||
address_t start;
|
||||
start = 0xa000 - size;
|
||||
if (start < 0x9000 + sizeof(bzimage_bootsect) + sizeof(bzimage_setup)) {
|
||||
printf("Fatal: command-lines too long: need %ld, have %ld bytes\n",
|
||||
size,
|
||||
0x1000L - (sizeof(bzimage_bootsect) + sizeof(bzimage_setup)));
|
||||
exit(1);
|
||||
}
|
||||
if (!quiet) {
|
||||
printf("Placed MBI and strings (%p+%p)\n",
|
||||
_p(start), _p(size));
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
void make_bzImage(section_t *sections,
|
||||
address_t entry,
|
||||
address_t mbi,
|
||||
FILE *fp)
|
||||
/* Rework this list of sections into a bzImage and write it out to fp */
|
||||
{
|
||||
int i;
|
||||
size_t offset;
|
||||
section_t *s;
|
||||
|
||||
/* Patch the kernel and mbi addresses into the setup code */
|
||||
*(address_t *)(bzimage_setup + BZ_ENTRY_OFFSET) = eswap(entry);
|
||||
*(address_t *)(bzimage_setup + BZ_MBI_OFFSET) = eswap(mbi);
|
||||
if (!quiet) printf("Kernel entry is %p, MBI is %p.\n",_p(entry), _p(mbi));
|
||||
|
||||
/* Write out header and trampoline */
|
||||
if (fseek(fp, 0, SEEK_SET) < 0) {
|
||||
printf("Fatal: error seeking in output file: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (fwrite(bzimage_bootsect, sizeof(bzimage_bootsect), 1, fp) != 1) {
|
||||
printf("Fatal: error writing to output file: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (fwrite(bzimage_setup, sizeof(bzimage_setup), 1, fp) != 1) {
|
||||
printf("Fatal: error writing to output file: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!quiet) printf("Wrote bzImage header: %ld + %ld bytes.\n",
|
||||
(long)sizeof(bzimage_bootsect),
|
||||
(long)sizeof(bzimage_setup));
|
||||
|
||||
/* Sorted list of sections below 1MB: write them out */
|
||||
for (s = sections, i = 0; s; s = s->next) {
|
||||
if (s->start >= HIGHMEM_START) continue;
|
||||
offset = (s->start - 0x9000);
|
||||
if (fseek(fp, offset, SEEK_SET) < 0) {
|
||||
printf("Fatal: error seeking in output file: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (fwrite(s->buffer, s->size, 1, fp) != 1) {
|
||||
printf("Fatal: error writing to output file: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!quiet) printf("Wrote %i low-memory sections.\n", i);
|
||||
|
||||
/* Sorted list of sections higher than 1MB: write them out */
|
||||
for (s = sections, i = 0; s; s = s->next) {
|
||||
if (s->start < HIGHMEM_START) continue;
|
||||
offset = (s->start - HIGHMEM_START) + BZ_SETUP_OFFSET;
|
||||
if (fseek(fp, offset, SEEK_SET) < 0) {
|
||||
printf("Fatal: error seeking in output file: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (fwrite(s->buffer, s->size, 1, fp) != 1) {
|
||||
printf("Fatal: error writing to output file: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!quiet) printf("Wrote %i high-memory sections.\n", i);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* EOF(buildimage.c)
|
||||
*/
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MultiBoot Header description
|
||||
*/
|
||||
|
||||
struct multiboot_header
|
||||
{
|
||||
/* Must be MULTIBOOT_MAGIC - see below. */
|
||||
unsigned magic;
|
||||
|
||||
/* Feature flags - see below. */
|
||||
unsigned flags;
|
||||
|
||||
/*
|
||||
* Checksum
|
||||
*
|
||||
* The above fields plus this one must equal 0 mod 2^32.
|
||||
*/
|
||||
unsigned checksum;
|
||||
|
||||
/* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
|
||||
unsigned header_addr;
|
||||
unsigned load_addr;
|
||||
unsigned load_end_addr;
|
||||
unsigned bss_end_addr;
|
||||
unsigned entry_addr;
|
||||
|
||||
/* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
|
||||
unsigned mode_type;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned depth;
|
||||
};
|
||||
|
||||
/*
|
||||
* The entire multiboot_header must be contained
|
||||
* within the first MULTIBOOT_SEARCH bytes of the kernel image.
|
||||
*/
|
||||
#define MULTIBOOT_SEARCH 8192
|
||||
#define MULTIBOOT_FOUND(addr, len) \
|
||||
(! ((addr) & 0x3) \
|
||||
&& (len) >= 12 \
|
||||
&& *((int *) (addr)) == MULTIBOOT_MAGIC \
|
||||
&& ! (*((unsigned *) (addr)) + *((unsigned *) (addr + 4)) \
|
||||
+ *((unsigned *) (addr + 8))) \
|
||||
&& (! (MULTIBOOT_AOUT_KLUDGE & *((int *) (addr + 4))) || (len) >= 32) \
|
||||
&& (! (MULTIBOOT_VIDEO_MODE & *((int *) (addr + 4))) || (len) >= 48))
|
||||
|
||||
/* Magic value identifying the multiboot_header. */
|
||||
#define MULTIBOOT_MAGIC 0x1BADB002
|
||||
|
||||
/*
|
||||
* Features flags for 'flags'.
|
||||
* If a boot loader sees a flag in MULTIBOOT_MUSTKNOW set
|
||||
* and it doesn't understand it, it must fail.
|
||||
*/
|
||||
#define MULTIBOOT_MUSTKNOW 0x0000FFFF
|
||||
|
||||
/* currently unsupported flags... this is a kind of version number. */
|
||||
#define MULTIBOOT_UNSUPPORTED 0x0000FFF8
|
||||
|
||||
/* Align all boot modules on i386 page (4KB) boundaries. */
|
||||
#define MULTIBOOT_PAGE_ALIGN 0x00000001
|
||||
|
||||
/* Must pass memory information to OS. */
|
||||
#define MULTIBOOT_MEMORY_INFO 0x00000002
|
||||
|
||||
/* Must pass video information to OS. */
|
||||
#define MULTIBOOT_VIDEO_MODE 0x00000004
|
||||
|
||||
/* This flag indicates the use of the address fields in the header. */
|
||||
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The structure type "mod_list" is used by the "multiboot_info" structure.
|
||||
*/
|
||||
|
||||
struct mod_list
|
||||
{
|
||||
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
|
||||
unsigned long mod_start;
|
||||
unsigned long mod_end;
|
||||
|
||||
/* Module command line */
|
||||
unsigned long cmdline;
|
||||
|
||||
/* padding to take it to 16 bytes (must be zero) */
|
||||
unsigned long pad;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* INT-15, AX=E820 style "AddressRangeDescriptor"
|
||||
* ...with a "size" parameter on the front which is the structure size - 4,
|
||||
* pointing to the next one, up until the full buffer length of the memory
|
||||
* map has been reached.
|
||||
*/
|
||||
|
||||
struct AddrRangeDesc
|
||||
{
|
||||
unsigned long size;
|
||||
unsigned long long BaseAddr;
|
||||
unsigned long long Length;
|
||||
unsigned long Type;
|
||||
|
||||
/* unspecified optional padding... */
|
||||
};
|
||||
|
||||
/* usable memory "Type", all others are reserved. */
|
||||
#define MB_ARD_MEMORY 1
|
||||
|
||||
|
||||
/* Drive Info structure. */
|
||||
struct drive_info
|
||||
{
|
||||
/* The size of this structure. */
|
||||
unsigned long size;
|
||||
|
||||
/* The BIOS drive number. */
|
||||
unsigned char drive_number;
|
||||
|
||||
/* The access mode (see below). */
|
||||
unsigned char drive_mode;
|
||||
|
||||
/* The BIOS geometry. */
|
||||
unsigned short drive_cylinders;
|
||||
unsigned char drive_heads;
|
||||
unsigned char drive_sectors;
|
||||
|
||||
/* The array of I/O ports used for the drive. */
|
||||
unsigned short drive_ports[0];
|
||||
};
|
||||
|
||||
/* Drive Mode. */
|
||||
#define MB_DI_CHS_MODE 0
|
||||
#define MB_DI_LBA_MODE 1
|
||||
|
||||
|
||||
/* APM BIOS info. */
|
||||
struct apm_info
|
||||
{
|
||||
unsigned short version;
|
||||
unsigned short cseg;
|
||||
unsigned long offset;
|
||||
unsigned short cseg_16;
|
||||
unsigned short dseg_16;
|
||||
unsigned short cseg_len;
|
||||
unsigned short cseg_16_len;
|
||||
unsigned short dseg_16_len;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* MultiBoot Info description
|
||||
*
|
||||
* This is the struct passed to the boot image. This is done by placing
|
||||
* its address in the EAX register.
|
||||
*/
|
||||
|
||||
struct multiboot_info
|
||||
{
|
||||
/* MultiBoot info version number */
|
||||
unsigned long flags;
|
||||
|
||||
/* Available memory from BIOS */
|
||||
unsigned long mem_lower;
|
||||
unsigned long mem_upper;
|
||||
|
||||
/* "root" partition */
|
||||
unsigned long boot_device;
|
||||
|
||||
/* Kernel command line */
|
||||
unsigned long cmdline;
|
||||
|
||||
/* Boot-Module list */
|
||||
unsigned long mods_count;
|
||||
unsigned long mods_addr;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/* (a.out) Kernel symbol table info */
|
||||
unsigned long tabsize;
|
||||
unsigned long strsize;
|
||||
unsigned long addr;
|
||||
unsigned long pad;
|
||||
}
|
||||
a;
|
||||
|
||||
struct
|
||||
{
|
||||
/* (ELF) Kernel section header table */
|
||||
unsigned long num;
|
||||
unsigned long size;
|
||||
unsigned long addr;
|
||||
unsigned long shndx;
|
||||
}
|
||||
e;
|
||||
}
|
||||
syms;
|
||||
|
||||
/* Memory Mapping buffer */
|
||||
unsigned long mmap_length;
|
||||
unsigned long mmap_addr;
|
||||
|
||||
/* Drive Info buffer */
|
||||
unsigned long drives_length;
|
||||
unsigned long drives_addr;
|
||||
|
||||
/* ROM configuration table */
|
||||
unsigned long config_table;
|
||||
|
||||
/* Boot Loader Name */
|
||||
unsigned long boot_loader_name;
|
||||
|
||||
/* APM table */
|
||||
unsigned long apm_table;
|
||||
|
||||
/* Video */
|
||||
unsigned long vbe_control_info;
|
||||
unsigned long vbe_mode_info;
|
||||
unsigned short vbe_mode;
|
||||
unsigned short vbe_interface_seg;
|
||||
unsigned short vbe_interface_off;
|
||||
unsigned short vbe_interface_len;
|
||||
};
|
||||
|
||||
/*
|
||||
* Flags to be set in the 'flags' parameter above
|
||||
*/
|
||||
|
||||
/* is there basic lower/upper memory information? */
|
||||
#define MB_INFO_MEMORY 0x00000001
|
||||
/* is there a boot device set? */
|
||||
#define MB_INFO_BOOTDEV 0x00000002
|
||||
/* is the command-line defined? */
|
||||
#define MB_INFO_CMDLINE 0x00000004
|
||||
/* are there modules to do something with? */
|
||||
#define MB_INFO_MODS 0x00000008
|
||||
|
||||
/* These next two are mutually exclusive */
|
||||
|
||||
/* is there a symbol table loaded? */
|
||||
#define MB_INFO_AOUT_SYMS 0x00000010
|
||||
/* is there an ELF section header table? */
|
||||
#define MB_INFO_ELF_SHDR 0x00000020
|
||||
|
||||
/* is there a full memory map? */
|
||||
#define MB_INFO_MEM_MAP 0x00000040
|
||||
|
||||
/* Is there drive info? */
|
||||
#define MB_INFO_DRIVE_INFO 0x00000080
|
||||
|
||||
/* Is there a config table? */
|
||||
#define MB_INFO_CONFIG_TABLE 0x00000100
|
||||
|
||||
/* Is there a boot loader name? */
|
||||
#define MB_INFO_BOOT_LOADER_NAME 0x00000200
|
||||
|
||||
/* Is there a APM table? */
|
||||
#define MB_INFO_APM_TABLE 0x00000400
|
||||
|
||||
/* Is there video information? */
|
||||
#define MB_INFO_VIDEO_INFO 0x00000800
|
||||
|
||||
/*
|
||||
* The following value must be present in the EAX register.
|
||||
*/
|
||||
|
||||
#define MULTIBOOT_VALID 0x2BADB002
|
||||
@@ -1,704 +0,0 @@
|
||||
/*
|
||||
* mbootpack.c
|
||||
*
|
||||
* Takes a multiboot image, command-line and modules, and repackages
|
||||
* them as if they were a linux kernel. Only supports a subset of
|
||||
* the multiboot info page options (enough to boot the Xen hypervisor).
|
||||
*
|
||||
* Copyright (C) 2003-2004 Tim Deegan (tjd21@cl.cam.ac.uk)
|
||||
*
|
||||
* Parts based on GNU GRUB, Copyright (C) 2000 Free Software Foundation, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* $Id: mbootpack.c,v 1.3 2005/03/23 10:38:36 tjd21 Exp tjd21 $
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "mbootpack.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <elf.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
/* From GNU GRUB */
|
||||
#include "mb_header.h"
|
||||
#include "mb_info.h"
|
||||
|
||||
|
||||
/*
|
||||
* The plan: Marshal up the multiboot modules and strings as if we
|
||||
* were loading them into memory on a fresh ix86 PC. Attach
|
||||
* a linux bzImage header to the front, which sets up the machine
|
||||
* appropriately and then jumps to the kernel entry address.
|
||||
*
|
||||
* The memory map will be made up roughly like so:
|
||||
*
|
||||
* =============
|
||||
* multiboot information (mbi) struct
|
||||
* -------
|
||||
* kernel command line
|
||||
* -------
|
||||
* bootloader name
|
||||
* -------
|
||||
* module command lines
|
||||
* -------
|
||||
* module information structs
|
||||
* =============
|
||||
* (memory hole)
|
||||
* =============
|
||||
* kernel
|
||||
* -------------
|
||||
* module 1
|
||||
* -------------
|
||||
* module 2
|
||||
* -------------
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
*
|
||||
* ==============
|
||||
*
|
||||
*
|
||||
* For allocation of memory we assume that the target machine has 'low'
|
||||
* memory from 0 to 640K and 'high' memory starting at 1M. We allocate
|
||||
* the kernel first, wherever it wants to be. After that, sections
|
||||
* are added at the next available aligned address, always in the order
|
||||
* given above, and skipping the memory hole at 640K. Allocated sections
|
||||
* are stored in a linked list of buffers.
|
||||
*
|
||||
* Re-packaging as a bzImage file happens in buildimage.c
|
||||
*
|
||||
*/
|
||||
|
||||
/* Version */
|
||||
static const char version_string[] = "mbootpack " MBOOTPACK_VERSION_STRING;
|
||||
|
||||
/* Flags */
|
||||
int quiet = 0;
|
||||
|
||||
/* How much of the start of a kernel we read looking for headers.
|
||||
* Must be >= MULTIBOOT_SEARCH */
|
||||
#define HEADERBUF_SIZE MULTIBOOT_SEARCH
|
||||
|
||||
|
||||
/* Linked list of loaded sections, and a pointer to the next
|
||||
* available space (i.e. just above the highest allocation so far). */
|
||||
static section_t *sections = NULL;
|
||||
static section_t *last_section = NULL;
|
||||
static address_t next_free_space = 0;
|
||||
|
||||
static void usage(void)
|
||||
/* If we don't understand the command-line options */
|
||||
{
|
||||
printf(
|
||||
"Usage: mbpack [OPTIONS] kernel-image\n\n"
|
||||
" -h --help Print this text.\n"
|
||||
" -q --quiet Only output errors and warnings.\n"
|
||||
" -o --output=filename Output to filename (default \"bzImage\").\n"
|
||||
" -M --multiboot-output Produce a multiboot kernel, not a bzImage\n"
|
||||
" (sets default output file to \"mbImage\").\n"
|
||||
" -c --command-line=STRING Set the kernel command line (DEPRECATED!).\n"
|
||||
" -m --module=\"MOD arg1 arg2...\" Load module MOD with arguments \"arg1...\"\n"
|
||||
" (can be used multiple times).\n"
|
||||
"\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define _p(x) ((void *)(unsigned long)(x))
|
||||
|
||||
static void place_kernel_section(address_t start, long int size)
|
||||
/* Place the kernel in memory, checking for the memory hole. */
|
||||
{
|
||||
if (start >= MEM_HOLE_END) {
|
||||
/* Above the memory hole: easy */
|
||||
next_free_space = MAX(next_free_space, start + size);
|
||||
if (!quiet) {
|
||||
printf("Placed kernel section (%p+%p)\n",
|
||||
_p(start), _p(size));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (start >= MEM_HOLE_START) {
|
||||
/* In the memory hole. Not so good */
|
||||
printf("Fatal: kernel load address (%p) is in the memory hole.\n",
|
||||
_p(start));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (start + size > MEM_HOLE_START) {
|
||||
/* Too big for low memory */
|
||||
printf("Fatal: kernel (%p+%p) runs into the memory hole.\n",
|
||||
_p(start), _p(size));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Kernel loads below the memory hole */
|
||||
next_free_space = MAX(next_free_space, start + size);
|
||||
|
||||
if (!quiet) {
|
||||
printf("Placed kernel section (%p+%p)\n", _p(start), _p(size));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static address_t place_section(long int size, int align)
|
||||
/* Find the next available place for this section.
|
||||
* "align" must be a power of 2 */
|
||||
{
|
||||
address_t start;
|
||||
assert(next_free_space != 0);
|
||||
assert(((~align + 1) & align) == align);
|
||||
|
||||
start = ROUNDUP_P2(next_free_space, align);
|
||||
|
||||
/* Check that we don't hit the memory hole */
|
||||
if (start < MEM_HOLE_END && (start + size) > MEM_HOLE_START)
|
||||
start = ROUNDUP_P2(MEM_HOLE_END, align);
|
||||
|
||||
next_free_space = start + size;
|
||||
|
||||
if (!quiet) {
|
||||
printf("Placed section (%p+%p), align=%p\n",
|
||||
_p(start), _p(size), _p(align));
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
static address_t load_kernel(const char *filename)
|
||||
/* Load an elf32/multiboot kernel from this file
|
||||
* Returns the entry address for the kernel. */
|
||||
{
|
||||
unsigned int i;
|
||||
address_t start;
|
||||
size_t len;
|
||||
long int size, loadsize;
|
||||
FILE *fp;
|
||||
char *buffer;
|
||||
section_t *sec, *s;
|
||||
Elf32_Ehdr *ehdr;
|
||||
Elf32_Phdr *phdr;
|
||||
struct multiboot_header *mbh;
|
||||
struct stat sb;
|
||||
|
||||
static char headerbuf[HEADERBUF_SIZE];
|
||||
|
||||
/* Stat and open the file */
|
||||
if (stat(filename, &sb) != 0) {
|
||||
printf("Fatal: cannot stat %s: %s\n", filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if ((fp = fopen(filename, "r")) == NULL) {
|
||||
printf("Fatal: cannot open %s: %s\n", filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Load the first 8k of the file */
|
||||
if (fseek(fp, 0, SEEK_SET) < 0) {
|
||||
printf("Fatal: seek error in %s: %s\n", filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if ((len = fread(headerbuf, 1, HEADERBUF_SIZE, fp))
|
||||
< HEADERBUF_SIZE)
|
||||
{
|
||||
if (feof(fp)) /* Short file */
|
||||
{
|
||||
if (len < 12) {
|
||||
printf("Fatal: %s is too short to be a multiboot file.",
|
||||
filename);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
printf("Fatal: read error in %s: %s\n", filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity-check: is this file compressed? */
|
||||
if ((headerbuf[0] == '\037' &&
|
||||
(headerbuf[1] == '\235' /* .Z */ ||
|
||||
headerbuf[1] == '\213' /* .gz */)) ||
|
||||
(headerbuf[0] == 'B' && headerbuf[1] == 'Z') /* .bz[2] */) {
|
||||
printf("Warning: %s looks like a compressed file.\n"
|
||||
" You should uncompress it first!\n", filename);
|
||||
}
|
||||
|
||||
/* Now look for a multiboot header */
|
||||
for (i = 0; i <= MIN(len - 12, MULTIBOOT_SEARCH - 12); i += 4)
|
||||
{
|
||||
mbh = (struct multiboot_header *)(headerbuf + i);
|
||||
if (eswap(mbh->magic) != MULTIBOOT_MAGIC
|
||||
|| ((eswap(mbh->magic)+eswap(mbh->flags)+eswap(mbh->checksum))
|
||||
& 0xffffffff))
|
||||
{
|
||||
/* Not a multiboot header */
|
||||
continue;
|
||||
}
|
||||
if (eswap(mbh->flags) & MULTIBOOT_UNSUPPORTED) {
|
||||
/* Requires options we don't support */
|
||||
printf("Fatal: found a multiboot header, but it "
|
||||
"requires multiboot options that I\n"
|
||||
"don't understand. Sorry.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (eswap(mbh->flags) & MULTIBOOT_VIDEO_MODE) {
|
||||
/* Asked for screen mode information */
|
||||
/* XXX carry on regardless */
|
||||
printf("Warning: found a multiboot header which asks "
|
||||
"for screen mode information.\n"
|
||||
" This kernel will NOT be given valid"
|
||||
"screen mode information at boot time.\n");
|
||||
}
|
||||
/* This kernel will do: place and load it */
|
||||
|
||||
if (eswap(mbh->flags) & MULTIBOOT_AOUT_KLUDGE) {
|
||||
|
||||
/* Load using the offsets in the multiboot header */
|
||||
if(!quiet)
|
||||
printf("Loading %s using multiboot header.\n", filename);
|
||||
|
||||
/* How much is there? */
|
||||
start = eswap(mbh->load_addr);
|
||||
if (eswap(mbh->load_end_addr) != 0)
|
||||
loadsize = eswap(mbh->load_end_addr) - eswap(mbh->load_addr);
|
||||
else
|
||||
loadsize = sb.st_size;
|
||||
|
||||
/* How much memory will it take up? */
|
||||
if (eswap(mbh->bss_end_addr) != 0)
|
||||
size = eswap(mbh->bss_end_addr) - eswap(mbh->load_addr);
|
||||
else
|
||||
size = loadsize;
|
||||
|
||||
if (loadsize > size) {
|
||||
printf("Fatal: can't load %ld bytes of kernel into %ld bytes "
|
||||
"of memory.\n", loadsize, size);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Does it fit where it wants to be? */
|
||||
place_kernel_section(start, size);
|
||||
|
||||
/* Load the kernel */
|
||||
if ((buffer = malloc(size)) == NULL) {
|
||||
printf("Fatal: malloc() for kernel load failed: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if ((fread(buffer, loadsize, 1, fp)) != 1) {
|
||||
printf("Fatal: cannot read %s: %s\n",
|
||||
filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
/* Clear the kernel BSS */
|
||||
memset(buffer + loadsize, 0, size - loadsize);
|
||||
|
||||
/* Start off the linked list of sections */
|
||||
if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL) {
|
||||
printf("Fatal: malloc() for section_t failed: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
sec->buffer = buffer;
|
||||
sec->start = start;
|
||||
sec->size = size;
|
||||
sec->next = NULL;
|
||||
sec->prev = NULL;
|
||||
sections = sec;
|
||||
last_section = sec;
|
||||
|
||||
/* Done. */
|
||||
if (!quiet) printf("Loaded kernel from %s\n", filename);
|
||||
return eswap(mbh->entry_addr);
|
||||
|
||||
} else {
|
||||
|
||||
/* Now look for an ELF32 header */
|
||||
ehdr = (Elf32_Ehdr *)headerbuf;
|
||||
if (*(unsigned long *)ehdr != eswap(0x464c457f)
|
||||
|| ehdr->e_ident[EI_DATA] != ELFDATA2LSB
|
||||
|| ehdr->e_ident[EI_CLASS] != ELFCLASS32
|
||||
|| eswap(ehdr->e_machine) != EM_386)
|
||||
{
|
||||
printf("Fatal: kernel has neither ELF32/x86 nor multiboot load"
|
||||
" headers.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (eswap(ehdr->e_phoff) + eswap(ehdr->e_phnum)*sizeof(*phdr)
|
||||
> HEADERBUF_SIZE) {
|
||||
/* Don't expect this will happen with sane kernels */
|
||||
printf("Fatal: too much ELF for me. Try increasing "
|
||||
"HEADERBUF_SIZE in mbootpack.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (eswap(ehdr->e_phoff) + eswap(ehdr->e_phnum)*sizeof (*phdr)
|
||||
> len) {
|
||||
printf("Fatal: malformed ELF header overruns EOF.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (eswap(ehdr->e_phnum) <= 0) {
|
||||
printf("Fatal: ELF kernel has no program headers.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!quiet)
|
||||
printf("Loading %s using ELF header.\n", filename);
|
||||
|
||||
if (eswap(ehdr->e_type) != ET_EXEC
|
||||
|| eswap(ehdr->e_version) != EV_CURRENT
|
||||
|| eswap(ehdr->e_phentsize) != sizeof (Elf32_Phdr)) {
|
||||
printf("Warning: funny-looking ELF header.\n");
|
||||
}
|
||||
phdr = (Elf32_Phdr *)(headerbuf + eswap(ehdr->e_phoff));
|
||||
|
||||
/* Obey the program headers to load the kernel */
|
||||
for(i = 0; i < eswap(ehdr->e_phnum); i++) {
|
||||
|
||||
start = eswap(phdr[i].p_paddr);
|
||||
size = eswap(phdr[i].p_memsz);
|
||||
if (eswap(phdr[i].p_type) != PT_LOAD)
|
||||
loadsize = 0;
|
||||
else
|
||||
loadsize = MIN((long int)eswap(phdr[i].p_filesz), size);
|
||||
|
||||
if ((buffer = malloc(size)) == NULL) {
|
||||
printf("Fatal: malloc() for kernel load failed: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Place the section where it wants to be */
|
||||
place_kernel_section(start, size);
|
||||
|
||||
/* Load section from file */
|
||||
if (loadsize > 0) {
|
||||
if (fseek(fp, eswap(phdr[i].p_offset), SEEK_SET) != 0) {
|
||||
printf("Fatal: seek failed in %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if ((fread(buffer, loadsize, 1, fp)) != 1) {
|
||||
printf("Fatal: cannot read %s: %s\n",
|
||||
filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the rest of the buffer */
|
||||
memset(buffer + loadsize, 0, size - loadsize);
|
||||
|
||||
/* Add this section to the list (keeping it ordered) */
|
||||
if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL) {
|
||||
printf("Fatal: malloc() for section_t failed: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
sec->buffer = buffer;
|
||||
sec->start = start;
|
||||
sec->size = size;
|
||||
|
||||
for(s = sections; s; s = s->next) {
|
||||
if (s->start > start) {
|
||||
sec->next = s;
|
||||
if (s->prev == NULL) {
|
||||
/* sec becomes the new first item */
|
||||
s->prev = sec;
|
||||
sections = sec;
|
||||
} else {
|
||||
/* sec goes between s->prev and s */
|
||||
sec->prev = s->prev;
|
||||
sec->prev->next = sec;
|
||||
s->prev = sec;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (s == NULL) {
|
||||
/* sec becomes the new last item */
|
||||
sec->next = NULL;
|
||||
sec->prev = last_section;
|
||||
if (last_section) {
|
||||
last_section->next = sec;
|
||||
} else {
|
||||
sections = sec;
|
||||
}
|
||||
last_section = sec;
|
||||
}
|
||||
}
|
||||
|
||||
/* Done! */
|
||||
if (!quiet) printf("Loaded kernel from %s\n", filename);
|
||||
return eswap(ehdr->e_entry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* This is not a multiboot kernel */
|
||||
printf("Fatal: %s is not a multiboot kernel.\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *buffer, *imagename, *command_line, *p;
|
||||
char *mod_filename, *mod_command_line, *mod_clp;
|
||||
char *out_filename;
|
||||
section_t *sec;
|
||||
FILE *fp;
|
||||
struct stat sb;
|
||||
struct multiboot_info *mbi;
|
||||
struct mod_list *modp;
|
||||
address_t start, kernel_entry;
|
||||
long int size, mod_command_line_space, command_line_len;
|
||||
int modules, opt, mbi_reloc_offset;
|
||||
|
||||
static const char short_options[] = "hc:m:o:qM";
|
||||
static const struct option options[] = {
|
||||
{ "help", 0, 0, 'h' },
|
||||
{ "command-line", 1, 0, 'c' },
|
||||
{ "append", 1, 0, 'c' },
|
||||
{ "module", 1, 0, 'm' },
|
||||
{ "output", 1, 0, 'o' },
|
||||
{ "quiet", 0, 0, 'q' },
|
||||
{ 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
/* Parse the command line */
|
||||
out_filename = NULL;
|
||||
command_line = "";
|
||||
command_line_len = 0;
|
||||
modules = 0;
|
||||
mod_command_line_space = 0;
|
||||
while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'c':
|
||||
command_line = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
modules++;
|
||||
mod_command_line_space += strlen(optarg) + 1;
|
||||
break;
|
||||
case 'o':
|
||||
out_filename = optarg;
|
||||
break;
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
imagename = argv[optind];
|
||||
if (!imagename || strlen(imagename) == 0) usage();
|
||||
command_line_len = strlen(command_line) + strlen(imagename) + 2;
|
||||
/* Leave space to overwritethe command-line at boot time */
|
||||
command_line_len = MAX(command_line_len, CMD_LINE_SPACE);
|
||||
if (!out_filename) out_filename = "bzImage";
|
||||
|
||||
/* Place and load the kernel */
|
||||
kernel_entry = load_kernel(imagename);
|
||||
assert(sections != NULL);
|
||||
assert(last_section != NULL);
|
||||
assert(next_free_space != 0);
|
||||
|
||||
/* Next section is all the metadata between kernel and modules */
|
||||
size = ((((sizeof (struct multiboot_info)
|
||||
+ command_line_len
|
||||
+ strlen(version_string) + 1
|
||||
+ mod_command_line_space)
|
||||
+ 3 ) & ~3)
|
||||
+ modules * sizeof (struct mod_list));
|
||||
/* Locate this section after the setup sectors, in *low* memory */
|
||||
start = place_mbi(size);
|
||||
|
||||
if ((buffer = malloc(size)) == NULL) {
|
||||
printf("Fatal: malloc() for boot metadata failed: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL) {
|
||||
printf("Fatal: malloc() for section_t failed: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
sec->buffer = buffer;
|
||||
sec->start = start;
|
||||
sec->size = size;
|
||||
sec->next = NULL;
|
||||
sec->prev = last_section;
|
||||
last_section->next = sec;
|
||||
last_section = sec;
|
||||
|
||||
/* Multiboot info struct */
|
||||
mbi = (struct multiboot_info *)buffer;
|
||||
memset(buffer, 0, sizeof (struct multiboot_info));
|
||||
mbi_reloc_offset = start - (address_t)buffer;
|
||||
|
||||
/* Command line */
|
||||
p = (char *)(mbi + 1);
|
||||
sprintf(p, "%s %s", imagename, command_line);
|
||||
mbi->cmdline = eswap(((address_t)p) + mbi_reloc_offset);
|
||||
p += command_line_len;
|
||||
|
||||
/* Bootloader ID */
|
||||
sprintf(p, version_string);
|
||||
mbi->boot_loader_name = eswap(((address_t)p) + mbi_reloc_offset);
|
||||
p += strlen(version_string) + 1;
|
||||
|
||||
/* Next is space for the module command lines */
|
||||
mod_clp = p;
|
||||
|
||||
/* Last come the module info structs */
|
||||
modp = (struct mod_list *)
|
||||
((((address_t)p + mod_command_line_space) + 3) & ~3);
|
||||
mbi->mods_count = eswap(modules);
|
||||
mbi->mods_addr = eswap(((address_t)modp) + mbi_reloc_offset);
|
||||
|
||||
/* Memory information will be added at boot time, by setup.S
|
||||
* or trampoline.S. */
|
||||
mbi->flags = eswap(MB_INFO_CMDLINE | MB_INFO_BOOT_LOADER_NAME);
|
||||
|
||||
|
||||
/* Load the modules */
|
||||
if (modules) {
|
||||
mbi->flags = eswap(eswap(mbi->flags) | MB_INFO_MODS);
|
||||
|
||||
/* Go back and parse the module command lines */
|
||||
optind = opterr = 1;
|
||||
while((opt = getopt_long(argc, argv,
|
||||
short_options, options, 0)) != -1)
|
||||
{
|
||||
if (opt != 'm') continue;
|
||||
|
||||
/* Split module filename from command line */
|
||||
mod_command_line = mod_filename = optarg;
|
||||
if ((p = strchr(mod_filename, ' ')) != NULL) {
|
||||
/* See as I discard the 'const' modifier */
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
/* Find space for it */
|
||||
if (stat(mod_filename, &sb) != 0) {
|
||||
printf("Fatal: cannot stat %s: %s\n",
|
||||
mod_filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
size = sb.st_size;
|
||||
start = place_section(size, X86_PAGE_SIZE);
|
||||
/* XXX should be place_section(size, 4) if the MBH hasn't got
|
||||
* XXX MULTIBOOT_PAGE_ALIGN set, but that breaks Xen */
|
||||
|
||||
/* Load it */
|
||||
if ((buffer = malloc(sb.st_size)) == NULL) {
|
||||
printf("Fatal: malloc failed for module load: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if ((fp = fopen(mod_filename, "r")) == NULL) {
|
||||
printf("Fatal: cannot open %s: %s\n",
|
||||
mod_filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if ((fread(buffer, sb.st_size, 1, fp)) != 1) {
|
||||
printf("Fatal: cannot read %s: %s\n",
|
||||
mod_filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
/* Sanity-check: is this file compressed? */
|
||||
if ((buffer[0] == '\037' &&
|
||||
(buffer[1] == '\235' /* .Z */ ||
|
||||
buffer[1] == '\213' /* .gz */)) ||
|
||||
(buffer[0] == 'B' && buffer[1] == 'Z') /* .bz[2] */) {
|
||||
printf("Warning: %s looks like a compressed file.\n",
|
||||
mod_filename);
|
||||
}
|
||||
|
||||
if (!quiet) printf("Loaded module from %s\n", mod_filename);
|
||||
|
||||
/* Restore the command line to its former glory */
|
||||
if (p != NULL) *p = ' ';
|
||||
|
||||
/* Fill in the module info struct */
|
||||
modp->mod_start = eswap(start);
|
||||
modp->mod_end = eswap(start + size);
|
||||
modp->cmdline = eswap((address_t)mod_clp + mbi_reloc_offset);
|
||||
modp->pad = eswap(0);
|
||||
modp++;
|
||||
|
||||
/* Store the module command line */
|
||||
sprintf(mod_clp, "%s", mod_command_line);
|
||||
mod_clp += strlen(mod_clp) + 1;
|
||||
|
||||
/* Add the section to the list */
|
||||
if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL) {
|
||||
printf("Fatal: malloc() for section_t failed: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
sec->buffer = buffer;
|
||||
sec->start = start;
|
||||
sec->size = size;
|
||||
sec->next = NULL;
|
||||
sec->prev = last_section;
|
||||
last_section->next = sec;
|
||||
last_section = sec;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Everything is placed and loaded. Now we package it all up
|
||||
* as a bzImage */
|
||||
if ((fp = fopen(out_filename, "w")) == NULL) {
|
||||
printf("Fatal: cannot open %s: %s\n", out_filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
make_bzImage(sections,
|
||||
kernel_entry,
|
||||
((address_t)mbi) + mbi_reloc_offset,
|
||||
fp);
|
||||
fclose(fp);
|
||||
|
||||
/* Success! */
|
||||
if(!quiet) printf("Finished.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* EOF (mbootpack.c)
|
||||
*/
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* mbootpack.h
|
||||
*
|
||||
* Common definitions for mbootpack
|
||||
*
|
||||
* Copyright (C) 2003-2004 Tim Deegan (tjd21@cl.cam.ac.uk)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* $Id: mbootpack.h,v 1.2 2005/03/23 10:38:37 tjd21 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MBOOTPACK__H__
|
||||
#define __MBOOTPACK__H__
|
||||
|
||||
#ifndef __MB_ASM
|
||||
|
||||
#undef NDEBUG
|
||||
#include <stdio.h>
|
||||
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define eswap(x) (x)
|
||||
#else
|
||||
#define eswap(x) \
|
||||
({ \
|
||||
typeof(x) y = (x); \
|
||||
switch(sizeof(y)) \
|
||||
{ \
|
||||
case 2: y = __bswap_16(y); break; \
|
||||
case 4: y = __bswap_32(y); break; \
|
||||
case 8: y = __bswap_64(y); break; \
|
||||
} \
|
||||
y; \
|
||||
})
|
||||
#endif
|
||||
|
||||
/* Flags */
|
||||
extern int quiet;
|
||||
|
||||
/* Types */
|
||||
typedef unsigned long address_t;
|
||||
|
||||
typedef struct section_t {
|
||||
char *buffer;
|
||||
address_t start;
|
||||
long int size;
|
||||
struct section_t *prev;
|
||||
struct section_t *next;
|
||||
} section_t;
|
||||
|
||||
/* buildimage.c */
|
||||
extern void make_bzImage(section_t *sections,
|
||||
address_t entry,
|
||||
address_t mbi,
|
||||
FILE *fp);
|
||||
|
||||
address_t place_mbi(long int size);
|
||||
|
||||
|
||||
/* trampoline.S */
|
||||
extern unsigned char mb_trampoline[];
|
||||
extern unsigned char mb_trampoline_end[];
|
||||
extern volatile address_t mb_mbi_address, mb_entry_address;
|
||||
|
||||
/* Macros */
|
||||
#define MIN(_x,_y) (((_x)<=(_y))?(_x):(_y))
|
||||
#define MAX(_x,_y) (((_x)<=(_y))?(_y):(_x))
|
||||
#define ROUNDUP_P2(_x, _a) (((_x)+((_a)-1))&(~((_a)-1)))
|
||||
|
||||
#endif
|
||||
|
||||
/* x86 memory: such fun */
|
||||
#define MEM_HOLE_START 0xa0000
|
||||
#define MEM_HOLE_END 0x100000
|
||||
#define HIGHMEM_START MEM_HOLE_END
|
||||
#define X86_PAGE_SIZE 0x1000
|
||||
|
||||
/* How much command line we'll take from the bootloader. */
|
||||
#define CMD_LINE_SPACE 0x300
|
||||
|
||||
/* Number of 512-byte sectors to load in low memory (max 7) */
|
||||
#define SETUPSECTS 7
|
||||
|
||||
|
||||
/* Who are we? */
|
||||
#define MBOOTPACK_VERSION_STRING "v0.2 (alpha)"
|
||||
|
||||
#endif /* __MBOOTPACK__H__ */
|
||||
|
||||
/*
|
||||
* EOF (mbootpack.h)
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large.
Load diff