summaryrefslogtreecommitdiffstats
path: root/arch/arm/lib32/bootz.c
diff options
context:
space:
mode:
authorRaphael Poggi <poggi.raph@gmail.com>2016-07-04 13:52:46 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2016-07-06 11:23:48 +0200
commite1287b1a8b27d366f459e890fb260deea2906749 (patch)
treeb2cca10b510e578438db046639fb6aa0f6e0d043 /arch/arm/lib32/bootz.c
parent375170a3c9fad9d119a0a729da87b6285a2731ca (diff)
downloadbarebox-e1287b1a8b27d366f459e890fb260deea2906749.tar.gz
barebox-e1287b1a8b27d366f459e890fb260deea2906749.tar.xz
arm: rework lib directory to support arm64
This commit create a common directory, lib/, for arm and arm64 common code. It also create lib32/ and lib64/ for 32bit and 64bit code respectively. Signed-off-by: Raphael Poggi <poggi.raph@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/lib32/bootz.c')
-rw-r--r--arch/arm/lib32/bootz.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/arch/arm/lib32/bootz.c b/arch/arm/lib32/bootz.c
new file mode 100644
index 0000000000..5167c9d20d
--- /dev/null
+++ b/arch/arm/lib32/bootz.c
@@ -0,0 +1,136 @@
+#include <common.h>
+#include <command.h>
+#include <fs.h>
+#include <of.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <malloc.h>
+#include <linux/sizes.h>
+#include <asm/byteorder.h>
+#include <asm/armlinux.h>
+#include <asm/system.h>
+#include <asm-generic/memory_layout.h>
+#include <memory.h>
+
+struct zimage_header {
+ u32 unused[9];
+ u32 magic;
+ u32 start;
+ u32 end;
+};
+
+#define ZIMAGE_MAGIC 0x016F2818
+
+static int do_bootz(int argc, char *argv[])
+{
+ int fd, ret, swap = 0;
+ struct zimage_header __header, *header;
+ void *zimage;
+ void *oftree = NULL;
+ u32 end;
+ int usemap = 0;
+ struct memory_bank *bank = list_first_entry(&memory_banks, struct memory_bank, list);
+ struct resource *res = NULL;
+
+ if (argc != 2)
+ return COMMAND_ERROR_USAGE;
+
+ fd = open(argv[1], O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+
+ /*
+ * We can save the memcpy of the zImage if it already is in
+ * the first 128MB of SDRAM.
+ */
+ zimage = memmap(fd, PROT_READ);
+ if (zimage && (unsigned long)zimage >= bank->start &&
+ (unsigned long)zimage < bank->start + SZ_128M) {
+ usemap = 1;
+ header = zimage;
+ }
+
+ if (!usemap) {
+ header = &__header;
+ ret = read(fd, header, sizeof(*header));
+ if (ret < sizeof(*header)) {
+ printf("could not read %s\n", argv[1]);
+ goto err_out;
+ }
+ }
+
+ switch (header->magic) {
+#ifdef CONFIG_BOOT_ENDIANNESS_SWITCH
+ case swab32(ZIMAGE_MAGIC):
+ swap = 1;
+ /* fall through */
+#endif
+ case ZIMAGE_MAGIC:
+ break;
+ default:
+ printf("invalid magic 0x%08x\n", header->magic);
+ goto err_out;
+ }
+
+ end = header->end;
+
+ if (swap)
+ end = swab32(end);
+
+ if (!usemap) {
+ if (bank->size <= SZ_128M) {
+ zimage = xmalloc(end);
+ } else {
+ zimage = (void *)bank->start + SZ_8M;
+ res = request_sdram_region("zimage",
+ bank->start + SZ_8M, end);
+ if (!res) {
+ printf("can't request region for kernel\n");
+ goto err_out1;
+ }
+ }
+
+ memcpy(zimage, header, sizeof(*header));
+
+ ret = read(fd, zimage + sizeof(*header), end - sizeof(*header));
+ if (ret < end - sizeof(*header)) {
+ printf("could not read %s\n", argv[1]);
+ goto err_out2;
+ }
+ }
+
+ if (swap) {
+ void *ptr;
+ for (ptr = zimage; ptr < zimage + end; ptr += 4)
+ *(u32 *)ptr = swab32(*(u32 *)ptr);
+ }
+
+ printf("loaded zImage from %s with size %d\n", argv[1], end);
+#ifdef CONFIG_OFTREE
+ oftree = of_get_fixed_tree(NULL);
+#endif
+
+ start_linux(zimage, swap, 0, 0, oftree);
+
+ return 0;
+
+err_out2:
+ if (res)
+ release_sdram_region(res);
+err_out1:
+ free(zimage);
+err_out:
+ close(fd);
+
+ return 1;
+}
+
+BAREBOX_CMD_START(bootz)
+ .cmd = do_bootz,
+ BAREBOX_CMD_DESC("boot Linux zImage")
+ BAREBOX_CMD_OPTS("FILE")
+ BAREBOX_CMD_GROUP(CMD_GRP_BOOT)
+BAREBOX_CMD_END
+