内核:linux-2.6.37.3
nor flash芯片:SST39VF6401B
网上有文章说了如何让linux内核支持nor flash。不过那些转载的文章中没有头文件(因为使用了<尖括号>,在HTML语言中是注释的意思)。后来研究了类似的驱动文件,发现它们都是大同小异,只是在一些参数上有改变而已。本文中源代码基于那些转载文章的代码。
MTD设备驱动程序在./driver/mtd下面,分为nor flash和nand flash两种。在chips中定义了几种访问nor的接口,包括cfi、jedec、map_ram和map_rom,而实际芯片所要添加的“驱动程序”放到maps目录下(比如本文使用的s3c2440-flash.c文件,详见文章后面)。从map这个单词来看,它描述的是一些映射信息,当然也包括了芯片信息,如总大小、块总数、访问接口等等。
这个过程其实是在内核代码树中添加自己的驱动的过程,当然是一些“标准”步骤了:在对应的代码树目录下,添加驱动源代码文件、在Makefile添加内容、在Kconfig添加内容,当然,还需要在make menuconfig里配置。
1、./driver/mtd/maps/Makefile
在这个Makefile最后添加:
obj-$(CONFIG_MTD_S3C2440) += s3c2440-flash.o
这个CONFIG_MTD_S3C2440由内核配置所得。
2、./driver/mtd/maps/Kconfig
在这个Kconfig文件最后添加(但在endmenu之前):
config MTD_S3C2440
tristate "CFI Flash device mapped on S3C2440"
depends on ARM && MTD_CFI
help
This enables access to the CFI Flash on the SMDK2440 board.
If you have such a board, say 'Y' here.
这里的MTD_S3C2440就是前面Makefile中的那个,注意,CONFIG_前缀是内核自己添加的。可以在编译内核后生成的autoconf.h文件中查看该宏定义。
3、内核配置
在Device Drivers ---> <*> Memory Technology Device (MTD) support ---> 下面:
Mapping drivers for chip access ---> <*> CFI Flash device mapped on S3C2440 RAM/ROM/Flash chip drivers ---> <*> Detect flash chips by Common Flash Interface (CFI) probe [*] Flash chip driver advanced configuration options [*] Specific CFI Flash geometry selection [*] Support 16-bit buswidth [*] Support 1-chip flash interleave
4、./driver/mtd/maps/s3c2440-flash.c
代码见文章后面。
这个文件主要是修改前面的几个宏定义。我特地添加一些调试语句。开始时我使用2.6.30.2内核,驱动中使用cfi_probe接口,但是没有显示分区信息,后来我添加多几个接口才发现它是使用map_rom。这个过程花费了一些时间。
在2.6.30.2内核中,启动信息如下:
S3C2440-NOR:0x00800000 at 0x01000000 S3C2440-NOR:func:init_s3c2440nor[120] mymtd:0 type:cfi_probe S3C2440-NOR:func:init_s3c2440nor[120] mymtd:0 type:jedec_probe S3C2440-NOR:func:init_s3c2440nor[120] mymtd:c39cb600 type:map_rom S3C2440-NOR:using static partition definition Creating 4 MTD partitions on "NOR Flash(SST39VF6401B) on S3C2440": 0x000000000000-0x000000030000 : "U-Boot" 0x000000030000-0x000000240000 : "Kernel" 0x000000240000-0x0000007f0000 : "RootFS(jffs2)" 0x0000007f0000-0x000000800000 : "Parameter"
可以看到,的确是使用map_rom接口。但是,当我使用2.6.37.2时,发现它使用的是cfi_probe接口,启动信息如下: