BOOL CDlgBatteryParam::SaveKernel( BYTE *pKernel,UINT uiKernelSize,CString strKernelPath ) { CString strTmpKernelFile; PUINT puiCrc; GetModuleFileName(NULL, strTmpKernelFile.GetBuffer(MAX_PATH), MAX_PATH); strTmpKernelFile.ReleaseBuffer(); strTmpKernelFile = strTmpKernelFile.Left(strTmpKernelFile.ReverseFind(_T('\\'))+1); strTmpKernelFile += _T("tmp_file.bin"); CFile file; BOOL bRet; bRet = file.Open(strTmpKernelFile,CFile::modeCreate|CFile::modeReadWrite|CFile::typeBinary); if (!bRet) { return FALSE; } try { puiCrc = (PUINT)(pKernel+uiKernelSize-4); *puiCrc = CRC_32(pKernel+8,uiKernelSize-12); file.WriteHuge(pKernel,uiKernelSize); } catch (...) { file.Close(); return FALSE; } file.Close(); bRet = CopyFile(strTmpKernelFile,strKernelPath,FALSE); if (bRet) { DeleteFile(strTmpKernelFile); } return bRet; }
/************************************************************** *This is parameter packaging tool, the format of command is: * *mkparameter [src_path] [target_path] */ int main(int argc, char **argv) { if(argc != 3) { printf("args error! the command is: mkparameter [src_path] [target_path]\n"); return -1; } printf("src_path: %s, target_path: %s\n", argv[1], argv[2]); char* src_path = argv[1]; //original parameter file char* target_path = argv[2]; FILE* fp_src = fopen(src_path, FILE_OPEN_RO); if(!fp_src) { printf("can't open file %s!\n", src_path); return -1; } struct stat srcFileInfo; stat(src_path, &srcFileInfo); unsigned int uiParmLength = srcFileInfo.st_size; printf("the original parameter size: %u\n", uiParmLength); unsigned char* buffer = malloc(uiParmLength + 20); *(unsigned int*)buffer = PARM_TAG; *(unsigned int*)(buffer + 4) = uiParmLength; unsigned int readCount = fread(buffer + 8, 1, uiParmLength, fp_src); if(readCount != uiParmLength) { printf("read original parameter error!\n"); fclose(fp_src); free(buffer); return -1; } *(unsigned int*)(buffer + 8 + uiParmLength) = CRC_32(buffer + 8, uiParmLength); fclose(fp_src); //write buffer to target file FILE* fp_target = fopen(target_path, FILE_OPEN_RW_CREATE); if(!fp_target) { printf("can't open file %s\n", target_path); free(buffer); return -1; } if(fwrite(buffer, 1, uiParmLength + 12, fp_target) != uiParmLength + 12) { printf("write file fail!"); fclose(fp_target); free(buffer); return -1; } fclose(fp_target); free(buffer); return 0; }
unsigned long File_Crc32( unsigned char*pfilebuf, unsigned long *filelen,FILE *fp,char*File_Name) { int file_block_length=0; unsigned long CRC32=0; unsigned char*temp=NULL; unsigned long file_length=0; /*参数容错*/ if(pfilebuf==NULL||File_Name==NULL||filelen==NULL) { LogDisplay("File_Crc32:parameter error!\r\n"); return -1; } temp=pfilebuf; *filelen=0; if((fp=fopen(File_Name,"rb")) == NULL) { LogDisplay("升级文件打开失败!\r\n"); return -1; } while(!feof(fp)) { /*每次读BUFFER_SIZE个字节,并返回成功读取的字节数*/ if((file_block_length = fread(temp,sizeof(char),BUF_SIZE,fp))>0) { temp+=file_block_length; file_length+=file_block_length; } } fclose(fp); sprintf(Print_Buf,"File:\t%s Read In Buffer Finished!\r\n",File_Name); LogDisplay(Print_Buf); sprintf(Print_Buf,"File Length is %d\r\n",file_length); LogDisplay(Print_Buf); LogDisplay("添加CRC校验\r\n"); CRC32=CRC_32(pfilebuf,file_length); *(pfilebuf+file_length)= (CRC32&0xff000000)>>24; *(pfilebuf+file_length+1)=(CRC32&0x00ff0000)>>16; *(pfilebuf+file_length+2)=(CRC32&0x0000ff00)>>8; *(pfilebuf+file_length+3)=(CRC32&0x000000ff); *filelen=file_length; return CRC32; }
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"); }