ST NAND driver on OSK5912的開發過程

1. 修改driver/mtd/nand/Kconfig:

--------------------------------------------------
config MTD_NAND_OMAP_HW
--------------------------------------------------
上一行添加
--------------------------------------------------
config MTD_NAND_OMAP_OSK
        tristate "NAND Flash device on OSK5912 board"
        depends on ARM && ARCH_OMAP1 && MTD_NAND && MACH_OMAP_OSK
        help
          Support for NAND flash on Texas Instruments OSK5912 platforms.
--------------------------------------------------

2. 修改driver/mtd/nand/Makefile:

--------------------------------------------------
obj-$(CONFIG_MTD_NAND_OMAP_HW)          += omap-hw.o
--------------------------------------------------
上一行添加
--------------------------------------------------
obj-$(CONFIG_MTD_NAND_OMAP_OSK)         += osk-nand-flash.o
--------------------------------------------------

3. 執行make menuconfig;
標記
--------------------------------------------------
[*] device driver->MTD->NAND->"NAND Flash support"
[M] device driver->MTD->NAND->"NAND Flash device on OSK5912 board"
--------------------------------------------------

4. 新建驅動文件osk-nand-flash.c在driver/mtd/nand下。

5. 修改文件arch/arm/mach-omap1/board-osk.c內容:
添加
--------------------------------------------------
#include <linux/mtd/nand.h>
......
......
#define OSK_NAND_BASEADDR    0x05000000    //Reading/writing to this address will issue a data access to NFMC
......
......
static struct nand_platform_data osk5912_nand_data = {
    .options    = NAND_ST_SP_OPTIONS,
};

static struct resource osk5912_nand_resource = {
    .start        = OSK_NAND_BASEADDR,
    .end            = OSK_NAND_BASEADDR+ SZ_4K - 1, //In fact it doesn't need SZ_4K so much space, SZ_4B is OK
    .flags        = IORESOURCE_MEM,
};

static struct platform_device osk5912_nand_device = {
    .name        = "osknand",
    .id        = 0,
    .dev        = {
        .platform_data    = &osk5912_nand_data,
    },
    .num_resources    = 1,
    .resource    = &osk5912_nand_resource,
};
...... ......
static struct platform_device *osk5912_devices[] __initdata = {
    &osk5912_flash_device,
    &osk5912_nand_device,    //add for NAND
    &osk5912_smc91x_device,
    &osk5912_cf_device,
    &osk5912_mcbsp1_device,
};
--------------------------------------------------

6. 修改文件include/linux/mtd/nand.h內容:
--------------------------------------------------
/* Options valid for ST small page devices */
#define NAND_ST_SP_OPTIONS /
    (NAND_NO_AUTOINCR | NAND_NO_PADDING | NAND_COPYBACK | NAND_NO_READRDY)
--------------------------------------------------

7. make menuconfig時候disable PCMCIA,因爲我們的NAND FLASH佔用CS1 bank,和PCMCIA衝突。
參考:
--------------------------------------------------
drivers/pcmcia/omap_cf.c:               cf->phys_cf = OMAP_CS1_PHYS;
--------------------------------------------------

