]> git.ipfire.org Git - thirdparty/u-boot.git/blame - cmd/booti.c
Merge branch '2024-05-02-assorted-updates'
[thirdparty/u-boot.git] / cmd / booti.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
5db28905
TR
2/*
3 * (C) Copyright 2000-2009
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5db28905
TR
5 */
6
7#include <common.h>
8#include <bootm.h>
9#include <command.h>
10#include <image.h>
36bf446b 11#include <irq_func.h>
5db28905 12#include <lmb.h>
f7ae49fc 13#include <log.h>
5db28905 14#include <mapmem.h>
401d1c4f 15#include <asm/global_data.h>
28085764
MY
16#include <linux/kernel.h>
17#include <linux/sizes.h>
5db28905 18
414c34ed 19DECLARE_GLOBAL_DATA_PTR;
5db28905
TR
20/*
21 * Image booting support
22 */
a6c49161 23static int booti_start(struct bootm_info *bmi)
5db28905 24{
a6c49161 25 struct bootm_headers *images = bmi->images;
5db28905 26 int ret;
6808ef9a
BC
27 ulong ld;
28 ulong relocated_addr;
29 ulong image_size;
414c34ed
AP
30 uint8_t *temp;
31 ulong dest;
32 ulong dest_end;
33 unsigned long comp_len;
34 unsigned long decomp_len;
35 int ctype;
5db28905 36
b5d397f4 37 ret = bootm_run_states(bmi, BOOTM_STATE_START);
5db28905
TR
38
39 /* Setup Linux kernel Image entry point */
a6c49161 40 if (!bmi->addr_img) {
bb872dd9 41 ld = image_load_addr;
5db28905 42 debug("* kernel: default image load address = 0x%08lx\n",
bb872dd9 43 image_load_addr);
5db28905 44 } else {
a6c49161 45 ld = hextoul(bmi->addr_img, NULL);
bf14d9a7 46 debug("* kernel: cmdline image address = 0x%08lx\n", ld);
5db28905
TR
47 }
48
414c34ed
AP
49 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
7f13b374 76 ret = booti_setup(ld, &relocated_addr, &image_size, false);
04fc470c 77 if (ret)
5db28905
TR
78 return 1;
79
6808ef9a
BC
80 /* Handle BOOTM_STATE_LOADOS */
81 if (relocated_addr != ld) {
9b83f9c5
TK
82 printf("Moving Image from 0x%lx to 0x%lx, end=%lx\n", ld,
83 relocated_addr, relocated_addr + image_size);
6808ef9a
BC
84 memmove((void *)relocated_addr, (void *)ld, image_size);
85 }
5db28905 86
6808ef9a 87 images->ep = relocated_addr;
683cdd68
LV
88 images->os.start = relocated_addr;
89 images->os.end = relocated_addr + image_size;
90
6808ef9a 91 lmb_reserve(&images->lmb, images->ep, le32_to_cpu(image_size));
5db28905
TR
92
93 /*
94 * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
95 * have a header that provide this informaiton.
96 */
a6c49161
SG
97 if (bootm_find_images(image_load_addr, bmi->conf_ramdisk, bmi->conf_fdt,
98 relocated_addr, image_size))
5db28905
TR
99 return 1;
100
101 return 0;
102}
103
09140113 104int do_booti(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
5db28905 105{
a6c49161 106 struct bootm_info bmi;
0c96b681 107 int states;
5db28905
TR
108 int ret;
109
110 /* Consume 'booti' */
111 argc--; argv++;
112
a6c49161
SG
113 bootm_init(&bmi);
114 if (argc)
115 bmi.addr_img = argv[0];
116 if (argc > 1)
117 bmi.conf_ramdisk = argv[1];
118 if (argc > 2)
119 bmi.conf_fdt = argv[2];
120 bmi.boot_progress = true;
121 bmi.cmd_name = "booti";
122 /* do not set up argc and argv[] since nothing uses them */
123
124 if (booti_start(&bmi))
5db28905
TR
125 return 1;
126
127 /*
128 * We are doing the BOOTM_STATE_LOADOS state ourselves, so must
129 * disable interrupts ourselves
130 */
131 bootm_disable_interrupts();
132
133 images.os.os = IH_OS_LINUX;
0c96b681
SG
134 if (IS_ENABLED(CONFIG_RISCV_SMODE))
135 images.os.arch = IH_ARCH_RISCV;
136 else if (IS_ENABLED(CONFIG_ARM64))
137 images.os.arch = IH_ARCH_ARM64;
138
139 states = BOOTM_STATE_MEASURE | BOOTM_STATE_OS_PREP |
140 BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO;
141 if (IS_ENABLED(CONFIG_SYS_BOOT_RAMDISK_HIGH))
142 states |= BOOTM_STATE_RAMDISK;
a6c49161 143
b5d397f4 144 ret = bootm_run_states(&bmi, states);
5db28905
TR
145
146 return ret;
147}
148
3616218b 149U_BOOT_LONGHELP(booti,
5db28905 150 "[addr [initrd[:size]] [fdt]]\n"
414c34ed 151 " - boot Linux flat or compressed 'Image' stored at 'addr'\n"
5db28905
TR
152 "\tThe argument 'initrd' is optional and specifies the address\n"
153 "\tof an initrd in memory. The optional parameter ':size' allows\n"
154 "\tspecifying the size of a RAW initrd.\n"
414c34ed
AP
155 "\tCurrently only booting from gz, bz2, lzma and lz4 compression\n"
156 "\ttypes are supported. In order to boot from any of these compressed\n"
d1896e36 157 "\timages, user have to set kernel_comp_addr_r and kernel_comp_size environment\n"
414c34ed 158 "\tvariables beforehand.\n"
5db28905
TR
159#if defined(CONFIG_OF_LIBFDT)
160 "\tSince booting a Linux kernel requires a flat device-tree, a\n"
161 "\tthird argument providing the address of the device-tree blob\n"
162 "\tis required. To boot a kernel with a device-tree blob but\n"
163 "\twithout an initrd image, use a '-' for the initrd argument.\n"
164#endif
3616218b 165 );
5db28905
TR
166
167U_BOOT_CMD(
168 booti, CONFIG_SYS_MAXARGS, 1, do_booti,
3cedc974 169 "boot Linux kernel 'Image' format from memory", booti_help_text
5db28905 170);