精华内容
下载资源
问答
  • YAFFS(Yet Another Flash File System)是由Aleph One公司所发展出来的NAND flash 嵌入式文件系统。 此文来源于对CSDN博客整理,对NAND FLASH的移植指导
  • 基于VxWorks的YAFFS2文件系统移植,郭利军,戴志涛,目前,NAND Flash已经广泛应用在各种嵌入式系统中。VxWorks操作系统使用TFFS软件管理NAND Flash,TFFS使用NFTL转换层将NAND Flash设备模拟成磁盘��
  • yaffs2文件系统移植

    2019-11-26 11:58:28
    (1)文件系统中没有包含linuxrc的可执行文件。在文件系统中添加linuxrc就可完成linux的启动。 (2)在/driver/mtd/nand/s3c2410.c中将chip->ecc.mode = NAND_ECC_SOFT;改为chip->ecc.mode = NAND_ECC_NON...

    4.内核启动时,出现Failed to execute /linuxrc的错误,原因是:
    (1)文件系统中没有包含linuxrc的可执行文件。在文件系统中添加linuxrc就可完成linux的启动。
    (2)在/driver/mtd/nand/s3c2410.c中将chip->ecc.mode = NAND_ECC_SOFT;改为chip->ecc.mode = NAND_ECC_NONE;并在配置内核中将Samsung S3C NAND Hardware ECC选项删掉。

    这个问题纠结了我好久,我遇见这个问题后,先尝试用nfs挂载,能够挂载上,所以我确定肯定是nandflash出了问题了,以为nandflash坏了(因为被我不停的擦写,嘿嘿),后来用天嵌自带的镜像试了是好的,我就明白了,估计是我的nand驱动有问题了,仔细检查驱动,发现内核配置中的Samsung S3C NAND Hardware ECC没有去掉,,一个小小的问题折磨了我这么久。所以一定一定要仔细啊。
    ————————————————
    版权声明:本文为CSDN博主「wzw12315」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/wzw12315/article/details/6366754/

    展开全文
  • 构建驱动模块3--基于STM32 Nand Flash yaffs2文件系统移植  Yaffs(Yet Another FlashFile System)文件系统是专门针对NAND闪存设计的嵌入式文件系统,目前有YAFFSYAFFS2两个版本,两个版本的主要区别之一在于...

                构建驱动模块3--基于STM32 Nand Flash yaffs2文件系统移植

      Yaffs(Yet Another FlashFile System)文件系统是专门针对NAND闪存设计的嵌入式文件系统,目前有YAFFS和YAFFS2两个版本,两个版本的主要区别之一在于YAFFS2能够更好的支持大容量的NAND FLASH芯片。本程序实现YAFFS2的移植。

    一、硬件环境

       NAND FLASH 芯片:K9F1G08

      STM32 :STM32F103ZET6 CPU 72MHz

    二、实现代码

          首先根据STM32 NANDFLASH管理器,实现基本NAND FLASH操作,包括读写、擦除操作等。

    #define NANDFLASH_RW_PAGE_SIZE 2048
    #define NANDFLASH_SPARE_SIZE 64
    #define NANDFLASH_PAGE_PER_BLOCK		64
    #define NANDFLASH_PAGE_FSIZE		(NANDFLASH_RW_PAGE_SIZE + NANDFLASH_SPARE_SIZE)
    #define NANDFLASH_BLOCK_FSIZE	(NANDFLASH_PAGE_FSIZE * NANDFLASH_PAGE_PER_BLOCK)
    #define NANDFLASH_INVALIDBLOCK_CHECK_COLUMM			(1024)
    #define NANDFLASH_NUMOF_BLOCK		1024
    ht_uint8_t InvalidBlockTable[NANDFLASH_NUMOF_BLOCK];
    ht_int32_t NandFlash_PageReadFromAddr(ht_uint32_t blockNum, ht_uint32_t pageNum, ht_uint32_t addrInPage, ht_uint8_t* bufPtr, ht_uint32_t size);
    ht_int32_t NandFlash_ReadFromAddr(ht_uint32_t addrInWholeNand, ht_uint8_t* bufPtr, ht_uint32_t size);
    ht_int32_t NandFlash_PageReadFromBeginning(ht_uint32_t blockNum, ht_uint32_t pageNum, ht_uint8_t* bufPtr);
    
    
      /**********************************************************************************************************
     *
     *  函数名:NAND_Init
     *  功 能:
     *  参  数:
     *  返回值:
     *  版 本: 
     *
     **********************************************************************************************************/
    void NAND_Init(void)
    {
    	GPIO_InitTypeDef GPIO_InitStructure; 
    	FSMC_NANDInitTypeDef FSMC_NANDInitStructure;
    	FSMC_NAND_PCCARDTimingInitTypeDef  p;
    
      	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
    	
    	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOD | 
      							RCC_APB2Periph_GPIOE | 
                             	RCC_APB2Periph_GPIOF | 
    							RCC_APB2Periph_GPIOG, ENABLE);
      
    // CLE, ALE, D0->D3, NOE, NWE and NCE2  NAND pin configuration  
      	GPIO_InitStructure.GPIO_Pin = 	GPIO_Pin_11 | 	// PD.11(A16->CLE)
      									GPIO_Pin_12 |	// PD.12(A17->ALE)
    									GPIO_Pin_14 |  	// PD.14(D0)
    									GPIO_Pin_15 |  	// PD.15(D1)
                                     	GPIO_Pin_0 	| 	// PD.00(D2)
    								 	GPIO_Pin_1 	| 	// PD.01(D3)
    								 	GPIO_Pin_4 	| 	// PD.04(NOE)
    								 	GPIO_Pin_5 	| 	// PD.05(NWE)
                                     	GPIO_Pin_7;    	// PD.07(NCE2)                              
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
    	GPIO_Init(GPIOD, &GPIO_InitStructure); 
    
    // D4->D7 NAND pin configuration  
    	GPIO_InitStructure.GPIO_Pin = 	GPIO_Pin_7 |  	// PE.07(D4)
    									GPIO_Pin_8 | 	// PE.08(D5)
    									GPIO_Pin_9 | 	// PE.09(D6)
    									GPIO_Pin_10;	// PE.10(D7) 
    	GPIO_Init(GPIOE, &GPIO_InitStructure);
    
    
    //NWAIT NAND pin configuration 
    //  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    //  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    //  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	
    //  GPIO_Init(GPIOD, &GPIO_InitStructure); 
    
    
    // INT2 NAND pin configuration   
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;		// PG.06(R/B)
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    	GPIO_Init(GPIOD, &GPIO_InitStructure); 
    
    //-- FSMC Configuration --
    	p.FSMC_SetupTime = 0x1;
    	p.FSMC_WaitSetupTime = 0x3;
    	p.FSMC_HoldSetupTime = 0x2;
    	p.FSMC_HiZSetupTime = 0x1;
    
    	FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;
    	FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;
    	FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
    	FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;
    	FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_2048Bytes;
    	FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;
    	FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;
    	FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
    	FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;
    
    	FSMC_NANDInit(&FSMC_NANDInitStructure);
    
    	FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);
    }
    
     
     
      /**********************************************************************************************************
     *
     *  函数名:NAND_Reset
     *  功 能:
     *  参  数:
     *  返回值:
     *  版 本: 
     *
     **********************************************************************************************************/
    ht_uint32_t NAND_Reset(void)
    {
    	NAND_WriteCmd(0xFF);  	
    	return (NAND_READY);
    }
    
     /**********************************************************************************************************
     *
     *  函数名:NAND_GetStatus
     *  功 能:
     *  参  数:
     *  返回值:
     *  版 本: 
     *
     **********************************************************************************************************/
    ht_uint32_t NAND_GetStatus(void)
    {
    	ht_uint32_t timeout = 0x10000, status = NAND_READY;
    	
    	status = NAND_ReadStatus(); 
    	
    	while ((status != NAND_READY) &&( timeout != 0x00))
    	{
    		status = NAND_ReadStatus();
    		timeout --;      
    	}
    	
    	if(timeout == 0x00)
    	{          
    		status =  NAND_TIMEOUT_ERROR;
    	} 
    	
    	return (status);
    }
     
    
     
    
     /**********************************************************************************************************
     *
     *  函数名:NAND_ReadStatus
     *  功 能:
     *  参  数:
     *  返回值:
     *  版 本: 
     *
     **********************************************************************************************************/
    ht_uint32_t NAND_ReadStatus(void)
    {
    	ht_uint32_t data = 0x00, status = NAND_BUSY;
    	
    	NAND_WriteCmd(0x70);
    	data = NAND_ReadDat();
    	
    	if((data & NAND_ERROR) == NAND_ERROR)
    	{
    		status = NAND_ERROR;
    	} 
    	else 
    	if((data & NAND_READY) == NAND_READY)
    	{
    		status = NAND_READY;
    	}
    	else
    	{
    		status = NAND_BUSY; 
    	}
    	
    	return (status);
    }
    
    /**********************************************************************************************************
     *
     *  鍑芥暟鍚嶏細NandFlash_ReadId
     *  鍔熴€€鑳斤細 
     *  鍙? 鏁帮細
     *  杩斿洖鍊硷細
     *  鐗堛€€鏈細REV1.0.0          2016/04/27    Create
     *
     **********************************************************************************************************/
    ht_uint32_t NandFlash_ReadId(void)
    {
    	ht_uint32_t a,b,c,d;
    		
    	NAND_WriteCmd(0x90);
    	NAND_WriteAddr(0x00);
    
    	a = NAND_ReadDat();
    	b = NAND_ReadDat();
    	c = NAND_ReadDat();
    	d = NAND_ReadDat();
    	
    	return ((a << 24) | (b << 16) | (c << 8) | d);
    }
    
    /**********************************************************************************************************
     *
     *  鍑芥暟鍚嶏細NandFlash_BlockErase
     *  鍔熴€€鑳斤細 
     *  鍙? 鏁帮細
     *  杩斿洖鍊硷細
     *  鐗堛€€鏈細REV1.0.0          2016/04/27    Create
     *
     **********************************************************************************************************/
    
    ht_bool_t NandFlash_BlockErase( ht_uint32_t blockNum )
    {
    
    	ht_uint32_t rowAddr;
    	ht_int32_t iResult=1;
    	rowAddr = blockNum * NANDFLASH_PAGE_PER_BLOCK;
    	NAND_WriteCmd(0x60); 
    	NAND_WriteAddr((ht_uint8_t)(rowAddr&0xFF));  
        NAND_WriteAddr((ht_uint8_t)((rowAddr&0xFF00) >> 8));  
    	NAND_WriteCmd(0xD0);
    	while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );
    	iResult= (NAND_GetStatus());
    	if(iResult==NAND_TIMEOUT_ERROR)
    	  iResult=e_FALSE; 
    		else
    	  iResult=e_TRUE; 
    	  return iResult;
    
    
    }
    /**********************************************************************************************************
     *
     *  鍑芥暟鍚嶏細NandFlash_ValidBlockCheck
     *  鍔熴€€鑳斤細 
     *  鍙? 鏁帮細
     *  杩斿洖鍊硷細
     *  鐗堛€€鏈細REV1.0.0          2016/04/27    Create
     *
     **********************************************************************************************************/
    
    ht_bool_t NandFlash_ValidBlockCheck( void )
    {
    	ht_int32_t block, page;
    	ht_bool_t retValue = e_TRUE;
    
    	ht_int8_t data = 0;
    
    	for ( block = 0; block < NANDFLASH_NUMOF_BLOCK; block++ )
    	{
    		for ( page = 0; page < 2; page++ )
    		{
    	 
    			NandFlash_PageReadFromAddr(block, page, NANDFLASH_INVALIDBLOCK_CHECK_COLUMM, &data, 1);
    
    			if(data != 0xFF)
    			{
    				// found invalid block number, mark block number in the invalid
    				// block table
    				InvalidBlockTable[block] = 0;
    				//At least one block is invalid
    				retValue = e_FALSE;
    			}else{
    			   	InvalidBlockTable[block] = 1;
    			}
    		}
    	}
    
    	return(retValue);
    }
    /**********************************************************************************************************
     *
     *  鍑芥暟鍚嶏細NandFlash_PageRead
     *  鍔熴€€鑳斤細 
     *  鍙? 鏁帮細
     *  杩斿洖鍊硷細
     *  鐗堛€€鏈細REV1.0.0          2016/04/27    Create
     *
     **********************************************************************************************************/
    
    ht_int32_t NandFlash_PageRead( ht_uint32_t pageNum, ht_uint32_t blockNum, ht_uint8_t *bufPtr )
    {
    	return (NandFlash_PageReadFromBeginning(pageNum, blockNum, bufPtr) != 0);
    }
    /**********************************************************************************************************
     *
     *  鍑芥暟鍚嶏細NandFlash_PageReadFromBeginning
     *  鍔熴€€鑳斤細 
     *  鍙? 鏁帮細
     *  杩斿洖鍊硷細
     *  鐗堛€€鏈細REV1.0.0          2016/04/27    Create
     *
     **********************************************************************************************************/
    
    ht_int32_t NandFlash_PageReadFromBeginning(ht_uint32_t blockNum, ht_uint32_t pageNum, ht_uint8_t* bufPtr)
    {
    	return (NandFlash_PageReadFromAddr(blockNum, pageNum, 0, bufPtr, NANDFLASH_PAGE_FSIZE));// 鎿嶄綔鐨勬槸fsize
    }
    /**********************************************************************************************************
     *
     *  鍑芥暟鍚嶏細NandFlash_PageReadFromAddr
     *  鍔熴€€鑳斤細 
     *  鍙? 鏁帮細
     *  杩斿洖鍊硷細
     *  鐗堛€€鏈細REV1.0.0          2016/04/27    Create
     *
     **********************************************************************************************************/
    
    ht_int32_t NandFlash_PageReadFromAddr(ht_uint32_t blockNum, ht_uint32_t pageNum, ht_uint32_t addrInPage, ht_uint8_t* bufPtr, ht_uint32_t size)
    {
    	ht_uint32_t curAddr = 0;
    
    	curAddr += blockNum * NANDFLASH_BLOCK_FSIZE;	// 鎿嶄綔鐨勬槸fsize
    
    	curAddr += pageNum * NANDFLASH_PAGE_FSIZE;	// 鎿嶄綔鐨勬槸fsize
    
    	curAddr += addrInPage;
    
    	return (NandFlash_ReadFromAddr(curAddr, bufPtr, size));
    }
    
    /**********************************************************************************************************
     *
     *  鍑芥暟鍚嶏細NandFlash_ReadFromAddr
     *  鍔熴€€鑳斤細 
     *  鍙? 鏁帮細
     *  杩斿洖鍊硷細
     *  鐗堛€€鏈細REV1.0.0          2016/04/27    Create
     *
     **********************************************************************************************************/
     ht_int32_t NandFlash_ReadFromAddr(ht_uint32_t addrInWholeNand, ht_uint8_t* bufPtr, ht_uint32_t size)
    {
    
    	volatile ht_uint8_t nand_buf;
    	ht_uint32_t i, curColumm, curRow;
    	ht_int32_t iResult=1;
    
    	i = 0;
    	curColumm = addrInWholeNand % NANDFLASH_PAGE_FSIZE;		// 鎿嶄綔鐨勬槸fsize
    	curRow = addrInWholeNand / NANDFLASH_PAGE_FSIZE;			// 鎿嶄綔鐨勬槸fsize
    	NAND_WriteCmd(0x00); 
    	NAND_WriteCmd( (ht_uint8_t)(curColumm & 0x000000FF));			/* column address low */
    	NAND_WriteCmd( (ht_uint8_t)((curColumm & 0x00000F00) >> 8));		/* column address high */
    	NAND_WriteCmd( (ht_uint8_t)(curRow & 0x000000FF));		/* row address low */
    	NAND_WriteCmd( (ht_uint8_t)((curRow & 0x0000FF00) >> 8));
    	NAND_WriteCmd(0x30); 
    	while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );
    	//Get data from the current address in the page til the end of the page
    	for ( i = 0; i < (NANDFLASH_PAGE_FSIZE - curColumm); i++ )
    	{
    		*bufPtr = NAND_ReadDat();
    		if((i + 1) >= size)
    			break;
    		bufPtr++;
    	}
    	iResult= NAND_GetStatus();
    	if(iResult==NAND_TIMEOUT_ERROR)
    		   iResult=0;
    			  else
    		  iResult=i;
    	return iResult;
    }
    
    
    /**********************************************************************************************************
     *
     *  鍑芥暟鍚嶏細NandFlash_SectorRead
     *  鍔熴€€鑳斤細 
     *  鍙? 鏁帮細
     *  杩斿洖鍊硷細
     *  鐗堛€€鏈細REV1.0.0          2016/04/27    Create
     *
     **********************************************************************************************************/
    
    ht_int32_t NandFlash_SectorRead(ht_uint32_t sectorNum, ht_uint8_t* bufPtr)
    {
    	ht_uint32_t curAddr = 0;
    
    	curAddr += sectorNum * 512;
    	curAddr +=(sectorNum/4)*NANDFLASH_SPARE_SIZE;
    	return (NandFlash_ReadFromAddr(curAddr, bufPtr, 512));
    }
    /**********************************************************************************************************
     *
     *  鍑芥暟鍚嶏細Nand_EraseBlockLarge
     *  鍔熴€€鑳斤細 
     *  鍙? 鏁帮細
     *  杩斿洖鍊硷細
     *  鐗堛€€鏈細REV1.0.0          2016/04/27    Create
     *
     **********************************************************************************************************/
    
    ht_int32_t  Nand_EraseBlockLarge(ht_int32_t BlockAddr)
    {
    	ht_uint32_t rowAddr;
    	ht_int32_t iResult=1;
    	rowAddr = BlockAddr * NANDFLASH_PAGE_PER_BLOCK;
    	NAND_WriteCmd(0x60); 
    	NAND_WriteAddr((ht_uint8_t)(rowAddr&0xFF));  
        NAND_WriteAddr((ht_uint8_t)((rowAddr&0xFF00) >> 8));  
    	NAND_WriteCmd(0xD0);
    	while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );
    	iResult= (NAND_GetStatus());
    	if(iResult==NAND_TIMEOUT_ERROR)
    	  iResult=0; 
    		else
    	  iResult=1; 
    	  return iResult;
    
    }
    
    
    /**********************************************************************************************************
     *
     *  鍑芥暟鍚嶏細Nand_WritePageWithSpare2048
     *  鍔熴€€鑳斤細 
     *  鍙? 鏁帮細
     *  杩斿洖鍊硷細
     *  鐗堛€€鏈細REV1.0.0          2016/04/27    Create
     *
     **********************************************************************************************************/
    
    ht_int32_t  Nand_WritePageWithSpare2048(ht_int32_t PageNum,const ht_uint8_t * DataBuf,const ht_uint8_t *Spare)
    {
    	ht_int32_t iResult=1;
    	volatile ht_uint32_t i, curAddr, curColumm,curRow,k;
        if(DataBuf == NULL)
    	    curColumm = NANDFLASH_RW_PAGE_SIZE;
        else
            curColumm = 0;
    	curRow = PageNum;
    	NAND_WriteCmd(0x80);
    	NAND_WriteAddr( (ht_uint8_t)(curColumm & 0x000000FF));		/* column address low */
    	NAND_WriteAddr( (ht_uint8_t)((curColumm & 0x00000F00) >> 8));	/* column address high */
    	NAND_WriteAddr((ht_uint8_t)(curRow & 0x000000FF));		/* row address low */
    	NAND_WriteAddr((ht_uint8_t)((curRow & 0x0000FF00) >> 8));
        if(DataBuf != NULL)
        {
        	for ( i = 0; i < NANDFLASH_RW_PAGE_SIZE; i++ )
        	{
        		NAND_WriteDat( DataBuf[i]);
        	}
        }
    
        if(Spare != NULL)
        {
            for ( i = 0; i < NANDFLASH_SPARE_SIZE; i++ ) // 娣诲姞鍐檚pare
        	{
        		NAND_WriteDat( Spare[i]);
        	}
        }
        
        NAND_WriteCmd(0x10);	
    k=10000;
     	while( (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 )&&(k>0))
    	{
    		k--;
    	}
     
      	iResult= (NAND_GetStatus());
    	if(iResult==NAND_ERROR)
    	  iResult=0; 
    		else
    	  iResult=1; 
    
    }
    /**********************************************************************************************************
     *
     *  鍑芥暟鍚嶏細Nand_ReadPageWithSpare2048
     *  鍔熴€€鑳斤細 
     *  鍙? 鏁帮細
     *  杩斿洖鍊硷細
     *  鐗堛€€鏈細REV1.0.0          2016/04/27    Create
     *
     **********************************************************************************************************/
    
    ht_int32_t Nand_ReadPageWithSpare2048(ht_int32_t PageNum,ht_uint8_t *const DataBuf, ht_uint8_t *const Spare)
    {
    	volatile ht_uint8_t nand_buf;
    	ht_uint32_t i, curColumm, curRow;
        volatile ht_uint8_t j;
        ht_int32_t iResult=1;
    	i = 0;
       /*if(DataBuf == NULL)
    	    curColumm = NANDFLASH_RW_PAGE_SIZE;
        else
            curColumm = 0;*/
    	curColumm = 0;
    	curRow = PageNum;
    	NAND_WriteCmd(0x00); 
    	NAND_WriteAddr((ht_uint8_t)(curColumm & 0x000000FF));			/* column address low */
    	NAND_WriteAddr((ht_uint8_t)((curColumm & 0x00000F00) >> 8));		/* column address high */
    	NAND_WriteAddr((ht_uint8_t)(curRow & 0x000000FF));		/* row address low */
    	NAND_WriteAddr((ht_uint8_t)((curRow & 0x0000FF00) >> 8));
    	NAND_WriteCmd(0x30); 
    	while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );
        
        if(DataBuf != NULL)
        {
            for(i=0;i<NANDFLASH_RW_PAGE_SIZE;i++)
            {
                DataBuf[i]=NAND_ReadDat();
            }
        }
        else
        {
            for(i=0;i<NANDFLASH_RW_PAGE_SIZE;i++)
            {
                j=NAND_ReadDat();
            } 
        }
        if(Spare!=NULL)
        {
            for(i=0;i<NANDFLASH_SPARE_SIZE;i++)
            {
            	Spare[i]=NAND_ReadDat();
            }
        }
        else
        {
            for(i=0;i<NANDFLASH_SPARE_SIZE;i++)
            {
            	j=NAND_ReadDat();
            }
        }
        
      	iResult= (NAND_GetStatus());
    	if(iResult==NAND_TIMEOUT_ERROR)
    	  iResult=0; 
    		else
    	  iResult=1; 
    
    }
    

    2、实现与硬件相关的yaffs2函数接口

    int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_ExtendedTags *tags);
    
    int yflash2_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
    
    int yflash2_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags);
    
    int yflash2_GetNumberOfBlocks();
     
     
     
    int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_ExtendedTags *tags)
    {
        yaffs_PackedTags2  *pkt;
        __u8  tmp[64]={'\0'};
        int result;
     
    	pkt=(yaffs_PackedTags2*)tmp;
    	yaffs_PackTags2(pkt,tags);
        
       result = Nand_WritePageWithSpare2048(chunkInNAND,data,tmp);// 返回1时表示写成功
        
    	if(result)
    	{
    		return  YAFFS_OK;
    	}	
     
    	return YAFFS_FAIL;
    }
    
    
    
     
    int yflash2_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags)
    {
        yaffs_PackedTags2   *upt;
        __u8  tmp[64]={'\0'};
        int result;
       
        result = Nand_ReadPageWithSpare2048(chunkInNAND,data,tmp);// 返回1时表示读成功
    
        upt = (yaffs_PackedTags2*)tmp;
    
        if(result)
    	{
    		yaffs_UnpackTags2(tags,upt);
            
    		return  YAFFS_OK;
    	}
    	
    	return YAFFS_FAIL;
    }

     

    3、yaffs2内存分配 <注意 yaffs2内存分配比较大,配置最小也得需要几十K内存>

    void *yaffs_malloc(size_t size)
    { 
    
        return (void *)cmMalloc(size);
    }
    
    void yaffs_free(void *ptr)
    {
        cmFree(ptr);
    }

    内存分配结果:

     4、yaffs2 参数配置

    int yaffs_StartUp(void)
    {   
    	memset(&flashDev,0,sizeof(flashDev));
    
        flashDev.name="yaffs2";
    	flashDev.totalBytesPerChunk = 1024;
        flashDev.nDataBytesPerChunk =2048;
        flashDev.spareBytesPerChunk = 64;
    	flashDev.nChunksPerBlock = 64;
    	flashDev.nReservedBlocks = 5;
    	flashDev.inbandTags = 0;
    
    	flashDev.startBlock = 0;
    	flashDev.endBlock = yflash2_GetNumberOfBlocks()-1;
    	flashDev.isYaffs2 = 1;
    	flashDev.wideTnodesDisabled=0;
    	flashDev.nShortOpCaches = 4; // Use caches
    	flashDev.genericDevice = (void *) 2;	// Used to identify the device in fstat.
    	flashDev.writeChunkWithTagsToNAND = yflash2_WriteChunkWithTagsToNAND;
    	flashDev.readChunkWithTagsFromNAND = yflash2_ReadChunkWithTagsFromNAND;
    	flashDev.eraseBlockInNAND = yflash2_EraseBlockInNAND;
    	flashDev.initialiseNAND = yflash2_InitialiseNAND;
    	flashDev.markNANDBlockBad = yflash2_MarkNANDBlockBad;
    	flashDev.queryNANDBlock = yflash2_QueryNANDBlock;
    
    	yaffs_initialise(yaffsfs_config);
    	
    	return 0;
    }
    

    5、yaffs2 测试程序

    void fstest(void)
    {
        int32_t i,file;
        uint32_t FlashID;
        uint8_t  BufToRead[256];
        uint8_t  BufWriteTo[256];
        
      
        
        for(i=0;i<256;i++)
        {
            BufToRead[i]=0;
            BufWriteTo[i]=i;
        }
        
        yaffs_StartUp();
        
        ht_printk("yaffs start up\r\n");
    
        i=yaffs_mount("//");
        
        if(i != 0)
        {
            ht_printk("yaffs mount error\r\n");
            
        }
        else
        {
            ht_printk("yaffs mount finsh\r\n");
        }
         i=yaffs_mkdir("/test",S_IFDIR);
        if(i != 0)
        {
            ht_printk("yaffs mkdir error\r\n");
        }
        else
        {
            ht_printk("yaffs mkdir finsh\r\n");
        }
    
     
    
        // 返回的是handle
        file= yaffs_open("/test/23.txt", O_CREAT | O_RDWR | O_APPEND, S_IREAD | S_IWRITE);
        ht_printk("yaffs open finsh\r\n");
        ht_printk("yaffs write\r\n");
        i=yaffs_write(file,BufWriteTo,256);
        ht_printk("yaffs read\r\n");
        i=yaffs_pread(file,BufToRead,256,0);
        ht_printk("yaffs_pread: ");
    		for(i=0;i<256;i++)
    		ht_printk("%02x ",BufToRead[i]);
    		ht_printk("\r\n");
        yaffs_close(file);
        
    }

    6、测试结果

    展开全文
  • yaffs2文件系统.pdf

    2020-03-05 10:01:41
     YAFFS文件系统性能优越且易于移植,已经成功应用于linux、uClinux和Windows CE等嵌入式操作系统上。 YAFFS是目前为止唯一一个专门为NAND flash设计的文件系统,目前有YAFFS 和YAFFS2 两个版本,两个版本的主要区别...
  • Yaffs2文件系统移植到mini2440

    千次阅读 2011-08-18 13:37:33
    Yaffs2文件系统移植到mini2440 现在大部分开发板都可以支持yaffs2 文件系统,它是专门针对嵌入式设备,特别是使用nand flash作为存储器的嵌入式设备而创建的一种文件系统,早先的yaffs仅支持小页(512byte/page)的...

    Yaffs2文件系统移植到mini2440

    现在大部分开发板都可以支持yaffs2 文件系统,它是专门针对嵌入式设备,特别是使用nand flash作为存储器的嵌入式设备而创建的一种文件系统,早先的yaffs仅支持小页(512byte/page)的nand flash,使用 yaffs2 就可以支持大页的 nand flash。

    所谓的根文件系统,就是创建各个目录,并且在里面创建各种文件,比如在/bin,/sbin/目录下存放各种可执行的程序,在/etc目录下存放配置文件,在/lib目录下存放库文件,下面就开始文件系统的移植。

    一、准备工作

    1.Yaffs2源代码的获取

    在http://www.yaffs.net/node/346可以下载到最新的yaffs2 源代码, 如果使用git工具,在命令行输入:

    #git clone git://www.aleph1.co.uk/yaffs2

    就可以下载到yaffs2的源代码,到当前目录下。

    2.下载Busybox-1.13.3

    可以从http://www.busybox.net/downloads/下载Busybox-1.13.3。

    3.下载Yaffs2的制作工具

    可以到友善之臂的网站下载,mkyaffs2image.tgz,其中解压出来有两个可执行的文件,一个是针对小页的,一个是针对NandFlash大页的,其名字为mkyaffs2image-128M,一开始在这里犯了错误,我的NandFlash是128MB的,可以按照网上用的是mkyaffs2image文件,所以老是出来假坏块的提示,仔细一分析,NandFlash不可能一下子出来这么多的坏块,而且我用他们公司提供的根文件系统却没有任何的问题,所以问题处在了制作Yaffs2的工具上面。因为这两种大小NandFlash的ECC校验是不一样的,也就是spare区的大小是不一样的,造成了ECC校验出错。

    4.链接库

    制作根文件系统时,要使用到链接库,这里直接使用友善之臂根文件系统中的链接库。从网站下载root_qtopia.tgz。使用lib目录下的链接库。

    5.给内核打上YAffs2补丁

    然后进入yaffs2源代码目录执行:

    #cd yaffs2
    #./patch-ker.sh c /opt/mini2440/linux-2.6.33.3

    此时进入linux-2.6.32.2/fs目录,可以看到已经多了一个yaffs2目录。

    上面命令完成下面三件事情:

    (1)   修改内核fs/Kconfig

    增加一行:source"fs/yaffs2/Kconfig"

    (2)   修改内核fs/Kconfig

    增加一行:ojb-$(CONFIG_YAFFS_FS)+=yaffs2/

    (3)   在内核fs/目录下创建yaffs2目录

    将yaffs2源码目录下面的Makefile.kernel文件复制为内核fs/yaffs2/Makefie;

    将yaffs2 源码目录的Kconfig文件复制到内核fs/yaffs2目录下;

    将yaffs2源码目录下的*.c *.h文件复制到内核fs/yaffs2目录下.

    6.配置内核以支持Yaffs2文件系统

    在Linux内核源代码根目录运行:make menuconfig,找到File Systems,再找到“Miscellaneousfilesystems”菜单项,找到“YAFFS2 file system support”,并选中它(如上图),这样我们就在内核中添加了yaffs2 文件系统的支持,保存退出。然后在命令行中,执行make uImage,这时不要在执行mage mini2440_defconfig了,如果再执行的话,前面的配置就失效了,在这我也犯了一个低级的错误。


    二、构建根文件系统

    1.根文件系统的目录结构

    bin 存放所有用户都可以使用的、基本的命令。
    sbin 存放的是基本的系统命令,它们用于启动系统、修复系统等。
    usr 里面存放的是共享、只读的程序和数据。
    proc 这是个空目录,常作为proc文件系统的挂载点。
    dev 该目录存放设备文件和其它特殊文件。
    etc 存放系统配置文件,包括启动文件。
    lib 存放共享库和可加载块(即驱动程序),共享库用于启动系统、运行根文件系统中的可执行程序。
    boot 引导加载程序使用的静态文件
    home 用户主目录,包括供服务账号锁使用的主目录,如FTP
    mnt 用于临时挂接某个文件系统的挂接点,通常是空目录。也可以在里面创建空的子目录。
    opt 给主机额外安装软件所摆放的目录。
    root root用户的主目录
    tmp 存放临时文件,通常是空目录。
    var 存放可变的数据。

    2.建立根文件系统的目录

    进入opt/mini2440/fs,创建一个shell的脚本用于构建根文件系统的各个目录。create_rootfs_bash,平且改变执行的权限。

    #chmod +x create_rootfs_bash

    在kernel目录下,运行./create_rootfs_bash,其脚本的内容如下:

    #!/bin/sh
    echo "------Create rootfs directons start...--------"
    mkdir rootfs
    cd rootfs
    echo "--------Create root,dev....----------"
    mkdir root dev etc boot tmp var sys proc lib mnt home usr
    mkdir etc/init.d etc/rc.d etc/sysconfig
    mkdir usr/sbin usr/bin usr/lib usr/modules
    echo "make node in dev/console dev/null"
    mknod -m 600 dev/console c 5 1
    mknod -m 600 dev/null c 1 3
    mkdir mnt/etc mnt/jffs2 mnt/yaffs mnt/data mnt/temp
    mkdir var/lib var/lock var/run var/tmp
    chmod 1777 tmp
    chmod 1777 var/tmp
    echo "-------make direction done---------"

    改变了tmp目录的使用权,让它开启sticky位,为tmp目录的使用权开启此位,可确保tmp目录底下建立的文件,只有建立它的用户有权删除。

    3.建立动态的链接库

    动态链接库直接使用友善之臂的,首先,下载友善之臂的根文件系统解压后得到root_qtopia,把该文件下的Lib下的文件全部复制到我们自己建立的lib/文件夹下。

    4.编译和安装Busybox

    Bosybox 是一个遵循GPL v2协议的开源项目,它在编写过程总对文件大小进行优化,并考虑了系统资源有限(比如内存等)的情况,使用 Busybox 可以自动生成根文件系统所需的bin、sbin、usr 目录和 linuxrc 文件。

    解压Busybox,然后

    #cd busybox-1.13.3

    //修改该目录下的makefile文件,修改平台为arm平台,修改编译器为默认的交叉编译器

    CROSS_COMPILE ?=arm-linux-   //大约在164行

    ARCH ?=arm  //大约在189行

    配置busybox,在busybox-1.13.3目录下,这里我们只关心改动的地方。执行make menuconfig,其各个选项的配置如下(只列出更改的):

    (1)Busybox Settings--->

    BuildOptions--->

    [*]Build BusyBox as a static binary(no shared libs)

    BusyboxLibrary Tuning --->

    (1024)Maximumlength of input

    [*]vi-style line editing commands

    [*]Fancyshell prompts

    (2)Linux System Utilities --->

    [*]Support/etc/mdev.conf

    [*]Supportcommand execution at device addition/removal

    (3) Linux Module Utilities---> [ ]simplified  modutils

    [*]insmod

    [*]rmmod

    [*]lsmod

    [*]modprobe

    5.编译busybox

    编译busybox到指定目录:#cd /opt/mini2440/busybox-1.13.3

    make CONFIG_PREFIX=/opt/kernel/rootfs install

    即:执行make CONFIG_PREFIX=根文件系统目录 install

    在rootfs目录下会生成目录bin、sbin、usr和文件linuxrc的内容。

    6.建立etc目录

    init进程根据/etc/inittab文件来创建其他的子进程,比如调用脚本文件配置IP地址,挂载其他的文件系统,最后启动shell等。

    (1)拷贝主机etc目录下的passwd、group、shadow文件到rootfs/etc目录下。

    (2)在etc/下创建mdev.conf文件

    内容为:

    # system all-writable devices

    full  0:0  0666

    null  0:0  0666

    ptmx  0:0  0666

    random  0:0  0666

    tty  0:0  0666

    zero  0:0  0666

    # console devices

    tty[0-9]* 0:5 0660

    vc/[0-9]* 0:5 0660

    # serial port devices

    s3c2410_serial0  0:5  0666  =ttySAC0

    s3c2410_serial1  0:5  0666  =ttySAC1

    s3c2410_serial2  0:5  0666  =ttySAC2

    s3c2410_serial3  0:5  0666  =ttySAC3

    # loop devices

    loop[0-9]*  0:0  0660  =loop/

    # i2c devices

    i2c-0  0:0  0666  =i2c/0

    i2c-1  0:0  0666  =i2c/1

    # frame buffer devices

    fb[0-9]  0:0  0666

    # input devices

    mice  0:0  0660  =input/

    mouse.*  0:0  0660  =input/

    event.*  0:0  0660  =input/

    ts.*  0:0  0660  =input/

    # rtc devices

    rtc0  0:0  0644  >rtc

    rtc[1-9]  0:0  0644

    # misc devices

    mmcblk0p1  0:0  0600  =sdcard */bin/hotplug.sh

    sda1  0:0  0600  =udisk * /bin/hotplug.sh

    (3)etc/inittab文件:仿照Busybox的examples/inittab文件,在etc/目录下创建一个inittab文件,写上以下内容:

    #etc/inittab

    ::sysinit:/etc/init.d/rcS

    ::askfirst:-/bin/sh

    ::ctrlaltdel:/sbin/reboot

    ::shutdown:/bin/umount -a -r

    (4)创建etc/init.d/rcS文件:

    这是一个脚本文件,可以在里面添加自动执行的命令

    #!/bin/sh

    PATH=/sbin:/bin:/usr/sbin:/usr/bin

    runlevel=S    //运行的级别

    prevlevel=N

    umask 022    //文件夹的掩码
    export PATH runlevel prevlevel
    echo"--------- munt all--------"
    mount –a    //挂载/etc/fstab/文件指定的所有的文件系统
    echo /sbin/mdev>/proc/sys/kernel/hotplug
    mdev -s
    echo "*************************"
    echo "**********************yuyang ARM**************"
    echo "Kernel version:linux-2.33.3"
    echo "Author:yuyang"
    echo "Data:2010,05,08"
    echo "***********************"
    /bin/hostname -F /etc/sysconfig/HOSTNAME   //主机的名字

    最后,还要改变它的属性,使它能够运行

    sudo chmod +x etc/init.d/rcS

    (5)etc/sysconfig目录下新建文件HOSTNAME,内容为”yuyang-mini2440”。

    (6)创建etc/fstab文件:

    内容如下,表示执行完,“mount -a”命令后将挂载proc,tmpfs等包含在该文件中的所有的文件系统。

    #device mount-point type option dump fsck order
    proc /proc proc defaults 0 0
    tmpfs /tmp tmpfs defaults 0 0
    none /tmp ramfs defaults 0 0
    sysfs /sys sysfs defaults 0 0
    mdev /dev ramfs defaults 0 0

    (7)创建etc/profile文件:

    #Ash profile
    #vim:syntax=sh
    #No core file by defaults
    #ulimit -S -c 0>/dev/null 2>&1
    USER="id -un"
    LOGNAME=$USER
    PS1='[\u@\h\W]#'
    PATH=$PATH
    HOSTNAME='/bin/hostname'
    export USER LOGNAME PS1 PATH

    三、制作根文件系统映像文件

    在前面也已经讲过,我的NandFlash是128MB的,所以要使用友善之臂的mkyaffs2image-128这个可执行的文件生成映像文件,使用命令mkyaffs2image-128M rootfs rootfs.img生成根文件系统映像文件。

    把生成的rootsfs.img文件下载到nandFlash中的根文件系统区。然后从NANDFlash启动可以看到启动信息。不过现在只是一个最基本的Linux系统,里面的驱动程序还没有,网上驱动,LCD驱动等等,所以还有很多的东西要移植呢。这也是下一步的任务。

    展开全文
  • Linux-2.6.32内核在mini2440上的移植 主要讲述yaffs2文件系统移植
  • yaffs2裸机移植过程.pdf

    2020-06-10 13:46:41
    yaffs2指导文档,帮助开发人员进行yaffs2裸机移植,步骤详细方向明确。介绍yaffs2的使用方法和测试函数接口。
  • linux在TQ2440上移植3--yaffs2 文件系统移植----经典
  • linux移植开发实战指南》,制作rootfs文件夹及其相关文件夹和文件,使用busybox生成相关文件和命令。 3、宿主机安装mkyaffs2image-128M命令。 4、执行mkyaffs2image-128M rootfs rootfs.img 5、在uboot中设置好...

    1、为内核打补丁,并在menuconfig里做相关设置。

    2、参考《mini2440 linux移植开发实战指南》,制作rootfs文件夹及其相关文件夹和文件,使用busybox生成相关文件和命令。

    3、宿主机安装mkyaffs2image-128M命令。

    4、执行mkyaffs2image-128M rootfs rootfs.img

    5、在uboot中设置好bootargs ‘root=/dev/mtdblock2 rw init=/linux rootfstype=yaffs2 console=/dev/console,115200 mem=64M’

    6、下载文件系统:tftp 0x30008000 rootfs.img

    7、下载烧写文件系统:

        nand erase 0x600000

        nand write.yaffs 0x30008000 0x600000 0x....

    展开全文
  • Linux-2.6.32内核在mini2440上的移植 yaffs2文件系统移植 (2013-03-29 20:45:05) 转载▼     移植环境(红色粗字体字为修改后内容,蓝色粗体字为特别注意内容) 1. yaffs2文件系统移植 ...
  • 移植环境(红色粗字体字为修改后内容,蓝色粗体字为特别注意内容) 1,主机环境:VMare下CentOS 5.5 ,1G内存。 2,集成开发环境:Elipse IDE 3,编译编译环境:arm-linux-gcc v4.4.3,arm-none-linux-gnueabi-gcc v...
  • 移植yaffs2文件系统

    2020-06-21 20:47:22
    yaffs2-source.tar 二、编译busybox 1.解压busybox-1.21.1.tar.bz2到Ubuntu的家目录 tar -jxf /mnt/hgfs/share/busybox-1.21.1.tar.bz2 -C ~ cd busybox-1.21.1 2.设置顶层目录的Makefile文件 a.修改交叉编译 ...
  • 一、开发环境 1、内核:Linux 2.6.22.6; 2、JZ2440; 3、ubuntu 9.10;...二、移植yaffs文件系统 1、解压yaffs_source.tar.gz。本文直接解压到当前目录。使用命令:tar xzf yaffs_source.tar.gz;
  • Yaffs2 文件系统移植

    2013-07-14 23:03:11
    转载地址:点击打开链接... ...一....1、yaffs2源代码获取 进入 http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/ ,点击“Download GNU tarball”,下载后出
  • yaffs2文件系统介绍

    2014-03-01 21:07:25
     YAFFS文件系统性能优越且易于移植,已经成功应用于linux、uClinux和Windows CE等嵌入式操作系统上。 YAFFS是目前为止唯一一个专门为NAND flash设计的文件系统,目前有YAFFS 和YAFFS2 两个版本,两个版本的主要区别...
  • 首先说一下最小文件系统需要的文件 (1)/dev/null/dev/consore这两个节点时一定要有的,/dev/consore是标准输入,标准输出,标准错误时要用到,也就是说我们要输入东西显示出来就要用到它,/dev/null是默认控制台 ...
  • FL2400--YAFFS2文件系统移植(三)

    千次阅读 2013-10-08 16:15:12
    配置完内核以后,接下来就是弄根文件系统了. ...根文件制作完成后,就是最复杂困难的制作YAFFS2文件系统的工具了. 在yaffs2源码utils 目录下make一下会出现mkyaffsimage和mkyaffs2image两个文件,这两个文件就是制作
  • 2、如下所示,为我的学习的文件夹,其中,yaffs2文件夹为下载的yaffs2文件,learn3_yaffs2为内核,进入yaffs2文件夹下,运行  ./patch-ker.sh c m ../learn3_yaffs2/linux-2.6.30.4/ 然后按照手册上给的,进行...
  • 由于项目需要,我在TI的dm365上移植了完整的yaffs文件支持,包括uboot支持yaffs烧写移植,对yaffs移植可能遇到的问题做了详细的解释,对大小页提供了不同支持工具。 遇到问题联系我。
  • 本文章主要针对FS100,S5PC100的Android4.0.4 Yaffs2文件系统移植过程,对于类似Android系统或类似Linux内核(版本高于2.6.35)有参考意义。 本文分两部分: Nandflash驱动移植Yaffs2文件系统移植 ...
  • 本文章主要针对FS100,S5PC100的Android4.0.4 Yaffs2文件系统移植过程,对于类似Android系统或类似Linux内核(版本高于2.6.35)有参考意义。 本文分两部分:  1.Nandflash驱动移植  2.Yaffs2文件系统移植 一...
  • yaffsyaffs2补丁,用于linux内核移植过程中的yaffs2文件所需要的补丁
  • yaffs2文件系统移植 编者:前面用的文件系统都是友善自带的文件系统,其GUI是基于QTOPIA,这个文件系统的功能还是比较强大的。这里我们可以自己移植一个根文件系统,不过这只是一个最基本的系统,这样有助于理解...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,600
精华内容 1,840
关键字:

yaffs2文件系统移植