??????????????????????????????????????????????????????????????????ram???????????????????????????disk?????????????????????ramdisk????????????????????????????????????????????????????????????????????????????????????
????????????
-
- ????????????????????????
- ??????ramdisk??????????????????
-
- 2.1 ???????????????
- ??????ramdisk?????????
????????????????????????
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????512B????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????????????=??????????????????????????????????????????????????????????????????????????????
??????????????????????????????????????? ????????????????????? ?? ??????(??????)??? ?? ??????????????? ?? ?????????????????????512???
?????????????????????????????????????????????????????????????????????????????????????????????request_queue???????????????????????????????????????????????????????????????????????????/???IO??????????????????????????????/????????????????????????????????????????????????????????????????????????????????????IO??????????????????????????????
???????????????ram????????????????????????????????????????????????????????????????????????????????????
??????ramdisk??????????????????
???????????????????????????3.10.0-123????????????????????????????????????ramdisk?????????????????????4MB???????????????ram??????
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/major.h>
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/highmem.h>
#include <linux/mutex.h>
#include <linux/radix-tree.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/sizes.h>
#include <linux/kernel.h>
#include <linux/genhd.h>
#include <linux/hdreg.h>
#include <linux/blkpg.h>
#define DEVICE_NAME "ramdisk_test"
#define ram_size SZ_4M
static DEFINE_SPINLOCK(ramdisk_lock);
struct gendisk *ramdisk;
static struct request_queue *disk_queue;
void *ram_addr;
static int ramdisk_getgeo(struct block_device *blk_dev, struct hd_geometry *geo)
{
geo->cylinders = 32; //?????????????????????
geo->heads = 2; //????????????
geo->sectors = ram_size/2/32/512; //??????????????????????????????
printk(KERN_INFO "capacity %d\n", get_capacity(blk_dev->bd_disk)); //get_capacity(blk_dev->bd_disk)=8292
return 0;
}
static struct kobject *ramdisk_probe(dev_t dev, int *part, void *data)
{
printk(KERN_INFO "%s called\n", __FUNCTION__);
*part = 0;
return get_disk(ramdisk);
}
/*
?????????disk_queue?????????request????????????
*/
static void ramdisk_request(struct request_queue *q)
{
struct request *req;
printk(KERN_INFO "%s called\n", __FUNCTION__);
req = blk_fetch_request(q); //???????????????disk_queue?????????request
while (req) {
unsigned long offset = blk_rq_pos(req) *512; //?????????????????????????????????
unsigned long len = blk_rq_cur_bytes(req); //request??????
int err = 0;
printk(KERN_INFO "%s offset:%d len %d\n", __FUNCTION__, offset, len);
if((u32)(offset+len) < ram_size)
{
if (rq_data_dir(req) == READ) //???????????????
{
printk(KERN_INFO "%s read len %d\n", __FUNCTION__, len);
memcpy(req->buffer, (char *)(ram_addr + offset), len); //?????????(request??????buffer?????????????????????ramdisk????????????offset???????????????)
}
else
{
printk(KERN_INFO "%s write len %d\n", __FUNCTION__, len);
memcpy((char *)(ram_addr + offset), req->buffer, len); //?????????
}
}
else
{
printk(KERN_INFO "fail %s offset:%d len %d\n", __FUNCTION__, offset, len);
}
done:
if (!__blk_end_request_cur(req, err)) //end_request ??????
req = blk_fetch_request(q);
}
}
static const struct block_device_operations disk_fops =
{
.owner = THIS_MODULE,
.getgeo = ramdisk_getgeo,
//.open = ramdisk_open,
//.release = ramdisk_release,
};
int major;
static int __init ramdisk_init(void)
{
int ret;
printk(KERN_INFO "%s called\n", __FUNCTION__);
major = register_blkdev(0, DEVICE_NAME); //???????????????????????????????????????
disk_queue = blk_init_queue(ramdisk_request, &ramdisk_lock); //??????????????? request_queue????????????????????????ramdisk_request
if (!disk_queue)
goto out_queue;
ramdisk = alloc_disk(1); //????????????gendisk(??????????????????=?????????=1)
ramdisk->queue = disk_queue; //???gendisk???????????????
ramdisk->major = major;
ramdisk->first_minor = 0; //??????0---???????????????????????????????????????
ramdisk->fops = &disk_fops;
sprintf(ramdisk->disk_name, DEVICE_NAME);
set_capacity(ramdisk, ram_size/512); //??????????????????????????????????????????
add_disk(ramdisk); //??????gendisk
blk_register_region(MKDEV(major, 0), 1, THIS_MODULE, //???????????????[0-1)
ramdisk_probe, NULL, NULL);
ram_addr = kzalloc(ram_size, GFP_KERNEL);
if(!ram_addr)
{
kfree(ram_addr);
goto out_queue;
}
printk(KERN_INFO "%s end\n", __FUNCTION__);
return 0;
out_queue:
put_disk(ramdisk);
out_disk:
unregister_blkdev(major, DEVICE_NAME);
err:
return -1;
}
static void __exit ramdisk_exit(void)
{
blk_unregister_region(MKDEV(major, 0), 1);
unregister_blkdev(major, DEVICE_NAME);
put_disk(ramdisk);
//del_gendisk(ramdisk);
blk_cleanup_queue(disk_queue);
kfree(ram_addr);
return;
}
module_init(ramdisk_init);
module_exit(ramdisk_exit);
MODULE_LICENSE("GPL");
2.1 ???????????????
???????????????????????????????????????????????????
- ????????????????????????????????? register_blkdev
- ????????????????????????????????????????????????????????? blk_init_queue
- ??????gendisk??????????????????????????????????????????????????????fop?????? alloc_disk
- ????????????????????????????????? set_capacity
- ?????????????????? add_disk
?????????????????????4MB???????????????????????????????????????:
- ram_addr = kzalloc(ram_size, GFP_KERNEL); //??????4MB??????
- ??????????????????????????????ramdisk_request????????????????????????????????????
ramdisk_request???????????????????????????
- ???????????????????????????????????????request_queue????????????quest???
- ??????quest?????????????????????????????????????????????request?????????
- ?????????????????????????????????????????????ram???????????????memcpy ?????????req->buffer???ram?????????????????????
?????????????????????request_queue?????????????????????????????????????????????????????????????????????????????????????????????request???IO????????????????????????????????????
??????????????????:??????????????????request???????????????????????????if((u32)(offset+len) < ram_size)??????????????????????????????4M????????????????????????
???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????sync????????????????????????????????????????????????????????????????????????????????????????????????buffer???????????????ramdisk_request??????????????????????????????????????????request?????????
??????ramdisk?????????
- ??????????????????????????????????????????????????????/dev/ramdisk_test???
[[email??protected] mnt]# ls /dev/ramdisk_test -l
brw-rw----. 1 root disk 252, 0 Feb 2 05:47 /dev/ramdisk_test
- ????????????????????????????????????????????????ramdisk_getgeo????????????????????????????????????????????????????????????????????????geo->heads ????????????/????????????geo->cylinders?????????????????????????????????geo->sectors??????
[[email??protected] ramdisk]# mkfs.ext4 /dev/ramdisk_test #????????????ext4
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
1024 inodes, 4096 blocks
204 blocks (4.98%) reserved for the super user
First data block=1
Maximum filesystem blocks=4194304
1 block group
8192 blocks per group, 8192 fragments per group
1024 inodes per group
Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done
[[email??protected] ramdisk]# mkfs.fat /dev/ramdisk_test #???????????????fat
mkfs.fat 3.0.20 (12 Jun 2013)
????????????????????????ramdisk_getgeo????????????????????????????????????????????????????????????????????????????????????????????????[[email??protected] ramdisk]# mkfs.fat /dev/ramdisk_test mkfs.fat 3.0.20 (12 Jun 2013) unable to get drive geometry, using default 255/63 ```
- fdisk????????????ramdisk???????????????????????????????????????????????????4MB???
[[email??protected] mnt]# fdisk -l /dev/ramdisk_test
Disk /dev/ramdisk_test: 4 MB, 4194304 bytes, 8192 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
- ??????????????????????????????????????????/mnt/?????????????????????
[[email??protected] /]# mount /dev/ramdisk_test /mnt/
[[email??protected] /]# mount |grep ramdisk
/dev/ramdisk_test on /mnt type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro)
[[email??protected] /]#