685 lines
25 KiB
Diff
685 lines
25 KiB
Diff
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;
|