JZ2440笔记:块设备驱动程序(内存模拟磁盘)

vi ramblock.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>


static struct gendisk *ramblock_disk;
static request_queue_t *ramblock_queue;
static int major;
static DEFINE_SPINLOCK(ramblock_lock);

static struct block_device_operations ramblock_fops = {
	.owner	= THIS_MODULE,
};

#define RAMBLOCK_SIZE (1024*1024)


static void do_ramblock_request(request_queue_t * q)
{
	static int cnt = 0;
	struct request *req;
	printk("do_ramblock_request %d\n",++cnt);
	while ((req = elv_next_request(q)) != NULL) {
		end_request(req, 1);	
	}
}


static int ramblock_init(void)
{
	ramblock_disk = alloc_disk(16);
	
	ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);
	ramblock_disk->queue = ramblock_queue;

	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;
	set_capacity(ramblock_disk, RAMBLOCK_SIZE/512);//p->heads * p->cylinders * p->sectors);	

	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);
}


module_init(ramblock_init);
module_exit(ramblock_exit);
MODULE_LICENSE("GPL");

测试驱动程序:

# insmod ramblock.ko
 ramblock:do_ramblock_request 1
 unknown partition table
# ls /dev/ramblock -l
brw-rw----    1 0        0        254,   0 Jan  1 00:00 /dev                                                                                                                             /ramblock
# cat /proc/devices

Block devices:
254 ramblock

vi ramblock.c(增加读写)

static unsigned char *ramblock_buf;

static void do_ramblock_request(request_queue_t * q)
{
	static int cnt = 0;
	struct request *req;
	printk("do_ramblock_request %d\n",++cnt);
	while ((req = elv_next_request(q)) != NULL) {
		unsigned long offset = req->sector * 512;
		unsigned long len = req->current_nr_sectors * 512;
		if (rq_data_dir(req) == READ)
			memcpy(req->buffer, ramblock_buf+offset, len);
		else
			memcpy(ramblock_buf+offset, req->buffer, len);
		end_request(req, 1);	
	}
}


static int ramblock_init(void)
{
	ramblock_disk = alloc_disk(16);
	
	ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);
	ramblock_disk->queue = ramblock_queue;

	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;
	set_capacity(ramblock_disk, RAMBLOCK_SIZE/512);//p->heads * p->cylinders * p->sectors);	

	ramblock_buf = 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_buf);
}

测试驱动程序:

# insmod ramblock.ko
 ramblock:do_ramblock_request 1
 unknown partition table
# mkdosfs /dev/ramblock
mkdosfs 2.11 (12 Mar 2005)
do_ramblock_request 2
do_ramblock_request 3
unable to get drive geometry, using ddo_ramblock_request 4
# mount /dev/ramblock /tmp/
do_ramblock_request 5
do_ramblock_request 6
# cd /tmp
# vi hello.txt

# ls
hello.txt                                                                                                                                               # cd /
# umount /tmp                                                                                                                                     do_ramblock_request 45
# mount /dev/ramblock /tmp/
do_ramblock_request 46
do_ramblock_request 47
do_ramblock_request 48
# cd /tmp
# ls
hello.txt

# fdisk /dev/ramblock
do_ramblock_request 85
Unknown value(s) for: cylinders (settable in the extra functions menu)

Command (m for help):
 

vi ramblock.c(增加分区)

static int ramblock_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
	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,
};

测试驱动程序:

# insmod ramblock.ko
 ramblock:do_ramblock_request 1
 unknown partition table
# ls /dev/ramblock -l
brw-rw----    1 0        0        254,   0 Jan  1 00:00 /dev/ramblock
# fdisk /dev/ramblock
do_ramblock_request 2
Device contains neither a valid DOS partition table, nor Sun, SGI or OS                                                                                                                  F disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that the previous content
won't be recoverable.

Warning: invalid flag 0x00,0x00 of partition table 4 will be corrected                                                                                                                   by w(rite)

Command (m for help): m
Command Action
a       toggle a bootable flag
b       edit bsd disklabel
c       toggle the dos compatibility flag
d       delete a partition
l       list known partition types
n       add a new partition
o       create a new empty DOS partition table
p       print the partition table
q       quit without saving changes
s       create a new empty Sun disklabel
t       change a partition's system id
u       change display/entry units
v       verify the partition table
w       write table to disk and exit
x       extra functionality (experts only)

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-32, default 1): Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-32, default 32): 5

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (6-32, default 6): 6
Last cylinder or +size or +sizeM or +sizeK (6-32, default 32): Using de                                                                                                                  fault value 32

Command (m for help): p

Disk /dev/ramblock: 1 MB, 1048576 bytes
2 heads, 32 sectors/track, 32 cylinders
Units = cylinders of 64 * 512 = 32768 bytes

        Device Boot      Start         End      Blocks  Id System
/dev/ramblock1               1           5         144  83 Linux
/dev/ramblock2               6          32         864  83 Linux

Command (m for help): w
The partition table has been altered!
do_ramblock_request 3
 ramblock:do_ramblock_request 4
 ramblock1 ramblock2

Calling ioctl() to re-read partition table
# ls /dev/ramblock* -l
brw-rw----    1 0        0        254,   0 Jan  1 00:05 /dev/ramblock
brw-rw----    1 0        0        254,   1 Jan  1 00:05 /dev/ramblock1
brw-rw----    1 0        0        254,   2 Jan  1 00:05 /dev/ramblock2
#
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值