Linux开发十六_nand驱动

来源:互联网 发布:手机淘宝更新在哪里 编辑:程序博客网 时间:2024/06/08 16:50

Linux开发十六

nand驱动

象棋小子    1048272975

nand flash具有大容量、改写速度快、接口简单等优点,适用于大量数据的存储,为固态大容量存储提供了廉价有效的解决方案。Linux内核已经支持s3c2416的nand控制器,可以支持各种容量的nand flash。

1. nand设备

nand设备包含了名字、独有的资源等等一些驱动程序的硬件或自定义信息。通过platform_add_devices(platform_device_register)函数将定义的平台设备注册到内核中,用于匹配设备驱动。

内核在drivers\mtd\nand\ s3c2410.c目录中实现了s3c2416 nand驱动, nand设备平台代码如下。

static struct mtd_partitionhome_default_nand_part[] = {

       [0]= {

              .name            = "Bootloader",

              .offset            = 0,

              .size        = 0x100000,

              .mask_flags   = MTD_CAP_NANDFLASH,

       },

       [1]= {

              .name            = "Logo",

              .offset            = 0x100000,

              .size        = 0x200000,

              .mask_flags   = MTD_CAP_NANDFLASH,

       },

       [2]= {

              .name            = "Kernel",

              .offset            = 0x300000,

              .size        = 0x400000,

              .mask_flags   = MTD_CAP_NANDFLASH,

       },

       [3]= {

              .name            = "Rootfs",

              .offset            = 0x700000,

              .size        = MTDPART_SIZ_FULL,

       },

};

 

static struct s3c2410_nand_sethome_nand_sets[] = {

       [0]= {

              .name            = "NAND",

              .nr_chips       = 1,

              .nr_partitions       = ARRAY_SIZE(home_default_nand_part),

              .partitions      = home_default_nand_part,

       },

};

 

static struct s3c2410_platform_nandhome_nand_info = {

       .tacls             = 10,

       .twrph0  = 20,

       .twrph1  = 10,

       .ecc_mode     = NAND_ECC_HW,

       .nr_sets  = ARRAY_SIZE(home_nand_sets),

       .sets              = home_nand_sets,

};

 

staticstruct resource s3c_nand_resource[] = {

       [0] = DEFINE_RES_MEM(S3C_PA_NAND, SZ_1M),

};

 

structplatform_device s3c_device_nand = {

       .name            ="s3c2410-nand",

       .id          =-1,

       .num_resources    = ARRAY_SIZE(s3c_nand_resource),

       .resource       =s3c_nand_resource,

};

nand ecc校验方式在home_nand_info结构体中设置,设置为NAND_ECC_HW。在板级初始化函数home2416_machine_init()中加入nand平台数据s3c_nand_set_platdata(&home_nand_info),在static struct platform_device *home2416_devices[]板级平台设备列表中加入&s3c_device_nand,使nand设备能够注册到内核中。

2. 内核配置

Linux配置支持nand设备驱动,选中Device Drivers->Memory Technology Device(MTD) support->NAND Device Support->NAND Flash support for Samsung S3CSoCs。

nand ecc校验方式在nand platform data中设置,由于nand flash会出现位翻转的问题,一般需要对nand flash进行ecc校验和纠错。Linux内核支持无ecc、软件ecc、硬件ecc这三种方式,内核无ecc情况下,应该保证数据的其他地方有ecc校验(如yaffs允许使用自身的ecc校验),不然数据可能是不可靠的。一般情况下是在内核做ecc校验,对于支持硬件方式产生ecc的nand控制器,驱动层应优先让内核采用硬件ecc,软件ecc会耗费更多的cpu资源,也远达不到硬件ecc的速度性能。

3. nand测试

cat /proc/mtd可以知道分区信息。我们在nand平台设备中设置了四个分区,第一个分区用来存放bootloader,第二个分区用来存放Logo,第三个分区用来存放Linux内核,剩余空间作为第四个分区根文件系统区域。

cat /proc/partitions可以知道有四个mtd设备,分别对应nand flash的四个分区。在/dev目录中创建这四个mtd设备文件。

mknod /dev/mtdblock0 c 31 0

mknod /dev/mtdblock1 c 31 1

mknod /dev/mtdblock2 c 31 2

mknod /dev/mtdblock3 c 31 3

bootloader是上电启动后最先运行的一段代码,它的固化以及启动是与芯片平台息息相关的,需要参考相应芯片平台手册。例如对于s3c2416  nand启动,要求bootloader必须放在nand flash的0地址处,其中的8k SteppingStone必须采用8位ecc校验。

对于Linux内核,根文件系统,数据(如Logo)是由bootloader来固化的,其中Linux内核是由bootloader加载的,Linux内核固化的方式,如nand flash固化地址、固化采用的ecc校验等并无强制要求,只需bootloader采用与固化时相同的方式去加载即可。

根文件系统是由Linux内核启动去挂载的。因此,Linux内核在挂载根文件系统时,就采用内核的ecc校验方式去读取nand flash。这就要求bootloader在固化根文件系统时,固化的方式(如ecc layout、ecc校验纠错方式)必须与内核nand驱动层采用的方式完全一致,不然内核将无法读取根文件系统中的数据并挂载。

我们在Linux内核配置中选择了硬件ecc,驱动层每256 byte产生3 byte的硬件ecc,ecc layout方式可以查看Linux内核源码。笔者在bootloader中实现了跟Linux内核一致的方式,可以固化并启动Linux系统,具体实现可以参考笔者的bootloader源码。

读取Bootloader分区的512字节数据,bootloader有相应的ecc校验方式,与Linux的ecc校验方式不一致,Linux内核无法读取数据。

读取Kernel分区512字节的数据,bootloader固化Linux内核时,采用了与Linux内核nand驱动层一致的方式,可以正确地读取数据。

4. 附录

https://pan.baidu.com/s/1slczwhJ

bootloader源码以及使用说明

https://pan.baidu.com/s/1eRDJtNs

Qt5.8官网源码

https://pan.baidu.com/s/1nuGmSqt

本系列例程的根文件系统

https://pan.baidu.com/s/1i5btLGT

opev3.2.0官网源码

https://pan.baidu.com/s/1pLpuHw3

yaffs官网源码 

https://pan.baidu.com/s/1bpkZynt

busybox-1.26.2官网源码

https://pan.baidu.com/s/1i4EtjfR

tslib官网源码

https://pan.baidu.com/s/1i5MGRhb

mplayer-1.3.0官网源码

https://pan.baidu.com/s/1sl0fXlr

基于S3C2416修改的linux-4.10.10源码

 

0 0
原创粉丝点击