块设备驱动之NOR FLASH驱动
轉(zhuǎn)載請(qǐng)注明出處:http://blog.csdn.net/ruoyunliufeng/article/details/25240947
一.硬件原理
從原理圖中我們能看到NOR FLASH有地址線,有數(shù)據(jù)線,能向內(nèi)存一樣讀,不能向內(nèi)存一樣寫(xiě)(要發(fā)出某些命令)。這也使得NOR的數(shù)據(jù)非常可靠,所以一般用來(lái)存儲(chǔ)bootloader。當(dāng)然現(xiàn)在手機(jī)上都只有nand flash了,節(jié)約成本嘛。下節(jié)我會(huì)帶大家去分析nand flash驅(qū)動(dòng),并進(jìn)行總結(jié)。
二.驅(qū)動(dòng)程序
/** 參考 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;/*分區(qū)數(shù)組*/ static struct mtd_partition s3c_nor_parts[] = {[0] = {.name = "bootloader_nor",.size = 0x00040000,.offset = 0,},[1] = {.name = "root_nor",.offset = MTDPART_OFS_APPEND, //緊接著上一個(gè).size = MTDPART_SIZ_FULL, //到最后} };static int s3c_nor_init(void) //入口函數(shù) {/* 1. 分配map_info結(jié)構(gòu)體 */s3c_nor_map = kzalloc(sizeof(struct map_info), GFP_KERNEL);;/* 2. 設(shè)置: 物理基地址(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); //簡(jiǎn)單初始化/* 3. 使用: 調(diào)用NOR FLASH協(xié)議層提供的函數(shù)來(lái)識(shí)別 */printk("use cfi_probe\n");s3c_nor_mtd = do_map_probe("cfi_probe", s3c_nor_map);/*如果沒(méi)識(shí)別就用jedec*/if (!s3c_nor_mtd){printk("use jedec_probe\n");s3c_nor_mtd = do_map_probe("jedec_probe", s3c_nor_map);}/*如果仍然沒(méi)事別就釋放掉,返回錯(cuò)誤*/if (!s3c_nor_mtd){ iounmap(s3c_nor_map->virt);kfree(s3c_nor_map);return -EIO;}/* 4. add_mtd_partitions (添加分區(qū))*/add_mtd_partitions(s3c_nor_mtd, s3c_nor_parts, 2);return 0; }static void s3c_nor_exit(void) //出口函數(shù) {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");
三.驅(qū)動(dòng)分析
?? 1. 分配map_info結(jié)構(gòu)體
?? 2. 設(shè)置: 物理基地址(phys), 大小(size), 位寬(bankwidth), 虛擬基地址(virt)
?? 3. 使用: 調(diào)用NOR FLASH協(xié)議層提供的函數(shù)來(lái)識(shí)別
?? 4. add_mtd_partitions (添加分區(qū))
其實(shí)我們的這個(gè)驅(qū)動(dòng),主要把硬件上的差異性寫(xiě)出來(lái)就可以了,大部分的工作內(nèi)核已經(jīng)幫我們做了。現(xiàn)在我主要來(lái)分析第三步。cfi和jedec,這里主要分析cfi
/*NOR FLASH識(shí)別過(guò)程*/ do_map_probe("cfi_probe", s3c_nor_map);drv = get_mtd_chip_driver(name)ret = drv->probe(map); // cfi_probe.ccfi_probemtd_do_chip_probe(map, &cfi_chip_probe);cfi = genprobe_ident_chips(map, cp);genprobe_new_chip(map, cp, &cfi)cp->probe_chip(map, 0, NULL, cfi)cfi_probe_chip// 進(jìn)入CFI模式cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);// 看是否能讀出"QRY"qry_present(map,base,cfi)
我們進(jìn)行的操作其實(shí)在協(xié)議層已經(jīng)幫我們寫(xiě)好了,我們需要提供的其實(shí)就是硬件上的差異。因?yàn)樗械膎or都是支持這套協(xié)議的。
參考:韋東山視頻第二期
總結(jié)
以上是生活随笔為你收集整理的块设备驱动之NOR FLASH驱动的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 图嵌入 (Graph Embedding
- 下一篇: ZedGraph使用(一) 柱形图