PowerPC平台,norflash及nandflash驱动及设备注册全过程

/*************************************************************************************************************************************************************

*

*  鄙人第一次发表博客,尝试下,格式,对于下面提到的有关文档会在后期发表,此次做个测试,uboot版本为2011.09,kernel为2.6.34

* 前面对于英文的借鉴出自Sreekrishnan Venkateswaran 所著的《Essential Linux Device Driver》,有些许删改

* 对于下面的预留的一些疑惑问题,鄙人会尽量抽出时间,在Linux4.0内核源码中给大家解惑

* 由于鄙人水平有限,对于博文中的错误及不足,请联系

*

***************************************************************************************************************************************************************/





此文档仅作为开发随笔记录文档,可作为正式文档做材料参考,但不做正式文档。

 

Written bywolfgang huang([email protected])

 

此类文档仅记录powerpc(MPC8313E)平台各模块开发要点,备注好资料应用,以供后续开发人员快速入手,也可作为科普类资料,供其他相关人员学习。

 

 

 

PowerPC nor and nand flash

 

此文档对PowerPC(MPC8313e)平台的uboot及kernel对于nor flash和nand flash的启动流程进行细节分析,且附加PowerPC平台及相应的芯片datasheet的相关知识。对于在MMU中使用BAT及local windows的设置,在此不再重复细述,请参考《ppc_uboot_start_up.pdf》。

 

对于MTD子系统,我们先借鉴相关英文图书描述。

Linux MTD subsystem

Architecture

PowerPC平台,norflash及nandflash驱动及设备注册全过程_第1张图片

Map Drivers

To MTD-enable your device, yourfirst task is to tell MTD how to access the flash device. For this, you have tomap your flash memory range for CPU access and provide methods to operate onthe flash. The next task is to inform MTD about the different storage partitionsresiding on your flash.

 

NOR Chip Drivers

CFI stands for Common FlashInterface, a specification designed to do away with the need for developingseparate drivers to support chips from different vendors. Software can queryCFI-compliant flash chips and automatically detect block sizes, timingparameters, and the command-set to be used for communication. Drivers that implementspecifications such as CFI and JEDEC are called chip drivers.

 

The CFI specification definesvarious command-sets that compliant chips can implement. Some of the common onesare as follows:

         Command-set0001, supported by Intel and Sharp flash chips

         Command-set0002, implemented on AMD and Fujitsu flash chips

         Command-set0020, used on ST flash chips

MTD supports these command-sets askernel modules. You can enable the one supported by your flash chip via thekernel configuration menu.

 

NAND Chip Drivers

NAND flash chips, unlike their NORcounterparts, are not connected to the CPU via data and address lines. Theyinterface to the CPU through special electronics called a NAND flash controllerthat is part of many embedded processors. To read data from NAND flash, the CPUissues an appropriate read command to the NAND controller. The controllertransfers data from the requested flash location to an internal RAM memory,also part of the controller. The data transfer is done in units of the flash chip'spage size (for example, 2KB). In general, the denser the flash chip, the largeris its page size. Note that the page size is different from the flash chip'sblock size, which is the minimum erasable flash memory unit (for example,16KB). After the transfer operation completes, the CPU reads the requested NANDcontents from the internal RAM. Writes to NAND flash are done similarly, exceptthat the controller transfers data from the internal RAM to flash. Theconnection diagram of NAND flash memory on an embedded device is shown in follow.

PowerPC平台,norflash及nandflash驱动及设备注册全过程_第2张图片

Because of this unconventional modeof addressing, you need special drivers to work with NAND storage. MTD providessuch drivers to manage NAND-resident data. If you are using a supported chip,you have to enable only the appropriate low-level MTD NAND driver. If you arewriting a NAND flash driver, however, you need to explore two datasheets: theNAND flash controller and the NAND flash chip.

 

