diff options
-rw-r--r-- | arch/arm/Kconfig | 5 | ||||
-rw-r--r-- | arch/arm/include/asm/armlinux.h | 6 | ||||
-rw-r--r-- | arch/arm/lib/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/lib/armlinux.c | 215 | ||||
-rw-r--r-- | arch/arm/lib/bootm.c | 92 | ||||
-rw-r--r-- | arch/arm/lib/bootu.c | 38 | ||||
-rw-r--r-- | arch/arm/lib/bootz.c | 100 |
7 files changed, 248 insertions, 213 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index aae0e992c8..4392620419 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -21,6 +21,11 @@ config ARM config ARM_AMBA bool +config ARM_LINUX + bool + default y + depends on CMD_BOOTZ || CMD_BOOTU || CMD_BOOTM + menu "System Type" choice diff --git a/arch/arm/include/asm/armlinux.h b/arch/arm/include/asm/armlinux.h index 2765f0dfe2..3cab209d60 100644 --- a/arch/arm/include/asm/armlinux.h +++ b/arch/arm/include/asm/armlinux.h @@ -25,9 +25,13 @@ static inline void armlinux_set_revision(unsigned int rev) { } -void armlinux_set_serial(u64 serial) +static inline void armlinux_set_serial(u64 serial) { } #endif +struct image_data; + +void start_linux(void *adr, int swap, struct image_data *data); + #endif /* __ARCH_ARMLINUX_H */ diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 3a010838b7..9383ae1472 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -1,4 +1,7 @@ -obj-y += armlinux.o +obj-$(CONFIG_ARM_LINUX) += armlinux.o +obj-$(CONFIG_CMD_BOOTM) += bootm.o +obj-$(CONFIG_CMD_BOOTZ) += bootz.o +obj-$(CONFIG_CMD_BOOTU) += bootu.o obj-y += div0.o obj-y += findbit.o obj-y += arm.o diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c index 9927b766d9..ce1cc6bce3 100644 --- a/arch/arm/lib/armlinux.c +++ b/arch/arm/lib/armlinux.c @@ -215,162 +215,11 @@ void armlinux_set_serial(u64 serial) system_serial = serial; } -#ifdef CONFIG_CMD_BOOTM -static int do_bootm_linux(struct image_data *data) +void start_linux(void *adr, int swap, struct image_data *data) { - void (*theKernel)(int zero, int arch, void *params); - image_header_t *os_header = &data->os->header; + void (*kernel)(int zero, int arch, void *params) = adr; - if (image_get_type(os_header) == IH_TYPE_MULTI) { - printf("Multifile images not handled at the moment\n"); - return -1; - } - - if (armlinux_architecture == 0) { - printf("arm architecture not set. Please specify with -a option\n"); - return -1; - } - - if (!armlinux_bootparams) { - printf("Bootparams not set. Please fix your board code\n"); - return -1; - } - - theKernel = (void *)image_get_ep(os_header); - - debug("## Transferring control to Linux (at address 0x%p) ...\n", - theKernel); - - setup_tags(data, 0); - - if (relocate_image(data->os, (void *)image_get_load(os_header))) - return -1; - - if (data->initrd) - if (relocate_image(data->initrd, (void *)image_get_load(&data->initrd->header))) - return -1; - - /* we assume that the kernel is in place */ - printf("\nStarting kernel %s...\n\n", data->initrd ? "with initrd " : ""); - - shutdown_barebox(); - theKernel (0, armlinux_architecture, armlinux_bootparams); - - return -1; -} - -static int image_handle_cmdline_parse(struct image_data *data, int opt, - char *optarg) -{ - int ret = 1; - - switch (opt) { - case 'a': - armlinux_architecture = simple_strtoul(optarg, NULL, 0); - ret = 0; - break; - case 'R': - system_rev = simple_strtoul(optarg, NULL, 0); - ret = 0; - break; - default: - break; - } - - return ret; -} - -static struct image_handler handler = { - .cmdline_options = "a:R:", - .cmdline_parse = image_handle_cmdline_parse, - .help_string = " -a <arch> use architecture number <arch>\n" - " -R <system_rev> use system revison <system_rev>\n", - - .bootm = do_bootm_linux, - .image_type = IH_OS_LINUX, -}; - -static int armlinux_register_image_handler(void) -{ - return register_image_handler(&handler); -} - -late_initcall(armlinux_register_image_handler); -#endif /* CONFIG_CMD_BOOTM */ - -#ifdef CONFIG_CMD_BOOTZ -struct zimage_header { - u32 unused[9]; - u32 magic; - u32 start; - u32 end; -}; - -#define ZIMAGE_MAGIC 0x016F2818 - -static int do_bootz(struct command *cmdtp, int argc, char *argv[]) -{ - void (*theKernel)(int zero, int arch, void *params); - int fd, ret, swap = 0; - struct zimage_header header; - void *zimage; - u32 end; - - if (argc != 2) { - barebox_cmd_usage(cmdtp); - return 1; - } - - fd = open(argv[1], O_RDONLY); - if (fd < 0) { - perror("open"); - return 1; - } - - 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); - - zimage = xmalloc(end); - 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_out1; - } - - if (swap) { - void *ptr; - for (ptr = zimage; ptr < zimage + end; ptr += 4) - *(u32 *)ptr = swab32(*(u32 *)ptr); - } - - theKernel = zimage; - - printf("loaded zImage from %s with size %d\n", argv[1], end); - - setup_tags(NULL, swap); + setup_tags(data, swap); shutdown_barebox(); if (swap) { @@ -380,61 +229,5 @@ static int do_bootz(struct command *cmdtp, int argc, char *argv[]) __asm__ __volatile__("mcr p15, 0, %0, c1, c0" :: "r" (reg)); } - theKernel(0, armlinux_architecture, armlinux_bootparams); - - return 0; - -err_out1: - free(zimage); -err_out: - close(fd); - - return 1; + kernel(0, armlinux_architecture, armlinux_bootparams); } - -static const __maybe_unused char cmd_bootz_help[] = -"Usage: bootz [FILE]\n" -"Boot a Linux zImage\n"; - -BAREBOX_CMD_START(bootz) - .cmd = do_bootz, - .usage = "bootz - start a zImage", - BAREBOX_CMD_HELP(cmd_bootz_help) -BAREBOX_CMD_END -#endif /* CONFIG_CMD_BOOTZ */ - -#ifdef CONFIG_CMD_BOOTU -static int do_bootu(struct command *cmdtp, int argc, char *argv[]) -{ - void (*theKernel)(int zero, int arch, void *params) = NULL; - int fd; - - if (argc != 2) { - barebox_cmd_usage(cmdtp); - return 1; - } - - fd = open(argv[1], O_RDONLY); - if (fd > 0) - theKernel = (void *)memmap(fd, PROT_READ); - - if (!theKernel) - theKernel = (void *)simple_strtoul(argv[1], NULL, 0); - - setup_tags(NULL, 0); - - shutdown_barebox(); - theKernel(0, armlinux_architecture, armlinux_bootparams); - - return 1; -} - -static const __maybe_unused char cmd_bootu_help[] = -"Usage: bootu <address>\n"; - -BAREBOX_CMD_START(bootu) - .cmd = do_bootu, - .usage = "bootu - start a raw linux image", - BAREBOX_CMD_HELP(cmd_bootu_help) -BAREBOX_CMD_END -#endif /* CONFIG_CMD_BOOTU */ diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c new file mode 100644 index 0000000000..b09fe70e3e --- /dev/null +++ b/arch/arm/lib/bootm.c @@ -0,0 +1,92 @@ +#include <boot.h> +#include <common.h> +#include <command.h> +#include <driver.h> +#include <environment.h> +#include <image.h> +#include <zlib.h> +#include <init.h> +#include <fs.h> +#include <linux/list.h> +#include <xfuncs.h> +#include <malloc.h> +#include <fcntl.h> +#include <errno.h> + +#include <asm/byteorder.h> +#include <asm/global_data.h> +#include <asm/setup.h> +#include <asm/barebox-arm.h> +#include <asm/armlinux.h> +#include <asm/system.h> + +static int do_bootm_linux(struct image_data *data) +{ + void (*theKernel)(int zero, int arch, void *params); + image_header_t *os_header = &data->os->header; + + if (image_get_type(os_header) == IH_TYPE_MULTI) { + printf("Multifile images not handled at the moment\n"); + return -1; + } + + theKernel = (void *)image_get_ep(os_header); + + debug("## Transferring control to Linux (at address 0x%p) ...\n", + theKernel); + + if (relocate_image(data->os, (void *)image_get_load(os_header))) + return -1; + + if (data->initrd) + if (relocate_image(data->initrd, (void *)image_get_load(&data->initrd->header))) + return -1; + + /* we assume that the kernel is in place */ + printf("\nStarting kernel %s...\n\n", data->initrd ? "with initrd " : ""); + + start_linux(theKernel, 0, data); + + return -1; +} + +static int image_handle_cmdline_parse(struct image_data *data, int opt, + char *optarg) +{ + int ret = 1; + int no; + + switch (opt) { + case 'a': + no = simple_strtoul(optarg, NULL, 0); + armlinux_set_architecture(no); + ret = 0; + break; + case 'R': + no = simple_strtoul(optarg, NULL, 0); + armlinux_set_revision(no); + ret = 0; + break; + default: + break; + } + + return ret; +} + +static struct image_handler handler = { + .cmdline_options = "a:R:", + .cmdline_parse = image_handle_cmdline_parse, + .help_string = " -a <arch> use architecture number <arch>\n" + " -R <system_rev> use system revison <system_rev>\n", + + .bootm = do_bootm_linux, + .image_type = IH_OS_LINUX, +}; + +static int armlinux_register_image_handler(void) +{ + return register_image_handler(&handler); +} + +late_initcall(armlinux_register_image_handler); diff --git a/arch/arm/lib/bootu.c b/arch/arm/lib/bootu.c new file mode 100644 index 0000000000..e97ded0e47 --- /dev/null +++ b/arch/arm/lib/bootu.c @@ -0,0 +1,38 @@ +#include <common.h> +#include <command.h> +#include <fs.h> +#include <fcntl.h> +#include <errno.h> +#include <asm/armlinux.h> + +static int do_bootu(struct command *cmdtp, int argc, char *argv[]) +{ + int fd; + void *kernel = NULL; + + if (argc != 2) { + barebox_cmd_usage(cmdtp); + return 1; + } + + fd = open(argv[1], O_RDONLY); + if (fd > 0) + kernel = (void *)memmap(fd, PROT_READ); + + if (!kernel) + kernel = (void *)simple_strtoul(argv[1], NULL, 0); + + start_linux(kernel, 0, NULL); + + return 1; +} + +static const __maybe_unused char cmd_bootu_help[] = +"Usage: bootu <address>\n"; + +BAREBOX_CMD_START(bootu) + .cmd = do_bootu, + .usage = "bootu - start a raw linux image", + BAREBOX_CMD_HELP(cmd_bootu_help) +BAREBOX_CMD_END + diff --git a/arch/arm/lib/bootz.c b/arch/arm/lib/bootz.c new file mode 100644 index 0000000000..cd8f4958f8 --- /dev/null +++ b/arch/arm/lib/bootz.c @@ -0,0 +1,100 @@ +#include <common.h> +#include <command.h> +#include <fs.h> +#include <fcntl.h> +#include <errno.h> +#include <malloc.h> +#include <asm/byteorder.h> +#include <asm/armlinux.h> +#include <asm/system.h> + +struct zimage_header { + u32 unused[9]; + u32 magic; + u32 start; + u32 end; +}; + +#define ZIMAGE_MAGIC 0x016F2818 + +static int do_bootz(struct command *cmdtp, int argc, char *argv[]) +{ + int fd, ret, swap = 0; + struct zimage_header header; + void *zimage; + u32 end; + + if (argc != 2) { + barebox_cmd_usage(cmdtp); + return 1; + } + + fd = open(argv[1], O_RDONLY); + if (fd < 0) { + perror("open"); + return 1; + } + + 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); + + zimage = xmalloc(end); + 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_out1; + } + + 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); + + start_linux(zimage, swap, NULL); + + return 0; + +err_out1: + free(zimage); +err_out: + close(fd); + + return 1; +} + +static const __maybe_unused char cmd_bootz_help[] = +"Usage: bootz [FILE]\n" +"Boot a Linux zImage\n"; + +BAREBOX_CMD_START(bootz) + .cmd = do_bootz, + .usage = "bootz - start a zImage", + BAREBOX_CMD_HELP(cmd_bootz_help) +BAREBOX_CMD_END + |