第四季-專題18-FLASH驅動程序設計

專題18-FLASH驅動程序設計

第1課-塊設備驅動系統架構

  1. 塊設備快速體驗

塊設備是指只能以塊爲單位進行訪問的設備,塊大小通常是512個字節的整數倍。常見的塊設備包括硬件,SD卡,光盤等。node

l  insmod simple-blk.kolinux

l  ls /dev/simp_blkdev0算法

l  mkfs.ext3 /dev/simp_blk0緩存

l  mkdir –p /mnt/blk架構

l  mount /dev/simp_blk0 /mnt/blkapp

l  cp /etc/init.d/* /mnt/blk函數

l  ls /mnt/blkfetch

l  umount /mnt/blk設計

l  ls /mnt/blkcode

  1. 塊設備驅動系統架構

 

(1)     系統架構-VFS

VFS是對各類具體文件系統的一種封裝,爲用戶程序訪問文件提供統一的接口。

 

(2)     系統架構-cache

當用戶發起文件訪問請求的時候,首先會到Disk Cache中尋找文件是否被緩存了,若是在cache中,則直接從cache中讀取。若是數據不在緩存中,就必需要到具體的文件系統中讀取數據了。

(3)     Mapping Layer

l  首先肯定文件系統的block size,而後計算所請求的數據包含多少個block。

l  調用具體文件系統的函數來訪問文件的inode結構,肯定所請求的數據在磁盤上的地址。

(4)     Generic Block Layer

Linux內核把把塊設備看做是由若干個扇區組成的數據空間。上層的讀寫請求在通用塊層被構形成一個或多個bio結構。

(5)     I/O Scheduler Layer

I/O調度層負責採用某種算法(如:電梯調度算法)將I/O操做進行排序。

 

電梯調度算法的基本原則:若是電梯如今朝上運動,若是當前樓層的上方和下方都有請求,則先響應全部上方的請求,而後才向下響應下方的請求;若是電梯向下運動,則恰好相反。

(6)在塊系統架構的最底層,由塊設備驅動根據排序好的請求,對硬件進行數據訪問。

第2課-塊設備驅動系統實例分析

 

#include <linux/module.h>

#include <linux/moduleparam.h>

#include <linux/init.h>

 

#include <linux/sched.h>

#include <linux/kernel.h> /* printk() */

#include <linux/slab.h>   /* kmalloc() */

#include <linux/fs.h>   /* everything... */

#include <linux/errno.h> /* error codes */

#include <linux/timer.h>

#include <linux/types.h> /* size_t */

#include <linux/fcntl.h> /* O_ACCMODE */

#include <linux/hdreg.h> /* HDIO_GETGEO */

#include <linux/kdev_t.h>

#include <linux/vmalloc.h>

#include <linux/genhd.h>

#include <linux/blkdev.h>

#include <linux/buffer_head.h> /* invalidate_bdev */

#include <linux/bio.h>

 

MODULE_LICENSE("Dual BSD/GPL");

 

static int major = 0;

 

static int sect_size = 512;

 

static int nsectors = 1024;

 

/*

* The internal representation of our device.

*/

struct blk_dev{

         int size;                        /* Device size in sectors */

         u8 *data;                        /* The data array */

         struct request_queue *queue;     /* The device request queue */

         struct gendisk *gd;              /* The gendisk structure */

};

 

struct blk_dev *dev;

 

 

/*

* Handle an I/O request, in sectors.

*/

static void blk_transfer(struct blk_dev *dev, unsigned long sector,

   unsigned long nsect, char *buffer, int write)

{

unsigned long offset = sector*sect_size;

unsigned long nbytes = nsect*sect_size;

 

if ((offset + nbytes) > dev->size) {

   printk (KERN_NOTICE "Beyond-end write (%ld %ld)\n", offset, nbytes);

   return;

}

if (write)

   memcpy(dev->data + offset, buffer, nbytes);

else

   memcpy(buffer, dev->data + offset, nbytes);

}

 

/*

* The simple form of the request function.

*/

static void blk_request(struct request_queue *q)

{

struct request *req;

 

req = blk_fetch_request(q);

while (req != NULL) {

   struct blk_dev *dev = req->rq_disk->private_data;

 

   blk_transfer(dev, blk_rq_pos(req), blk_rq_cur_sectors(req), req->buffer, rq_data_dir(req));

  

   if(!__blk_end_request_cur(req, 0))

   {

    req = blk_fetch_request(q);

   }

}

}

 

/*

* The device operations structure.

*/

static struct block_device_operations blk_ops = {

.owner            = THIS_MODULE,

};

 

 

/*

* Set up our internal device.

*/

static void setup_device()

{

/*

* Get some memory.

*/

dev->size = nsectors*sect_size;

dev->data = vmalloc(dev->size);

if (dev->data == NULL) {

   printk (KERN_NOTICE "vmalloc failure.\n");

   return;

}

 

   dev->queue = blk_init_queue(blk_request, NULL);

   if (dev->queue == NULL)

    goto out_vfree;

 

blk_queue_logical_block_size(dev->queue, sect_size);

dev->queue->queuedata = dev;

/*

* And the gendisk structure.

*/

dev->gd = alloc_disk(1);

if (! dev->gd) {

   printk (KERN_NOTICE "alloc_disk failure\n");

   goto out_vfree;

}

dev->gd->major = major;

dev->gd->first_minor = 0;

dev->gd->fops = &blk_ops;

dev->gd->queue = dev->queue;

dev->gd->private_data = dev;

sprintf (dev->gd->disk_name, "simp_blk%d", 0);

set_capacity(dev->gd, nsectors*(sect_size/sect_size));

add_disk(dev->gd);

return;

 

out_vfree:

if (dev->data)

   vfree(dev->data);

}

 

static int __init blk_init(void)

{

/*

* Get registered.

*/

major = register_blkdev(major, "blk");

if (major <= 0) {

   printk(KERN_WARNING "blk: unable to get major number\n");

   return -EBUSY;

}

 

dev = kmalloc(sizeof(struct blk_dev), GFP_KERNEL);

if (dev == NULL)

   goto out_unregister;

 

   setup_device();

    

return 0;

 

out_unregister:

unregister_blkdev(major, "sbd");

return -ENOMEM;

}

 

static void blk_exit(void)

{

 

   if (dev->gd) {

    del_gendisk(dev->gd);

    put_disk(dev->gd);

   }

   if (dev->queue)

    blk_cleanup_queue(dev->queue);

   if (dev->data)

    vfree(dev->data);

 

   unregister_blkdev(major, "blk");

kfree(dev);

}

 

module_init(blk_init);

module_exit(blk_exit);

 

 

第3課-簡單塊設備驅動設計

第4課-MTD系統架構

  1. MTD設備體驗

FLASH在嵌入式系統中是必不可少的,它是bootloader、linux內核和文件系統的最佳載體。在Linux內核中引入了MTD子系統爲NORFLASH和NAND FLASH設備提供統一的接口,從而使得FLASH驅動的設計大爲簡化。

  1. MTD架構分析

 

第5課-yaffs2文件系統使用

  1. MTD分區設置
  2. Yaffs2文件系統製做
  3. Uboot參數設置
  4. 下載燒寫與啓動

第6課-nandflash驅動程序設計

相關文章
相關標籤/搜索