块设备驱动框架
Posted zsy12138
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了块设备驱动框架相关的知识,希望对你有一定的参考价值。
以RAM模拟一个分区为例
框架入口源文件:armblock.c
(可根据入口源文件,再按着框架到内核走一遍)
内核版本:linux_2.6.22.6 硬件平台:JZ2440
以下是驱动代码 armblock.c :
#include <linux/module.h> #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/kernel.h> #include <linux/timer.h> #include <linux/genhd.h> #include <linux/hdreg.h> #include <linux/ioport.h> #include <linux/init.h> #include <linux/wait.h> #include <linux/blkdev.h> #include <linux/blkpg.h> #include <linux/delay.h> #include <linux/io.h> #include <asm/system.h> #include <asm/uaccess.h> #include <asm/dma.h> // ram_block_disk 独立的磁盘设备或则分区 static struct gendisk *ram_block_disk; //定义一个request_queue 结构体 static struct request_queue *ram_block_req; //定义一个自旋锁 static DEFINE_SPINLOCK(ramblock_lock); //定义一个主设备号 static int major; //磁盘大小 #define GENDISK_SIZE (1024*1024) //缓存起始地址 static unsigned char *gendisk_buffer; //getgeo 获得驱动器信息 static int gendisk_getgeo(struct block_device *dev, struct hd_geometry *geo) { geo->heads = 2; geo->cylinders = 32; geo->sectors = (GENDISK_SIZE/2/32/512); return 0; } static struct block_device_operations gendisk_fops= { .owner = THIS_MODULE, .getgeo = gendisk_getgeo, }; //请求函数 static void ram_block_req_fn(request_queue_t * q) { struct request *req; unsigned long offset=0, len=0; while((req = elv_next_request(q))!=NULL) { offset = req->sector*512; len = req->current_nr_sectors*512; if(rq_data_dir(req) == READ) memcpy( req->buffer,gendisk_buffer+offset,len ); //read dest src len else memcpy( gendisk_buffer+offset, req->buffer, len ); // write end_request(req,1); } } static int ram_block_init(void) { //申请gendisk ram_block_disk = alloc_disk(16); //设置gendisk //绑定请求函数 ram_block_req = blk_init_queue(ram_block_req_fn,&ramblock_lock); ram_block_disk->queue = ram_block_req; //设置gendisk参数 注册blk major = register_blkdev(0, "armblock" ); /* cat /proc/devices */ sprintf(ram_block_disk->disk_name, "armblock"); ram_block_disk->fops = &gendisk_fops; ram_block_disk->first_minor = 0; ram_block_disk->major = major; set_capacity(ram_block_disk, GENDISK_SIZE/512); gendisk_buffer = kzalloc(GENDISK_SIZE,GFP_KERNEL); //磁盘起始地址 //添加gendisk add_disk(ram_block_disk); return 0; } static void ram_block_exit(void) { del_gendisk(ram_block_disk); put_disk(ram_block_disk); blk_cleanup_queue(ram_block_req); unregister_blkdev(major,"armblock"); kfree(gendisk_buffer); } module_init(ram_block_init); module_exit(ram_block_exit); MODULE_LICENSE("GPL");
以下是编译驱动的Makefile:
KERN_DIR = /work/systems/kernel/linux-2/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 += armblock.o
以上是关于块设备驱动框架的主要内容,如果未能解决你的问题,请参考以下文章