Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/mkubootimage Add support for writing "AArch64 Linux ...
details: https://anonhg.NetBSD.org/src/rev/2317d75f8d6d
branches: trunk
changeset: 359204:2317d75f8d6d
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sun Feb 04 15:44:51 2018 +0000
description:
Add support for writing "AArch64 Linux kernel image" format images.
These images begin with a 64-byte header that includes a load offset,
image size, some flags, and a small (2 word) area at the start for
executable code.
These images are compatible with U-Boot's "booti" command, and can be
used to make U-Boot relocate our kernel to a 2MB aligned base address.
After relocation, U-Boot will jump to the code at the beginning of the
header, where we encode a relative branch forward instruction to branch
to the beginning of the kernel at offset +0x40.
diffstat:
usr.bin/mkubootimage/arm64.h | 67 +++++++++++++
usr.bin/mkubootimage/mkubootimage.1 | 27 ++++-
usr.bin/mkubootimage/mkubootimage.c | 180 ++++++++++++++++++++++++++++++-----
3 files changed, 241 insertions(+), 33 deletions(-)
diffs (truncated from 452 to 300 lines):
diff -r 8f9efe00c0e8 -r 2317d75f8d6d usr.bin/mkubootimage/arm64.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/mkubootimage/arm64.h Sun Feb 04 15:44:51 2018 +0000
@@ -0,0 +1,67 @@
+/* $NetBSD: arm64.h,v 1.1 2018/02/04 15:44:51 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _HAVE_ARM64_H
+#define _HAVE_ARM64_H
+
+/*
+ * AArch64 Linux kernel image header, as specified in
+ * https://www.kernel.org/doc/Documentation/arm64/booting.txt
+ */
+
+/* 64-byte kernel image header */
+struct arm64_image_header {
+ uint32_t code0; /* Executable code */
+ uint32_t code1; /* Executable code */
+ uint64_t text_offset; /* Image load offset */
+ uint64_t image_size; /* Effective image size */
+ uint64_t flags; /* kernel flags */
+ uint64_t res2; /* reserved */
+ uint64_t res3; /* reserved */
+ uint64_t res4; /* reserved */
+ uint32_t magic; /* Magic number ("ARM\x64") */
+ uint32_t res5; /* reserved (used for PE COFF offset) */
+};
+
+/* Kernel flags */
+#define ARM64_FLAGS_ENDIAN_BE __BIT(0)
+#define ARM64_FLAGS_PAGE_SIZE __BITS(2,1)
+#define ARM64_FLAGS_PAGE_SIZE_UNSPEC 0
+#define ARM64_FLAGS_PAGE_SIZE_4K 1
+#define ARM64_FLAGS_PAGE_SIZE_16K 2
+#define ARM64_FLAGS_PAGE_SIZE_64K 3
+#define ARM64_FLAGS_PHYS_PLACEMENT __BIT(3)
+#define ARM64_FLAGS_PHYS_PLACEMENT_DRAM_BASE 0
+#define ARM64_FLAGS_PHYS_PLACEMENT_ANY 1
+
+/* Magic */
+#define ARM64_MAGIC 0x644d5241
+
+/* Executable code. Program relative branch forward 64 bytes. */
+#define ARM64_CODE0 0x14000010
+
+#endif /* !_HAVE_ARM64_H */
diff -r 8f9efe00c0e8 -r 2317d75f8d6d usr.bin/mkubootimage/mkubootimage.1
--- a/usr.bin/mkubootimage/mkubootimage.1 Sun Feb 04 11:08:16 2018 +0000
+++ b/usr.bin/mkubootimage/mkubootimage.1 Sun Feb 04 15:44:51 2018 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: mkubootimage.1,v 1.11 2017/09/29 21:18:28 jmcneill Exp $
+.\" $NetBSD: mkubootimage.1,v 1.12 2018/02/04 15:44:51 jmcneill Exp $
.\"
.\" Copyright (c) 2012 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd September 29, 2017
+.Dd February 4, 2018
.Dt MKUBOOTIMAGE 1
.Os
.Sh NAME
@@ -41,6 +41,7 @@
.Op Fl C Po bz2 Ns | Ns gz Ns | Ns lzma Ns | Ns lzo Ns | Ns none Pc
.Op Fl E Ar address
.Op Fl e Ar address
+.Op Fl f Po arm64 Ns | Ns uimg Pc
.Op Fl m Ar magic
.Fl n Ar image
.Op Fl O Po freebsd Ns | Ns linux Ns | Ns netbsd Ns | Ns openbsd Pc
@@ -57,12 +58,16 @@
.Bl -tag -width indent
.It Fl A No ( arm Ns | Ns arm64 Ns | Ns i386 Ns | Ns mips Ns | Ns mips64 Ns | Ns or1k Ns | Ns powerpc Ns | Ns sh )
Defines the architecture.
-This is required.
+This is required for
+.Qq uimg
+format images.
.It Fl a Ar address
Sets the image load address.
This is an integer between 0 and
.Dv UINT32_MAX .
-This is required for all image types except for script, ramdisk, and kernel_noload.
+This is required for all
+.Qq uimg
+image types except for script, ramdisk, and kernel_noload.
.It Fl C No ( bz2 Ns | Ns gz Ns | Ns lzma Ns | Ns lzo Ns | Ns none )
Defines the compression.
The default is
@@ -93,10 +98,16 @@
are not set, the entry point defaults to the
image load address
.Pq Fl a .
+.It Fl f No ( arm64 Ns | Ns uimg )
+Defines the output image format type.
+The default is
+.Qq uimg .
.It Fl h
Display the usage and exit.
.It Fl m Ar magic
-Set the magic.
+Set the magic used for
+.Qq uimg
+format images.
This is an integer between 0 and
.Dv UINT32_MAX .
The default is
@@ -110,7 +121,9 @@
.Qq netbsd .
.It Fl T No ( fs Ns | Ns kernel Ns | Ns kernel_noload Ns | Ns ramdisk Ns | Ns standalone Ns | Ns script )
Defines the image type.
-This is required.
+This is required for
+.Qq uimg
+format images.
.El
.Pp
The required
@@ -161,7 +174,7 @@
The
.Nm
utility was originally written by
-.An Jared D. McNeill .
+.An Jared McNeill .
This manual page was written by
.An Jeremy C. Reed .
.\" .Sh CAVEATS
diff -r 8f9efe00c0e8 -r 2317d75f8d6d usr.bin/mkubootimage/mkubootimage.c
--- a/usr.bin/mkubootimage/mkubootimage.c Sun Feb 04 11:08:16 2018 +0000
+++ b/usr.bin/mkubootimage/mkubootimage.c Sun Feb 04 15:44:51 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mkubootimage.c,v 1.22 2017/11/05 11:07:32 jmcneill Exp $ */
+/* $NetBSD: mkubootimage.c,v 1.23 2018/02/04 15:44:51 jmcneill Exp $ */
/*-
* Copyright (c) 2010 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -30,15 +30,17 @@
#endif
#include <sys/cdefs.h>
-__RCSID("$NetBSD: mkubootimage.c,v 1.22 2017/11/05 11:07:32 jmcneill Exp $");
+__RCSID("$NetBSD: mkubootimage.c,v 1.23 2018/02/04 15:44:51 jmcneill Exp $");
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/endian.h>
+#include <sys/param.h>
#include <sys/uio.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
@@ -48,11 +50,18 @@
#include <unistd.h>
#include "uboot.h"
+#include "arm64.h"
#ifndef __arraycount
#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0]))
#endif
+enum image_format {
+ FMT_UNKNOWN,
+ FMT_UIMG, /* Legacy U-Boot image */
+ FMT_ARM64, /* Linux ARM64 image (booti) */
+};
+
extern uint32_t crc32(const void *, size_t);
extern uint32_t crc32v(const struct iovec *, int);
@@ -64,6 +73,41 @@
static uint32_t image_entrypoint = 0;
static char *image_name;
static uint32_t image_magic = IH_MAGIC;
+static enum image_format image_format = FMT_UIMG;
+
+static const struct uboot_image_format {
+ enum image_format format;
+ const char *name;
+} uboot_image_format[] = {
+ { FMT_UIMG, "uimg" },
+ { FMT_ARM64, "arm64" },
+};
+
+static enum image_format
+get_image_format(const char *name)
+{
+ unsigned int i;
+
+ for (i = 0; i < __arraycount(uboot_image_format); i++) {
+ if (strcmp(uboot_image_format[i].name, name) == 0)
+ return uboot_image_format[i].format;
+ }
+
+ return FMT_UNKNOWN;
+}
+
+static const char *
+get_image_format_name(enum image_format format)
+{
+ unsigned int i;
+
+ for (i = 0; i < __arraycount(uboot_image_format); i++) {
+ if (uboot_image_format[i].format == format)
+ return uboot_image_format[i].name;
+ }
+
+ return "Unknown";
+}
static const struct uboot_os {
enum uboot_image_os os;
@@ -225,13 +269,14 @@
fprintf(stderr, " -O <openbsd|netbsd|freebsd|linux>");
fprintf(stderr, " -T <standalone|kernel|kernel_noload|ramdisk|fs|script>");
fprintf(stderr, " -a <addr> [-e <ep>] [-m <magic>] -n <name>");
+ fprintf(stderr, " [-f <uimg|arm64>]");
fprintf(stderr, " <srcfile> <dstfile>\n");
exit(EXIT_FAILURE);
}
static void
-dump_header(struct uboot_image_header *hdr)
+dump_header_uimg(struct uboot_image_header *hdr)
{
time_t tm = ntohl(hdr->ih_time);
@@ -254,7 +299,7 @@
}
static int
-generate_header(struct uboot_image_header *hdr, int kernel_fd)
+generate_header_uimg(struct uboot_image_header *hdr, int kernel_fd)
{
uint8_t *p;
struct stat st;
@@ -310,13 +355,56 @@
crc = crc32((void *)hdr, sizeof(*hdr));
hdr->ih_hcrc = htonl(crc);
- dump_header(hdr);
+ dump_header_uimg(hdr);
+
+ return 0;
+}
+
+static void
+dump_header_arm64(struct arm64_image_header *hdr)
+{
+ printf(" magic: 0x%" PRIx32 "\n", le32toh(hdr->magic));
+ printf(" text offset: 0x%" PRIx64 "\n", le64toh(hdr->text_offset));
+ printf(" image size: %" PRIu64 "\n", le64toh(hdr->image_size));
+ printf(" flags: 0x%" PRIx64 "\n", le64toh(hdr->flags));
+}
+
+static int
+generate_header_arm64(struct arm64_image_header *hdr, int kernel_fd)
+{
+ struct stat st;
+ uint32_t flags;
+ int error;
+
+ error = fstat(kernel_fd, &st);
+ if (error == -1) {
+ perror("stat");
+ return errno;
+ }
+
Home |
Main Index |
Thread Index |
Old Index