NAND flash chips do not supportautomatic configuration using protocols such as CFI. You have to manually informMTD about the properties of your NAND chip by adding an entry to thenand_flash_ids[] table defined in drivers/mtd/nand/nand_ids.c. Each entry inthe table consists of an identifier name, the device ID, page size, erase blocksize, chip size, and options such as the bus width.

 

There is another characteristic thatgoes hand in hand with NAND memory. NAND flash chips, unlike NOR chips, are notfaultless. It's normal to have some problem bits and bad blocks scatteredacross NAND flash regions. To handle this, NAND devices associate a spare areawith each flash page (for example, 64 bytes of spare area for each 2KB datapage). The spare area contains out-of-band (OOB) information to help performbad block management and error correction. The OOB area includes errorcorrecting codes (ECCs) to implement error correction and detection. ECCalgorithms correct single-bit errors and detect multibit errors. The nand_ecclayoutstructure defined in include/mtd/mtd-abi.h specifies the layout of the OOBspare area:

 

struct nand_ecclayout {

         uint32_t eccbytes;

         uint32_teccpos[64];

         uint32_toobavail;

         structnand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];

};

 

In this structure, eccbytes holdsthe number of OOB bytes that store ECC data, and eccpos is an array of offsetsinto the OOB area that contains the ECC data. oobfree records the unused bytesin the OOB area available to flash filesystems for storing flags such as cleanmarkers that signal successful completion of erase operations.

Individual NAND drivers initializetheir nand_ecclayout according to the chip's properties. Following figureillustrates the layout of a NAND flash chip having a page size of 2KB. The OOBsemantics used by the figure is the default for 2KB page-sized chips as definedin the generic NAND driver, drivers/mtd/nand/nand_base.c.

PowerPC平台,norflash及nandflash驱动及设备注册全过程_第3张图片

 

Often, the NAND controller performserror correction and detection in hardware by operating on the ECC fields inthe OOB area. If your NAND controller does not support error management,however, you will need to get MTD to do that for you in software. The MTDnand_ecc driver (drivers/mtd/nand/nand_ecc.c) implements software ECC.

That figure also shows OOB memorybytes that contain bad block markers. These markers are used to flag faultyflash blocks and are usually present in the OOB region belonging to the firstpage of each block. The position of the marker inside the OOB area depends onthe properties of the chip. Bad block markers are either set at the factoryduring manufacture, or by software when it detects wear in a block. MTDimplements bad block management in drivers/mtd/nand/nand_bbt.c.

 

The mtd_partition structure worksfor NAND memory, too. After you MTD-enable your NAND flash, you can access theconstituent partitions using standard device nodes such as /dev/mtd/X and /dev/mtdblock/X.If you have a mix of NOR and NAND memories on your hardware, X can be either aNOR or a NAND partition. If you have a total of more than 32 flash partitions, accordinglychange the value of MAX_MTD_DEVICES in include/linux/mtd/mtd.h.

U-boot

 

我们的程序装载在norflash中,PowerPC上电后,系统上电初始化时,CFG_RESET_SOURCE[0::3]管脚作为功能管脚使用,其与TSEC2_TXD[3:0]复用IO管脚,会根据CFG_RESET_SOURCE[0::3]选择加载PowerPC上电配置八个字节。  根据我们的连接线,则我们配置其数值为0x0000。PowerPC则知道,我们的配置数据存在NORFLASH中。

 

且PowerPC会对norflash或nandflash的相关 localbus进行最低端的默认配置,即读取数据最慢,但是确定可以读取到配置数据,我们将u-boot.bin烧录到norflash中,前八字节即配置数据。PowerPC加载后,会根据配置字节进行诸如时钟,PLL等寄存器的设置,此处我们省略对其的关注,我们关注RCWHR中的BMS设置,其定义中断向量表及后续的BOOT ROM的地址,其设置为0时,启动地址区间为0x00000000-0x007FFFFF的8MB空间,若设置为1,则启动地址区间为0xFF80_0000 to 0xFFFF_FFFF的8MB空间。

 

