先來看看NAND_FLASH 和 NOR_FLASH 的不同點
使用uboot操作nor_flash
先把開發板設置爲nor 啓動
看看nor_flash的操作手冊
看完操作手冊 之後 我們嘗試讀出id
往地址555H寫AAH --> 往地址2AAH寫55H —> 往地址555H寫入90H ---->讀0地址得到廠家ID: C2H ----->讀1地址得到設備ID:22DAH
但是由於2440soc的A1接到 A0 所以2440的地址要左移1位 ,nor才能收到
所以更改
往地址AAAH寫AAH --> 往地址554H寫55H —> 往地址AAAH寫入90H ---->讀0地址得到廠家ID: C2H ----->讀2地址得到設備ID:22DAH
變成在uboot上面的操作
mw.w aaa aa —> mw.w 554 55 —> mw.w aaa 90 ------> md.w 0 1 ------> md.w 2 1
進行驅動的編寫
1 分配map_info結構體
在init函數裏面 進行分配
2 設置 : 物理基地址(phys),大小(size),位寬(bankwidth),虛擬地址(virt)
名字隨意 ,物理啓動地址分配爲0 ,大小 超過真實大小即可,位寬是16位(單位是字節,就是8*2,所以填2)
3 使用 :調用NOR_FLASH協議層提供的函數來識別
從之前別人原有的協議中調用函數 ,來對我們的nor_flash 來進行識別
4 add_mtd_parttitions
構造出分區
在init函數裏面,加上自己的分區,有兩個數組
下面是完整代碼
/*
* 參考 drivers\mtd\maps\physmap.c
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>
static struct map_info *s3c_nor_map;
static struct mtd_info *s3c_nor_mtd;
static struct mtd_partition s3c_nor_parts[] = {
[0] = {
.name = "bootloader_nor",
.size = 0x00040000,
.offset = 0,
},
[1] = {
.name = "root_nor",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
}
};
static int s3c_nor_init(void)
{
/* 1. 分配map_info結構體 */
s3c_nor_map = kzalloc(sizeof(struct map_info), GFP_KERNEL);;
/* 2. 設置: 物理基地址(phys), 大小(size), 位寬(bankwidth), 虛擬基地址(virt) */
s3c_nor_map->name = "s3c_nor";
s3c_nor_map->phys = 0;
s3c_nor_map->size = 0x1000000; /* >= NOR的真正大小 */
s3c_nor_map->bankwidth = 2;
s3c_nor_map->virt = ioremap(s3c_nor_map->phys, s3c_nor_map->size);
simple_map_init(s3c_nor_map);
/* 3. 使用: 調用NOR FLASH協議層提供的函數來識別 */
printk("use cfi_probe\n");
s3c_nor_mtd = do_map_probe("cfi_probe", s3c_nor_map);
if (!s3c_nor_mtd)
{
printk("use jedec_probe\n");
s3c_nor_mtd = do_map_probe("jedec_probe", s3c_nor_map);
}
if (!s3c_nor_mtd)
{
iounmap(s3c_nor_map->virt);
kfree(s3c_nor_map);
return -EIO;
}
/* 4. add_mtd_partitions */
add_mtd_partitions(s3c_nor_mtd, s3c_nor_parts, 2);
return 0;
}
static void s3c_nor_exit(void)
{
del_mtd_partitions(s3c_nor_mtd);
iounmap(s3c_nor_map->virt);
kfree(s3c_nor_map);
}
module_init(s3c_nor_init);
module_exit(s3c_nor_exit);
MODULE_LICENSE("GPL");
makefile:
KERN_DIR = /work/system/linux-2.6.22.6
all:
make -C $(KERN_DIR) M=`pwd` modules
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
obj-m += s3c_nor.o
開始測試
測試1 :嘗試用內核自帶的驅動程序 由於在之前的nand_flash 已經去掉驅動 所以這次只編譯模塊
編譯內核
這個模塊選擇m
並且物理起始地址選擇爲0
長度設置爲16兆 只要大於等於真實長度就行,因爲寫驅動要ioremap進行映射
位寬 是16 也就是28bit
這時候就能進行 make modules
把編譯出來的驅動文件拷貝到網絡的文件系統裏面
ls /dev/mtd 好想就是多了一些東西 也不知道多的是啥
cat proc/mtd 我們的nor_falsh 作爲一塊 已經進來
測試2: 用自己寫的驅動程序
進行編譯後加載進入模塊
ls /dev/mtd* 經過裝載和不裝載驅動的對比
開始進行格式化
flash_eraseall -j /dev/mtd5 //對比上面的文件多了mtd5 ,4 就是自己建的兩個nor_falsh 分區
mount -t jffs2 /dev/mtdblock5 /mnt //在mnt目錄裏面掛接我們的nor_falsh
對於nor_flash 我們用jfss2文件系統 對於nand_falsh 我們用yaffs2 文件系統
現在在mnt目錄裏面新建 文件 取消掛接 重新掛接後 文件還在