NOR_FLASH分析和啓動流程

先來看看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目錄裏面新建 文件 取消掛接 重新掛接後 文件還在

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章