对应于我们具体应用,我们norflash的地址映射到0x00000000处,我们的BMS设置为0。故对于后续BOOT ROM数据的加载,我们可以平缓过度至此。

 

 

 

对于使用默认设置加载norflash小部分数据,其后,我们必须对norflash进行合理性设置后,再进行大数据的搬迁及操作等,此部分才是我们关注的重点。下面直接进行norflash及nandflash的合理化设置进行细述。

 

 

U-boot对于norflash及nandflash包括控制器设置及驱动挂载,kernel部分则只是对于其驱动的挂载及文件系统分区管理等。

 

 

norflash及nand flash控制器设置

在uboot中arch/powerpc/cpu/mpc8xxx/fsl_lbc.c中init_early_memctl_regs对localbus的地址及时序进行设置,设置的寄存器为BR及OR,其配置选用GPCM、FCM或UPM模式,及相应模式下的时序配置等,之后的的操作寄存器等都有具体驱动根据我们的配置数据进行设置,诸如FCM模式下对于大页(2048字节)的nandflash的支持,我们对其也不做重点关注,细节部分可根据个人情况进行跟踪。

 

 

下面我们着重细述对于norflash及nandflash时序设置的合理化方案。

对于不太明白其时序的,只能根据个人情况wikipedia或google….在此不做傻瓜式细述。

 

对于一款norflash,对于软件驱动人员比较关注的即sector,size,command timing。

对于我们选用的S29GL256,其sector大小为128KB,且size为32MB,我们供给localbus控制器的时钟频率为33MHZ。

 

我们贴上其读写时序图及时间区间值系数

 PowerPC平台,norflash及nandflash驱动及设备注册全过程_第4张图片

PowerPC平台,norflash及nandflash驱动及设备注册全过程_第5张图片PowerPC平台,norflash及nandflash驱动及设备注册全过程_第6张图片

 

 

再贴上MPC8313E GPCM控制器的读写时序图

则把两个时序图对应好后,选取时间宽度,最后设置我们控制器的读取时序。

 PowerPC平台,norflash及nandflash驱动及设备注册全过程_第7张图片

PowerPC平台,norflash及nandflash驱动及设备注册全过程_第8张图片

 

我们再贴上norflash芯片的写时序时间及时序图

PowerPC平台,norflash及nandflash驱动及设备注册全过程_第9张图片

 

 

同读取一样设置控制器时序。

在选择合理的设置后,进行板卡适度的放宽,我们给出我们最终设置的结果。

#defineCONFIG_SYS_NOR_BR_PRELIM          (CONFIG_SYS_FLASH_BASE\

                                               |BR_PS_16      /* 16 bit port */ \

                                               |BR_MS_GPCM      /* MSEL = GPCM */ \

                                               |BR_V)             /* valid */

 

#defineCONFIG_SYS_NOR_OR_PRELIM         (MEG_TO_AM(CONFIG_SYS_FLASH_SIZE)\

                                     |OR_GPCM_XACS \

                                     |OR_GPCM_CSNT \

                                     |OR_GPCM_SCY_3 \

                                     |OR_GPCM_EHTR \

                                     |OR_GPCM_ACS)

                                     /*0xFF006FF7 TODO SLOW 16 MB flash size */

 

 

对于nand flash,我们也如上参考其对应的AC时序要求,并参考我们的FCM控制器,由于MPC8313e对于nandflash的发展没跟上,参考最新的我们选用的MT29F4G08ABADAWP,我们选用最快的FCM控制器时序都可以满足,且我们的nandflash芯片选用的是2048页大小,故我们需要在FCM控制器端追加大页支持选项。

 

给出我们最终的设置:

#defineCONFIG_SYS_NAND_BR_PRELIM       (CONFIG_SYS_NAND_BASE\

                                     |BR_DECC_CHK_GEN    /* Use HW ECC */ \

                                     | BR_PS_8                  /* 8 bit port */ \

                                     | BR_MS_FCM                   /* MSEL = FCM */ \

                                     | BR_V)                       /* valid */

