安装驱动后,可在/dev/目录下发现已经生成了相应的设备文件。
格式化设备:mkdosfs /dev/ramblock。
挂载设备。
读写设备 。
驱动程序代码:
/************************************************************************* > File Name: ramblock.c > Author: > Mail: > Created Time: 2016年11月05日 星期六 22时17分28秒 ************************************************************************/ #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> #define RAMBLOCK_SIZE (1024*1024) struct gendisk *ramblock_disk; static request_queue_t *ramblock_queue; static DEFINE_SPINLOCK(ramblock_lock); static int major; static unsigned char *ramblock_buff; static int ramblock_getgeo(struct block_device *bdev, struct hd_geometry *geo) { /* 容量 = heads*sectors*cylinders*512 */ geo->heads = 2; geo->sectors = 32; geo->cylinders = RAMBLOCK_SIZE/2/32/512; return 0; } static struct block_device_operations ramblock_fops = { .owner= THIS_MODULE, .getgeo = ramblock_getgeo, }; static void do_ramblock_request(request_queue_t * q) { struct request *req; static int r_cnt = 0; static int w_cnt = 0; while ((req = elv_next_request(q)) != NULL) { /* 数据传输3要素 */ /* 源/目的 */ unsigned long offset = req->sector*512; /* 目的 */ //req->buff /* 长度 */ unsigned long len = req->current_nr_sectors * 512; if(rq_data_dir(req)==READ) { memcpy(req->buffer,ramblock_buff+offset, len); printk("read %d ",r_cnt++); } else { memcpy(ramblock_buff+offset, req->buffer, len); printk("write %d ",w_cnt++); } end_request(req, 1);/* wrap up, 0 = fail, 1 = success */ } } static int ramblock_init(void) { /* 分配一个gendisk结构体 */ ramblock_disk = alloc_disk(16); //次设备号个数=分区个数+1 /* 设置 */ /* 分配/设置队列:提供读写能力 */ ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock); /* 设置其他属性 */ major = register_blkdev(0,"ramblock"); ramblock_disk->major = major; ramblock_disk->first_minor = 0; sprintf(ramblock_disk->disk_name, "ramblock"); ramblock_disk->fops = &ramblock_fops; ramblock_disk->queue = ramblock_queue; set_capacity(ramblock_disk, RAMBLOCK_SIZE/512); /* 硬件相关 */ ramblock_buff = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL); /* 注册 */ add_disk(ramblock_disk); return 0; } static void ramblock_exit(void) { unregister_blkdev(major,"ramblock"); del_gendisk(ramblock_disk); put_disk(ramblock_disk); blk_cleanup_queue(ramblock_queue); kfree(ramblock_buff); } module_init(ramblock_init); module_exit(ramblock_exit); MODULE_LICENSE("GPL");
sd