#include <linux/fs.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/blkdev.h>
#include <linux/genhd.h>
#include <linux/errno.h>
#include <linux/hdreg.h>
#include <linux/version.h>
#define MY_DEVICE_NAME "myramdisk"
static int mybdrv_ma_no, diskmb = 256, disk_size;
static char *ramdisk;
static struct gendisk *my_gd;
static spinlock_t lock;
static unsigned short sector_size = 512;
static struct request_queue *my_request_queue;
module_param_named(size, diskmb, int, 0);
static void my_request(struct request_queue *q)
{
struct request *rq;
int size, res = 0;
char *ptr;
unsigned nr_sectors, sector;
pr_info("start handle request\n");
rq = blk_fetch_request(q); // 从请求队列中拉一个request出来
while (rq)
{
nr_sectors = blk_rq_cur_sectors(rq); // 这个请求需要多少个sector
sector = blk_rq_pos(rq);
ptr = ramdisk + sector * sector_size;
size = nr_sectors * sector_size;
if ((ptr + size) > (ramdisk + disk_size))
{
pr_err("end of device\n");
goto done;
}
if (rq_data_dir(rq))
{
pr_info("writing at sector %d, %u sectors\n",
sector, nr_sectors);
memcpy(ptr, bio_data(rq->bio), size);
}
else
{
pr_info("reading at sector %d, %u sectors\n",
sector, nr_sectors);
memcpy(bio_data(rq->bio), ptr, size);
}
done:
if (!blk_end_request(rq, res, size))
rq = blk_fetch_request(q);
}
pr_info("handle request done\n");
}
static int my_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
long size;
struct hd_geometry geo;
pr_info("cmd=%d\n", cmd);
switch (cmd)
{
case HDIO_GETGEO:
pr_info("HIT HDIO_GETGEO\n");
size = disk_size;
size &= ~0x3f;
geo.cylinders = size >> 6;
geo.heads = 2;
geo.sectors = 16;
geo.start = 4;
if (copy_to_user((void __user *)arg, &geo, sizeof(geo)))
return -EFAULT;
return 0;
}
pr_warn("return -ENOTTY\n");
return -ENOTTY;
}
static const struct block_device_operations mybdrv_fops = {
.owner = THIS_MODULE,
.ioctl = my_ioctl,
};
static int __init my_init(void)
{
disk_size = diskmb * 1024 * 1024;
spin_lock_init(&lock);
ramdisk = vmalloc(disk_size);
if (!ramdisk)
return -ENOMEM;
my_request_queue = blk_init_queue(my_request, &lock);
if (!my_request_queue)
{
vfree(ramdisk);
return -ENOMEM;
}
blk_queue_logical_block_size(my_request_queue, sector_size);
mybdrv_ma_no = register_blkdev(0, MY_DEVICE_NAME);
if (mybdrv_ma_no < 0)
{
pr_err("Failed registering mybdrv, returned %d\n",
mybdrv_ma_no);
vfree(ramdisk);
return mybdrv_ma_no;
}
my_gd = blk_alloc_disk(GFP_KERNEL);
if (!my_gd)
{
unregister_blkdev(mybdrv_ma_no, MY_DEVICE_NAME);
vfree(ramdisk);
return -ENOMEM;
}
my_gd->major = mybdrv_ma_no;
my_gd->first_minor = 0;
my_gd->fops = &mybdrv_fops;
strcpy(my_gd->disk_name, MY_DEVICE_NAME);
my_gd->queue = my_request_queue;
set_capacity(my_gd, disk_size / sector_size);
add_disk(my_gd);
pr_info("device successfully registered, Major No. = %d\n",
mybdrv_ma_no);
pr_info("Capacity of ram disk is: %d MB\n", diskmb);
return 0;
}
static void __exit my_exit(void)
{
del_gendisk(my_gd);
put_disk(my_gd);
unregister_blkdev(mybdrv_ma_no, MY_DEVICE_NAME);
pr_info("module successfully unloaded, Major No. = %d\n", mybdrv_ma_no);
blk_cleanup_queue(my_request_queue);
vfree(ramdisk);
}
module_init(my_init);
module_exit(my_exit);
MODULE_AUTHOR("Benshushu");
MODULE_LICENSE("GPL v2");
Makefile文件
CONFIG_MODULE_SIG=n
PWD := $(shell pwd)
obj-m += ramdisk_driver.o
all :
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
install:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules_install;
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
rm -f *.ko;
一直报错,有没有知道如何解决呀
报错为
sudo make
make -C /lib/modules/5.15.0-91-generic/build M=/home/dream/code modules
make[1]: Entering directory '/usr/src/linux-headers-5.15.0-91-generic'
CC [M] /home/dream/code/ramdisk_driver.o
/home/dream/code/ramdisk_driver.c: In function ‘my_request’:
/home/dream/code/ramdisk_driver.c:32:11: error: implicit declaration of function ‘blk_mq_dequeue’ [-Werror=implicit-function-declaration]
32 | rq = blk_mq_dequeue(q); // 从请求队列中拉一个request出来
| ^~~~~~~~~~~~~~
/home/dream/code/ramdisk_driver.c:32:9: warning: assignment to ‘struct request *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
32 | rq = blk_mq_dequeue(q); // 从请求队列中拉一个request出来
| ^
/home/dream/code/ramdisk_driver.c:61:14: error: implicit declaration of function ‘blk_end_request_cur’; did you mean ‘blk_get_request’? [-Werror=implicit-function-declaration]
61 | if (!blk_end_request_cur(rq, res))
| ^~~~~~~~~~~~~~~~~~~
| blk_get_request
/home/dream/code/ramdisk_driver.c:62:18: error: implicit declaration of function ‘blk_fetch_request’; did you mean ‘blk_get_request’? [-Werror=implicit-function-declaration]
62 | rq = blk_fetch_request(q);
| ^~~~~~~~~~~~~~~~~
| blk_get_request
/home/dream/code/ramdisk_driver.c:62:16: warning: assignment to ‘struct request *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
62 | rq = blk_fetch_request(q);
| ^
/home/dream/code/ramdisk_driver.c: In function ‘my_init’:
/home/dream/code/ramdisk_driver.c:113:24: error: implicit declaration of function ‘blk_init_queue’; did you mean ‘blk_put_queue’? [-Werror=implicit-function-declaration]
113 | my_request_queue = blk_init_queue(my_request, &lock); // 初始化请求队列,第一个参数是函数指针
| ^~~~~~~~~~~~~~
| blk_put_queue
/home/dream/code/ramdisk_driver.c:113:22: warning: assignment to ‘struct request_queue *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
113 | my_request_queue = blk_init_queue(my_request, &lock); // 初始化请求队列,第一个参数是函数指针
| ^
/home/dream/code/ramdisk_driver.c:130:13: error: implicit declaration of function ‘blk_mq_alloc_disk’; did you mean ‘blk_alloc_disk’? [-Werror=implicit-function-declaration]
130 | my_gd = blk_mq_alloc_disk(my_request_queue, NULL); // 分配一个gendisk
| ^~~~~~~~~~~~~~~~~
| blk_alloc_disk
/home/dream/code/ramdisk_driver.c:130:11: warning: assignment to ‘struct gendisk *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
130 | my_gd = blk_mq_alloc_disk(my_request_queue, NULL); // 分配一个gendisk
| ^
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:297: /home/dream/code/ramdisk_driver.o] Error 1
make[1]: *** [Makefile:1909: /home/dream/code] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.15.0-91-generic'
make: *** [Makefile:5: all] Error 2
dream@ubuntu:~/code$ ^C
dream@ubuntu:~/code$ sudo make clean
make -C /lib/modules/5.15.0-91-generic/build M=/home/dream/code clean
make[1]: Entering directory '/usr/src/linux-headers-5.15.0-91-generic'
make[1]: Leaving directory '/usr/src/linux-headers-5.15.0-91-generic'
rm -f *.ko;
dream@ubuntu:~/code$ sudo make
make -C /lib/modules/5.15.0-91-generic/build M=/home/dream/code modules
make[1]: Entering directory '/usr/src/linux-headers-5.15.0-91-generic'
CC [M] /home/dream/code/ramdisk_driver.o
/home/dream/code/ramdisk_driver.c: In function ‘my_request’:
/home/dream/code/ramdisk_driver.c:31:10: error: implicit declaration of function ‘blk_fetch_request’; did you mean ‘blk_get_request’? [-Werror=implicit-function-declaration]
31 | rq = blk_fetch_request(q); // 从请求队列中拉一个request出来
| ^~~~~~~~~~~~~~~~~
| blk_get_request
/home/dream/code/ramdisk_driver.c:31:8: warning: assignment to ‘struct request *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
31 | rq = blk_fetch_request(q); // 从请求队列中拉一个request出来
| ^
/home/dream/code/ramdisk_driver.c:59:14: error: implicit declaration of function ‘blk_end_request’; did you mean ‘blk_get_request’? [-Werror=implicit-function-declaration]
59 | if (!blk_end_request(rq, res, size))
| ^~~~~~~~~~~~~~~
| blk_get_request
/home/dream/code/ramdisk_driver.c:60:16: warning: assignment to ‘struct request *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
60 | rq = blk_fetch_request(q);
| ^
/home/dream/code/ramdisk_driver.c: In function ‘my_init’:
/home/dream/code/ramdisk_driver.c:108:24: error: implicit declaration of function ‘blk_init_queue’; did you mean ‘blk_put_queue’? [-Werror=implicit-function-declaration]
108 | my_request_queue = blk_init_queue(my_request, &lock);
| ^~~~~~~~~~~~~~
| blk_put_queue
/home/dream/code/ramdisk_driver.c:108:22: warning: assignment to ‘struct request_queue *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
108 | my_request_queue = blk_init_queue(my_request, &lock);
| ^
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:297: /home/dream/code/ramdisk_driver.o] Error 1
make[1]: *** [Makefile:1909: /home/dream/code] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.15.0-91-generic'
make: *** [Makefile:5: all] Error 2