#defineCONFIG_SYS_NAND_OR_PRELIM      \

                                     (P2SZ_TO_AM(CONFIG_SYS_NAND_WINDOW_SIZE)\

                                     |OR_FCM_PGS        \

                                     )

 

 

对于该类驱动的支持,细述会造成文章长度达到无法控制地步,故概述之。

 

对于norflash的驱动支持,我们配置后运行到flash_init后,最终会运行到flash_dete_cfi执行探测,且逐个对于x8,x16,x32,x64设备进行探测,探测的原理请参考《jedec68.pdf》及《jep137b.pdf》,在此不做过多的细述。

 

对于nandflash的驱动支持,我们配置后运行到nand_init,对逐个芯片调用nand_init_chip,nand_init_chip调用board_nand_init对FCM控制器进行初始化后调用nand_scan。nand_scan通过nandflash的读取ID命令,读取后,到nand_ids中查找对应的nandflash页大小等设置,之后通过后续的ID属性规划nandflash的bbt操作及各种未设置的操作接口进行默认设置后返回。

 

此后我们cmd_flash及cmd_nand就可以根据norflash的控制结构flash_info和nandflash的控制结构nand_info完成对应的命令操作。

 

 

Kernel

Kernel对于norflash和nandflash的支持,驱动部分也是类似uboot这样的识别挂载过程(uboot就是从kernel中移过来的)。故我们对于驱动对具体存储设备的识别,我们不在做细述。

 

但是掺杂到kernel中的驱动识别过程,则必须设计驱动模型,故我们对于其对于存储设备的配置还是进行相关的描述。

 

先贴出我们的的DTS(以最新的MT29F4G08ABADAWP)

 

         flash@0,0{

                   #address-cells= <1>;

                   #size-cells= <1>;

                   compatible= "cfi-flash";

                   reg= <0x0 0x0 0x2000000>;   //32MB NorFlash

                   bank-width= <2>;

                   device-width= <1>;

                   partition@0{

                            label = "U-boot";

                            reg = <0x0 0x80000>;      //U-boot: 512KB

                   };

                           

                   partition@80000{

                            label= "Kernel";

                            reg= <0x80000 0x300000>; //kernel: 3MB

                   };

                   partition@380000{

                            label= "JFFS2";

                            reg= <0x380000 0xa00000>; //Ramdisk: 10MB

                   };

                           

                   partition@d80000{

                            label= "DTB";

                            reg= <0xd80000 0x40000>; //DTB: 256KB

                   };

                   partition@dc0000{

                            label= "Bin";

                            reg= <0xdc0000 0xc00000>; //Bin: 12M

                   };

                                                       

              partition@19c0000{

                            label= "Etc";

                            reg= <0x19c0000 0x640000>; //Etc: 6.25M

                   };

         };

 

         nand@1,0{

                  #address-cells = <1>;

                  #size-cells = <1>;

                  compatible ="fsl,mpc8313-fcm-nand",

                               "fsl,elbc-fcm-nand";

                  reg = <0x1 0x0 0x2000>;

                  partition@0 {

                            label= "Data";

                            reg= <0x0 0x20000000>;                  /*Data 512 RW */

                   };               

         };

 

此处我们不纠缠DTS的语法及表达方式,我们只需要了解其定义一块norflash和一块nandflash,分别又有各自的分区。

 

下面我们贴出我们的MTD子系统的配置参数

