blob: 4fff8cfcf69f95440a6ba9bec28f18491bf2bbc0 [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>
13#include <mapmem.h>
Masahiro Yamada28085762017-03-09 16:28:25 +090014#include <linux/kernel.h>
15#include <linux/sizes.h>
Tom Rini5db28902016-08-12 08:31:15 -040016
Atish Patra414c34e2020-03-05 16:24:23 -080017DECLARE_GLOBAL_DATA_PTR;
Tom Rini5db28902016-08-12 08:31:15 -040018/*
19 * Image booting support
20 */
21static int booti_start(cmd_tbl_t *cmdtp, int flag, int argc,
22 char * const argv[], bootm_headers_t *images)
23{
24 int ret;
Bin Chen6808ef92018-01-27 16:59:09 +110025 ulong ld;
26 ulong relocated_addr;
27 ulong image_size;
Atish Patra414c34e2020-03-05 16:24:23 -080028 uint8_t *temp;
29 ulong dest;
30 ulong dest_end;
31 unsigned long comp_len;
32 unsigned long decomp_len;
33 int ctype;
Tom Rini5db28902016-08-12 08:31:15 -040034
35 ret = do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START,
36 images, 1);
37
38 /* Setup Linux kernel Image entry point */
39 if (!argc) {
Simon Glassbb872dd2019-12-28 10:45:02 -070040 ld = image_load_addr;
Tom Rini5db28902016-08-12 08:31:15 -040041 debug("* kernel: default image load address = 0x%08lx\n",
Simon Glassbb872dd2019-12-28 10:45:02 -070042 image_load_addr);
Tom Rini5db28902016-08-12 08:31:15 -040043 } else {
Bin Chen6808ef92018-01-27 16:59:09 +110044 ld = simple_strtoul(argv[0], NULL, 16);
Masahiro Yamadabf14d9a2018-02-13 12:10:02 +090045 debug("* kernel: cmdline image address = 0x%08lx\n", ld);
Tom Rini5db28902016-08-12 08:31:15 -040046 }
47
Atish Patra414c34e2020-03-05 16:24:23 -080048 temp = map_sysmem(ld, 0);
49 ctype = image_decomp_type(temp, 2);
50 if (ctype > 0) {
51 dest = env_get_ulong("kernel_comp_addr_r", 16, 0);
52 comp_len = env_get_ulong("kernel_comp_size", 16, 0);
53 if (!dest || !comp_len) {
54 puts("kernel_comp_addr_r or kernel_comp_size is not provided!\n");
55 return -EINVAL;
56 }
57 if (dest < gd->ram_base || dest > gd->ram_top) {
58 puts("kernel_comp_addr_r is outside of DRAM range!\n");
59 return -EINVAL;
60 }
61
62 debug("kernel image compression type %d size = 0x%08lx address = 0x%08lx\n",
63 ctype, comp_len, (ulong)dest);
64 decomp_len = comp_len * 10;
65 ret = image_decomp(ctype, 0, ld, IH_TYPE_KERNEL,
66 (void *)dest, (void *)ld, comp_len,
67 decomp_len, &dest_end);
68 if (ret)
69 return ret;
70 /* dest_end contains the uncompressed Image size */
71 memmove((void *) ld, (void *)dest, dest_end);
72 }
73 unmap_sysmem((void *)ld);
74
Marek Vasut7f13b372018-06-13 06:13:32 +020075 ret = booti_setup(ld, &relocated_addr, &image_size, false);
Tom Rini5db28902016-08-12 08:31:15 -040076 if (ret != 0)
77 return 1;
78
Bin Chen6808ef92018-01-27 16:59:09 +110079 /* Handle BOOTM_STATE_LOADOS */
80 if (relocated_addr != ld) {
81 debug("Moving Image from 0x%lx to 0x%lx\n", ld, relocated_addr);
82 memmove((void *)relocated_addr, (void *)ld, image_size);
83 }
Tom Rini5db28902016-08-12 08:31:15 -040084
Bin Chen6808ef92018-01-27 16:59:09 +110085 images->ep = relocated_addr;
Lokesh Vutla683cdd62019-10-07 13:52:16 +053086 images->os.start = relocated_addr;
87 images->os.end = relocated_addr + image_size;
88
Bin Chen6808ef92018-01-27 16:59:09 +110089 lmb_reserve(&images->lmb, images->ep, le32_to_cpu(image_size));
Tom Rini5db28902016-08-12 08:31:15 -040090
91 /*
92 * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
93 * have a header that provide this informaiton.
94 */
95 if (bootm_find_images(flag, argc, argv))
96 return 1;
97
98 return 0;
99}
100
101int do_booti(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
102{
103 int ret;
104
105 /* Consume 'booti' */
106 argc--; argv++;
107
108 if (booti_start(cmdtp, flag, argc, argv, &images))
109 return 1;
110
111 /*
112 * We are doing the BOOTM_STATE_LOADOS state ourselves, so must
113 * disable interrupts ourselves
114 */
115 bootm_disable_interrupts();
116
117 images.os.os = IH_OS_LINUX;
Atish Patra3cedc972019-05-06 17:49:39 -0700118#ifdef CONFIG_RISCV_SMODE
119 images.os.arch = IH_ARCH_RISCV;
120#elif CONFIG_ARM64
Scott Wood0fff19a2017-01-26 16:55:44 -0600121 images.os.arch = IH_ARCH_ARM64;
Atish Patra3cedc972019-05-06 17:49:39 -0700122#endif
Tom Rini5db28902016-08-12 08:31:15 -0400123 ret = do_bootm_states(cmdtp, flag, argc, argv,
Cédric Schieli4943dc22017-01-23 16:51:45 +0100124#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
125 BOOTM_STATE_RAMDISK |
126#endif
Tom Rini5db28902016-08-12 08:31:15 -0400127 BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
128 BOOTM_STATE_OS_GO,
129 &images, 1);
130
131 return ret;
132}
133
134#ifdef CONFIG_SYS_LONGHELP
135static char booti_help_text[] =
136 "[addr [initrd[:size]] [fdt]]\n"
Atish Patra414c34e2020-03-05 16:24:23 -0800137 " - boot Linux flat or compressed 'Image' stored at 'addr'\n"
Tom Rini5db28902016-08-12 08:31:15 -0400138 "\tThe argument 'initrd' is optional and specifies the address\n"
139 "\tof an initrd in memory. The optional parameter ':size' allows\n"
140 "\tspecifying the size of a RAW initrd.\n"
Atish Patra414c34e2020-03-05 16:24:23 -0800141 "\tCurrently only booting from gz, bz2, lzma and lz4 compression\n"
142 "\ttypes are supported. In order to boot from any of these compressed\n"
143 "\timages, user have to set kernel_comp_addr_r and kernel_comp_size enviornment\n"
144 "\tvariables beforehand.\n"
Tom Rini5db28902016-08-12 08:31:15 -0400145#if defined(CONFIG_OF_LIBFDT)
146 "\tSince booting a Linux kernel requires a flat device-tree, a\n"
147 "\tthird argument providing the address of the device-tree blob\n"
148 "\tis required. To boot a kernel with a device-tree blob but\n"
149 "\twithout an initrd image, use a '-' for the initrd argument.\n"
150#endif
151 "";
152#endif
153
154U_BOOT_CMD(
155 booti, CONFIG_SYS_MAXARGS, 1, do_booti,
Atish Patra3cedc972019-05-06 17:49:39 -0700156 "boot Linux kernel 'Image' format from memory", booti_help_text
Tom Rini5db28902016-08-12 08:31:15 -0400157);