diff -uprN dvflasher_1_14_080121.new/ubl/include/nand.h dvflasher_1_14_080121/ubl/include/nand.h
--- dvflasher_1_14_080121.new/ubl/include/nand.h	2007-11-15 17:48:12.000000000 +0530
+++ dvflasher_1_14_080121/ubl/include/nand.h	2008-04-15 10:23:40.000000000 +0530
@@ -15,6 +15,8 @@
               Hefty modifications to NAND code, reducing code path to one, 
 			  regardless of page size.  Also adding ECC correction code.
 			  Removing static allocation of temp page data.
+		v1.14 - Amol Lad - 11-April-2008
+			  Factory marked bad block support
  ----------------------------------------------------------------------------- */
 
 
@@ -44,6 +46,7 @@
 // NAND flash commands
 #define NAND_LO_PAGE        0x00
 #define NAND_HI_PAGE        0x01
+#define NAND_PAGE_OOB       0x50
 #define NAND_LOCK           0x2A
 #define NAND_UNLOCK_START   0x23
 #define NAND_UNLOCK_END     0x24
@@ -82,9 +85,14 @@
 #define MAX_BYTES_PER_OP_SHIFT  (9)             // Num of right shifts to enable division by MAX_BYTES_PER_OP
 #define SPAREBYTES_PER_OP_SHIFT (5)             // Num of right shifts to get spare_bytes per op from bytes per op
 
+#define MAX_SPARE_SIZE          64              // Max size, 2k page spare area size
 // Macro gets the page size in bytes without the spare bytes 
 #define NANDFLASH_PAGESIZE(x) ( ( x >> 8 ) << 8 )
 
+#define BITS_PER_LONG_SHIFT 5
+// Macros for BBT management
+#define MARK_BAD(blk)    gNandInfo.bbt[(blk) >> BITS_PER_LONG_SHIFT] |= 1 << ((blk) - (((blk) >> BITS_PER_LONG_SHIFT) << BITS_PER_LONG_SHIFT))
+#define BLOCK_BAD(blk)   (gNandInfo.bbt[(blk) >> BITS_PER_LONG_SHIFT] & (1 << ((blk) - (((blk) >> BITS_PER_LONG_SHIFT) << BITS_PER_LONG_SHIFT))))
 
 // ----------------- NAND device and information structures --------------------
 // NAND_DEVICE_INFO structure
