U_BOOT_CMD(
nand_boot, CONFIG_SYS_MAXARGS, 1, do_nand_boot,
" nand_boot - load linux and ramdisk from NAND flash and boot kernel\n",
NULL
);
int do_nand_boot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
DECLARE_GLOBAL_DATA_PTR;
int ret;
bd_t *bd = gd->bd;
ulong addr, data, len, initrd_start, initrd_end;
void (*theKernel)(int zero, int arch, uint params);
int strlen;
#ifdef CONFIG_CMDLINE_TAG
char *commandline = getenv ("bootargs");
#endif
#ifdef CFG_UBOOT_PROFILING
extern unsigned int boot_time;
unsigned int time_do_nand_boot= get_timer(0);
unsigned int time_rootfs;
unsigned int time_load_bootimg;
unsigned int ubt;
#endif
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
defined (CONFIG_CMDLINE_TAG) || \
defined (CONFIG_INITRD_TAG) || \
defined (CONFIG_SERIAL_TAG) || \
defined (CONFIG_REVISION_TAG) || \
defined (CONFIG_LCD) || \
defined (CONFIG_VFD)
setup_start_tag (bd);
#ifdef CONFIG_SERIAL_TAG
setup_serial_tag (¶ms);
#endif
#ifdef CONFIG_REVISION_TAG
setup_revision_tag (¶ms);
#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS
if(g_boot_mode == FACTORY_BOOT)
{
setup_memory_tags_factory(bd);
}
else
{
setup_memory_tags(bd);
}
#endif
//#ifdef CONFIG_CMDLINE_TAG
//****************
//* according to current boot mode to set boot tag and related boot args
//*
switch(g_boot_mode)
{
//********************************************************************
//* NORMAL BOOT
//********************************************************************
case NORMAL_BOOT:
#if defined(CFG_NAND_BOOT)
strlen += sprintf(commandline, "%s%s%x%s%x",
commandline, NAND_MANF_CMDLINE, nand_flash_man_code, NAND_DEV_CMDLINE, nand_flash_dev_id);
#endif
setup_boot_tag(NORMAL_BOOT);
ret = mboot_android_load_bootimg_hdr(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_header_error("Android Boot Image");
}
#ifdef CFG_UBOOT_PROFILING
time_load_bootimg= get_timer(0);
#endif
ret = mboot_android_load_bootimg(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
#ifdef CFG_UBOOT_PROFILING
printf("[PROFILE] ------- load boot.img takes %d ms -------- \n", get_timer(time_load_bootimg));
#endif
if (ret < 0) {
msg_img_error("Android Boot Image");
}
break;
//********************************************************************
//* META
//********************************************************************
case META_BOOT:
#ifdef CFG_META_MODE
//printf("[META] - Old bootargs : %s\n",commandline);
//commandline=strcat(commandline,META_BOOTARGS);
//printf("[META] - New bootargs : %s\n",commandline);
setup_boot_tag(META_BOOT);
setup_meta_com_tag(g_boot_arg->meta_com_type, g_boot_arg->meta_com_id);
#endif
ret = mboot_android_load_bootimg_hdr(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_header_error("Android Boot Image");
}
ret = mboot_android_load_bootimg(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_img_error("Android Boot Image");
}
break;
//********************************************************************
//* ADVANCED META MODE
//********************************************************************
case ADVMETA_BOOT:
//printf("[META] - Old bootargs : %s\n",commandline);
//commandline=strcat(commandline, ADV_META_BOOTARGS);
//printf("[META] - New bootargs : %s\n",commandline);
setup_boot_tag(ADVMETA_BOOT);
setup_meta_com_tag(g_boot_arg->meta_com_type, g_boot_arg->meta_com_id);
ret = mboot_android_load_bootimg_hdr(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_header_error("Android Boot Image");
}
ret = mboot_android_load_bootimg(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_img_error("Android Boot Image");
}
break;
//********************************************************************
//* ANDROID RECOVERY
//********************************************************************
case RECOVERY_BOOT:
#ifdef CFG_RECOVERY_MODE
setup_boot_tag(RECOVERY_BOOT);
#endif
ret = mboot_android_load_recoveryimg_hdr(PART_RECOVERY, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_header_error("Android Recovery Image");
}
ret = mboot_android_load_recoveryimg(PART_RECOVERY, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_img_error("Android Recovery Image");
}
break;
//********************************************************************
//* FACTORY
//********************************************************************
case FACTORY_BOOT:
#if defined(CFG_NAND_BOOT)
strlen += sprintf(commandline, "%s%s%x%s%x",
commandline, NAND_MANF_CMDLINE, nand_flash_man_code, NAND_DEV_CMDLINE, nand_flash_dev_id);
#endif
#ifdef CFG_FACTORY_MODE
setup_boot_tag(FACTORY_BOOT);
#endif
//*************
//* parse recovery image header
//*
ret = mboot_android_load_factoryimg_hdr(CFG_FACTORY_NAME, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
printf("factory image doesn't exist in SD card\n");
// load boot image from nand
ret = mboot_android_load_bootimg_hdr(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_header_error("Android Boot Image");
}
ret = mboot_android_load_bootimg(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_img_error("Android Boot Image");
}
}
else
{
// load the factory image
ret = mboot_android_load_factoryimg(CFG_FACTORY_NAME, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_img_error("Android Factory Image");
}
}
break;
//********************************************************************
//* ATE_FACTORY_BOOT
//********************************************************************
case ATE_FACTORY_BOOT:
#if defined(CFG_NAND_BOOT)
strlen += sprintf(commandline, "%s%s%x%s%x",
commandline, NAND_MANF_CMDLINE, nand_flash_man_code, NAND_DEV_CMDLINE, nand_flash_dev_id);
#endif
#ifdef CFG_FACTORY_MODE
setup_boot_tag(ATE_FACTORY_BOOT);
#endif
//*************
//* parse recovery image header
//*
ret = mboot_android_load_factoryimg_hdr(CFG_FACTORY_NAME, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
printf("factory image doesn't exist in SD card\n");
// load boot image from nand
ret = mboot_android_load_bootimg_hdr(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_header_error("Android Boot Image");
}
ret = mboot_android_load_bootimg(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_img_error("Android Boot Image");
}
}
else
{
// load the factory image
ret = mboot_android_load_factoryimg(CFG_FACTORY_NAME, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_img_error("Android Factory Image");
}
}
break;
//********************************************************************
//* SW BOOT
//********************************************************************
case SW_REBOOT:
setup_boot_tag(SW_REBOOT);
ret = mboot_android_load_bootimg_hdr(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_header_error("Android Boot Image");
}
ret = mboot_android_load_bootimg(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_img_error("Android Boot Image");
}
break;
//********************************************************************
//* ALARM BOOT
//********************************************************************
case ALARM_BOOT:
#if defined(CFG_NAND_BOOT)
strlen += sprintf(commandline, "%s%s%x%s%x",
commandline, NAND_MANF_CMDLINE, nand_flash_man_code, NAND_DEV_CMDLINE, nand_flash_dev_id);
#endif
setup_boot_tag(ALARM_BOOT);
ret = mboot_android_load_bootimg_hdr(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
if (ret < 0) {
msg_header_error("Android Boot Image");
}
#ifdef CFG_UBOOT_PROFILING
time_load_bootimg= get_timer(0);
#endif
ret = mboot_android_load_bootimg(PART_BOOTIMG, CFG_BOOTIMG_LOAD_ADDR);
#ifdef CFG_UBOOT_PROFILING
printf("[PROFILE] ------- load boot.img takes %d ms -------- \n", get_timer(time_load_bootimg));
#endif
if (ret < 0) {
msg_img_error("Android Boot Image");
}
break;
}
//*************
//* relocate rootfs (ignore rootfs header)
//*
#ifdef CFG_UBOOT_PROFILING
time_rootfs = get_timer(0);
#endif
//if(g_boot_mode == RECOVERY_BOOT)
//{
memcpy((char *)CFG_RAMDISK_LOAD_ADDR, (char *)(g_rmem_off), g_rimg_sz);
//}
g_rmem_off = CFG_RAMDISK_LOAD_ADDR;
#ifdef CFG_UBOOT_PROFILING
printf("[PROFILE] ------- reloate rootfs takes %d ms -------- \n", get_timer(time_rootfs));
#endif
strlen += sprintf(commandline, "%s%s%s",
commandline,
" uboot_ver=" UBOOT_VERSION_CLI,
" uboot_build_ver=" BUILD_VERSION_CLI
);
#ifdef CFG_UBOOT_PROFILING
ubt = ((unsigned int)get_timer(boot_time)) + 810;
strlen += sprintf(commandline, "%s%s%d", commandline, ".ubt.", ubt);
#endif
/**
* The function "custom_port_in_kernel" is used to modify UART port acorrding different requirement.
* It may change ttyMT3 to ttyMT0. This function is implemented at uart.c.
*/
custom_port_in_kernel(g_boot_mode, commandline);
strlen += sprintf(commandline, "%s lcm=%1d-%s", commandline, DISP_IsLcmFound(), mt65xx_disp_get_lcm_id());
strlen += sprintf(commandline, "%s fps=%1d", commandline, mt65xx_disp_get_lcd_time());
setup_commandline_tag (bd, commandline);
//#endif //CONFIG_CMDLINE_TAG
//*************
//* dump some starting instruction for debug
//*
//printf(" theKernel (0x%x)\n",g_kmem_off);
//printf(" theKernel (0x%x) = 0x%x\n",g_kmem_off,DRV_Reg32(g_kmem_off));
//printf(" theKernel (0x%x) = 0x%x\n",g_kmem_off+0x4,DRV_Reg32(g_kmem_off+0x4));
//printf(" theKernel (0x%x) = 0x%x\n",g_kmem_off+0x8,DRV_Reg32(g_kmem_off+0x8));
//*************
//* dump some starting instruction for debug
//*
//printf("\n rootfs (0x%x)\n",g_rmem_off);
//printf(" rootfs (0x%x) = 0x%x\n",g_rmem_off,DRV_Reg32(g_rmem_off));
//printf(" rootfs (0x%x) = 0x%x\n",g_rmem_off+0x4,DRV_Reg32(g_rmem_off+0x4));
//printf(" rootfs (0x%x) = 0x%x\n",g_rmem_off+0x8,DRV_Reg32(g_rmem_off+0x8));
//*************
//* specify the kernel jumping address
//*
theKernel = (void (*)(int, int, uint)) (g_kmem_off);
//printf("\n > kernel mem offset (not include header) = 0x%x\n",theKernel);
//*************
//* specify the rootfs starting address
//*
initrd_start = g_rmem_off;
initrd_end = initrd_start + g_rimg_sz;
//printf(" > rootfs mem offset (not include header) = 0x%x\n\n",initrd_start);
#ifdef CONFIG_INITRD_TAG
if (initrd_start && initrd_end)
setup_initrd_tag (bd, initrd_start, initrd_end);
#endif
#if CONFIG_VIDEOLFB_TAG
setup_videolfb_tag ((gd_t *) gd);
#endif
setup_end_tag (bd);
#endif
#ifdef CFG_UBOOT_PROFILING
printf("[PROFILE] ------- do_nand_boot takes %d ms -------- \n", get_timer(time_do_nand_boot));
printf("[MBOOT] ------- UBoot boot kernel takes %d ms -------- \n", get_timer(boot_time));
#endif
printf("NAND BOOT\n");
#ifdef CONFIG_LCD
video_printf("NAND BOOT\n");
video_printf("Boot Linux Kernel\n");
#endif
//*****************
//* to centralize deinit process, moving
//* "Uboot_power_saving" to "cleanup_before_linux"
//*
cleanup_before_linux();
printf(" > kernel mem offset (not include header) = 0x%x\n",theKernel);
//*****************
//* jump to kernel
//*
theKernel(0, bd->bi_arch_number, bd->bi_boot_params);
return 0;
}
g_kmem_off = CFG_KIMAGE_LOAD_ADDR;
:#define CFG_KIMAGE_LOAD_ADDR (RIL_SIZE + 0x8000)
#ifdef CFG_RESERVE_MEM_FOR_RIL
#if defined (MODEM_3G)
#define RIL_SIZE 0x1600000
#elif defined (MODEM_2G)
#define RIL_SIZE 0x0A00000
#endif
#else
#define RIL_SIZE 0
#endif