aboutsummaryrefslogtreecommitdiff
path: root/system/mbootpack
diff options
context:
space:
mode:
Diffstat (limited to 'system/mbootpack')
-rw-r--r--system/mbootpack/mbootpack-0.6a_asm_page_fix.patch37
-rw-r--r--system/mbootpack/mbootpack.SlackBuild22
-rw-r--r--system/mbootpack/patches/mbootpack-0.6a-alt3.patch684
3 files changed, 697 insertions, 46 deletions
diff --git a/system/mbootpack/mbootpack-0.6a_asm_page_fix.patch b/system/mbootpack/mbootpack-0.6a_asm_page_fix.patch
deleted file mode 100644
index 0a5cb0d910d36..0000000000000
--- a/system/mbootpack/mbootpack-0.6a_asm_page_fix.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-# Well, since asm/page.h has been removed from make headers_install,
-# we replace it with sys/user.h
-# Copyright 2010, mario <mario@slackverse.org>
-
---- mbootpack-0.6a/buildimage.c.ORIG 2008-12-09 14:10:59.000000000 +0100
-+++ mbootpack-0.6a/buildimage.c 2010-06-18 18:15:11.130697044 +0200
-@@ -38,7 +38,7 @@
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/mman.h>
--#include <asm/page.h>
-+#include <sys/user.h>
-
- #include "mbootpack.h"
- #include "mb_header.h"
---- mbootpack-0.6a/mbootpack.c.ORIG 2008-12-09 14:10:59.000000000 +0100
-+++ mbootpack-0.6a/mbootpack.c 2010-06-18 18:15:21.709696839 +0200
-@@ -43,7 +43,7 @@
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/mman.h>
--#include <asm/page.h>
-+#include <sys/user.h>
-
- /* From GNU GRUB */
- #include "mb_header.h"
---- mbootpack-0.6a/setup.S.ORIG 2008-12-09 14:10:59.000000000 +0100
-+++ mbootpack-0.6a/setup.S 2010-06-18 18:15:33.899696996 +0200
-@@ -82,7 +82,7 @@
- #include <linux/compile.h>
- #include <asm/boot.h>
- #include <asm/e820.h>
--#include <asm/page.h>
-+#include <sys/user.h>
- */
-
- /* Definitions that should have come from these includes */
diff --git a/system/mbootpack/mbootpack.SlackBuild b/system/mbootpack/mbootpack.SlackBuild
index 2bc6f93335e8b..60d5f20f01574 100644
--- a/system/mbootpack/mbootpack.SlackBuild
+++ b/system/mbootpack/mbootpack.SlackBuild
@@ -2,7 +2,7 @@
# Slackware build script for mbootpack
-# Copyright 2010, 2015 Mario Preksavec, Zagreb, HR
+# Copyright 2010, 2015, 2017 Mario Preksavec, Zagreb, Croatia
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
@@ -24,12 +24,12 @@
PRGNAM=mbootpack
VERSION=${VERSION:-0.6a}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
TAG=${TAG:-_SBo}
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) ARCH=i486 ;;
+ i?86) ARCH=i586 ;;
arm*) ARCH=arm ;;
*) ARCH=$( uname -m ) ;;
esac
@@ -40,8 +40,8 @@ TMP=${TMP:-/tmp/SBo}
PKG=$TMP/package-$PRGNAM
OUTPUT=${OUTPUT:-/tmp}
-if [ "$ARCH" = "i486" ]; then
- SLKCFLAGS="-O2 -march=i486 -mtune=i686"
+if [ "$ARCH" = "i586" ]; then
+ SLKCFLAGS="-O2 -march=i586 -mtune=i686"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "i686" ]; then
SLKCFLAGS="-O2 -march=i686 -mtune=i686"
@@ -69,18 +69,22 @@ find -L . \
\( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
-o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
-# Fix asm/page.h error
-patch -p1 <$CWD/mbootpack-0.6a_asm_page_fix.patch
+# Some fixes from ALT Linux folks
+patch -p1 <$CWD/patches/mbootpack-0.6a-alt3.patch
make
# We have to do things manually since mbootpack doesn't have make install
-mkdir -p $PKG/usr/bin
+mkdir -p $PKG/usr/{bin,man/man1}
cp -a bootsect mbootpack mkhex setup $PKG/usr/bin
+cp -a mbootpack.man $PKG/usr/man/man1/mbootpack.1
-find $PKG | xargs file | grep -e "executable" -e "shared object" | grep ELF \
+find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
| cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
+find $PKG/usr/man -type f -exec gzip -9 {} \;
+for i in $( find $PKG/usr/man -type l ) ; do ln -s $( readlink $i ).gz $i.gz ; rm $i ; done
+
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
cp -a Changes GPL README $PKG/usr/doc/$PRGNAM-$VERSION
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
diff --git a/system/mbootpack/patches/mbootpack-0.6a-alt3.patch b/system/mbootpack/patches/mbootpack-0.6a-alt3.patch
new file mode 100644
index 0000000000000..84e318ff42794
--- /dev/null
+++ b/system/mbootpack/patches/mbootpack-0.6a-alt3.patch
@@ -0,0 +1,684 @@
+ Makefile | 20 +++-
+ buildimage.c | 15 ++-
+ mbootpack.c | 311 ++++++++++++++++++++++++++---------------------------------
+ mbootpack.h | 2 +-
+ 4 files changed, 162 insertions(+), 186 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index aba82f3..2096ffd 100644
+--- a/Makefile
++++ b/Makefile
+@@ -7,8 +7,10 @@
+ #
+
+ PROG := mbootpack
++MANPAGE := $(PROG).man
+ OBJS := mbootpack.o buildimage.o
+ DEPS := mbootpack.o.d buildimage.o.d
++VERSION := 0.6a
+
+ #
+ # Tools etc.
+@@ -25,17 +27,31 @@ CFLAGS += -Wmissing-prototypes
+ CFLAGS += -pipe -O3
+ DEPFLAGS = -Wp,-MD,$(@F).d
+
++ifneq ($(VERSION),)
++DEFS += -DVERSION=\"$(VERSION)\"
++endif
++
++ifneq ($(WITH_ZLIB),)
++DEFS += -DHAVE_ZLIB
++ZLIB = -lz
++else
++ZLIB =
++endif
++
+ #
+ # Rules
+ #
+
+-all: $(PROG)
++all: $(PROG) $(MANPAGE)
+
+ gdb: $(PROG)
+ $(GDB) $<
+
+ $(PROG): $(OBJS)
+- $(CC) -o $@ $(filter-out %.a, $^)
++ $(CC) $(CFLAGS) $(DEFS) -o $@ $(filter-out %.a, $^) $(ZLIB)
++
++$(MANPAGE): $(PROG)
++ help2man -n "packages a multiboot kernel and modules as a single file" -s 1 -N ./$< > $@
+
+ clean: FRC
+ $(RM) mbootpack *.o *.d bootsect setup bzimage_header.c
+diff --git a/buildimage.c b/buildimage.c
+index 033dcf8..7f3e054 100644
+--- a/buildimage.c
++++ b/buildimage.c
+@@ -38,7 +38,6 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h>
+-#include <asm/page.h>
+
+ #include "mbootpack.h"
+ #include "mb_header.h"
+@@ -84,14 +83,14 @@ address_t place_mbi(long int size)
+ address_t start;
+ start = 0xa000 - size;
+ if (start < 0x9000 + sizeof(bzimage_bootsect) + sizeof(bzimage_setup)) {
+- printf("Fatal: command-lines too long: need %i, have %i bytes\n",
++ printf("Fatal: command-lines too long: need %ld, have %ld bytes\n",
+ size,
+ 0x1000 - (sizeof(bzimage_bootsect) + sizeof(bzimage_setup)));
+ exit(1);
+ }
+ if (!quiet) {
+- printf("Placed MBI and strings (%p+%p)\n",
+- start, size);
++ printf("Placed MBI and strings (%lx+%lx)\n",
++ (unsigned long)start, size);
+ }
+ return start;
+ }
+@@ -110,7 +109,7 @@ void make_bzImage(section_t *sections,
+ /* Patch the kernel and mbi addresses into the setup code */
+ *(address_t *)(bzimage_setup + BZ_ENTRY_OFFSET) = entry;
+ *(address_t *)(bzimage_setup + BZ_MBI_OFFSET) = mbi;
+- if (!quiet) printf("Kernel entry is %p, MBI is %p.\n", entry, mbi);
++ if (!quiet) printf("Kernel entry is %lx, MBI is %lx.\n", (unsigned long)entry, (unsigned long)mbi);
+
+ /* If the high-memory sections don't start at 1MB, shuffle them down
+ * in the file and record how they should be relocated at boot time. */
+@@ -122,8 +121,8 @@ void make_bzImage(section_t *sections,
+ if (highmem_size != 0) {
+ *(address_t *)(bzimage_setup + BZ_HIGH_START_OFFSET) = highmem_start;
+ *(address_t *)(bzimage_setup + BZ_HIGH_SIZE_OFFSET) = highmem_size;
+- if (!quiet) printf("High sections: %p bytes at %p.\n",
+- highmem_size, highmem_start);
++ if (!quiet) printf("High sections: %lx bytes at %lx.\n",
++ (unsigned long)highmem_size, (unsigned long)highmem_start);
+ } else
+ highmem_start = HIGHMEM_START;
+
+@@ -144,7 +143,7 @@ void make_bzImage(section_t *sections,
+ exit(1);
+ }
+
+- if (!quiet) printf("Wrote bzImage header: %i + %i bytes.\n",
++ if (!quiet) printf("Wrote bzImage header: %zu + %zu bytes.\n",
+ sizeof(bzimage_bootsect), sizeof(bzimage_setup));
+
+ /* Sorted list of sections below 1MB: write them out */
+diff --git a/mbootpack.c b/mbootpack.c
+index eb0aa0f..16e44f3 100644
+--- a/mbootpack.c
++++ b/mbootpack.c
+@@ -43,7 +43,17 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h>
+-#include <asm/page.h>
++
++#ifdef HAVE_ZLIB
++#include <zlib.h>
++#else
++#define gzFile FILE*
++#define gzopen fopen
++#define gzclose fclose
++#define gzeof feof
++#define gzseek fseek
++#define gzread(f, buf, len) fread(buf, 1, len, fp)
++#endif
+
+ /* From GNU GRUB */
+ #include "mb_header.h"
+@@ -112,72 +122,79 @@ 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"
++static const char usage[] =
++"Usage: mbootpack [OPTIONS] kernel-image\n\n"
++"Takes a multiboot kernel and modules (e.g. a Xen VMM, linux kernel and initrd), and packages them up as a single file that looks like a bzImage linux kernel.\n\n"
+ " -q --quiet Only output errors and warnings.\n"
+ " -t --truncate Clip module paths in command-lines.\n"
+ " -o --output=filename Output to filename (default \"bzImage\").\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);
+-}
++" -h --help Display this help and exit.\n"
++#ifdef VERSION
++" -V --version Display version number and exit.\n"
++#endif
++"\n";
+
+ /* Return a pointer into the string, skipping over all leading directories. */
+ static char *clip_path(char *str)
+ {
+- const char *p, *last = NULL;
++ char *p, *last = NULL;
+ for (p = str; *p && *p != ' '; p++)
+ if (*p == '/')
+ last = p;
+ return (last ? last + 1 : str);
+ }
+
++static _Noreturn void fatal(const char *fmt, ...)
++{
++ va_list args;
++
++ fputs("Fatal: ", stderr);
++ fprintf(stderr, fmt, args);
++ exit(1);
++}
++
++static _Noreturn void fatal_err(const char *fmt, ...)
++{
++ va_list args;
++
++ fatal(fmt, args, strerror(errno));
++}
++
+ static void place_kernel_section(address_t start, long int size)
+ /* Place the kernel in memory, checking for the memory hole. */
+ {
+- if (start + size + 0x1000 - 0x100000 >= 0x2000000) {
++ if (start + size + 0x1000 - 0x100000 >= 0x2000000)
+ /* Arbitrary limit: output file would be too big to TFTP.
+ * This is really to catch insane load addresses: Xen 2.0.5
+ * comes in a version with symbols, which asks to be loaded
+ * at Xen's *virtual* address (nearly 4GB). */
+- printf("Fatal: kernel section loads too high: %#x+%#x\n", start);
+- exit(1);
+- }
++ fatal("kernel section loads too high: %#lx+%#lx\n", (unsigned long)start, size + 0x1000 - 0x100000);
+
+ 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", start, size);
++ printf("Placed kernel section (%lx+%lx)\n", (unsigned long)start, size);
+ }
+ return;
+ }
+
+- if (start >= MEM_HOLE_START) {
++ if (start >= MEM_HOLE_START)
+ /* In the memory hole. Not so good */
+- printf("Fatal: kernel load address (%p) is in the memory hole.\n",
+- start);
+- exit(1);
+- }
++ fatal("kernel load address (%lx) is in the memory hole.\n", (unsigned long)start);
+
+- if (start + size > MEM_HOLE_START) {
++ if (start + size > MEM_HOLE_START)
+ /* Too big for low memory */
+- printf("Fatal: kernel (%p+%p) runs into the memory hole.\n",
+- start, size);
+- exit(1);
+- }
++ fatal("kernel (%lx+%lx) runs into the memory hole.\n", (unsigned long)start, size);
+
+ /* Kernel loads below the memory hole */
+ next_free_space = MAX(next_free_space, start + size);
+
+ if (!quiet) {
+- printf("Placed kernel section (%p+%p)\n", start, size);
++ printf("Placed kernel section (%lx+%lx)\n", (unsigned long)start, size);
+ }
+ }
+
+@@ -199,8 +216,7 @@ static address_t place_section(long int size, int align)
+ next_free_space = start + size;
+
+ if (!quiet) {
+- printf("Placed section (%p+%p), align=%p\n",
+- start, size, align);
++ printf("Placed section (%lx+%lx), align=%d\n", (unsigned long)start, size, align);
+ }
+ return start;
+ }
+@@ -216,7 +232,7 @@ static address_t load_kernel(const char *filename)
+ address_t start;
+ size_t len;
+ long int size, loadsize;
+- FILE *fp;
++ gzFile fp;
+ char *buffer;
+ section_t *sec, *s;
+ Elf32_Ehdr *ehdr;
+@@ -227,44 +243,37 @@ static address_t load_kernel(const char *filename)
+ 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);
+- }
++ if (stat(filename, &sb) != 0)
++ fatal("cannot stat %s: %s\n", filename, strerror(errno));
++ if ((fp = gzopen(filename, "r")) == NULL)
++ fatal("cannot open %s: %s\n", filename, strerror(errno));
+
+ /* 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 (gzseek(fp, 0, SEEK_SET) < 0)
++ fatal("seek error in %s: %s\n", filename, strerror(errno));
++ len = gzread(fp, headerbuf, sizeof(headerbuf));
++ if (len < sizeof(headerbuf))
+ {
+- if (feof(fp)) /* Short file */
++ if (gzeof(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);
+- }
++ if (len < 12)
++ fatal("%s is too short to be a multiboot file.", filename);
++ } else
++ fatal("read error in %s: %s\n", filename, strerror(errno));
+ }
+
++#ifndef HAVE_ZLIB
+ /* 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);
++ fprintf(stderr,
++ "Warning: %s looks like a compressed file.\n"
++ " You should uncompress it first!\n",
++ filename);
+ }
++#endif
+
+ /* Now look for a multiboot header */
+ for (i = 0; i <= MIN(len - 12, MULTIBOOT_SEARCH - 12); i += 4)
+@@ -276,20 +285,16 @@ static address_t load_kernel(const char *filename)
+ /* Not a multiboot header */
+ continue;
+ }
+- if (mbh->flags & MULTIBOOT_UNSUPPORTED) {
++ if (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);
+- }
++ fatal("found a multiboot header, but it requires multiboot options that I don't\n"
++ "understand. Sorry.");
+ if (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");
++ fputs("Warning: found a multiboot header which asks for screen mode information.\n"
++ " This kernel will NOT be given valid screen mode information at boot\n"
++ " time.", stderr);
+ }
+ /* This kernel will do: place and load it */
+
+@@ -312,37 +317,25 @@ static address_t load_kernel(const char *filename)
+ else
+ size = loadsize;
+
+- if (loadsize > size) {
+- printf("Fatal: can't load %i bytes of kernel into %i bytes "
+- "of memory.\n", loadsize, size);
+- exit(1);
+- }
++ if (loadsize > size)
++ fatal("can't load %ld bytes of kernel into %ld bytes of memory.\n", loadsize, size);
+
+ /* 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);
++ if ((buffer = malloc(size)) == NULL)
++ fatal("malloc() for kernel load failed: %s\n", strerror(errno));
++ if ((gzread(fp, buffer, loadsize)) != loadsize)
++ fatal("cannot read %s: %s\n", filename, strerror(errno));
++ gzclose(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);
+- }
++ if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL)
++ fatal("malloc() for section_t failed: %s\n", strerror(errno));
+ sec->buffer = buffer;
+ sec->start = start;
+ sec->size = size;
+@@ -363,25 +356,14 @@ static address_t load_kernel(const char *filename)
+ || ehdr->e_ident[EI_DATA] != ELFDATA2LSB
+ || ehdr->e_ident[EI_CLASS] != ELFCLASS32
+ || ehdr->e_machine != EM_386)
+- {
+- printf("Fatal: kernel has neither ELF32/x86 nor multiboot load"
+- " headers.\n");
+- exit(1);
+- }
+- if (ehdr->e_phoff + ehdr->e_phnum*sizeof(*phdr) > HEADERBUF_SIZE) {
++ fatal("kernel has neither ELF32/x86 nor multiboot load headers.");
++ if (ehdr->e_phoff + 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 (ehdr->e_phoff + ehdr->e_phnum*sizeof (*phdr) > len) {
+- printf("Fatal: malformed ELF header overruns EOF.\n");
+- exit(1);
+- }
+- if (ehdr->e_phnum <= 0) {
+- printf("Fatal: ELF kernel has no program headers.\n");
+- exit(1);
+- }
++ fatal("too much ELF for me. Try increasing HEADERBUF_SIZE in mbootpack.");
++ if (ehdr->e_phoff + ehdr->e_phnum*sizeof (*phdr) > len)
++ fatal("malformed ELF header overruns EOF.");
++ if (ehdr->e_phnum <= 0)
++ fatal("ELF kernel has no program headers.");
+
+ if(!quiet)
+ printf("Loading %s using ELF header.\n", filename);
+@@ -389,7 +371,7 @@ static address_t load_kernel(const char *filename)
+ if (ehdr->e_type != ET_EXEC
+ || ehdr->e_version != EV_CURRENT
+ || ehdr->e_phentsize != sizeof (Elf32_Phdr)) {
+- printf("Warning: funny-looking ELF header.\n");
++ fputs("Warning: funny-looking ELF header.\n", stderr);
+ }
+ phdr = (Elf32_Phdr *)(headerbuf + ehdr->e_phoff);
+
+@@ -407,38 +389,26 @@ static address_t load_kernel(const char *filename)
+ * have one */
+ if (size == 0) continue;
+
+- if ((buffer = malloc(size)) == NULL) {
+- printf("Fatal: malloc() for kernel load failed: %s\n",
+- strerror(errno));
+- exit(1);
+- }
++ if ((buffer = malloc(size)) == NULL)
++ fatal_err("malloc() for kernel load failed");
+
+ /* Place the section where it wants to be */
+ place_kernel_section(start, size);
+
+ /* Load section from file */
+ if (loadsize > 0) {
+- if (fseek(fp, 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);
+- }
++ if (gzseek(fp, phdr[i].p_offset, SEEK_SET) < 0)
++ fatal("seek failed in %s\n", strerror(errno));
++ if ((gzread(fp, buffer, loadsize)) != loadsize)
++ fatal_err("cannot read", filename);
+ }
+
+ /* 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);
+- }
++ if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL)
++ fatal_err("malloc() for section_t failed");
+ sec->buffer = buffer;
+ sec->start = start;
+ sec->size = size;
+@@ -480,8 +450,7 @@ static address_t load_kernel(const char *filename)
+ }
+
+ /* This is not a multiboot kernel */
+- printf("Fatal: %s is not a multiboot kernel.\n", filename);
+- exit(1);
++ fatal("%s is not a multiboot kernel.\n", filename);
+ }
+
+
+@@ -501,7 +470,7 @@ int main(int argc, char **argv)
+ long int size, mod_command_line_space, command_line_len;
+ int modules, opt, mbi_reloc_offset, truncate;
+
+- static const char short_options[] = "hc:m:o:qtM";
++ static const char short_options[] = "hc:m:o:qtMV";
+ static const struct option options[] = {
+ { "help", 0, 0, 'h' },
+ { "command-line", 1, 0, 'c' },
+@@ -510,6 +479,9 @@ int main(int argc, char **argv)
+ { "output", 1, 0, 'o' },
+ { "quiet", 0, 0, 'q' },
+ { "truncate", 0, 0, 't' },
++#ifdef VERSION
++ { "version", 0, 0, 'V' },
++#endif
+ { 0, 0, 0, 0 },
+ };
+
+@@ -541,14 +513,26 @@ int main(int argc, char **argv)
+ case 't':
+ truncate = 1;
+ break;
++#ifdef VERSION
++ case 'V':
++ puts("mbootpack " VERSION);
++ return 0;
++#endif
+ case 'h':
+ case '?':
++ puts(usage);
++ return 0;
+ default:
+- usage();
++ fputs(usage, stderr);
++ return 1;
+ }
+ }
+ imagename = argv[optind];
+- if (!imagename || strlen(imagename) == 0) usage();
++ if (!imagename || strlen(imagename) == 0)
++ {
++ fputs(usage, stderr);
++ return 1;
++ }
+ command_line_len = strlen(command_line) + strlen(imagename) + 2;
+ /* Leave space to overwrite the command-line at boot time */
+ command_line_len = MAX(command_line_len, CMD_LINE_SPACE);
+@@ -570,17 +554,11 @@ int main(int argc, char **argv)
+ /* 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 ((buffer = malloc(size)) == NULL)
++ fatal_err("malloc() for boot metadata failed");
+
+- if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL) {
+- printf("Fatal: malloc() for section_t failed: %s\n",
+- strerror(errno));
+- exit(1);
+- }
++ if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL)
++ fatal_err("malloc() for section_t failed");
+ sec->buffer = buffer;
+ sec->start = start;
+ sec->size = size;
+@@ -601,7 +579,7 @@ int main(int argc, char **argv)
+ p += command_line_len;
+
+ /* Bootloader ID */
+- sprintf(p, version_string);
++ strcpy(p, version_string);
+ mbi->boot_loader_name = ((address_t)p) + mbi_reloc_offset;
+ p += strlen(version_string) + 1;
+
+@@ -638,32 +616,20 @@ int main(int argc, char **argv)
+ }
+
+ /* Find space for it */
+- if (stat(mod_filename, &sb) != 0) {
+- printf("Fatal: cannot stat %s: %s\n",
+- mod_filename, strerror(errno));
+- exit(1);
+- }
++ if (stat(mod_filename, &sb) != 0)
++ fatal_err("cannot stat", mod_filename);
+ 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);
+- }
++ if ((buffer = malloc(sb.st_size)) == NULL)
++ fatal_err("malloc failed for module load");
++ if ((fp = fopen(mod_filename, "r")) == NULL)
++ fatal_err("cannot open", mod_filename);
++ if ((fread(buffer, sb.st_size, 1, fp)) != 1)
++ fatal_err("cannot read", mod_filename);
+ fclose(fp);
+
+ /* Sanity-check: is this file compressed? */
+@@ -671,8 +637,7 @@ int main(int argc, char **argv)
+ (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);
++ fprintf(stderr, "Warning: %s looks like a compressed file.\n", mod_filename);
+ }
+
+ if (!quiet) printf("Loaded module from %s\n", mod_filename);
+@@ -690,15 +655,12 @@ int main(int argc, char **argv)
+ /* Store the module command line */
+ if (truncate)
+ mod_command_line = clip_path(mod_command_line);
+- sprintf(mod_clp, "%s", mod_command_line);
++ strcpy(mod_clp, 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);
+- }
++ if ((sec = (section_t *)malloc(sizeof (section_t))) == NULL)
++ fatal_err("malloc() for section_t failed");
+ sec->buffer = buffer;
+ sec->start = start;
+ sec->size = size;
+@@ -713,10 +675,8 @@ int main(int argc, char **argv)
+
+ /* 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);
+- }
++ if ((fp = fopen(out_filename, "w")) == NULL)
++ fatal_err("cannot open", out_filename);
+ make_bzImage(sections,
+ kernel_entry,
+ ((address_t)mbi) + mbi_reloc_offset,
+@@ -724,7 +684,8 @@ int main(int argc, char **argv)
+ fclose(fp);
+
+ /* Success! */
+- if(!quiet) printf("Finished.\n");
++ if(!quiet)
++ puts("Finished.");
+ return 0;
+ }
+
+diff --git a/mbootpack.h b/mbootpack.h
+index 361efaf..9f719b5 100644
+--- a/mbootpack.h
++++ b/mbootpack.h
+@@ -37,7 +37,7 @@
+ extern int quiet;
+
+ /* Types */
+-typedef uint32_t address_t;
++typedef uintptr_t address_t;
+
+ typedef struct section_t {
+ char *buffer;