@@ -113,9 +121,13 @@ typedef struct _NAND_MEDIA_STRUCT_ {
 	Uint8   ECCOffset;          // Offset in spareBytePerOp for ECC Value
 	Bool    ECCEnable;			// Error correction enable (should be on by default)
 	Bool    bigBlock;			// TRUE - Big block device, FALSE - small block device
+	Uint8   spareBytesPerPage;  // Number of bytes in spare byte area of each page   	
 	Uint8   blkShift;			// Number of bits by which block address is to be shifted
 	Uint8   pageShift;			// Number of bits by which page address is to be shifted
 	Uint8   CSOffset;           // 0 for CS2 space, 1 for CS3 space, 2 for CS4 space, 3 for CS5 space
+	Uint16  spareOffset;        // Offset where spare area starts in a given page
+	Uint8   bbOffset;           // bad block marker location in the spare area
+	Uint32  *bbt;               // This is bbt
 } NAND_INFO, *PNAND_INFO;
 
 typedef union {
@@ -153,6 +165,14 @@ Uint32 NAND_GetDetails();
 Uint32 NAND_ReadPage(Uint32 block, Uint32 page, Uint8 *dest);
 Uint32 NAND_WritePage(Uint32 block, Uint32 page, Uint8 *src);
 Uint32 NAND_VerifyPage(Uint32 block, Uint32 page, Uint8 *src, Uint8* dest);
+void   flash_write_addr_cycles_spare(PNAND_INFO pNandInfo, Uint32 block, Uint32 page);
+Uint32 NAND_ReadPageOOB(Uint32 block, Uint32 page, Uint8 *dest);
+Uint8  NAND_blockBad(Uint32 blockNum);
+Int32  NAND_getnextgoodblock(Uint32 blockNum);
+void   NAND_bbt(void);
+Bool   NAND_blockBadNoBBT(Uint32 block);
+Uint32 NAND_WriteUbl(NAND_BOOT *nandBoot, Uint8 *srcBuf);
+Uint32 NAND_WriteCore(NAND_BOOT *nandBoot, Uint8 *srcBuf, Int32 *endBlkNum, Int32 lastHeaderBlk);
 
 // Copy Application code from NAND to RAM (found in nandboot.c)
 Uint32 NAND_Copy();
diff -uprN dvflasher_1_14_080121.new/ubl/src/nandboot.c dvflasher_1_14_080121/ubl/src/nandboot.c
--- dvflasher_1_14_080121.new/ubl/src/nandboot.c	2007-11-15 17:48:12.000000000 +0530
+++ dvflasher_1_14_080121/ubl/src/nandboot.c	2008-04-15 10:13:51.000000000 +0530
@@ -14,6 +14,9 @@
  	                             application as a binary image and use the 
  	                             UBL_MAGIC_DMA magic number in the application
  	                             header.
+ 	     v1.11 
+ 	          Amol Lad - April-11-2008 - Skip Factory marked bad blocks in NAND_Copy
+	                                     and some cleanups 
  ----------------------------------------------------------------------------- */
 
 #ifdef UBL_NAND
@@ -41,7 +44,6 @@ Uint32 NAND_Copy() {
 	Uint32 entryPoint2,temp;
 	Uint32 block,page;
 	Uint32 readError = E_FAIL;
-	Bool failedOnceAlready = FALSE;
 
     // Maximum application size, in S-record form, is 16 MB
 	rxBuf = (Uint8*)ubl_alloc_mem((MAX_IMAGE_SIZE>>1));
@@ -52,10 +54,6 @@ Uint32 NAND_Copy() {
 	// NAND Initialization
 	if (NAND_Init() != E_PASS)
 		return E_FAIL;
-    
-NAND_startAgain:
-	if (blockNum > END_APP_BLOCK_NUM)
-		return E_FAIL;  /* NAND boot failed and return fail to main */
 
 	// Read data about Application starting at START_APP_BLOCK_NUM, Page 0
 	// and possibly going until block END_APP_BLOCK_NUM, Page 0
@@ -102,32 +100,40 @@ NAND_startAgain:
 		set_current_mem_loc(get_current_mem_loc() - (MAX_IMAGE_SIZE>>1));
 	}
 
-NAND_retry:
 	/* initialize block and page number to be used for read */
 	block = gNandBoot.block;
 	page = gNandBoot.page;
 
     // Perform the actual copying of the application from NAND to RAM
 	for(i=0;i<gNandBoot.numPage;i++) {
+		Uint8 err = 0;
 	    // if page goes beyond max number of pages increment block number and reset page number
 		if(page >= gNandInfo.pagesPerBlock) {
 			page = 0;
-			block++;
+			do {    
+				block++;
+				if (block >= gNandInfo.numBlocks)
+				{
+					UARTSendData("\r\nBad Flash !!\r\n", FALSE);
+					return E_FAIL;
+				}
+			} while(NAND_blockBadNoBBT(block));
 		}
-		readError = NAND_ReadPage(block,page++,(&rxBuf[i*gNandInfo.bytesPerPage]));	/* Copy the data */
 
-		// We attempt to read the app data twice.  If we fail twice then we go look for a new
-		// application header in the NAND flash at the next block.
-		if(readError != E_PASS) {
-			if(failedOnceAlready) {
-				blockNum++;
-				goto NAND_startAgain;
-			}
-		    else {
-		        failedOnceAlready = TRUE;
-				goto NAND_retry;
-			}
+		// try twice before emitting failure
+		do {
+			readError = NAND_ReadPage(block,page,(&rxBuf[i*gNandInfo.bytesPerPage]));	/* Copy the data */
+			err++;
+		} while(readError != E_PASS && err < 2);
+		if (readError != E_PASS)
+		{
+			UARTSendData("NAND read failed, block - 0x", FALSE);
+			UARTSendInt(block);
+			UARTSendData(" Page - ", FALSE);
+			UARTSendInt(page);
+			return E_FAIL;
 		}
+		page++;
 	}
 
 	// Application was read correctly, so set entrypoint
diff -uprN dvflasher_1_14_080121.new/ubl/src/nand.c dvflasher_1_14_080121/ubl/src/nand.c
--- dvflasher_1_14_080121.new/ubl/src/nand.c	2007-11-15 17:48:12.000000000 +0530
+++ dvflasher_1_14_080121/ubl/src/nand.c	2008-04-15 10:16:14.000000000 +0530
@@ -17,6 +17,11 @@
               Hefty modifications to NAND code, reducing code path to one, 
 			  regardless of page size.  Also adding ECC correction code.
 			  Removing static allocation of temp page data.
+	     v1.14 - Amol Lad - 11-April-2008
+              -- Added Factory Marked Bad Block Support. Skip bad blocks during
+                 NAND erase and program operations
+              -- Added NAND_writeUbl and NAND_writeCore for better maintainability
+
  ----------------------------------------------------------------------------- */
 
 #ifdef UBL_NAND
@@ -138,6 +143,13 @@ void flash_write_addr_cycles(PNAND_INFO 
     flash_write_row_addr_bytes(pNandInfo, block, page);
 }
 
+// Used for writing spare area in large page devices
+void flash_write_addr_cycles_spare(PNAND_INFO pNandInfo, Uint32 block, Uint32 page)
+{
+    flash_write_addr_bytes(pNandInfo, pNandInfo->numColAddrBytes, pNandInfo->spareOffset);
+    flash_write_row_addr_bytes(pNandInfo, block, page);
+}
+
 void flash_write_addr_bytes(PNAND_INFO pNandInfo, Uint32 numAddrBytes, Uint32 addr)
 {    
     Uint32 i;
@@ -319,6 +331,55 @@ Uint32 NAND_ECCCorrection(PNAND_INFO pNa
 // NAND Init Functions
 // *******************
 
+// Construct NAND bbt by identifying factory marked bad blocks
+void NAND_bbt(void)
+{
+	Uint32 i,page;
+	Uint8 dest[MAX_SPARE_SIZE];
+
+	for (i = 0; i < gNandInfo.numBlocks; i++)
+	{
+		for (page = 0; page < 2; page++)
+		{
+			if (NAND_ReadPageOOB(i, page, dest) != E_PASS || dest[gNandInfo.bbOffset] != 0xff)
+			{
+				MARK_BAD(i);
+				UARTSendData((Uint8 *)"\r\nBad block 0x", FALSE);
+				UARTSendInt(i);
+				break;
+			}
+
+		}
+	}
+}
+
+// Useful when bbt is not present. Used during read
+Bool NAND_blockBadNoBBT(Uint32 block)
+{
+	Uint32 page;
+	Uint8 dest[MAX_SPARE_SIZE];
+
+	for (page = 0; page < 2; page++)
+		if (NAND_ReadPageOOB(block, page, dest) != E_PASS || dest[gNandInfo.bbOffset] != 0xff)
+		{
+			UARTSendData((Uint8 *)"\r\nBad block 0x", FALSE);
+			UARTSendInt(block);
+			return 1;
+		}
+	return 0;
+}
+
+// Get the next good block
+Int32 NAND_getnextgoodblock(Uint32 blockNum)
+{
+	Uint32 i;
+	for (i = blockNum + 1; i < gNandInfo.numBlocks; i++)
+		if (!BLOCK_BAD(i))
+			return i;
+	return -1;
+
+}
+
 // Initialze NAND interface and find the details of the NAND used
 Uint32 NAND_Init()
 {
@@ -406,9 +467,24 @@ Uint32 NAND_GetDetails()
 	}
 	if (gNandDevInfo[i].devID == 0x00) return E_FAIL;
 
+	// Assign Spare Bytes and Spare bytes offset values
+	gNandInfo.spareBytesPerPage = gNandDevInfo[i].bytesPerPage - gNandInfo.bytesPerPage;
+	gNandInfo.spareOffset = gNandInfo.bytesPerPage;
+
+	// Alloc mem for bad block table - bbt
+	gNandInfo.bbt = (Uint32 *)ubl_alloc_mem((gNandDevInfo[j].numBlocks >> BITS_PER_LONG_SHIFT) + 1);
+	for (j = 0; j < (gNandDevInfo[i].numBlocks >> BITS_PER_LONG_SHIFT) + 1 ; j++)
+		gNandInfo.bbt[j] = 0;
+				
 	// Assign the big_block flag
 	gNandInfo.bigBlock = (gNandInfo.bytesPerPage>MAX_BYTES_PER_OP)?TRUE:FALSE;
-	
+
+	// Assign bad block byte offset in spare area
+	if ( gNandInfo.bigBlock)
+		gNandInfo.bbOffset = 0x00;
+	else
+		gNandInfo.bbOffset = 0x05;
+
 	// Assign the bytes per operation value
 	gNandInfo.bytesPerOp = (gNandInfo.bytesPerPage>MAX_BYTES_PER_OP)?MAX_BYTES_PER_OP:gNandInfo.bytesPerPage;
 	
@@ -533,6 +609,36 @@ Uint32 NAND_ReadPage(Uint32 block, Uint3
 	return NAND_WaitForStatus(NAND_TIMEOUT);
 }
 
+// Routine to read spare area of page from NAND
+Uint32 NAND_ReadPageOOB(Uint32 block, Uint32 page, Uint8 *dest) 
+{
+	if(gNandInfo.bigBlock) {
+		// Write read command
+		flash_write_cmd((PNAND_INFO)&gNandInfo,NAND_LO_PAGE);
+
+		// Write address bytes
+		flash_write_addr_cycles_spare((PNAND_INFO)&gNandInfo, block, page);
+
+		// Additional confirm command for big_block devices
+		flash_write_cmd((PNAND_INFO)&gNandInfo, NAND_READ_30H);
+	} else {
+		// Write read command
+		flash_write_cmd((PNAND_INFO)&gNandInfo,NAND_PAGE_OOB);
+
+		// Write address bytes
+		flash_write_addr_cycles((PNAND_INFO)&gNandInfo, block, page);
+	}	
+
+	// Wait for data to be available
+	if(NAND_WaitForRdy(NAND_TIMEOUT) != E_PASS)
+		return E_FAIL;
+
+	flash_read_bytes((PNAND_INFO)&gNandInfo, (void*)(dest), gNandInfo.spareBytesPerPage);
+
+	// Return status check result
+	return NAND_WaitForStatus(NAND_TIMEOUT);
+	
+}
 // ********************
 // NAND Write Functions
 // ********************
@@ -617,31 +723,64 @@ Uint32 NAND_VerifyPage(Uint32 block, Uin
 	return E_PASS;
 }
 
+// *********************
+// Write and Verify data 
+// *********************
+Uint32 NAND_WritePageAndVerify(Uint32 block, Uint32 page, Uint8* src, Uint8* dest)
+{
+	if (NAND_WritePage(block, page, src) != E_PASS)
+	{
+		UARTSendData((Uint8 *)"Write Failed\n", FALSE);
+		return E_FAIL;
+	}
+		
+	waitloop(200);
+
+	// Verify the page just written
+	if (NAND_VerifyPage(block, page, src, dest) != E_PASS)
+	{
+		UARTSendData((Uint8 *)"Verify Failed\n", FALSE);
+		return E_FAIL;
+	}
+
+	return E_PASS;
+}
+
 // *******************************
 // NAND Flash erase block function
 // *******************************
 Uint32 NAND_EraseBlocks(Uint32 startBlkNum, Uint32 blkCnt)
 {	
 	Uint32 i;
+	Uint32 endBlkNum = startBlkNum + blkCnt - 1;
 		
 	// Do bounds checking
-	if ( (startBlkNum + blkCnt - 1) >= gNandInfo.numBlocks )
+	if ( endBlkNum >= gNandInfo.numBlocks )
 		return E_FAIL;
 	
 	// Output info about what we are doing
 	UARTSendData((Uint8 *)"Erasing blocks 0x", FALSE);
 	UARTSendInt(startBlkNum);
 	UARTSendData((Uint8 *)" through 0x", FALSE);
-	UARTSendInt(startBlkNum + blkCnt - 1);
+	UARTSendInt(endBlkNum);
 	UARTSendData((Uint8 *)".\r\n", FALSE);
 
-	for (i = 0; i < blkCnt; i++)
+	for (i = startBlkNum; i <= endBlkNum; i++)
 	{
+		// Skip the bad block
+		if (BLOCK_BAD(i))
+		{
+			UARTSendData((Uint8 *)"Skipping block 0x", FALSE);
+			UARTSendInt(i);
+			UARTSendData((Uint8 *)"\r\n", FALSE);
+			continue;
+		}
+        
 		// Start erase command
 		flash_write_cmd((PNAND_INFO)&gNandInfo, NAND_BERASEC1);
 
 		// Write the row addr bytes only
-		flash_write_row_addr_bytes((PNAND_INFO)&gNandInfo, (startBlkNum+i), 0);
+		flash_write_row_addr_bytes((PNAND_INFO)&gNandInfo, i, 0);
 		
 		// Confirm erase command
 		flash_write_cmd((PNAND_INFO)&gNandInfo, NAND_BERASEC2);
@@ -696,65 +835,92 @@ void NAND_ProtectBlocks(void)
 	flash_write_cmd((PNAND_INFO)&gNandInfo, NAND_LOCK);
 }
 
-// Generic function to write a UBL or Application header and the associated data
-Uint32 NAND_WriteHeaderAndData(NAND_BOOT *nandBoot, Uint8 *srcBuf) {
-	Uint32     endBlockNum;
-	Uint32     *ptr;
-	Uint32     blockNum;
-	Uint32     count;
-	Uint32     countMask;
-	Uint32     numBlks;
-	
-	// Get total number of blocks needed
-	numBlks = 0;
-	while ( (numBlks * gNandInfo.pagesPerBlock)  < (nandBoot->numPage + 1) )
-	{
-		numBlks++;
-	}
-	UARTSendData((Uint8 *)"Number of blocks needed for header and data: 0x", FALSE);
-	UARTSendInt(numBlks);
-	UARTSendData((Uint8 *)"\r\n", FALSE);
-
-	// Check whether writing UBL or APP (based on destination block)
-	blockNum = nandBoot->block;
-	if (blockNum == START_UBL_BLOCK_NUM)
-	{
-		endBlockNum = END_UBL_BLOCK_NUM;
+// This does all what is needed for writing to a good block. If the current
+// block is bad then it prepares the next good block which is within blkLimit
+Int32 NAND_prepareBlock(Int32 blockNum, Int32 blkLimit)
+{
+	// If the current block is bad then get the next good block
+	if (BLOCK_BAD(blockNum))
+	{
+		UARTSendData((Uint8 *)"Skipping block 0x", FALSE);
+		UARTSendInt(blockNum);
+		UARTSendData((Uint8 *)"\r\n", FALSE);
+		blockNum = NAND_getnextgoodblock(blockNum);
+		if (blockNum < 0 || blockNum > blkLimit)
+		{
+			UARTSendData((Uint8 *)"No good blocks left, aborting\n", FALSE);
+			return -1;
+		}
 	}
-	else if (blockNum == START_APP_BLOCK_NUM)
+	// Unprotect 
+	if (NAND_UnProtectBlocks(blockNum,1) != E_PASS)
 	{
-		endBlockNum = END_APP_BLOCK_NUM;
+		UARTSendData((Uint8 *)"Unprotect failed, block 0x", FALSE);
+		UARTSendInt(blockNum);
+		UARTSendData((Uint8 *)"\r\n", FALSE);
+		return -1;
 	}
-	else
+
+	// Erase
+	if (NAND_EraseBlocks(blockNum,1) != E_PASS)
 	{
-		return E_FAIL; /* Block number is out of range */
+		UARTSendData((Uint8 *)"Erase failed, block 0x", FALSE);
+		UARTSendInt(blockNum);
+		UARTSendData((Uint8 *)"\r\n", FALSE);
+		return -1;
 	}
 
-NAND_WRITE_RETRY:
-	if (blockNum > endBlockNum)
-	{
-		return E_FAIL;
+	// return block prepared
+	return blockNum;
+}
+
+// Write ubl from block 1 to block 5
+Uint32 NAND_WriteUbl(NAND_BOOT *nandBoot, Uint8 *srcBuf) 
+{
+	Uint32     blockNum;
+	Uint16     writeCnt = 0;
+	Int32      endBlkNum = 0; 
+	Uint8      ret;
+
+	// If possible, write ubl to all 5 blocks
+	for (blockNum = START_UBL_BLOCK_NUM; blockNum <= END_UBL_BLOCK_NUM; )
+	{
+		nandBoot->block = blockNum;
+		ret = NAND_WriteCore(nandBoot, srcBuf, &endBlkNum, END_UBL_BLOCK_NUM);
+		if (endBlkNum < 0)
+			break;
+
+		if (ret != E_FAIL)
+			writeCnt++;
+
+		blockNum = endBlkNum + 1;
 	}
+	// return failure if ubl write to all blocks failed
+	if (!writeCnt)
+		return E_FAIL;
+
+	return E_PASS;
+}
+
+Uint32 NAND_WriteCore(NAND_BOOT *nandBoot, Uint8 *srcBuf, Int32 *endBlkNum, Int32 lastHeaderBlk) 
+{
+	Uint32     *ptr;
+	Int32      blockNum;
+	Uint32     count;
+	Uint32     countMask;
+
+	// Start flashing
+	blockNum = nandBoot->block;
+
+	// Prepare the current block if it's good
+	blockNum = NAND_prepareBlock(blockNum, lastHeaderBlk);
+	if (blockNum < 0)
+		goto fail;
+
 	UARTSendData((Uint8 *)"Attempting to start in block number 0x", FALSE);
 	UARTSendInt(blockNum);
 	UARTSendData((Uint8 *)".\n", FALSE);
 
-	// Unprotect all needed blocks of the Flash 
-	if (NAND_UnProtectBlocks(blockNum,numBlks) != E_PASS)
-	{
-		blockNum++;
-		UARTSendData((Uint8 *)"Unprotect failed\n", FALSE);
-		goto NAND_WRITE_RETRY;
-	}
-
-	// Erase the block where the header goes and the data starts
-	if (NAND_EraseBlocks(blockNum,numBlks) != E_PASS)
-	{
-		blockNum++;
-		UARTSendData((Uint8 *)"Erase failed\n", FALSE);
-		goto NAND_WRITE_RETRY;
-	}
-		
 	// Setup header to be written
 	ptr = (Uint32 *) gNandTx;
 	ptr[0] = nandBoot->magicNum;
@@ -766,14 +932,8 @@ NAND_WRITE_RETRY:
 
 	// Write the header to page 0 of the current blockNum
 	UARTSendData((Uint8 *)"Writing header...\n", FALSE);
-	if (NAND_WritePage(blockNum, 0, gNandTx) != E_PASS)
-		return E_FAIL;
-		
-	waitloop(200);
-
-	// Verify the page just written
-	if (NAND_VerifyPage(blockNum, 0, gNandTx, gNandRx) != E_PASS)
-		return E_FAIL;
+	if (NAND_WritePageAndVerify(blockNum, 0, gNandTx, gNandRx) != E_PASS)
+		goto fail;
 
 	count = 1; 
 
@@ -782,26 +942,40 @@ NAND_WRITE_RETRY:
 	UARTSendData((Uint8 *)"Writing data...\n", FALSE);
 	do {
 		// Write the UBL or APP data on a per page basis
-		if (NAND_WritePage(blockNum, (count & countMask), srcBuf) != E_PASS)
-			return E_FAIL;
+		if (NAND_WritePageAndVerify(blockNum, (count & countMask), srcBuf, gNandRx) != E_PASS)
+			goto fail;
 
-		waitloop(200);
-		
-		// Verify the page just written
-		if (NAND_VerifyPage(blockNum, (count & countMask), srcBuf, gNandRx) != E_PASS)
-		    return E_FAIL;
-		
 		count++;
 		srcBuf += gNandInfo.bytesPerPage;
 		if (!(count & countMask))
 		{
 			blockNum++;
+		blockNum = NAND_prepareBlock(blockNum, gNandInfo.numBlocks);
+		if (blockNum < 0)
+			goto fail;
 		}
 	} while (count <= nandBoot->numPage);
 
+	if (endBlkNum)
+		*endBlkNum = blockNum;
 	NAND_ProtectBlocks();
-
 	return E_PASS;
+
+fail:
+	if (endBlkNum)
+		*endBlkNum = blockNum;
+	NAND_ProtectBlocks();
+	return E_FAIL;
+}
+
+Uint32 NAND_WriteHeaderAndData(NAND_BOOT *nandBoot, Uint8 *srcBuf) 
+{
+	// Check whether writing UBL or APP (based on destination block)
+	if (nandBoot->block == START_UBL_BLOCK_NUM)
+		return NAND_WriteUbl(nandBoot, srcBuf);
+	else if (nandBoot->block == START_APP_BLOCK_NUM)
+		return NAND_WriteCore(nandBoot, srcBuf, NULL, END_APP_BLOCK_NUM);
+	return E_FAIL;
 }
 
 #endif
diff -uprN dvflasher_1_14_080121.new/ubl/src/uartboot.c dvflasher_1_14_080121/ubl/src/uartboot.c
--- dvflasher_1_14_080121.new/ubl/src/uartboot.c	2007-11-15 17:48:12.000000000 +0530
+++ dvflasher_1_14_080121/ubl/src/uartboot.c	2008-04-15 10:26:27.000000000 +0530
@@ -8,6 +8,8 @@
     HISTORY
  	     v1.00 completion 							 						      
  	          Daniel Allred - Jan-22-2007                                              
+	     v1.01 Bad Block Table creation during NAND erase, program operations
+	          Amol Lad - April-11-2008
  ----------------------------------------------------------------------------- */
 
 #include "ubl.h"
@@ -205,6 +207,9 @@ UART_tryAgain:
 			    goto UART_tryAgain;
 			}   
 
+			// Create NAND bbt
+			NAND_bbt();
+
 			// Get magicNum
 			nandBoot.magicNum = ackHeader.magicNum;
 
@@ -293,6 +298,9 @@ UART_tryAgain:
 			    goto UART_tryAgain;
 			}
 
+			// Create NAND bbt
+			NAND_bbt();
+
 			// Unprotect the NAND Flash
 			NAND_UnProtectBlocks(1,gNandInfo.numBlocks - 1);
 