8. 重新編譯,生成drivers/mtd/nand/osk-nand-flash.ko,複製到rootfs中。啓動kernel後,運行
--------------------------------------------------
oskboard#insmod osk-nand-flash.ko
--------------------------------------------------
系統提示:
--------------------------------------------------
Using root/osk-nand-flash.ko
NAND device: Manufacturer ID: 0x20, Chip ID: 0x76 (ST Micro NAND 64MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 1107 at 0x0114c000
--------------------------------------------------

9. 查看設備信息:
執行命令:
--------------------------------------------------
oskboard#cat /proc/mtd
--------------------------------------------------
得到如下信息:
--------------------------------------------------
dev:    size   erasesize  name
mtd0: 00020000 00020000 "bootloader"
mtd1: 00020000 00020000 "params"
mtd2: 00200000 00020000 "kernel"
mtd3: 01dc0000 00020000 "filesystem"
mtd4: 04000000 00004000 "osknand.0"
--------------------------------------------------
執行命令:
--------------------------------------------------
oskboard#cat /proc/partitions
--------------------------------------------------
得到如下信息:
--------------------------------------------------
major minor  #blocks  name

  31     0        128 mtdblock0
  31     1        128 mtdblock1
  31     2       2048 mtdblock2
  31     3      30464 mtdblock3
  31     4      65536 mtdblock4
--------------------------------------------------

10. 建立設備節點:
在/dev目錄下執行命令
    --------------------------------------------------
   # mknod -m 666 mtd4 c 90 8
   # mknod -m 666 mtdblock4 b 31 4
       --------------------------------------------------
      
11. 下載mtd-utils-1.0.0.tar.gz工具包from http://www.linux-mtd.infradead.org/。修改Makefile:
--------------------------------------------------
#CC := $(CROSS)gcc
--------------------------------------------------

--------------------------------------------------
CC := $(CROSS)gcc
--------------------------------------------------
編譯出來flash_erase,flash_eraseall,nandwrite工具。

12.在osk-linux下執行
./flash_eraseall -j /dev/mtd4
把nand按照jffs2格式erase;

至此,NAND flash已經可以以JFFS2格式被mount上去了。執行
# mount -t jffs2 /dev/mtdblock4 /mnt
然後在/mnt目錄下建立文件testfile,umount該設備後再次mount,仍然能正常讀出文件內容。

如果想把現成的目錄結構直接做成JFFS2格式的image複製到NAND設備上(例如,製作rootfs時),參考下面方法:
方法一:
1. 使用工具製作jffs2格式的image:
#./mkfs.jffs2.x86 -l -p 0x200  -s 0x200 -e 0x4000 -d rootdir/ -o target.jffs2
執行#./mkfs.jffs2.x86 -h可以查看參數含義。
如果沒有mkfs.jffs2工具,可以在上一步中生成,注意編譯工具是gcc。
2. 在osk-linux下執行
./nandwrite -o /dev/mtd4 target.jffs2
把image寫入flash。
這種方法可能需要調整參數設置才能OK。我使用的時候mount正常,讀取文件內容就出錯了。

方法二:
使用NFS時候,在PC端tar整個目錄爲target.tar.gz放到$(rootfs)下;
mount -t jffs2 /dev/mtdblock4 /mnt
cd /mnt
tar xvzf ../target.tar.gz
umount /mnt

附錄I:
NAND驅動中option的解釋: 
NAND_NO_AUTOINCR
    Most of the 1st generation chips (256/512 byte pagesize) have this
    feature. It's important to be aware of this.
    After reading a page, those chips are automatically transferring the
    next page into the read buffer.
    The 2nd generation chips (2K pagesize and a couple of the newer 512byte
    pagesize chips) do not have this feature, so you must explicitely issue
    a new page read command to get the next page data.
NAND_NO_PADDING
    Device supports partial programming without padding(指partial program時候芯片是否自動把未寫的地方填充0xFF)

附錄II:
QUESTION:
============================================================================
nand_base.c L2290是否應該被修改?
    /* Check if chip is a not a samsung device. Do not clear the
     * options for chips which are not having an extended id.
     */
    if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
        chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
============================================================================
ecc由誰解釋?
http://www.aoc.nrao.edu/~tjuerges/ALMA/Kernel/mtdnand/ch05s04.html
============================================================================

附錄III:
make menuconfig時候部分macro含義:
============================================================================
.config中
#
# NAND Flash Device Drivers
#
# CONFIG_MTD_NAND is not set

編譯omap-nand-flash.c的條件是CONFIG_MTD_NAND_OMAP

原來的Config.in在2.6中變成了Kconfig。

Verify NAND page writes (NEW)
    其實就是在nand_base.c中nand_write()中每次寫入後都重新read一遍做比較,相信性能一定下降的很快。
nandsim.c
    Nokia開發的模擬NAND設備,默認是Toshiba NAND 8MiB 1,8V 8-bit(根據ManufactureID)

附錄IV:
u-boot和linux kernel image中對osk5912 ID的匹配問題
http://linux.omap.com/pipermail/linux-omap-open-source/2004-October/001999.html
u-boot下的命令bdinfo可以show arch_number;
Linux下arch/arm/tools/mach-types中記錄板子的number,二者需要匹配。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章