一个极简单的 块设备驱动 的编写

目标平台:loongson 1B

目标系统:1b-linux-3.0

目标开发板架构:mipsel架构

实现平台:ubuntu 13.04 

#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 <linux/gfp.h>
#include <linux/slab.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/dma.h>

#define RAMDISK_SIZE (1024*1024)
static DEFINE_SPINLOCK(ramdisk_lock); // 申请自旋锁

static int major;
static struct gendisk *ramblock_disk;
static struct request_queue *ramblock_queue;
static unsigned char *ram_buff;

static const struct block_device_operations ramdisk_fops = {
.owner = THIS_MODULE,
};

  // 关键:offset, len 
static void ramblock_do_request(struct request_queue * q)
{
 	 struct request *req;
	u16 offset;
	u16 len;
	printk("ramblock do request \n");
    // 从request_queue 队列中获取一个request 
        req = blk_fetch_request(q);
	while (req)
    	 {
 	   offset = blk_rq_pos(req)*512;  //获取 ramdisk块设备的偏移位置
   	   len = blk_rq_cur_bytes(req);// 想要写入或读ramdisk块设备的大小
	
	    if (  rq_data_dir(req)== READ)    //
 	       memcpy(req->buffer, ram_buff+offset, len);
	   else
		memcpy(ram_buff+offset, req->buffer, len);

  	   if (!__blk_end_request_cur(req,0)) // 判断ramdisk块设备的读写是否完成。每个块设备都有一个请求队列
   	     req = blk_fetch_request(q);
        }


}

//关键: 块设备的的初始化:
 1) 块设备注册
 2) 请求队列的绑定
 3) 设置块容量
 4) 注册块设备
static int simp_blkdev_init(void)
{
	/*获得主设备号及 设备名*/
	major = register_blkdev(major, "ramdisk");

	/*1.1分配一个gendisk结构体*/
	ramblock_disk = alloc_disk(1);
	/*1.2设置其他信息*/
	ramblock_disk->major = major;
	ramblock_disk->first_minor = 0;
	sprintf(ramblock_disk->disk_name, "ramdisk");
	ramblock_disk->fops = &ramdisk_fops;

	/*2. 1 设置一个请求队列*/
	ramblock_queue = blk_init_queue(ramblock_do_request, &ramdisk_lock);
	ramblock_disk->queue = ramblock_queue;

	//设置块设备大小
	set_capacity(ramblock_disk, RAMDISK_SIZE);

	/*注册*/
	 add_disk(ramblock_disk);

         ram_buff = kzalloc(RAMDISK_SIZE, GFP_KERNEL);
	printk("module simp_blkdev added.\n");
  	return  0;
}

关键:
1) 注销设备号
2) 释放ramblock所占的内容
3)销毁队列
4)释放内存
static void simp_blkdev_exit(void)
{
  
	unregister_blkdev(major, "ramdisk");
	del_gendisk(ramblock_disk);
	put_disk(ramblock_disk);   //对应于set_capacity
	blk_cleanup_queue(ramblock_queue);
	kfree(ram_buff); 
	printk("exit\n");
}
module_init(simp_blkdev_init);
module_exit(simp_blkdev_exit);
MODULE_AUTHOR("<hzg>");
MODULE_DESCRIPTION("block dev ");
MODULE_LICENSE("GPL");
之后的步骤如下:

    a)make 一下,生成ramdisk.ko;

    b)编译好了之后,就可以安装驱动了,在linux下是这么做的,sudo insmod ramdisk.ko;

    c)安装好了,利用ls /dev/ram*, 就会发现在/dev下有个新结点,即/dev/ramdisk;

    d)进行分区处理, sudo fdisk /dev/ramdisk,简单处理的话就建立分区, 生成/dev/ramdisk;

    e)创建文件系统,sudo mkfs.ext3 /dev/ramdisk;

    f)有了上面的文件系统,就可以进行mount处理,不妨sudo mount /dev/ramdisk  /mnt;

    g)上面都弄好了,大家就可以copy、delete文件试试了,是不是很简单。




  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值