int VFL_Verify(void) { int i; int foundSignature = false; LOGDBG("ftl: Attempting to read %d pages from first block of first bank.\n", NANDGeometry->pagesPerBlock); for(i = 0; i < NANDGeometry->pagesPerBlock; i++) { int ret; if((ret = nand_read_alternate_ecc(0, i, PageBuffer)) == 0) { u32 id = *((u32*) PageBuffer); if(id == FTL_ID_V1 || id == FTL_ID_V2 || id == FTL_ID_V3) { LOG("ftl: Found production format: %x\n", id); foundSignature = true; break; } else { LOGDBG("ftl: Found non-matching signature: %x\n", ((u32*) PageBuffer)); } } else { LOGDBG("ftl: page %d of first bank is unreadable: %x!\n", i, ret); } } if(!foundSignature || !hasDeviceInfoBBT()) { LOG("ftl: no signature or production format.\n"); return -1; } return 0; }
static bool findDeviceInfoBBT(int bank, void* deviceInfoBBT) { int lowestBlock = NANDGeometry->blocksPerBank - (NANDGeometry->blocksPerBank / 10); int block; for(block = NANDGeometry->blocksPerBank - 1; block >= lowestBlock; block--) { int page; int badBlockCount = 0; for(page = 0; page < NANDGeometry->pagesPerBlock; page++) { int ret; if(badBlockCount > 2) { LOGDBG("ftl: findDeviceInfoBBT - too many bad pages, skipping block %d\n", block); break; } ret = nand_read_alternate_ecc(bank, (block * NANDGeometry->pagesPerBlock) + page, PageBuffer); if(ret != 0) { if(ret == 1) { LOGDBG("ftl: findDeviceInfoBBT - found 'badBlock' on bank %d, page %d\n", (block * NANDGeometry->pagesPerBlock) + page); badBlockCount++; } LOGDBG("ftl: findDeviceInfoBBT - skipping bank %d, page %d\n", (block * NANDGeometry->pagesPerBlock) + page); continue; } if(memcmp(PageBuffer, "DEVICEINFOBBT\0\0\0", 16) == 0) { if(deviceInfoBBT) { memcpy(deviceInfoBBT, PageBuffer + 0x38, *((u32*)(PageBuffer + 0x34))); } return true; } else { LOGDBG("ftl: did not find signature on bank %d, page %d\n", (block * NANDGeometry->pagesPerBlock) + page); } } } return false; }
static int findDeviceInfoBBT(int bank, void* deviceInfoBBT) { uint8_t* buffer = malloc(Data->bytesPerPage); int lowestBlock = Data->blocksPerBank - (Data->blocksPerBank / 10); int block; for(block = Data->blocksPerBank - 1; block >= lowestBlock; block--) { int page; int badBlockCount = 0; for(page = 0; page < Data->pagesPerBlock; page++) { if(badBlockCount > 2) { DebugPrintf("ftl: findDeviceInfoBBT - too many bad pages, skipping block %d\r\n", block); break; } int ret = nand_read_alternate_ecc(bank, (block * Data->pagesPerBlock) + page, buffer); if(ret != 0) { if(ret == 1) { DebugPrintf("ftl: findDeviceInfoBBT - found 'badBlock' on bank %d, page %d\r\n", (block * Data->pagesPerBlock) + page); badBlockCount++; } DebugPrintf("ftl: findDeviceInfoBBT - skipping bank %d, page %d\r\n", (block * Data->pagesPerBlock) + page); continue; } if(memcmp(buffer, "DEVICEINFOBBT\0\0\0", 16) == 0) { if(deviceInfoBBT) { memcpy(deviceInfoBBT, buffer + 0x38, *((uint32_t*)(buffer + 0x34))); } free(buffer); return TRUE; } else { DebugPrintf("ftl: did not find signature on bank %d, page %d\r\n", (block * Data->pagesPerBlock) + page); } } } free(buffer); return FALSE; }
int ftl_setup() { if(HasFTLInit) return 0; nand_setup(); Data = nand_get_geometry(); Data2 = nand_get_data(); if(VFL_Init() != 0) { bufferPrintf("ftl: VFL_Init failed\r\n"); return -1; } if(FTL_Init() != 0) { bufferPrintf("ftl: FTL_Init failed\r\n"); return -1; } int i; int foundSignature = FALSE; DebugPrintf("ftl: Attempting to read %d pages from first block of first bank.\r\n", Data->pagesPerBlock); uint8_t* buffer = malloc(Data->bytesPerPage); for(i = 0; i < Data->pagesPerBlock; i++) { int ret; if((ret = nand_read_alternate_ecc(0, i, buffer)) == 0) { uint32_t id = *((uint32_t*) buffer); if(id == FTL_ID_V1 || id == FTL_ID_V2) { bufferPrintf("ftl: Found production format: %x\r\n", id); foundSignature = TRUE; break; } else { DebugPrintf("ftl: Found non-matching signature: %x\r\n", ((uint32_t*) buffer)); } } else { DebugPrintf("ftl: page %d of first bank is unreadable: %x!\r\n", i, ret); } } free(buffer); if(!foundSignature || !hasDeviceInfoBBT()) { bufferPrintf("ftl: no signature or production format.\r\n"); return -1; } if(VFL_Open() != 0) { bufferPrintf("ftl: VFL_Open failed\r\n"); return -1; } int pagesAvailable; int bytesPerPage; if(FTL_Open(&pagesAvailable, &bytesPerPage) != 0) { bufferPrintf("ftl: FTL_Open failed\r\n"); return -1; } HasFTLInit = TRUE; return 0; }