blob: ae379754943b936821c20612fc1f1c3279abb7ad [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Tom Rini5db28902016-08-12 08:31:15 -04002/*
3 * (C) Copyright 2000-2009
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
Tom Rini5db28902016-08-12 08:31:15 -04005 */
6
7#include <common.h>
8#include <bootm.h>
9#include <command.h>
10#include <image.h>
Simon Glass36bf4462019-11-14 12:57:42 -070011#include <irq_func.h>
Tom Rini5db28902016-08-12 08:31:15 -040012#include <lmb.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060013#include <log.h>
Tom Rini5db28902016-08-12 08:31:15 -040014#include <mapmem.h>
Masahiro Yamada28085762017-03-09 16:28:25 +090015#include <linux/kernel.h>
16#include <linux/sizes.h>
Tom Rini5db28902016-08-12 08:31:15 -040017
Atish Patra414c34e2020-03-05 16:24:23 -080018DECLARE_GLOBAL_DATA_PTR;
Tom Rini5db28902016-08-12 08:31:15 -040019/*
20 * Image booting support
21 */
Simon Glass09140112020-05-10 11:40:03 -060022static int booti_start(struct cmd_tbl *cmdtp, int flag, int argc,
23 char *const argv[], bootm_headers_t *images)
Tom Rini5db28902016-08-12 08:31:15 -040024{
25 int ret;
Bin Chen6808ef92018-01-27 16:59:09 +110026 ulong ld;
27 ulong relocated_addr;
28 ulong image_size;
Atish Patra414c34e2020-03-05 16:24:23 -080029 uint8_t *temp;
30 ulong dest;
31 ulong dest_end;
32 unsigned long comp_len;
33 unsigned long decomp_len;
34 int ctype;
Tom Rini5db28902016-08-12 08:31:15 -040035
36 ret = do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START,
37 images, 1);
38
39 /* Setup Linux kernel Image entry point */
40 if (!argc) {
Simon Glassbb872dd2019-12-28 10:45:02 -070041 ld = image_load_addr;
Tom Rini5db28902016-08-12 08:31:15 -040042 debug("* kernel: default image load address = 0x%08lx\n",
Simon Glassbb872dd2019-12-28 10:45:02 -070043 image_load_addr);
Tom Rini5db28902016-08-12 08:31:15 -040044 } else {
Bin Chen6808ef92018-01-27 16:59:09 +110045 ld = simple_strtoul(argv[0], NULL, 16);
Masahiro Yamadabf14d9a2018-02-13 12:10:02 +090046 debug("* kernel: cmdline image address = 0x%08lx\n", ld);
Tom Rini5db28902016-08-12 08:31:15 -040047 }
48
Atish Patra414c34e2020-03-05 16:24:23 -080049 temp = map_sysmem(ld, 0);
50 ctype = image_decomp_type(temp, 2);
51 if (ctype > 0) {
52 dest = env_get_ulong("kernel_comp_addr_r", 16, 0);
53 comp_len = env_get_ulong("kernel_comp_size", 16, 0);
54 if (!dest || !comp_len) {
55 puts("kernel_comp_addr_r or kernel_comp_size is not provided!\n");
56 return -EINVAL;
57 }
58 if (dest < gd->ram_base || dest > gd->ram_top) {
59 puts("kernel_comp_addr_r is outside of DRAM range!\n");
60 return -EINVAL;
61 }
62
63 debug("kernel image compression type %d size = 0x%08lx address = 0x%08lx\n",
64 ctype, comp_len, (ulong)dest);
65 decomp_len = comp_len * 10;
66 ret = image_decomp(ctype, 0, ld, IH_TYPE_KERNEL,
67 (void *)dest, (void *)ld, comp_len,
68 decomp_len, &dest_end);
69 if (ret)
70 return ret;
71 /* dest_end contains the uncompressed Image size */
72 memmove((void *) ld, (void *)dest, dest_end);
73 }
74 unmap_sysmem((void *)ld);
75
Marek Vasut7f13b372018-06-13 06:13:32 +020076 ret = booti_setup(ld, &relocated_addr, &image_size, false);
Tom Rini5db28902016-08-12 08:31:15 -040077 if (ret != 0)
78 return 1;
79
Bin Chen6808ef92018-01-27 16:59:09 +110080 /* Handle BOOTM_STATE_LOADOS */
81 if (relocated_addr != ld) {
82 debug("Moving Image from 0x%lx to 0x%lx\n", ld, relocated_addr);
83 memmove((void *)relocated_addr, (void *)ld, image_size);
84 }
Tom Rini5db28902016-08-12 08:31:15 -040085
Bin Chen6808ef92018-01-27 16:59:09 +110086 images->ep = relocated_addr;
Lokesh Vutla683cdd62019-10-07 13:52:16 +053087 images->os.start = relocated_addr;
88 images->os.end = relocated_addr + image_size;
89
Bin Chen6808ef92018-01-27 16:59:09 +110090 lmb_reserve(&images->lmb, images->ep, le32_to_cpu(image_size));
Tom Rini5db28902016-08-12 08:31:15 -040091
92 /*
93 * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
94 * have a header that provide this informaiton.
95 */
96 if (bootm_find_images(flag, argc, argv))
97 return 1;
98
99 return 0;
100}
101
Simon Glass09140112020-05-10 11:40:03 -0600102int do_booti(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
Tom Rini5db28902016-08-12 08:31:15 -0400103{
104 int ret;
105
106 /* Consume 'booti' */
107 argc--; argv++;
108
109 if (booti_start(cmdtp, flag, argc, argv, &images))
110 return 1;
111
112 /*
113 * We are doing the BOOTM_STATE_LOADOS state ourselves, so must
114 * disable interrupts ourselves
115 */
116 bootm_disable_interrupts();
117
118 images.os.os = IH_OS_LINUX;
Atish Patra3cedc972019-05-06 17:49:39 -0700119#ifdef CONFIG_RISCV_SMODE
120 images.os.arch = IH_ARCH_RISCV;
121#elif CONFIG_ARM64
Scott Wood0fff19a2017-01-26 16:55:44 -0600122 images.os.arch = IH_ARCH_ARM64;
Atish Patra3cedc972019-05-06 17:49:39 -0700123#endif
Tom Rini5db28902016-08-12 08:31:15 -0400124 ret = do_bootm_states(cmdtp, flag, argc, argv,
Cédric Schieli4943dc22017-01-23 16:51:45 +0100125#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
126 BOOTM_STATE_RAMDISK |
127#endif
Tom Rini5db28902016-08-12 08:31:15 -0400128 BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
129 BOOTM_STATE_OS_GO,
130 &images, 1);
131
132 return ret;
133}
134
135#ifdef CONFIG_SYS_LONGHELP
136static char booti_help_text[] =
137 "[addr [initrd[:size]] [fdt]]\n"
Atish Patra414c34e2020-03-05 16:24:23 -0800138 " - boot Linux flat or compressed 'Image' stored at 'addr'\n"
Tom Rini5db28902016-08-12 08:31:15 -0400139 "\tThe argument 'initrd' is optional and specifies the address\n"
140 "\tof an initrd in memory. The optional parameter ':size' allows\n"
141 "\tspecifying the size of a RAW initrd.\n"
Atish Patra414c34e2020-03-05 16:24:23 -0800142 "\tCurrently only booting from gz, bz2, lzma and lz4 compression\n"
143 "\ttypes are supported. In order to boot from any of these compressed\n"
144 "\timages, user have to set kernel_comp_addr_r and kernel_comp_size enviornment\n"
145 "\tvariables beforehand.\n"
Tom Rini5db28902016-08-12 08:31:15 -0400146#if defined(CONFIG_OF_LIBFDT)
147 "\tSince booting a Linux kernel requires a flat device-tree, a\n"
148 "\tthird argument providing the address of the device-tree blob\n"
149 "\tis required. To boot a kernel with a device-tree blob but\n"
150 "\twithout an initrd image, use a '-' for the initrd argument.\n"
151#endif
152 "";
153#endif
154
155U_BOOT_CMD(
156 booti, CONFIG_SYS_MAXARGS, 1, do_booti,
Atish Patra3cedc972019-05-06 17:49:39 -0700157 "boot Linux kernel 'Image' format from memory", booti_help_text
Tom Rini5db28902016-08-12 08:31:15 -0400158);