void boot_from_mem(unsigned int addr, int size) { if(kernel_addr != addr) memcpy(kernel_addr, addr, size); kernel_size = size; if(init_boot_linux()) { DISPLAY_MSG("FAILinvalid boot image"); } // DISPLAY_MSG("\nTrying to reset modem...\n"); smsm_ack_amss_crash(); // DISPLAY_MSG("\nbooting linux...\n"); mdelay(10); boot_linux(); return; }
static void usb_rx_cmd_complete(struct usb_request *req, unsigned actual, int status) { if(status != 0) return; if(actual > 4095) actual = 4095; cmdbuf[actual] = 0; dprintf("\n> %s\n",cmdbuf); // dprintf("usb_rx_cmd_complete() '%s'\n", cmdbuf); if(memcmp(cmdbuf, "reboot", 6) == 0) { tx_status("OKAY"); rx_cmd(); mdelay(100); board_reboot(); } #if 0 if(memcmp(cmdbuf, "debug:", 6) == 0) { void debug(char *cmd, char *resp); memcpy(cmdbuf, "OKAY", 5); tx_status(cmdbuf); rx_cmd(); mdelay(5000); dprintf("NOW!\n"); debug(cmdbuf + 6, cmdbuf + 4); return; } #endif if(memcmp(cmdbuf, "getvar:", 7) == 0) { char response[64]; strcpy(response,"OKAY"); if(!strcmp(cmdbuf + 7, "version")) { strcpy(response + 4, VERSION); } else if(!strcmp(cmdbuf + 7, "product")) { strcpy(response + 4, PRODUCTNAME); } else if(!strcmp(cmdbuf + 7, "serialno")) { strcpy(response + 4, serialno); } else { board_getvar(cmdbuf + 7, response + 4); } tx_status(response); rx_cmd(); return; } if(memcmp(cmdbuf, "download:", 9) == 0) { char status[16]; rx_addr = kernel_addr; rx_length = hex2unsigned(cmdbuf + 9); if (rx_length > (64*1024*1024)) { tx_status("FAILdata too large"); rx_cmd(); return; } kernel_size = rx_length; dprintf("recv data addr=%x size=%x\n", rx_addr, rx_length); strcpy(status,"DATA"); num_to_hex8(rx_length, status + 4); tx_status(status); rx_data(); return; } if(memcmp(cmdbuf, "erase:", 6) == 0){ struct ptentry *ptn; ptn = flash_find_ptn(cmdbuf + 6); if(ptn == 0) { tx_status("FAILpartition does not exist"); rx_cmd(); return; } dprintf("erasing '%s'\n", ptn->name); cprintf("erasing '%s'", ptn->name); if(flash_erase(ptn)) { tx_status("FAILfailed to erase partition"); rx_cmd(); cprintf(" - FAIL\n"); return; } else { dprintf("partition '%s' erased\n", ptn->name); cprintf(" - OKAY\n"); } tx_status("OKAY"); rx_cmd(); return; } if(memcmp(cmdbuf, "flash:", 6) == 0){ struct ptentry *ptn; int extra = 0; ptn = flash_find_ptn(cmdbuf + 6); if(kernel_size == 0) { tx_status("FAILno image downloaded"); rx_cmd(); return; } if(ptn == 0) { tx_status("FAILpartition does not exist"); rx_cmd(); return; } if(!strcmp(ptn->name,"boot") || !strcmp(ptn->name,"recovery")) { if(memcmp((void*) kernel_addr, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { tx_status("FAILimage is not a boot image"); rx_cmd(); return; } } #if REQUIRE_SIGNATURE { unsigned char digest[DIGEST_SIZE]; compute_digest((void*) kernel_addr, kernel_size, digest); if (is_signature_okay(digest, signature, key_engineering)) { dprintf("verified by engineering key\n"); } else { tx_status("FAILsignature did not verify"); rx_cmd(); return; } } #endif if(!strcmp(ptn->name,"system") || !strcmp(ptn->name,"userdata")) { extra = 64; } else { kernel_size = (kernel_size + 2047) & (~2047); } dprintf("writing %d bytes to '%s'\n", kernel_size, ptn->name); cprintf("writing '%s' (%d bytes)", ptn->name, kernel_size); if(flash_write(ptn, extra, (void*) kernel_addr, kernel_size)) { tx_status("FAILflash write failure"); rx_cmd(); cprintf(" - FAIL\n"); return; } else { dprintf("partition '%s' updated\n", ptn->name); cprintf(" - OKAY\n"); } tx_status("OKAY"); rx_cmd(); return; } if(memcmp(cmdbuf, "boot", 4) == 0) { if(init_boot_linux()) { tx_status("FAILinvalid boot image"); rx_cmd(); return; } dprintf("booting linux...\n"); cprintf("\nbooting linux...\n"); tx_status("OKAY"); mdelay(10); usb_shutdown(); boot_linux(); return; } if(memcmp(cmdbuf, "signature", 9) == 0) { if (kernel_size != SIGNATURE_SIZE) { tx_status("FAILsignature not 256 bytes long"); rx_cmd(); return; } memcpy(signature, (void*)kernel_addr, SIGNATURE_SIZE); tx_status("OKAY"); rx_cmd(); return; } tx_status("FAILinvalid command"); rx_cmd(); }
void nand_boot(int nand_boot_select) { unsigned int offset, size; void (*kernel)(int, char **, char *); int i; static u32 *param_addr = 0; static u8 *tmpbuf = 0; static u8 cmdline[256] = CFG_CMDLINE; serial_puts_info("Enter nand_boot routine ...\n"); switch (nand_boot_select) { case NORMAL_BOOT: offset = CFG_BOOT_OFFS; size = CFG_BOOT_SIZE; #ifdef BOOTARGS_NORMAL strcpy((char *)cmdline, BOOTARGS_NORMAL); #endif serial_puts_info("Normal boot ...\n"); break; case RECOVERY_BOOT: offset = CFG_RECOVERY_OFFS; size = CFG_RECOVERY_SIZE; #ifdef BOOTARGS_RECOVERY strcpy((char *)cmdline, BOOTARGS_RECOVERY); #endif serial_puts_info("Recovery boot ...\n"); break; #if defined(CONFIG_JZ4760_PT701_8) case PRETEST_BOOT: offset = CFG_PRETEST_OFFS; size = CFG_PRETEST_SIZE; serial_puts_info("Pretest boot ...\n"); break; #endif default: serial_puts_info("Get nand boot select failed, defualt normal boot ...\n"); offset = CFG_BOOT_OFFS; size = CFG_BOOT_SIZE; break; } serial_puts_info("Load kernel from NAND ...\n"); /* Load kernel and ramdisk */ do_nand(offset,CFG_NAND_PAGE_SIZE,(u8 *)CFG_KERNEL_DST); struct boot_img_hdr *bootimginfo; int kernel_actual; int ramdisk_actual; unsigned int page_mask; if(2048 < sizeof(struct boot_img_hdr)){ serial_puts_info("size too small"); } bootimginfo = (struct boot_img_hdr *)CFG_KERNEL_DST; page_mask = CFG_NAND_PAGE_SIZE - 1; kernel_actual = (bootimginfo->kernel_size + page_mask) & (~page_mask); ramdisk_actual = (bootimginfo->ramdisk_size + page_mask) & (~page_mask); size = kernel_actual + ramdisk_actual + M; // ' + M' to make sure including the special data. do_nand(offset + CFG_NAND_PAGE_SIZE, size, (u8 *)(CFG_KERNEL_DST + CFG_NAND_PAGE_SIZE)); #ifdef CONFIG_SECURITY_ENABLE // Special data is 4M from head. if(data_verify((unsigned char *)CFG_KERNEL_DST, 4 * M, ENV_BOOTLOADER) < 0) { serial_puts_spl("kernel verify failed, power off\n"); //powerdown(); while(1); } #endif #if 0 serial_puts_info("CRC32 = 0x"); serial_put_hex(CRC_32(CFG_KERNEL_DST,2973696)); serial_put_hex(*((unsigned int *)(CFG_KERNEL_DST+0))); serial_put_hex(*((unsigned int *)(CFG_KERNEL_DST+4))); serial_put_hex(*((unsigned int *)(CFG_KERNEL_DST+8))); serial_put_hex(*((unsigned int *)(CFG_KERNEL_DST+12))); #endif serial_puts_info("Prepare kernel parameters ...\n"); /* init kernel, ramdisk and prepare parameters */ if (init_boot_linux((unsigned char*)CFG_KERNEL_DST, size) == 0) { serial_puts_info("Jump to kernel start Addr 0x"); dump_uint(CFG_KERNEL_DST); serial_puts("\n\n"); kernel = (void (*)(int, char **, char *))CFG_KERNEL_DST; flush_cache_all(); #if CONFIG_XBOOT_LOGO_FILE //__lcd_display_off(); #endif /* Jump to kernel image */ (*kernel)(2, (char **)(PARAM_BASE + 16), (char *)PARAM_BASE); serial_puts_info("We should not come here ... \n"); } else serial_puts_info("Magic number error,boot error...\n"); }