blob: 4fff8cfcf69f95440a6ba9bec28f18491bf2bbc0 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Tom Rini36f067f2016-08-12 08:31:15 -04002/*
3 * (C) Copyright 2000-2009
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
Tom Rini36f067f2016-08-12 08:31:15 -04005 */
6
7#include <common.h>
8#include <bootm.h>
9#include <command.h>
10#include <image.h>
Simon Glass8f3f7612019-11-14 12:57:42 -070011#include <irq_func.h>
Tom Rini36f067f2016-08-12 08:31:15 -040012#include <lmb.h>
13#include <mapmem.h>
Masahiro Yamada56c4ed62017-03-09 16:28:25 +090014#include <linux/kernel.h>
15#include <linux/sizes.h>
Tom Rini36f067f2016-08-12 08:31:15 -040016
Atish Patra99c469c2020-03-05 16:24:23 -080017DECLARE_GLOBAL_DATA_PTR;
Tom Rini36f067f2016-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 Chendac184b2018-01-27 16:59:09 +110025 ulong ld;
26 ulong relocated_addr;
27 ulong image_size;
Atish Patra99c469c2020-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 Rini36f067f2016-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 Glass892265d2019-12-28 10:45:02 -070040 ld = image_load_addr;
Tom Rini36f067f2016-08-12 08:31:15 -040041 debug("* kernel: default image load address = 0x%08lx\n",
Simon Glass892265d2019-12-28 10:45:02 -070042 image_load_addr);
Tom Rini36f067f2016-08-12 08:31:15 -040043 } else {
Bin Chendac184b2018-01-27 16:59:09 +110044 ld = simple_strtoul(argv[0], NULL, 16);
Masahiro Yamada76913252018-02-13 12:10:02 +090045 debug("* kernel: cmdline image address = 0x%08lx\n", ld);
Tom Rini36f067f2016-08-12 08:31:15 -040046 }
47
Atish Patra99c469c2020-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 Vasut85ed2892018-06-13 06:13:32 +020075 ret = booti_setup(ld, &relocated_addr, &image_size, false);
Tom Rini36f067f2016-08-12 08:31:15 -040076 if (ret != 0)
77 return 1;
78
Bin Chendac184b2018-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 Rini36f067f2016-08-12 08:31:15 -040084
Bin Chendac184b2018-01-27 16:59:09 +110085 images->ep = relocated_addr;
Lokesh Vutla62dd16e2019-10-07 13:52:16 +053086 images->os.start = relocated_addr;
87 images->os.end = relocated_addr + image_size;
88
Bin Chendac184b2018-01-27 16:59:09 +110089 lmb_reserve(&images->lmb, images->ep, le32_to_cpu(image_size));
Tom Rini36f067f2016-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 Patra583b4092019-05-06 17:49:39 -0700118#ifdef CONFIG_RISCV_SMODE
119 images.os.arch = IH_ARCH_RISCV;
120#elif CONFIG_ARM64
Scott Wood4ba6a862017-01-26 16:55:44 -0600121 images.os.arch = IH_ARCH_ARM64;
Atish Patra583b4092019-05-06 17:49:39 -0700122#endif
Tom Rini36f067f2016-08-12 08:31:15 -0400123 ret = do_bootm_states(cmdtp, flag, argc, argv,
Cédric Schieli80d5e6b2017-01-23 16:51:45 +0100124#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
125 BOOTM_STATE_RAMDISK |
126#endif
Tom Rini36f067f2016-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 Patra99c469c2020-03-05 16:24:23 -0800137 " - boot Linux flat or compressed 'Image' stored at 'addr'\n"
Tom Rini36f067f2016-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 Patra99c469c2020-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 Rini36f067f2016-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 Patra583b4092019-05-06 17:49:39 -0700156 "boot Linux kernel 'Image' format from memory", booti_help_text
Tom Rini36f067f2016-08-12 08:31:15 -0400157);