Device Drivers  ---> 

         <*>Memory Technology Device (MTD) support --->

                   ---Memory Technology Device (MTD) support                     

                  [ ]  Debugging                                            

                < >  MTD tests support                                    

                    < >  MTD concatenating support                             

                    [*]  MTD partitioning support                               

                    < >    RedBoot partition table parsing                    

                    [ ]    Command line partition table parsing                  

                    <*>    Flash partition map based on OF description          

                    < >    TI AR7 partitioning support                        

                           *** User Modules And Translation Layers***

                   <*>   Direct char device access to MTDdevices                

                    -*-  Common interface to block layer for MTD 'translation layers

                    <*>  Caching block device access to MTD devices              

                    < >  FTL (Flash Translation Layer) support                 

                    <*>  NFTL (NAND Flash Translation Layer) support            

                    [*]    Write support for NFTL                                

                    < >  INFTL (Inverse NAND Flash Translation Layer) support      

                    < >  Resident Flash Disk (Flash Translation Layer) support   

                    <>  NAND SSFDC (SmartMedia) read only translation layer

                    < >  Log panic/oops to an MTD buffer                 

                           RAM/ROM/Flashchip drivers  --->                    

                             Mappingdrivers for chip access  --->                  

                            Self-contained MTD device drivers  --->               

                    <*>  NAND Device Support  --->                      

                    < >  OneNAND Device Support --->                       

                       LPDDR flash memory drivers  --->                      

                       UBI - Unsorted block images  --->

 

                   /*选择norflash的CFI驱动及AMD/Fujitsu命令集支持 */

                   RAM/ROM/Flashchip drivers  --->

                   <*>Detect flash chips by Common Flash Interface (CFI) probe  

                   <> Detect non-CFI AMD/JEDEC-compatible flash chips      

                   [] Flash chip driver advanced configuration options      

                   <> Support for Intel/Sharp flash chips                    

                   <*>Support for AMD/Fujitsu/Spansion flash chips              

                   <> Support for ST (Advanced Architecture) flash chips         

                   <> Support for RAM chips in bus mapping                

                   <> Support for ROM chips in bus mapping                  

                   <> Support for absent chips in bus mapping

                  

                   /*使能of_flash驱动,从而使驱动模型和DTS中追加的of_node,进行platform总线匹配后probe */

                   Mappingdrivers for chip access  --->

                   [] Support non-linear mappings of flash chips               

                 <> Flash device in physical memory map                      

                   <*>Flash device in physical memory map based on OF description 

                   <> NOR flash on Intel Vermilion Range Expansion Bus CS0   

                   <> Map driver for platform device RAM (mtd-ram)

 

                   /*nandflash驱动使能,从而匹配后probe */

                   <*>   NAND Device Support  --->

                   ---NAND Device Support                                  

                   [*]   Verify NAND page writes                            

                   []   NAND ECC Smart Media byte order                  

                   []   Enable chip ids for obsolete ancientNAND devices       

                   <>   DiskOnChip 2000, Millennium andMillennium Plus (NAND reimp

                   <>   NAND support for OLPC CAFM-C~Ichip                  

                   <>   Support for NAND FlashSimulator                    

                   <>   Support for generic platform NANDdriver            

                   <*>   NAND support for Freescale eLBCcontrollers         

                   <>   Support for NAND on Freescale UPM

 

根据DTS解析device_node后,加入到platform_bus总线后,进而又of_flash驱动和fsl_elbc_init初始化后,设备模型匹配后,分别运行到norflash的probe函数(of_flash_probe)和nandflash的probe函数(fsl_elbc_ctrl_probe)。有兴趣的可以继续跟踪着两个函数,下面我们以简略图的方法分析之后的过程。对于CFI探测及nand flash的scan过程,与uboot一样,我们在此从略。

 PowerPC平台,norflash及nandflash驱动及设备注册全过程_第10张图片

 

 

对于add_mtd_device的实现,在/sys下的结果如下图:

对于norflash,有


对于nandflash有:


注意:为啥mtd6会在虚设备里面呢?这个涉及太多的驱动模型及sysfs的知识,故在此不细述。

 

 

对于sysfs文件系统,我们还可以查看各种设备的属性,诸如下图:


诸如,我们查看属性,知道该分区为nandflash类型,大小为512MB,页擦写大小为128KB。实际上这些都是mtd_info结构中的一些结构成员的值,对于怎么回事?这个要花大量的时间,不在此细述。

你可能感兴趣的:(PowerPC)