void do_usb (void) { boot_os_fn *boot_fn; int res; u32 usb_inbuffer[512]; u32 total; u8 *addr; u32 bytes; int size; int cntr = 0; usb_msg (USBLOAD_CMD_FILE_REQ, "file req"); while(++cntr < 200000) /* try for 1 second then bail out */ { res = usb_recv ((u8 *) usb_inbuffer, sizeof (usb_inbuffer)); switch (usb_inbuffer[0]) { case USBLOAD_CMD_FILE: printf ("USBLOAD_CMD_FILE total = %d cmd = %c%c%c%c val = 0x%x val = 0x%x\n", res, ((char*)&usb_inbuffer[0])[0], ((char*)&usb_inbuffer[0])[1], ((char*)&usb_inbuffer[0])[2], ((char*)&usb_inbuffer[0])[3], usb_inbuffer[1], usb_inbuffer[2]); total = usb_inbuffer[1]; /* get size and address */ addr = (u8 *) usb_inbuffer[2]; usb_code (USBLOAD_CMD_ECHO_SZ, total); bytes = 0; while (bytes < total) { size = usb_recv ((u8 *) usb_inbuffer, sizeof (usb_inbuffer)); memcpy(addr, usb_inbuffer, size); addr += size; bytes += size; } usb_code (USBLOAD_CMD_REPORT_SZ, total); /* tell him we got this many bytes */ printf ("got file addr = 0x%x counter = %d\n", addr, cntr); usb_msg (USBLOAD_CMD_FILE_REQ, "file req"); /* see if they have another file for us */ cntr = 0; break; case USBLOAD_CMD_JUMP: printf ("USBLOAD_CMD_JUMP total = %d addr = 0x%x val = 0x%x\n", res, usb_inbuffer[0], usb_inbuffer[1]); boot_fn = (boot_os_fn *) usb_inbuffer[1]; boot_fn(); /* go to u-boot and maybe kernel */ break; default: break; } udelay(10); /* delay 10 us */ } printf("USB done\n"); hang(); }
static int boot_selected_os(int argc, char * const argv[], int state, bootm_headers_t *images, boot_os_fn *boot_fn) { arch_preboot_os(); boot_fn(state, argc, argv, images); /* Stand-alone may return when 'autostart' is 'no' */ if (images->os.type == IH_TYPE_STANDALONE || 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; }
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_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int ret = 0; int state; cmd_tbl_t *c; boot_os_fn *boot_fn; c = find_cmd_tbl(argv[1], &cmd_bootm_sub[0], ARRAY_SIZE(cmd_bootm_sub)); if (c) { state = (int)c->cmd; /* treat start special since it resets the state machine */ if (state == BOOTM_STATE_START) { argc--; argv++; return bootm_start(cmdtp, flag, argc, argv); } } /* Unrecognized command */ else { cmd_usage(cmdtp); return 1; } if (images.state >= state) { printf ("Trying to execute a command out of order\n"); cmd_usage(cmdtp); return 1; } images.state |= state; boot_fn = boot_os[images.os.os]; switch (state) { ulong load_end; case BOOTM_STATE_START: /* should never occur */ break; case BOOTM_STATE_LOADOS: ret = bootm_load_os(images.os, &load_end, 0); if (ret) return ret; lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); break; #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) case BOOTM_STATE_RAMDISK: { ulong rd_len = images.rd_end - images.rd_start; char str[17]; ret = boot_ramdisk_high(&images.lmb, images.rd_start, rd_len, &images.initrd_start, &images.initrd_end); if (ret) return ret; sprintf(str, "%lx", images.initrd_start); setenv("initrd_start", str); sprintf(str, "%lx", images.initrd_end); setenv("initrd_end", str); } break; #endif #ifdef CONFIG_OF_LIBFDT case BOOTM_STATE_FDT: { ulong bootmap_base = getenv_bootm_low(); ret = boot_relocate_fdt(&images.lmb, bootmap_base, &images.ft_addr, &images.ft_len); break; } #endif case BOOTM_STATE_OS_CMDLINE: ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, &images); if (ret) printf ("cmdline subcommand not supported\n"); break; case BOOTM_STATE_OS_BD_T: ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, &images); if (ret) printf ("bdt subcommand not supported\n"); break; case BOOTM_STATE_OS_PREP: ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, &images); if (ret) printf ("prep subcommand not supported\n"); break; case BOOTM_STATE_OS_GO: disable_interrupts(); boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images); break; } return ret; }
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; }
static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int ret = 0; long state; cmd_tbl_t *c; boot_os_fn *boot_fn; c = find_cmd_tbl(argv[1], &cmd_bootm_sub[0], ARRAY_SIZE(cmd_bootm_sub)); if (c) { state = (long)c->cmd; /* treat start special since it resets the state machine */ if (state == BOOTM_STATE_START) { argc--; argv++; return bootm_start(cmdtp, flag, argc, argv); } } else { /* Unrecognized command */ return CMD_RET_USAGE; } if (images.state < BOOTM_STATE_START || images.state >= state) { printf("Trying to execute a command out of order\n"); return CMD_RET_USAGE; } images.state |= state; boot_fn = boot_os[images.os.os]; switch (state) { ulong load_end; case BOOTM_STATE_START: /* should never occur */ break; case BOOTM_STATE_LOADOS: ret = bootm_load_os(images.os, &load_end, 0); if (ret) return ret; lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); break; #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH case 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) return ret; setenv_hex("initrd_start", images.initrd_start); setenv_hex("initrd_end", images.initrd_end); } break; #endif #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB) case 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); break; } #endif case BOOTM_STATE_OS_CMDLINE: ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, &images); if (ret) printf("cmdline subcommand not supported\n"); break; case BOOTM_STATE_OS_BD_T: ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, &images); if (ret) printf("bdt subcommand not supported\n"); break; case BOOTM_STATE_OS_PREP: ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, &images); if (ret) printf("prep subcommand not supported\n"); break; case BOOTM_STATE_OS_GO: disable_interrupts(); #ifdef CONFIG_NETCONSOLE /* * Stop the ethernet stack if NetConsole could have * left it up */ eth_halt(); #endif arch_preboot_os(); boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images); break; } return ret; }
/** * 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; }
/** * 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; 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 */ } /* * 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 /* Load the OS */ if (!ret && (states & BOOTM_STATE_LOADOS)) { ulong load_end; ret = bootm_load_os(images, &load_end, 0); if (ret && ret != BOOTM_ERR_OVERLAP) goto err; if (ret == 0) lmb_reserve(&images->lmb, images->os.load, (load_end - images->os.load)); else if (ret == BOOTM_ERR_OVERLAP) ret = 0; } /* 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]; 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; } /* 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 /* 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); if (ret) goto err; } return ret; /* 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); else puts("subcommand not supported\n"); return ret; }
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; }
int do_bootz (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong iflag; ulong load_end = 0; int ret; boot_os_fn *boot_fn; int is_zImage, is_autoboot; char cmd_buf[CONFIG_SYS_CBSIZE]; if(argc < 2) images.ep = CONFIG_SYS_LOAD_ADDR; else { if (isxdigit(*(argv[1]))) images.ep = simple_strtoul(argv[1], NULL, 16); else { printf("Input address is not digital, ERROR!!\n"); return -1; } } is_autoboot = (strncmp(getenv("autoboot"), "boot", 4) == 0) ? 1 : 0; /* Autoboot sequence is NAND, OneNAND .. */ if (is_autoboot) { int n, col; #ifdef CONFIG_CMD_NAND if (nand_curr_device >= 0) { /* NAND Device Exist, try to boot from NAND */ printf("read zImage from NAND\n"); run_command(CONFIG_NANDBOOT, 0); #ifdef CONFIG_CMD_ONENAND } else if (onenand_mtd.size > 0) { /* OneNAND Device Exist, try to boot from OneNAND */ printf("read zImage from OneNAND\n"); run_command(CONFIG_ONENANDBOOT, 0); #endif } else #endif printf("No flash device, fail to AUTOBOOT!!!\n\n"); } is_zImage = (((ulong *)images.ep)[9] == 0x016f2818) ? 1 : 0; /* AUTOBOOT support, check if the sepecified addr contain valid zImage */ if (is_autoboot && !is_zImage) { printf("The address specified contains no valid zImage.\n AutoBOOT failed!!!\n\n"); return 0; } images.os.os = IH_OS_LINUX; /* relocate boot function table */ if (!relocated) { int i; for (i = 0; i < ARRAY_SIZE(boot_os); i++) boot_os[i] += gd->reloc_off; relocated = 1; } printf("Ready to boot %s from %x\n\n", is_zImage ? "zImage" : "Image", images.ep); boot_fn = boot_os[images.os.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; }