目標平臺: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文件試試了,是不是很簡單。