Linux-FLASH驱动设计二
来源:互联网 发布:被淘宝大学骗了怎么办 编辑:程序博客网 时间:2024/05/22 10:25
块设备驱动系统分析:
功能:把内存划出512k,然后利用驱动程序做成块设备进行相应的访问。
#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 gendisk结构体描述};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;<span style="white-space:pre"></span>//计算分配的设备大小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);//为块设备分配struct gendisk结构if (! dev->gd) {printk (KERN_NOTICE "alloc_disk failure\n");goto out_vfree;}/*初始化struct gendisk结构体*/ 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");//注册块设备驱动程序,如果主设备号(major)填写为0,内核会自动分配设备号,通过返回值传递给majorif (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);
0 0
- Linux-FLASH驱动设计二
- Linux-FLASH驱动设计一
- Linux-FLASH驱动设计三
- Linux-FLASH驱动设计四
- linux nand flash 驱动(二) --- 驱动实现
- Linux-Flash驱动(3)-简单块设备驱动设计
- linux nor flash 驱动
- Nand Flash裸机驱动设计
- FLASH 驱动程序设计 --- 块设备驱动设计
- Nand flash linux 驱动研究
- spi flash驱动代码分析(二)
- linux驱动(二)
- linux UART驱动 二
- linux 驱动笔记(二)
- linux驱动设计----helloword
- linux驱动设计知识点
- Linux SPI驱动设计
- Linux网卡驱动设计
- js页面跳转整理
- UIPickerView和UIDatePicker常用属性
- 用代码为视图添加约束, VFL语法总结, 网址:www.iphonetrain.com 公司:星宇无限(北京)科技有限公司
- 博客开启
- 添加一个c文件,编译报错
- Linux-FLASH驱动设计二
- Java EE自动提示设置
- [leetcode] Permutations
- PHP运行模式
- C# Dictionary用法总结
- Servlet 初步(五) session
- 8.17
- 认识StringBuffer
- IOS微信音乐播放问题