static 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 have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ disable_interrupts(); #ifdef CONFIG_NETCONSOLE /* Stop the ethernet stack if NetConsole could have left it up */ eth_halt(); #endif #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the * SDRAM while Linux is booting. This could happen (at least for OHCI * controller), because the HCCA (Host Controller Communication Area) * lies within the SDRAM and the host controller writes continously to * this area (as busmaster!). The HccaFrameNumber is for example * updated every 1 ms within the HCCA structure in SDRAM! For more * details see the OpenHCI specification. */ usb_stop(); #endif #ifdef CONFIG_SBOOT bootm_sboot(); #endif #ifdef CONFIG_SILENT_CONSOLE fixup_silent_linux(); #endif arch_preboot_os(); do_bootm_linux(0, argc, argv, &images); #ifdef DEBUG puts("\n## Control returned to monitor - resetting...\n"); #endif do_reset(cmdtp, flag, argc, argv); return 1; }
static int boot_selected_os(int argc, char * const argv[], int state, bootm_headers_t *images, boot_os_fn *boot_fn) { if (images->os.type == IH_TYPE_STANDALONE) { /* This may return when 'autostart' is 'no' */ bootm_start_standalone(argc, argv); return 0; } #ifdef CONFIG_SILENT_CONSOLE if (images->os.os == IH_OS_LINUX) fixup_silent_linux(); #endif arch_preboot_os(); boot_fn(state, argc, argv, images); if (state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */ return 0; bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED); #ifdef DEBUG puts("\n## Control returned to monitor - resetting...\n"); #endif return BOOTM_ERR_RESET; }
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong iflag; ulong load_end = 0; int ret; boot_os_fn *boot_fn; /* relocate boot function table */ if (!relocated) { int i; for (i = 0; i < ARRAY_SIZE(boot_os); i++) if (boot_os[i] != NULL) boot_os[i] += gd->reloc_off; relocated = 1; } /* determine if we have a sub command */ if (argc > 1) { char *endp; simple_strtoul(argv[1], &endp, 16); /* endp pointing to NULL means that argv[1] was just a * valid number, pass it along to the normal bootm processing * * If endp is ':' or '#' assume a FIT identifier so pass * along for normal processing. * * Right now we assume the first arg should never be '-' */ if ((*endp != 0) && (*endp != ':') && (*endp != '#')) return do_bootm_subcommand(cmdtp, flag, argc, argv); } if (bootm_start(cmdtp, flag, argc, argv)) return 1; /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ iflag = disable_interrupts(); #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the * SDRAM while Linux is booting. This could happen (at least for OHCI * controller), because the HCCA (Host Controller Communication Area) * lies within the SDRAM and the host controller writes continously to * this area (as busmaster!). The HccaFrameNumber is for example * updated every 1 ms within the HCCA structure in SDRAM! For more * details see the OpenHCI specification. */ usb_stop(); #endif #ifdef CONFIG_AMIGAONEG3SE /* * We've possible left the caches enabled during * bios emulation, so turn them off again */ icache_disable(); dcache_disable(); #endif ret = bootm_load_os(images.os, &load_end, 1); if (ret < 0) { if (ret == BOOTM_ERR_RESET) do_reset (cmdtp, flag, argc, argv); if (ret == BOOTM_ERR_OVERLAP) { if (images.legacy_hdr_valid) { if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI) puts ("WARNING: legacy format multi component " "image overwritten\n"); } else { puts ("ERROR: new format image overwritten - " "must RESET the board to recover\n"); show_boot_progress (-113); do_reset (cmdtp, flag, argc, argv); } } if (ret == BOOTM_ERR_UNIMPLEMENTED) { if (iflag) enable_interrupts(); show_boot_progress (-7); return 1; } } lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); if (images.os.type == IH_TYPE_STANDALONE) { if (iflag) enable_interrupts(); /* This may return when 'autostart' is 'no' */ bootm_start_standalone(iflag, argc, argv); return 0; } show_boot_progress (8); #ifdef CONFIG_SILENT_CONSOLE if (images.os.os == IH_OS_LINUX) fixup_silent_linux(); #endif boot_fn = boot_os[images.os.os]; if (boot_fn == NULL) { if (iflag) enable_interrupts(); printf ("ERROR: booting os '%s' (%d) is not supported\n", genimg_get_os_name(images.os.os), images.os.os); show_boot_progress (-8); return 1; } boot_fn(0, argc, argv, &images); show_boot_progress (-9); #ifdef DEBUG puts ("\n## Control returned to monitor - resetting...\n"); #endif do_reset (cmdtp, flag, argc, argv); return 1; }
int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong iflag; ulong load_end = 0; int ret; boot_os_fn *boot_fn; #ifdef CONFIG_NEEDS_MANUAL_RELOC static int relocated = 0; if (!relocated) { int i; /* relocate boot function table */ for (i = 0; i < ARRAY_SIZE(boot_os); i++) if (boot_os[i] != NULL) boot_os[i] += gd->reloc_off; /* relocate names of sub-command table */ for (i = 0; i < ARRAY_SIZE(cmd_bootm_sub); i++) cmd_bootm_sub[i].name += gd->reloc_off; relocated = 1; } #endif /* determine if we have a sub command */ if (argc > 1) { char *endp; simple_strtoul(argv[1], &endp, 16); /* endp pointing to NULL means that argv[1] was just a * valid number, pass it along to the normal bootm processing * * If endp is ':' or '#' assume a FIT identifier so pass * along for normal processing. * * Right now we assume the first arg should never be '-' */ if ((*endp != 0) && (*endp != ':') && (*endp != '#')) return do_bootm_subcommand(cmdtp, flag, argc, argv); } if (bootm_start(cmdtp, flag, argc, argv)) return 1; /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ iflag = disable_interrupts(); #ifdef CONFIG_NETCONSOLE /* Stop the ethernet stack if NetConsole could have left it up */ eth_halt(); #endif #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the * SDRAM while Linux is booting. This could happen (at least for OHCI * controller), because the HCCA (Host Controller Communication Area) * lies within the SDRAM and the host controller writes continously to * this area (as busmaster!). The HccaFrameNumber is for example * updated every 1 ms within the HCCA structure in SDRAM! For more * details see the OpenHCI specification. */ usb_stop(); #endif ret = bootm_load_os(images.os, &load_end, 1); if (ret < 0) { if (ret == BOOTM_ERR_RESET) do_reset(cmdtp, flag, argc, argv); if (ret == BOOTM_ERR_OVERLAP) { if (images.legacy_hdr_valid) { image_header_t *hdr; hdr = &images.legacy_hdr_os_copy; if (image_get_type(hdr) == IH_TYPE_MULTI) puts("WARNING: legacy format multi " "component image " "overwritten\n"); } else { puts("ERROR: new format image overwritten - " "must RESET the board to recover\n"); bootstage_error(BOOTSTAGE_ID_OVERWRITTEN); do_reset(cmdtp, flag, argc, argv); } } if (ret == BOOTM_ERR_UNIMPLEMENTED) { if (iflag) enable_interrupts(); bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL); return 1; } } lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); if (images.os.type == IH_TYPE_STANDALONE) { if (iflag) enable_interrupts(); /* This may return when 'autostart' is 'no' */ bootm_start_standalone(iflag, argc, argv); return 0; } bootstage_mark(BOOTSTAGE_ID_CHECK_BOOT_OS); #if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) if (images.os.os == IH_OS_LINUX) fixup_silent_linux(); #endif boot_fn = boot_os[images.os.os]; if (boot_fn == NULL) { if (iflag) enable_interrupts(); printf("ERROR: booting os '%s' (%d) is not supported\n", genimg_get_os_name(images.os.os), images.os.os); bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS); return 1; } arch_preboot_os(); boot_fn(0, argc, argv, &images); bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED); #ifdef DEBUG puts("\n## Control returned to monitor - resetting...\n"); #endif do_reset(cmdtp, flag, argc, argv); return 1; }
/** * Execute selected states of the bootm command. * * Note the arguments to this state must be the first argument, Any 'bootm' * or sub-command arguments must have already been taken. * * Note that if states contains more than one flag it MUST contain * BOOTM_STATE_START, since this handles and consumes the command line args. * * Also note that aside from boot_os_fn functions and bootm_load_os no other * functions we store the return value of in 'ret' may use a negative return * value, without special handling. * * @param cmdtp Pointer to bootm command table entry * @param flag Command flags (CMD_FLAG_...) * @param argc Number of subcommand arguments (0 = no arguments) * @param argv Arguments * @param states Mask containing states to run (BOOTM_STATE_...) * @param images Image header information * @param boot_progress 1 to show boot progress, 0 to not do this * @return 0 if ok, something else on error. Some errors will cause this * function to perform a reboot! If states contains BOOTM_STATE_OS_GO * then the intent is to boot an OS, so this function will not return * unless the image type is standalone. */ static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], int states, bootm_headers_t *images, int boot_progress) { boot_os_fn *boot_fn; ulong iflag = 0; int ret = 0, need_boot_fn; images->state |= states; /* * Work through the states and see how far we get. We stop on * any error. */ if (states & BOOTM_STATE_START) ret = bootm_start(cmdtp, flag, argc, argv); if (!ret && (states & BOOTM_STATE_FINDOS)) ret = bootm_find_os(cmdtp, flag, argc, argv); if (!ret && (states & BOOTM_STATE_FINDOTHER)) { ret = bootm_find_other(cmdtp, flag, argc, argv); argc = 0; /* consume the args */ } /* Load the OS */ if (!ret && (states & BOOTM_STATE_LOADOS)) { ulong load_end; iflag = bootm_disable_interrupts(); ret = bootm_load_os(images, &load_end, 0); if (ret == 0) lmb_reserve(&images->lmb, images->os.load, (load_end - images->os.load)); else if (ret && ret != BOOTM_ERR_OVERLAP) goto err; else if (ret == BOOTM_ERR_OVERLAP) ret = 0; #if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) if (images->os.os == IH_OS_LINUX) fixup_silent_linux(); #endif } /* Relocate the ramdisk */ #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH if (!ret && (states & BOOTM_STATE_RAMDISK)) { ulong rd_len = images->rd_end - images->rd_start; ret = boot_ramdisk_high(&images->lmb, images->rd_start, rd_len, &images->initrd_start, &images->initrd_end); if (!ret) { setenv_hex("initrd_start", images->initrd_start); setenv_hex("initrd_end", images->initrd_end); } } #endif #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB) if (!ret && (states & BOOTM_STATE_FDT)) { boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); ret = boot_relocate_fdt(&images->lmb, &images->ft_addr, &images->ft_len); } #endif /* From now on, we need the OS boot function */ if (ret) return ret; boot_fn = boot_os[images->os.os]; need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE | BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO); if (boot_fn == NULL && need_boot_fn) { if (iflag) enable_interrupts(); printf("ERROR: booting os '%s' (%d) is not supported\n", genimg_get_os_name(images->os.os), images->os.os); bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS); return 1; } /* Call various other states that are not generally used */ if (!ret && (states & BOOTM_STATE_OS_CMDLINE)) ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images); if (!ret && (states & BOOTM_STATE_OS_BD_T)) ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images); if (!ret && (states & BOOTM_STATE_OS_PREP)) ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images); #ifdef CONFIG_TRACE /* Pretend to run the OS, then run a user command */ if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) { char *cmd_list = getenv("fakegocmd"); ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO, images, boot_fn); if (!ret && cmd_list) ret = run_command_list(cmd_list, -1, flag); } #endif /* Check for unsupported subcommand. */ if (ret) { puts("subcommand not supported\n"); return ret; } /* Now run the OS! We hope this doesn't return */ if (!ret && (states & BOOTM_STATE_OS_GO)) ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO, images, boot_fn); /* Deal with any fallout */ err: if (iflag) enable_interrupts(); if (ret == BOOTM_ERR_UNIMPLEMENTED) bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL); else if (ret == BOOTM_ERR_RESET) do_reset(cmdtp, flag, argc, argv); return ret; }
int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ ulong addr, data, len; uint unc_len = CFG_BOOTM_LEN; int i; image_header_t *hdr = &header; #ifdef CONFIG_TPLINK_IMAGE_HEADER tplink_image_header_t *fileTag; #endif if(argc < 2){ addr = load_addr; } else { addr = simple_strtoul(argv[1], NULL, 16); } printf("Booting image at: 0x%08lX\n", addr); #ifndef CONFIG_TPLINK_IMAGE_HEADER memmove(&header, (char *)addr, sizeof(image_header_t)); print_image_hdr(hdr); data = addr + sizeof(image_header_t); #else fileTag = (tplink_image_header_t *)addr; print_image_hdr(fileTag); fake_image_header(hdr, fileTag); data = addr + TAG_LEN; #endif /* !CONFIG_TPLINK_IMAGE_HEADER */ len = ntohl(hdr->ih_size); /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ #ifdef CONFIG_NETCONSOLE /* * Stop the ethernet stack if NetConsole could have * left it up */ eth_halt(); #endif /* TODO: should we flush caches for kernel? */ /* * Flush everything, restore caches for linux */ //mips_cache_flush(); //mips_icache_flush_ix(); /* XXX - this causes problems when booting from flash */ /* dcache_disable(); */ /* case IH_COMP_LZMA:*/ puts("Uncompressing kernel image... "); i = lzma_inflate((unsigned char *)data, len, (unsigned char*)ntohl(hdr->ih_load), (int *)&unc_len); if(i != LZMA_RESULT_OK){ printf("## Error: LZMA error num: %d\n", i); return(-1); } puts("OK!\n"); #ifdef CONFIG_SILENT_CONSOLE fixup_silent_linux(); #endif do_bootm_linux(cmdtp, flag, argc, argv); #ifdef DEBUG puts("\n## Error: control returned to monitor - resetting...\n"); do_reset(cmdtp, flag, argc, argv); #endif return(1); }
int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *s; u32 *len_ptr; u32 addr, data, len; int i, tpl_type, verify; u32 unc_len = CFG_BOOTM_LEN; image_header_t *hdr = &header; tplink_image_header_t *tpl_hdr; /* * By default don't verify data CRC checksum, * but allow to enable it, using environment **/ s = getenv("verify_data"); verify = (s && (*s == 'y')) ? 1 : 0; if (argc < 2) { addr = load_addr; } else { addr = simple_strtoul(argv[1], NULL, 16); } printf("Booting image from 0x%08lX...\n", addr); /* Check what header type we have */ memmove(&data, (char *)addr, sizeof(u32)); tpl_type = 0; switch (ntohl(data)) { case TPL_IH_VERSION_V1: tpl_type = 1; tpl_hdr = (tplink_image_header_t *)addr; print_tpl_ih_v1(tpl_hdr); /* Convert to general format */ tpl_to_uboot_header(hdr, tpl_hdr); break; case IH_MAGIC: print_uboot_ih((image_header_t *)addr); memmove(&header, (char *)addr, sizeof(image_header_t)); break; case TPL_IH_VERSION_V2: case TPL_IH_VERSION_V3: default: puts("## Error: unsupported image header\n"); return 1; } /* Always verify header CRC */ if (ih_header_crc(hdr, tpl_type) != 0) { puts("## Error: header checksum mismatch!\n"); return 1; } /* And data if enabled */ if (tpl_type) { data = addr + sizeof(tplink_image_header_t); } else { data = addr + sizeof(image_header_t); } if (ih_data_crc(data, hdr, tpl_type, verify) != 0) { puts("## Error: data checksum mismatch!\n"); return 1; } puts("\n"); len = ntohl(hdr->ih_size); len_ptr = (u32 *)data; /* We support only MIPS */ if (hdr->ih_arch != IH_CPU_MIPS) { puts("## Error: unsupported architecture!\n"); return 1; } /* Image type... */ switch (hdr->ih_type) { case IH_TYPE_KERNEL: break; case IH_TYPE_MULTI: /* OS kernel is always in first image */ len = ntohl(len_ptr[0]); data += 8; /* Move over list to first image */ for (i = 1; len_ptr[i]; ++i) data += 4; break; default: puts("## Error: unsupported image type!\n"); return 1; } /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ #ifdef CONFIG_NETCONSOLE /* * Stop the ethernet stack if NetConsole could have * left it up */ puts("Stopping network... "); eth_halt(); puts("OK!\n"); #endif /* TODO: should we flush caches for kernel? */ /* * Flush everything, restore caches for linux */ //mips_cache_flush(); //mips_icache_flush_ix(); /* XXX - this causes problems when booting from flash */ /* dcache_disable(); */ /* Compression type... */ switch (hdr->ih_comp) { case IH_COMP_LZMA: printf("Uncompressing %s... ", ih_img_type(hdr->ih_type)); /* Try to extract LZMA data... */ i = lzma_inflate((u8 *)data, len, (u8 *)ntohl(hdr->ih_load), (int *)&unc_len); /* TODO: more verbose LZMA errors */ if (i != LZMA_RESULT_OK) { puts("ERROR\n"); printf("## Error: LZMA error '%d'!\n", i); return 1; } puts("OK!\n"); break; default: printf("## Error: unsupported compression type '%s'!\n", ih_comp_type(hdr->ih_comp)); return 1; } #ifdef CONFIG_SILENT_CONSOLE fixup_silent_linux(); #endif do_bootm_linux(cmdtp, flag, argc, argv); return 1; }
int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { //ulong iflag; ulong addr; ulong data, len; ulong *len_ptr; uint unc_len = CFG_BOOTM_LEN; int i, verify = 0; image_header_t *hdr = &header; LINUX_FILE_TAG *fileTag; // by lqm, 17Sep07 if (argc < 2) { addr = load_addr; } else { addr = simple_strtoul(argv[1], NULL, 16); } //SHOW_BOOT_PROGRESS (1); printf("Booting image at: 0x%08lX...\n", addr); fileTag = (LINUX_FILE_TAG *) addr; /* printf("---- fileTag = %08x\n", fileTag); printf("\t text base = %08x\n", fileTag->kernelTextAddr); printf("\t entry point = %08x\n", fileTag->kernelEntryPoint); */ fake_image_header(hdr, fileTag->kernelTextAddr, fileTag->kernelEntryPoint, fileTag->kernelLen); data = addr + TAG_LEN; len = ntohl(hdr->ih_size); /* TODO: */ //SHOW_BOOT_PROGRESS (2); //SHOW_BOOT_PROGRESS (6); /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ //iflag = disable_interrupts(); // TODO: disable_interrupts() only returns 0... //disable_interrupts(); #ifdef CONFIG_AR7100 /* * Flush everything, restore caches for linux */ mips_cache_flush(); /* XXX - this causes problems when booting from flash */ /* dcache_disable(); */ #endif /* case IH_COMP_LZMA:*/ puts("Uncompressing kernel image...\n"); i = lzma_inflate((unsigned char *) data, len, (unsigned char*) ntohl(hdr->ih_load), (int *) &unc_len); if (i != LZMA_RESULT_OK) { //printf("## Error: LZMA error number %d\n", i); //SHOW_BOOT_PROGRESS(-6); //udelay(100000); return -1; //do_reset(cmdtp, flag, argc, argv); } puts("OK\n"); //SHOW_BOOT_PROGRESS(7); /* case IH_OS_LINUX: */ #ifdef CONFIG_SILENT_CONSOLE fixup_silent_linux(); #endif do_bootm_linux(cmdtp, flag, argc, argv, addr, len_ptr, verify); //SHOW_BOOT_PROGRESS(-9); #ifdef DEBUG puts ("\n## Error: control returned to monitor - resetting...\n"); do_reset (cmdtp, flag, argc, argv); #endif return 1; }
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { image_header_t *hdr; ulong addr; ulong iflag; const char *type_name; uint unc_len = CONFIG_SYS_BOOTM_LEN; uint8_t comp, type, os; void *os_hdr; ulong os_data, os_len; ulong image_start, image_end; ulong load_start, load_end; ulong mem_start; phys_size_t mem_size; struct lmb lmb; #if defined(CONFIG_SECURE_BOOT) int rv; #endif #if defined(CONFIG_SECURE_BOOT) rv = Check_Signature( (SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR, (unsigned char*)CONFIG_SECURE_KERNEL_BASE, CONFIG_SECURE_KERNEL_SIZE-128, (unsigned char*)(CONFIG_SECURE_KERNEL_BASE+CONFIG_SECURE_KERNEL_SIZE-128), 128 ); if(rv != SB_OK) { printf("Kernel Integrity check fail\nSystem Halt...."); while(1); } printf("Kernel Integirty check success.\n"); rv = Check_Signature( (SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR, (unsigned char*)CONFIG_SECURE_ROOTFS_BASE, CONFIG_SECURE_ROOTFS_SIZE-128, (unsigned char*)(CONFIG_SECURE_ROOTFS_BASE+CONFIG_SECURE_ROOTFS_SIZE-128), 128 ); if(rv != SB_OK) { printf("rootfs Integrity check fail\nSystem Halt...."); while(1); } printf("rootfs Integirty check success.\n"); #endif memset ((void *)&images, 0, sizeof (images)); images.verify = getenv_yesno ("verify"); // images.lmb = &lmb; memcpy (&images.lmb, &lmb, sizeof(struct lmb)); lmb_init(&lmb); mem_start = getenv_bootm_low(); mem_size = getenv_bootm_size(); lmb_add(&lmb, (phys_addr_t)mem_start, mem_size); board_lmb_reserve(&lmb); #ifdef CONFIG_ZIMAGE_BOOT #define LINUX_ZIMAGE_MAGIC 0x016f2818 /* find out kernel image address */ if (argc < 2) { addr = load_addr; debug ("* kernel: default image load address = 0x%08lx\n", load_addr); } else { addr = simple_strtoul(argv[1], NULL, 16); //debug ("* kernel: cmdline image address = 0x%08lx\n", img_addr); } if (*(ulong *)(addr + 9*4) == LINUX_ZIMAGE_MAGIC) { printf("Boot with zImage\n"); addr = virt_to_phys(addr); hdr = (image_header_t *)addr; hdr->ih_os = IH_OS_LINUX; hdr->ih_ep = ntohl(addr); memmove (&images.legacy_hdr_os_copy, hdr, sizeof(image_header_t)); /* save pointer to image header */ images.legacy_hdr_os = hdr; images.legacy_hdr_valid = 1; goto after_header_check; } #endif /* get kernel image header, start address and length */ os_hdr = boot_get_kernel (cmdtp, flag, argc, argv, &images, &os_data, &os_len); if (os_len == 0) { puts ("ERROR: can't get kernel image!\n"); return 1; } /* get image parameters */ switch (genimg_get_format (os_hdr)) { case IMAGE_FORMAT_LEGACY: type = image_get_type (os_hdr); comp = image_get_comp (os_hdr); os = image_get_os (os_hdr); image_end = image_get_image_end (os_hdr); load_start = image_get_load (os_hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: if (fit_image_get_type (images.fit_hdr_os, images.fit_noffset_os, &type)) { puts ("Can't get image type!\n"); show_boot_progress (-109); return 1; } if (fit_image_get_comp (images.fit_hdr_os, images.fit_noffset_os, &comp)) { puts ("Can't get image compression!\n"); show_boot_progress (-110); return 1; } if (fit_image_get_os (images.fit_hdr_os, images.fit_noffset_os, &os)) { puts ("Can't get image OS!\n"); show_boot_progress (-111); return 1; } image_end = fit_get_end (images.fit_hdr_os); if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os, &load_start)) { puts ("Can't get image load address!\n"); show_boot_progress (-112); return 1; } break; #endif default: puts ("ERROR: unknown image format type!\n"); return 1; } image_start = (ulong)os_hdr; load_end = 0; type_name = genimg_get_type_name (type); /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ iflag = disable_interrupts(); #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the * SDRAM while Linux is booting. This could happen (at least for OHCI * controller), because the HCCA (Host Controller Communication Area) * lies within the SDRAM and the host controller writes continously to * this area (as busmaster!). The HccaFrameNumber is for example * updated every 1 ms within the HCCA structure in SDRAM! For more * details see the OpenHCI specification. */ usb_stop(); #endif #ifdef CONFIG_AMIGAONEG3SE /* * We've possible left the caches enabled during * bios emulation, so turn them off again */ icache_disable(); invalidate_l1_instruction_cache(); flush_data_cache(); dcache_disable(); #endif switch (comp) { case IH_COMP_NONE: if (load_start == (ulong)os_hdr) { printf (" XIP %s ... ", type_name); } else { printf (" Loading %s ... ", type_name); memmove_wd ((void *)load_start, (void *)os_data, os_len, CHUNKSZ); } load_end = load_start + os_len; puts("OK\n"); break; case IH_COMP_GZIP: printf (" Uncompressing %s ... ", type_name); if (gunzip ((void *)load_start, unc_len, (uchar *)os_data, &os_len) != 0) { puts ("GUNZIP: uncompress or overwrite error " "- must RESET board to recover\n"); show_boot_progress (-6); do_reset (cmdtp, flag, argc, argv); } load_end = load_start + os_len; break; #ifdef CONFIG_BZIP2 case IH_COMP_BZIP2: printf (" Uncompressing %s ... ", type_name); /* * If we've got less than 4 MB of malloc() space, * use slower decompression algorithm which requires * at most 2300 KB of memory. */ int i = BZ2_bzBuffToBuffDecompress ((char*)load_start, &unc_len, (char *)os_data, os_len, CFG_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { printf ("BUNZIP2: uncompress or overwrite error %d " "- must RESET board to recover\n", i); show_boot_progress (-6); do_reset (cmdtp, flag, argc, argv); } load_end = load_start + unc_len; break; #endif /* CONFIG_BZIP2 */ default: if (iflag) enable_interrupts(); printf ("Unimplemented compression type %d\n", comp); show_boot_progress (-7); return 1; } puts ("OK\n"); debug (" kernel loaded at 0x%08lx, end = 0x%08lx\n", load_start, load_end); show_boot_progress (7); if ((load_start < image_end) && (load_end > image_start)) { debug ("image_start = 0x%lX, image_end = 0x%lx\n", image_start, image_end); debug ("load_start = 0x%lx, load_end = 0x%lx\n", load_start, load_end); if (images.legacy_hdr_valid) { if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI) puts ("WARNING: legacy format multi component " "image overwritten\n"); } else { puts ("ERROR: new format image overwritten - " "must RESET the board to recover\n"); show_boot_progress (-113); do_reset (cmdtp, flag, argc, argv); } } show_boot_progress (8); lmb_reserve(&lmb, load_start, (load_end - load_start)); #if defined(CONFIG_ZIMAGE_BOOT) after_header_check: os = hdr->ih_os; #endif switch (os) { default: /* handled by (original) Linux case */ case IH_OS_LINUX: #ifdef CONFIG_SILENT_CONSOLE fixup_silent_linux(); #endif do_bootm_linux (flag, argc, argv, &images); break; #ifdef CONFIG_BOOTM_NETBSD case IH_OS_NETBSD: do_bootm_netbsd (flag, argc, argv, &images); break; #endif #ifdef CONFIG_LYNXKDI case IH_OS_LYNXOS: do_bootm_lynxkdi (flag, argc, argv, &images); break; #endif #ifdef CONFIG_BOOTM_RTEMS case IH_OS_RTEMS: do_bootm_rtems (flag, argc, argv, &images); break; #endif /* #if defined(CONFIG_CMD_ELF) case IH_OS_VXWORKS: do_bootm_vxworks (cmdtp, flag, argc, argv, &images); break; case IH_OS_QNX: do_bootm_qnxelf (cmdtp, flag, argc, argv, &images); break; #endif */ #ifdef CONFIG_ARTOS case IH_OS_ARTOS: do_bootm_artos (cmdtp, flag, argc, argv, &images); break; #endif } show_boot_progress (-9); #ifdef DEBUG puts ("\n## Control returned to monitor - resetting...\n"); do_reset (cmdtp, flag, argc, argv); #endif if (iflag) enable_interrupts(); return 1; }
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong iflag; ulong load_end = 0; int ret; boot_os_fn *boot_fn; #ifdef CONFIG_SECURE_BOOT #ifndef CONFIG_SECURE_BL1_ONLY security_check(); #endif #endif char cmdbuffer[64]; sprintf(cmdbuffer,"sdfuse autocheck"); run_command(cmdbuffer, 0); exynos4412_screen_backlight(0); #ifdef CONFIG_ZIMAGE_BOOT #define LINUX_ZIMAGE_MAGIC 0x016f2818 image_header_t *hdr; ulong addr; /* find out kernel image address */ if (argc < 2) { addr = load_addr; debug ("* kernel: default image load address = 0x%08lx\n", load_addr); } else { addr = simple_strtoul(argv[1], NULL, 16); } if (*(ulong *)(addr + 9*4) == LINUX_ZIMAGE_MAGIC) { u32 val; printf("Boot with zImage\n"); //addr = virt_to_phys(addr); hdr = (image_header_t *)addr; hdr->ih_os = IH_OS_LINUX; hdr->ih_ep = ntohl(addr); memmove (&images.legacy_hdr_os_copy, hdr, sizeof(image_header_t)); /* save pointer to image header */ images.legacy_hdr_os = hdr; images.legacy_hdr_valid = 1; goto after_header_check; } #endif #ifdef CONFIG_NEEDS_MANUAL_RELOC static int relocated = 0; /* relocate boot function table */ if (!relocated) { int i; for (i = 0; i < ARRAY_SIZE(boot_os); i++) if (boot_os[i] != NULL) boot_os[i] += gd->reloc_off; relocated = 1; } #endif /* determine if we have a sub command */ if (argc > 1) { char *endp; simple_strtoul(argv[1], &endp, 16); /* endp pointing to NULL means that argv[1] was just a * valid number, pass it along to the normal bootm processing * * If endp is ':' or '#' assume a FIT identifier so pass * along for normal processing. * * Right now we assume the first arg should never be '-' */ if ((*endp != 0) && (*endp != ':') && (*endp != '#')) return do_bootm_subcommand(cmdtp, flag, argc, argv); } if (bootm_start(cmdtp, flag, argc, argv)) return 1; /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ iflag = disable_interrupts(); #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the * SDRAM while Linux is booting. This could happen (at least for OHCI * controller), because the HCCA (Host Controller Communication Area) * lies within the SDRAM and the host controller writes continously to * this area (as busmaster!). The HccaFrameNumber is for example * updated every 1 ms within the HCCA structure in SDRAM! For more * details see the OpenHCI specification. */ usb_stop(); #endif ret = bootm_load_os(images.os, &load_end, 1); if (ret < 0) { if (ret == BOOTM_ERR_RESET) do_reset (cmdtp, flag, argc, argv); if (ret == BOOTM_ERR_OVERLAP) { if (images.legacy_hdr_valid) { if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI) puts ("WARNING: legacy format multi component " "image overwritten\n"); } else { puts ("ERROR: new format image overwritten - " "must RESET the board to recover\n"); show_boot_progress (-113); do_reset (cmdtp, flag, argc, argv); } } if (ret == BOOTM_ERR_UNIMPLEMENTED) { if (iflag) enable_interrupts(); show_boot_progress (-7); return 1; } } lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); if (images.os.type == IH_TYPE_STANDALONE) { if (iflag) enable_interrupts(); /* This may return when 'autostart' is 'no' */ bootm_start_standalone(iflag, argc, argv); return 0; } show_boot_progress (8); #if defined(CONFIG_ZIMAGE_BOOT) after_header_check: images.os.os = hdr->ih_os; images.ep = image_get_ep (&images.legacy_hdr_os_copy); #endif #ifdef CONFIG_SILENT_CONSOLE if (images.os.os == IH_OS_LINUX) fixup_silent_linux(); #endif boot_fn = boot_os[images.os.os]; if (boot_fn == NULL) { if (iflag) enable_interrupts(); printf ("ERROR: booting os '%s' (%d) is not supported\n", genimg_get_os_name(images.os.os), images.os.os); show_boot_progress (-8); return 1; } arch_preboot_os(); boot_fn(0, argc, argv, &images); show_boot_progress (-9); #ifdef DEBUG puts ("\n## Control returned to monitor - resetting...\n"); #endif do_reset (cmdtp, flag, argc, argv); return 1; }
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong iflag; ulong load_end = 0; int ret = 0; boot_os_fn *boot_fn; AML_LOG_INIT("cmd_bootm"); AML_LOG_TE("cmd_bootm"); #ifdef TEST_UBOOT_BOOT_SPEND_TIME bootm_start_time = get_utimer(0); #endif #ifdef CONFIG_NEEDS_MANUAL_RELOC static int relocated = 0; /* relocate boot function table */ if (!relocated) { int i; for (i = 0; i < ARRAY_SIZE(boot_os); i++) if (boot_os[i] != NULL) boot_os[i] += gd->reloc_off; relocated = 1; } #endif AML_LOG_TE("cmd_bootm"); #ifdef CONFIG_RESET_TO_SYSTEM struct aml_pmu_driver *pmu_driver = NULL; pmu_driver = aml_pmu_get_driver(); if (pmu_driver && pmu_driver->pmu_reset_flag_operation) { pmu_driver->pmu_reset_flag_operation(RESET_FLAG_SET); } #endif AML_LOG_TE("cmd_bootm"); #ifdef CONFIG_M6_SECU_BOOT #ifdef CONFIG_MESON_TRUSTZONE extern int meson_trustzone_boot_check(unsigned char *addr); ret = meson_trustzone_boot_check((unsigned char*)load_addr); #else extern int aml_decrypt_kernel_image(void* kernel_image_address); ret = aml_decrypt_kernel_image((void*)load_addr); #endif if(ret != 0) { printf("Error! Illegal kernel image, please check!\n"); return ret; } #endif //CONFIG_M6_SECU_BOOT AML_LOG_TE("cmd_bootm"); #ifdef CONFIG_AML_SECU_BOOT_V2 #ifdef CONFIG_MESON_TRUSTZONE extern int meson_trustzone_boot_check(unsigned char *addr); if(!g_nIMGReadFlag) ret = meson_trustzone_boot_check(aml_get_kernel_crypto_addr(argc < 2 ? NULL : argv[1])); #else extern int aml_sec_boot_check(unsigned char *pSRC); if(!g_nIMGReadFlag) ret = aml_sec_boot_check(aml_get_kernel_crypto_addr(argc < 2 ? NULL : argv[1])); #endif if(0 != ret) return ret; #endif //CONFIG_AML_SECU_BOOT_V2 AML_LOG_TE("cmd_bootm"); #ifdef CONFIG_AML_GATE_INIT extern void gate_init(void); gate_init(); #endif /* determine if we have a sub command */ if (argc > 1) { char *endp; simple_strtoul(argv[1], &endp, 16); /* endp pointing to NULL means that argv[1] was just a * valid number, pass it along to the normal bootm processing * * If endp is ':' or '#' assume a FIT identifier so pass * along for normal processing. * * Right now we assume the first arg should never be '-' */ if ((*endp != 0) && (*endp != ':') && (*endp != '#')) return do_bootm_subcommand(cmdtp, flag, argc, argv); } AML_LOG_TE("cmd_bootm"); if (bootm_start(cmdtp, flag, argc, argv)) return 1; AML_LOG_TE("cmd_bootm"); /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ iflag = disable_interrupts(); #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the * SDRAM while Linux is booting. This could happen (at least for OHCI * controller), because the HCCA (Host Controller Communication Area) * lies within the SDRAM and the host controller writes continously to * this area (as busmaster!). The HccaFrameNumber is for example * updated every 1 ms within the HCCA structure in SDRAM! For more * details see the OpenHCI specification. */ usb_stop(); #endif AML_LOG_TE("cmd_bootm"); ret = bootm_load_os(images.os, &load_end, 1); AML_LOG_TE("cmd_bootm"); if (ret < 0) { if (ret == BOOTM_ERR_RESET) do_reset (cmdtp, flag, argc, argv); if (ret == BOOTM_ERR_OVERLAP) { if (images.legacy_hdr_valid) { if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI) puts ("WARNING: legacy format multi component " "image overwritten\n"); } else { puts ("ERROR: new format image overwritten - " "must RESET the board to recover\n"); show_boot_progress (-113); do_reset (cmdtp, flag, argc, argv); } } if (ret == BOOTM_ERR_UNIMPLEMENTED) { if (iflag) enable_interrupts(); show_boot_progress (-7); return 1; } } AML_LOG_TE("cmd_bootm"); lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); AML_LOG_TE("cmd_bootm"); if (images.os.type == IH_TYPE_STANDALONE) { if (iflag) enable_interrupts(); /* This may return when 'autostart' is 'no' */ bootm_start_standalone(iflag, argc, argv); return 0; } show_boot_progress (8); #if defined(CONFIG_SILENT_CONSOLE) && \ (defined(CONFIG_SILENT_CONSOLE_LINUX_QUIET) || defined(CONFIG_DEPRECATED_SILENT_LINUX_CONSOLE)) if (images.os.os == IH_OS_LINUX) fixup_silent_linux(); #endif AML_LOG_TE("cmd_bootm"); #ifdef CONFIG_AUTO_SET_BOOTARGS_MEM mem_size_arg_process(); #endif boot_fn = boot_os[images.os.os]; if (boot_fn == NULL) { if (iflag) enable_interrupts(); printf ("ERROR: booting os '%s' (%d) is not supported\n", genimg_get_os_name(images.os.os), images.os.os); show_boot_progress (-8); return 1; } AML_LOG_TE("cmd_bootm"); arch_preboot_os(); #ifdef TEST_UBOOT_BOOT_SPEND_TIME { int boot_kernel_start; boot_kernel_start = get_utimer(0); printf("bootm start to prepare boot kernel time:%dus\n",boot_kernel_start-bootm_start_time); printf("from main_loop start to kernel decompress finished time:%dus\n",boot_kernel_start-main_loop_start); } #endif ulong temp_img_addr; AML_LOG_TE("cmd_bootm"); /* use fprintf to always show this print even if console is silenced with GD_FLG_SILENT */ fprintf(stderr, "uboot time: %d us.\n", get_utimer(0)); boot_fn(0, argc, argv, &images); show_boot_progress (-9); #ifdef DEBUG puts ("\n## Control returned to monitor - resetting...\n"); #endif do_reset (cmdtp, flag, argc, argv); return 1; }