阅读:12264回复:48
【原创】支持2K大页面NAND FLASH驱动的NBOOT改进源码
之前提供了2K大页面的WINCE5.0/4.2的驱动源码,并告知了eboot的修改,可能又很多网友是从nand flash启动的,nboot也需要修改,现在一并把源码发上来,与之前的驱动配套使用,nboot中有nand.h,选相应的FLASH类型设为1,如果都为0,则表示nboot只能用于小页面的K9S1208,否则就是2K大页面的,
#define K9F1G08_SUPPORT (0) #define K9F2G08_SUPPORT (0) #define K9F4G08_SUPPORT (1) /*选定512M的*/ #define K9F8G08_SUPPORT (0) 在NBOOT中只能设定一种FLASH类型,不支持动态识别,因为代码大小限制的原因,我不能把他们的处理接口同时编译进来,会超出4K的代码限制。 把该NBOOT解压到你的SMDK2440/目录下,它编译的时候会找loader.h,请确认是否能找到。 |
|
|
沙发#
发布于:2007-01-16 12:22
2440loader.c中存在一个bug,有个全局变量
TOC toc; 这个结构大小是512字节的,但把它的地址传入FMD_ReadSector(TOC_SECTOR, (LPBYTE)&toc, NULL, 1) 对于2K大页面的FLASH,它会越界,可能引起问题,建议修改如下: BYTE toc[2048]; TOC *ptoc=(TOC *)toc; // made global because it's too big for our tiny stack DWORD ReadImageFromNand(DWORD dwEntry, DWORD dwSig) { DWORD dwSectorsNeeded; DWORD dwSector, dwLength; // Start Sector & Length DWORD dwRAM, i; if ( !FMD_ReadSector(TOC_SECTOR, (LPBYTE)ptoc, NULL, 1) ) { Uart_SendString("ERR_DISK_OP_FAIL1\n"); return ERR_DISK_OP_FAIL1; } if ( !VALID_TOC(ptoc) ) { Uart_SendString("ERR_INVALID_TOC: "); Uart_SendDWORD(ptoc->dwSignature, TRUE); return ERR_INVALID_TOC; } if ( !(ptoc->id[dwEntry].dwImageType & IMAGE_TYPE_RAMIMAGE) ) { Uart_SendString("ERR_INVALID_FILE_TYPE: "); Uart_SendDWORD(ptoc->id[dwEntry].dwImageType, TRUE); return ERR_INVALID_FILE_TYPE; } // ?? // if ( !(toc.id[dwEntry].dwImageType & IMAGE_TYPE_BINFS) ) { // dwSectorsNeeded = toc.id[dwEntry].dwTtlSectors; // } else { dwSectorsNeeded = ptoc->id[dwEntry].dwTtlSectors; // xipkernel size = 0x9B4 // } Uart_SendString("Sector addr on NAND: "); Uart_SendDWORD(ptoc->id[dwEntry].sgList[0].dwSector, TRUE); Uart_SendString("TotalSector: "); Uart_SendDWORD(dwSectorsNeeded, TRUE); dwRAM = VIRTUAL_TO_PHYSICAL(ptoc->id[dwEntry].dwLoadAddress); JumpAddr = ptoc->id[dwEntry].dwJumpAddress ? VIRTUAL_TO_PHYSICAL(ptoc->id[dwEntry].dwJumpAddress) : VIRTUAL_TO_PHYSICAL(ptoc->id[dwEntry].dwLoadAddress); // // Load the disk image directly into RAM // BUGBUG: recover from read failures // Uart_SendString("Reading Kernel Image from NAND\r\n"); i = 0; while (dwSectorsNeeded && i < MAX_SG_SECTORS) { dwSector = ptoc->id[dwEntry].sgList.dwSector; dwLength = ptoc->id[dwEntry].sgList.dwLength; Uart_SendString(" dwSector: "); Uart_SendDWORD(dwSector, TRUE); Uart_SendString(" dwLength: "); Uart_SendDWORD(dwLength, TRUE); Uart_SendString(" dwRAM: "); Uart_SendDWORD(dwRAM, TRUE); // read each sg segment while (dwLength) { if ( !FMD_ReadSector(dwSector, (LPBYTE)dwRAM, NULL, 1) ) { Uart_SendString("ERR_DISK_OP_FAIL2: "); Uart_SendDWORD(dwSector, TRUE); dwSector++; continue; // return ERR_DISK_OP_FAIL2; } dwSector++; dwLength--; dwRAM += SECTOR_SIZE; } dwSectorsNeeded -= ptoc->id[dwEntry].sgList.dwLength; i++; } // We only do this if the dwRAM is not zero (The default tocblock1 // set the dwRAM to be 0) if (ptoc->chainInfo.dwLoadAddress == 0) { return ERR_SUCCESS; } // Load the Chain.bin stored on NAND to the SDRAM // if ( toc.id[dwEntry].dwImageType == 6 ) // For WinCE 4.2 Image // if ( 1 ) // For WinCE 4.2 Image // { // dwRAM = VIRTUAL_TO_PHYSICAL(toc.id[dwEntry].dwLoadAddress); // dwSectorsNeeded = toc.id[dwEntry].sgList->dwLength; // dwSector = toc.id[dwEntry].sgList->dwSector; // } // else { dwRAM = VIRTUAL_TO_PHYSICAL(ptoc->chainInfo.dwLoadAddress); // 0x303c0000 dwSectorsNeeded = ptoc->chainInfo.dwLength; // 0x20 dwSector = ptoc->chainInfo.dwFlashAddress; // 0x103c0 // dwSectorsNeeded = 0x20; // dwSector = 0x104C0; } |
|