Newer
Older
"\t'arg' can be the address of an initrd image\n"
#if defined(CONFIG_OF_LIBFDT)
"\tWhen booting a Linux kernel which requires a flat device-tree\n"
"\ta third argument is required which is the address of the\n"
"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
"\tuse a '-' for the second argument. If you do not pass a third\n"
"\ta bd_info struct will be passed instead\n"
#endif
#if defined(CONFIG_FIT)
"\t\nFor the new multi component uImage format (FIT) addresses\n"
"\tmust be extened to include component or configuration unit name:\n"
"\taddr:<subimg_uname> - direct component image specification\n"
"\taddr#<conf_uname> - configuration specification\n"
"\tUse iminfo command to get the list of existing component\n"
"\timages and configurations.\n"
#endif
"\nSub-commands to do part of the bootm sequence. The sub-commands "
"must be\n"
"issued in the order below (it's ok to not issue all sub-commands):\n"
"\tstart [addr [arg ...]]\n"
"\tloados - load OS image\n"
#if defined(CONFIG_SYS_BOOT_RAMDISK_HIGH)
"\tramdisk - relocate initrd, set env initrd_start/initrd_end\n"
#endif
#if defined(CONFIG_OF_LIBFDT)
"\tfdt - relocate flat device tree\n"
#endif
"\tcmdline - OS specific command line processing/setup\n"
"\tbdt - OS specific bd_t processing\n"
"\tprep - OS specific prep before relocation or go\n"
"\tgo - start OS";
#endif
U_BOOT_CMD(
bootm, CONFIG_SYS_MAXARGS, 1, do_bootm,
"boot application image from memory", bootm_help_text
/*******************************************************************/
/* bootd - boot default image */
/*******************************************************************/
#if defined(CONFIG_CMD_BOOTD)
int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (run_command(getenv("bootcmd"), flag) < 0)
/* keep old command name "bootd" for backward compatibility */
/*******************************************************************/
/* iminfo - print header info for a requested image */
/*******************************************************************/
#if defined(CONFIG_CMD_IMI)
static int do_iminfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
for (arg = 1; arg < argc; ++arg) {
addr = simple_strtoul(argv[arg], NULL, 16);
if (image_info(addr) != 0)
void *hdr = (void *)addr;
printf("\n## Checking Image at %08lx ...\n", addr);
case IMAGE_FORMAT_LEGACY:
puts(" Legacy image found\n");
if (!image_check_magic(hdr)) {
puts(" Bad Magic Number\n");
return 1;
}
if (!image_check_hcrc(hdr)) {
puts(" Bad Header Checksum\n");
puts(" Verifying Checksum ... ");
if (!image_check_dcrc(hdr)) {
puts(" Bad Data CRC\n");
return 0;
#if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT:
if (!fit_check_format(hdr)) {
puts("Bad FIT image format!\n");
return 1;
Bartlomiej Sieka
committed
if (!fit_all_image_verify(hdr)) {
Bartlomiej Sieka
committed
return 1;
}
return 0;
#endif
default:
iminfo, CONFIG_SYS_MAXARGS, 1, do_iminfo,
"addr [addr ...]\n"
" - print header information for application image starting at\n"
" address 'addr' in memory; this includes verification of the\n"
" image contents (magic number, header and payload checksums)"
#endif
/*******************************************************************/
/* imls - list all images found in flash */
/*******************************************************************/
#if defined(CONFIG_CMD_IMLS)
static int do_imls_nor(void)
{
flash_info_t *info;
int i, j;
for (i = 0, info = &flash_info[0];
i < CONFIG_SYS_MAX_FLASH_BANKS; ++i, ++info) {
if (info->flash_id == FLASH_UNKNOWN)
goto next_bank;
for (j = 0; j < info->sector_count; ++j) {
hdr = (void *)info->start[j];
if (!hdr)
goto next_sector;
case IMAGE_FORMAT_LEGACY:
goto next_sector;
printf("Legacy Image at %08lX:\n", (ulong)hdr);
image_print_contents(hdr);
puts(" Verifying Checksum ... ");
if (!image_check_dcrc(hdr)) {
puts("Bad Data CRC\n");
}
break;
#if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT:
goto next_sector;
printf("FIT Image at %08lX:\n", (ulong)hdr);
fit_print_contents(hdr);
goto next_sector;
}
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
return 0;
}
#endif
#if defined(CONFIG_CMD_IMLS_NAND)
static int nand_imls_legacyimage(nand_info_t *nand, int nand_dev, loff_t off,
size_t len)
{
void *imgdata;
int ret;
imgdata = malloc(len);
if (!imgdata) {
printf("May be a Legacy Image at NAND device %d offset %08llX:\n",
nand_dev, off);
printf(" Low memory(cannot allocate memory for image)\n");
return -ENOMEM;
}
ret = nand_read_skip_bad(nand, off, &len,
imgdata);
if (ret < 0 && ret != -EUCLEAN) {
free(imgdata);
return ret;
}
if (!image_check_hcrc(imgdata)) {
free(imgdata);
return 0;
}
printf("Legacy Image at NAND device %d offset %08llX:\n",
nand_dev, off);
image_print_contents(imgdata);
puts(" Verifying Checksum ... ");
if (!image_check_dcrc(imgdata))
puts("Bad Data CRC\n");
else
puts("OK\n");
free(imgdata);
return 0;
}
static int nand_imls_fitimage(nand_info_t *nand, int nand_dev, loff_t off,
size_t len)
{
void *imgdata;
int ret;
imgdata = malloc(len);
if (!imgdata) {
printf("May be a FIT Image at NAND device %d offset %08llX:\n",
nand_dev, off);
printf(" Low memory(cannot allocate memory for image)\n");
return -ENOMEM;
}
ret = nand_read_skip_bad(nand, off, &len,
imgdata);
if (ret < 0 && ret != -EUCLEAN) {
free(imgdata);
return ret;
}
if (!fit_check_format(imgdata)) {
free(imgdata);
return 0;
}
printf("FIT Image at NAND device %d offset %08llX:\n", nand_dev, off);
fit_print_contents(imgdata);
free(imgdata);
return 0;
}
static int do_imls_nand(void)
{
nand_info_t *nand;
int nand_dev = nand_curr_device;
size_t len;
loff_t off;
u32 buffer[16];
if (nand_dev < 0 || nand_dev >= CONFIG_SYS_MAX_NAND_DEVICE) {
puts("\nNo NAND devices available\n");
return -ENODEV;
}
printf("\n");
for (nand_dev = 0; nand_dev < CONFIG_SYS_MAX_NAND_DEVICE; nand_dev++) {
nand = &nand_info[nand_dev];
if (!nand->name || !nand->size)
continue;
for (off = 0; off < nand->size; off += nand->erasesize) {
const image_header_t *header;
int ret;
if (nand_block_isbad(nand, off))
continue;
len = sizeof(buffer);
ret = nand_read(nand, off, &len, (u8 *)buffer);
if (ret < 0 && ret != -EUCLEAN) {
printf("NAND read error %d at offset %08llX\n",
ret, off);
continue;
}
switch (genimg_get_format(buffer)) {
case IMAGE_FORMAT_LEGACY:
header = (const image_header_t *)buffer;
len = image_get_image_size(header);
nand_imls_legacyimage(nand, nand_dev, off, len);
break;
#if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT:
len = fit_get_size(buffer);
nand_imls_fitimage(nand, nand_dev, off, len);
break;
#endif
}
}
}
return 0;
}
#endif
#if defined(CONFIG_CMD_IMLS) || defined(CONFIG_CMD_IMLS_NAND)
static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int ret_nor = 0, ret_nand = 0;
#if defined(CONFIG_CMD_IMLS)
ret_nor = do_imls_nor();
#endif
#if defined(CONFIG_CMD_IMLS_NAND)
ret_nand = do_imls_nand();
#endif
if (ret_nor)
return ret_nor;
if (ret_nand)
return ret_nand;
return (0);
}
U_BOOT_CMD(
imls, 1, 1, do_imls,
"\n"
" - Prints information about all images found at sector/block\n"
" boundaries in nor/nand flash."
);
#endif
/*******************************************************************/
/* helper routines */
/*******************************************************************/
#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
#define CONSOLE_ARG "console="
#define CONSOLE_ARG_LEN (sizeof(CONSOLE_ARG) - 1)
static void fixup_silent_linux(void)
char *buf;
const char *env_val;
char *cmdline = getenv("bootargs");
/* Only fix cmdline when requested */
if (!(gd->flags & GD_FLG_SILENT))
return;
debug("before silent fix-up: %s\n", cmdline);
if (cmdline && (cmdline[0] != '\0')) {
char *start = strstr(cmdline, CONSOLE_ARG);
/* Allocate space for maximum possible new command line */
buf = malloc(strlen(cmdline) + 1 + CONSOLE_ARG_LEN + 1);
if (!buf) {
debug("%s: out of memory\n", __func__);
return;
}
char *end = strchr(start, ' ');
int num_start_bytes = start - cmdline + CONSOLE_ARG_LEN;
strncpy(buf, cmdline, num_start_bytes);
strcpy(buf + num_start_bytes, end);
buf[num_start_bytes] = '\0';
sprintf(buf, "%s %s", cmdline, CONSOLE_ARG);
buf = NULL;
env_val = CONSOLE_ARG;
setenv("bootargs", env_val);
debug("after silent fix-up: %s\n", env_val);
free(buf);
}
#endif /* CONFIG_SILENT_CONSOLE */
#if defined(CONFIG_BOOTM_NETBSD) || defined(CONFIG_BOOTM_PLAN9)
static void copy_args(char *dest, int argc, char * const argv[], char delim)
{
int i;
for (i = 0; i < argc; i++) {
if (i > 0)
*dest++ = delim;
strcpy(dest, argv[i]);
dest += strlen(argv[i]);
}
}
#endif
/*******************************************************************/
/* OS booting routines */
/*******************************************************************/
#ifdef CONFIG_BOOTM_NETBSD
static int do_bootm_netbsd(int flag, int argc, char * const argv[],
bootm_headers_t *images)
void (*loader)(bd_t *, image_header_t *, char *, char *);
image_header_t *os_hdr, *hdr;
ulong kernel_data, kernel_len;
char *consdev;
char *cmdline;
if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
}
#endif
hdr = images->legacy_hdr_os;
/*
* Booting a (NetBSD) kernel image
*
* This process is pretty similar to a standalone application:
* The (first part of an multi-) image must be a stage-2 loader,
* which in turn is responsible for loading & invoking the actual
* kernel. The only differences are the parameters being passed:
* besides the board info strucure, the loader expects a command
* line, the name of the console device, and (optionally) the
* address of the original image header.
*/
os_hdr = NULL;
if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
image_multi_getimg(hdr, 1, &kernel_data, &kernel_len);
if (kernel_len)
os_hdr = hdr;
len += strlen(argv[i]) + 1;
cmdline = malloc(len);
copy_args(cmdline, argc, argv, ' ');
} else if ((cmdline = getenv("bootargs")) == NULL) {
loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep;
printf("## Transferring control to NetBSD stage-2 loader "
"(at address %08lx) ...\n",
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
/*
* NetBSD Stage-2 Loader Parameters:
* r3: ptr to board info data
* r4: image address
* r5: console device
* r6: boot args string
*/
(*loader)(gd->bd, os_hdr, consdev, cmdline);
#endif /* CONFIG_BOOTM_NETBSD*/
static int do_bootm_lynxkdi(int flag, int argc, char * const argv[],
bootm_headers_t *images)
image_header_t *hdr = &images->legacy_hdr_os_copy;
if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
}
#endif
}
#endif /* CONFIG_LYNXKDI */
#ifdef CONFIG_BOOTM_RTEMS
static int do_bootm_rtems(int flag, int argc, char * const argv[],
bootm_headers_t *images)
{
void (*entry_point)(bd_t *);
if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
}
#endif
entry_point = (void (*)(bd_t *))images->ep;
printf("## Transferring control to RTEMS (at address %08lx) ...\n",
(ulong)entry_point);
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
/*
* RTEMS Parameters:
* r3: ptr to board info data
*/
#endif /* CONFIG_BOOTM_RTEMS */
static int do_bootm_ose(int flag, int argc, char * const argv[],
bootm_headers_t *images)
{
void (*entry_point)(void);
if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
return 1;
}
#endif
entry_point = (void (*)(void))images->ep;
printf("## Transferring control to OSE (at address %08lx) ...\n",
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
/*
* OSE Parameters:
* None
*/
(*entry_point)();
return 1;
}
#endif /* CONFIG_BOOTM_OSE */
#if defined(CONFIG_BOOTM_PLAN9)
static int do_bootm_plan9(int flag, int argc, char * const argv[],
bootm_headers_t *images)
{
void (*entry_point)(void);
if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
fit_unsupported_reset("Plan 9");
return 1;
}
#endif
/* See README.plan9 */
s = getenv("confaddr");
if (s != NULL) {
char *confaddr = (char *)simple_strtoul(s, NULL, 16);
if (argc > 0) {
copy_args(confaddr, argc, argv, '\n');
} else {
s = getenv("bootargs");
if (s != NULL)
strcpy(confaddr, s);
}
}
entry_point = (void (*)(void))images->ep;
printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
(ulong)entry_point);
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
/*
* Plan 9 Parameters:
* None
*/
(*entry_point)();
return 1;
}
#endif /* CONFIG_BOOTM_PLAN9 */
#if defined(CONFIG_CMD_ELF)
static int do_bootm_vxworks(int flag, int argc, char * const argv[],
bootm_headers_t *images)
if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
}
#endif
sprintf(str, "%lx", images->ep); /* write entry-point into string */
do_bootvx(NULL, 0, 0, NULL);
return 1;
static int do_bootm_qnxelf(int flag, int argc, char * const argv[],
bootm_headers_t *images)
if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
}
#endif
sprintf(str, "%lx", images->ep); /* write entry-point into string */
local_args[0] = argv[0];
local_args[1] = str; /* and provide it via the arguments */
do_bootelf(NULL, 0, 2, local_args);
return 1;
#ifdef CONFIG_INTEGRITY
static int do_bootm_integrity(int flag, int argc, char * const argv[],
bootm_headers_t *images)
{
void (*entry_point)(void);
if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
return 1;
}
#endif
entry_point = (void (*)(void))images->ep;
printf("## Transferring control to INTEGRITY (at address %08lx) ...\n",
(ulong)entry_point);
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
/*
* INTEGRITY Parameters:
* None
*/
(*entry_point)();
return 1;
}
#endif
#ifdef CONFIG_CMD_BOOTZ
int __weak bootz_setup(ulong image, ulong *start, ulong *end)
{
/* Please define bootz_setup() for your platform */
puts("Your platform's zImage format isn't supported yet!\n");
return -1;
}
/*
* zImage booting support
*/
static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[], bootm_headers_t *images)
{
int ret;
ret = do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START,
images, 1);
/* Setup Linux kernel zImage entry point */
if (argc < 2) {
images->ep = load_addr;
debug("* kernel: default image load address = 0x%08lx\n",
load_addr);
} else {
images->ep = simple_strtoul(argv[1], NULL, 16);
debug("* kernel: cmdline image address = 0x%08lx\n",
images->ep);
}
ret = bootz_setup(images->ep, &zi_start, &zi_end);
if (ret != 0)
return 1;
lmb_reserve(&images->lmb, images->ep, zi_end - zi_start);
ret = do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_FINDOTHER,
images, 1);
int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
bootm_headers_t images;
if (bootz_start(cmdtp, flag, argc, argv, &images))
return 1;
/*
* We are doing the BOOTM_STATE_LOADOS state ourselves, so must
* disable interrupts ourselves
*/
bootm_disable_interrupts();
ret = do_bootm_states(cmdtp, flag, argc, argv,
BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO,
&images, 1);
#ifdef CONFIG_SYS_LONGHELP
static char bootz_help_text[] =
"[addr [initrd[:size]] [fdt]]\n"
" - boot Linux zImage stored in memory\n"
"\tThe argument 'initrd' is optional and specifies the address\n"
"\tof the initrd in memory. The optional argument ':size' allows\n"
"\tspecifying the size of RAW initrd.\n"
#if defined(CONFIG_OF_LIBFDT)
"\tWhen booting a Linux kernel which requires a flat device-tree\n"
"\ta third argument is required which is the address of the\n"
"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
"\tuse a '-' for the second argument. If you do not pass a third\n"
"\ta bd_info struct will be passed instead\n"
#endif
"";
#endif
U_BOOT_CMD(
bootz, CONFIG_SYS_MAXARGS, 1, do_bootz,
"boot Linux zImage image from memory", bootz_help_text
);
#endif /* CONFIG_CMD_BOOTZ */