Newer
Older
/* 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;
}
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
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
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 */
/*******************************************************************/
/* 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);
for (i = 0, len = 0; i < argc; i += 1) {
if (i > 0)
strcpy(&cmdline[len], argv[i]);
len += strlen(argv[i]);
} 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 */
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
#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
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
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
#ifdef CONFIG_CMD_BOOTZ
static int __bootz_setup(void *image, void **start, void **end)
{
/* Please define bootz_setup() for your platform */
puts("Your platform's zImage format isn't supported yet!\n");
return -1;
}
int bootz_setup(void *image, void **start, void **end)
__attribute__((weak, alias("__bootz_setup")));
/*
* zImage booting support
*/
static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[], bootm_headers_t *images)
{
int ret;
void *zi_start, *zi_end;
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((void *)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;
ret = do_bootm_states(cmdtp, flag, argc, argv,
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 */