diff options
-rw-r--r-- | sys/stand/mkuboot/Makefile | 10 | ||||
-rw-r--r-- | sys/stand/mkuboot/mkuboot.8 | 79 | ||||
-rw-r--r-- | sys/stand/mkuboot/mkuboot.c | 234 |
3 files changed, 323 insertions, 0 deletions
diff --git a/sys/stand/mkuboot/Makefile b/sys/stand/mkuboot/Makefile new file mode 100644 index 00000000000..25054a4ea51 --- /dev/null +++ b/sys/stand/mkuboot/Makefile @@ -0,0 +1,10 @@ +# $OpenBSD: Makefile,v 1.1 2010/02/12 17:30:41 mk Exp $ + +MAN= mkuboot.8 + +PROG= mkuboot +DPADD= ${LIBZ} +LDADD= -lz +CFLAGS= -DMACHINE_ARCH=\"${MACHINE_ARCH}\" + +.include <bsd.prog.mk> diff --git a/sys/stand/mkuboot/mkuboot.8 b/sys/stand/mkuboot/mkuboot.8 new file mode 100644 index 00000000000..6bc40329fcd --- /dev/null +++ b/sys/stand/mkuboot/mkuboot.8 @@ -0,0 +1,79 @@ +.\" $OpenBSD: mkuboot.8,v 1.1 2010/02/12 17:30:41 mk Exp $ +.\" +.\" Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: February 12 2010 $ +.Dt MKUBOOT 8 +.Os +.Sh NAME +.Nm mkuboot +.Nd create U-Boot files +.Sh SYNOPSIS +.Nm +.Op Fl a Ar arch +.Op Fl e Ar entry +.Op Fl l Ar loadaddr +.Op Fl o Ar os +.Ar infile outfile +.Sh DESCRIPTION +The +.Nm +utility creates images suitable for loading using the U-Boot bootloader. +.Pp +The options are as follows: +.Bl -tag -width xxxxxxxxxxx +.It Fl a Ar arch +Sets the image architecture to +.Ar arch . +For a list of valid arguments, see below. +.It Fl e Ar entry +Sets the entry point to +.Ar entry . +.It Fl l Ar loadaddr +Sets the load address to +.Ar loadaddr . +.It Fl a Ar os +Sets the image OS to +.Ar os . +.Ar os +can be either +.Dq Linux +or +.Dq OpenBSD . +.El +.Pp +The following arguments are valid as the +.Ar arch +parameter: +.Bd -unfilled -offset indent -compact +alpha +amd64 +arm +i386 +m68k +mips +mips64 +powerpc +sparc +sparc64 +superh +.Ed +.Sh HISTORY +An +.Nm +utility first appeared in +.Ox 4.4 +as +.Nm mkboot . diff --git a/sys/stand/mkuboot/mkuboot.c b/sys/stand/mkuboot/mkuboot.c new file mode 100644 index 00000000000..516288a6ee4 --- /dev/null +++ b/sys/stand/mkuboot/mkuboot.c @@ -0,0 +1,234 @@ +/* $OpenBSD: mkuboot.c,v 1.1 2010/02/12 17:30:41 mk Exp $ */ + +/* + * Copyright (c) 2008 Mark Kettenis + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <err.h> +#include <fcntl.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <zlib.h> + +#define IH_OS_OPENBSD 1 /* OpenBSD */ +#define IH_OS_LINUX 5 /* Linux */ + +#define IH_ARCH_ALPHA 1 /* Alpha */ +#define IH_ARCH_ARM 2 /* ARM */ +#define IH_ARCH_I386 3 /* Intel x86 */ +#define IH_ARCH_IA64 4 /* IA64 */ +#define IH_ARCH_MIPS 5 /* MIPS */ +#define IH_ARCH_MIPS64 6 /* MIPS 64 Bit */ +#define IH_ARCH_PPC 7 /* PowerPC */ +#define IH_ARCH_SH 9 /* SuperH */ +#define IH_ARCH_SPARC 10 /* Sparc */ +#define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */ +#define IH_ARCH_M68K 12 /* M68K */ + +#define IH_TYPE_STANDALONE 1 /* Standalone */ +#define IH_TYPE_KERNEL 2 /* OS Kernel Image */ + +#define IH_COMP_NONE 0 /* No compression */ + +#define IH_MAGIC 0x27051956 /* Image Magic Number */ +#define IH_NMLEN 32 /* Image Name Length */ + +struct image_header { + uint32_t ih_magic; + uint32_t ih_hcrc; + uint32_t ih_time; + uint32_t ih_size; + uint32_t ih_load; + uint32_t ih_ep; + uint32_t ih_dcrc; + uint8_t ih_os; + uint8_t ih_arch; + uint8_t ih_type; + uint8_t ih_comp; + uint8_t ih_name[IH_NMLEN]; +}; + +extern char *__progname; + +void usage(void); + +struct arch_map { + int id; + const char *arch; +}; + +static const struct arch_map archmap[] = { + { IH_ARCH_ALPHA, "alpha" }, + { IH_ARCH_IA64, "amd64" }, + { IH_ARCH_ARM, "arm" }, + { IH_ARCH_I386, "i386" }, + { IH_ARCH_M68K, "m68k" }, + { IH_ARCH_MIPS, "mips" }, + { IH_ARCH_MIPS64, "mips64" }, + { IH_ARCH_PPC, "powerpc" }, + { IH_ARCH_SPARC, "sparc" }, + { IH_ARCH_SPARC64, "sparc64" }, + { IH_ARCH_SH, "superh" }, + { 0, NULL } +}; + +struct os_map { + int id; + const char *arch; +}; + +static const struct os_map osmap[] = { + { IH_OS_OPENBSD, "OpenBSD" }, + { IH_OS_LINUX, "Linux" }, + { 0, NULL } +}; + + +int +main(int argc, char *argv[]) +{ + struct image_header ih; + const struct arch_map *mapptr; + const struct os_map *osmapptr; + const char *iname, *oname; + const char *arch = MACHINE_ARCH; + const char *os = "OpenBSD"; + int ifd, ofd; + u_long crc; + ssize_t nbytes; + char buf[BUFSIZ]; + int c, ep, load; + + ep = load = 0; + while ((c = getopt(argc, argv, "a:e:l:o:")) != -1) { + switch (c) { + case 'a': + arch = optarg; + break; + case 'e': + sscanf(optarg, "0x%x", &ep); + break; + case 'l': + sscanf(optarg, "0x%x", &load); + break; + case 'o': + os = optarg; + break; + default: + usage(); + } + } + + for (mapptr = archmap; mapptr->arch; mapptr++) + if (strcasecmp(arch, mapptr->arch) == 0) + break; + + if (mapptr->arch == NULL) { + printf("unknown arch '%s'\n", arch); + usage(); + } + + for (osmapptr = osmap; osmapptr->arch; osmapptr++) + if (strcasecmp(os, osmapptr->arch) == 0) + break; + + if (osmapptr->arch == NULL) { + printf("unknown OS '%s'\n", os); + usage(); + } + + if (argc - optind != 2) + usage(); + + iname = argv[optind++]; + oname = argv[optind++]; + + /* Initialize U-Boot header. */ + bzero(&ih, sizeof ih); + ih.ih_magic = htobe32(IH_MAGIC); + ih.ih_time = htobe32(time(NULL)); + ih.ih_load = htobe32(load); + ih.ih_ep = htobe32(ep); + ih.ih_os = osmapptr->id; + ih.ih_arch = mapptr->id; + ih.ih_type = IH_TYPE_KERNEL; + ih.ih_comp = IH_COMP_NONE; + strlcpy(ih.ih_name, "boot", sizeof ih.ih_name); + + ifd = open(iname, O_RDONLY); + if (ifd < 0) + err(1, "%s", iname); + + ofd = open(oname, O_RDWR | O_TRUNC | O_CREAT, 0644); + if (ofd < 0) + err(1, "%s", oname); + + /* Write initial header. */ + if (write(ofd, &ih, sizeof ih) != sizeof ih) + err(1, "%s", oname); + + /* Copy data, calculating the data CRC as we go. */ + crc = crc32(0L, Z_NULL, 0); + while ((nbytes = read(ifd, buf, sizeof buf)) != 0) { + if (nbytes == -1) + err(1, "%s", iname); + if (write(ofd, buf, nbytes) != nbytes) + err(1, "%s", oname); + crc = crc32(crc, buf, nbytes); + ih.ih_size += nbytes; + } + ih.ih_dcrc = htobe32(crc); + ih.ih_size = htobe32(ih.ih_size); + + /* Calculate header CRC. */ + crc = crc32(0, (void *)&ih, sizeof ih); + ih.ih_hcrc = htobe32(crc); + + /* Write finalized header. */ + if (lseek(ofd, 0, SEEK_SET) != 0) + err(1, "%s", oname); + if (write(ofd, &ih, sizeof ih) != sizeof ih) + err(1, "%s", oname); + + return(0); +} + +void +usage(void) +{ + const struct arch_map *mapptr; + const struct os_map *osmapptr; + + (void)fprintf(stderr, + "usage: %s [-a arch] [-e entry] [-l loadaddr] [-o os] " + "infile outfile\n", __progname); + (void)fprintf(stderr, + "arch is one of:"); + for (mapptr = archmap; mapptr->arch; mapptr++) + (void)fprintf(stderr, " %s", mapptr->arch); + (void)fprintf(stderr, "\n"); + (void)fprintf(stderr, + "os is one of:"); + for (osmapptr = osmap; osmapptr->arch; osmapptr++) + (void)fprintf(stderr, " %s", osmapptr->arch); + (void)fprintf(stderr, "\n"); + + exit(1); +} |