blob: ae379754943b936821c20612fc1f1c3279abb7ad [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>
Simon Glass0f2af882020-05-10 11:40:05 -060013#include <log.h>
Tom Rini36f067f2016-08-12 08:31:15 -040014#include <mapmem.h>
Masahiro Yamada56c4ed62017-03-09 16:28:25 +090015#include <linux/kernel.h>
16#include <linux/sizes.h>
Tom Rini36f067f2016-08-12 08:31:15 -040017
Atish Patra99c469c2020-03-05 16:24:23 -080018DECLARE_GLOBAL_DATA_PTR;
Tom Rini36f067f2016-08-12 08:31:15 -040019/*
20 * Image booting support
21 */
Simon Glassed38aef2020-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 Rini36f067f2016-08-12 08:31:15 -040024{
25 int ret;
Bin Chendac184b2018-01-27 16:59:09 +110026 ulong ld;
27 ulong relocated_addr;
28 ulong image_size;
Atish Patra99c469c2020-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 Rini36f067f2016-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 Glass892265d2019-12-28 10:45:02 -070041 ld = image_load_addr;
Tom Rini36f067f2016-08-12 08:31:15 -040042 debug("* kernel: default image load address = 0x%08lx\n",
Simon Glass892265d2019-12-28 10:45:02 -070043 image_load_addr);
Tom Rini36f067f2016-08-12 08:31:15 -040044 } else {
Bin Chendac184b2018-01-27 16:59:09 +110045 ld = simple_strtoul(argv[0], NULL, 16);
Masahiro Yamada76913252018-02-13 12:10:02 +090046 debug("* kernel: cmdline image address = 0x%08lx\n", ld);
Tom Rini36f067f2016-08-12 08:31:15 -040047 }
48
Atish Patra99c469c2020-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 Vasut85ed2892018-06-13 06:13:32 +020076 ret = booti_setup(ld, &relocated_addr, &image_size, false);
Tom Rini36f067f2016-08-12 08:31:15 -040077 if (ret != 0)
78 return 1;
79
Bin Chendac184b2018-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 Rini36f067f2016-08-12 08:31:15 -040085
Bin Chendac184b2018-01-27 16:59:09 +110086 images->ep = relocated_addr;
Lokesh Vutla62dd16e2019-10-07 13:52:16 +053087 images->os.start = relocated_addr;
88 images->os.end = relocated_addr + image_size;
89
Bin Chendac184b2018-01-27 16:59:09 +110090 lmb_reserve(&images->lmb, images->ep, le32_to_cpu(image_size));
Tom Rini36f067f2016-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 Glassed38aef2020-05-10 11:40:03 -0600102int do_booti(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
Tom Rini36f067f2016-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 Patra583b4092019-05-06 17:49:39 -0700119#ifdef CONFIG_RISCV_SMODE
120 images.os.arch = IH_ARCH_RISCV;
121#elif CONFIG_ARM64
Scott Wood4ba6a862017-01-26 16:55:44 -0600122 images.os.arch = IH_ARCH_ARM64;
Atish Patra583b4092019-05-06 17:49:39 -0700123#endif
Tom Rini36f067f2016-08-12 08:31:15 -0400124 ret = do_bootm_states(cmdtp, flag, argc, argv,
Cédric Schieli80d5e6b2017-01-23 16:51:45 +0100125#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
126 BOOTM_STATE_RAMDISK |
127#endif
Tom Rini36f067f2016-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 Patra99c469c2020-03-05 16:24:23 -0800138 " - boot Linux flat or compressed 'Image' stored at 'addr'\n"
Tom Rini36f067f2016-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 Patra99c469c2020-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 Rini36f067f2016-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 Patra583b4092019-05-06 17:49:39 -0700157 "boot Linux kernel 'Image' format from memory", booti_help_text
Tom Rini36f067f2016-08-12 08:31:15 -0400158);