1 drivers
#include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> #include < linux/sched.h> #include <linux/kernel.h>/* PRINTK () */#include <linux/slab.h>/* KMALLOC () */#include <linux/fs.h>/ * Everything ... * * #include <linux/errno.h>/ * ERROR codes */#include <linux/timer.h> #include <linux/types.h>/ * size_t */#include <linux/fcntl.h>/ * O_accmode */#include <linux/hdreg.h>/ * Hdio_getgeo */#include <linux/kdev_t.h> #include <linux/vmalloc.h> #include <linux/genhd.h># Include <linux/blkdev.h> #include <linux/buffer_head.h>/ * Invalidate_bdev */#include <linux/bio.h>//block device file main device number 72#define block_devicemajor compaq_smart2_major// Block Device name # define BLOCK_DISKNAME "Queue_block"//Block Device Capacity # Block_dev_bytes (1*1024*1024)//1m//request queue Pointer St atic struct request_queue *block_request_queue;//gendisk struct pointer variable static struct Gendisk *block_dev_disk;// Simulated disk space unsigned char block_dev_data[block_dev_bytes];//The function cannot be called by the system called by the calling system when callingstatic voidblock_dev_do_request(struct request_queue *q) { //GET request queue first IO request struct request *req =blk_fetch_request (q); & nbsp while (req != NULL) { sector_t sector = b Lk_rq_pos (req); //get sector first position unsigned Long nsector = blk_rq_cur_sectors (req); /Get Sector number //determine if it is greater than total capacity if ((Sector + nsector) <<9 > BLOCK _dev_bytes) { PRINTK (kern_err block_diskname ": Bad Request:block=%llu, count=%llu\n", &NB Sp (UNSIG)Ned Long Long) sector, &NB Sp (unsigned long Long) nsector); &NB Sp __blk_end_request_all (req,-eio); Conti nue; //determine data transmission direction &NB Sp Switch (Rq_data_dir (req)) { Case read: & nbsp memcpy (req->buffer, &N Bsp Block_dev_data + (sector<<9), &NB Sp nsector<<9 ; &NBSp &NBS P break; Case write: memcpy (Block_dev_data + (sector<<9), &NB Sp Req->buffer, &NBSP;NSECTOR&L t;<9); &N Bsp break; DEFAULT:&NB Sp &NBSP ; break; } &NB Sp; //Notification request queue Current IO has been processed if (! __blk_end_request_cur (req, 0 ) ) {req = blk_fetch_request (q);//Continue to read the next IO request} }}static int block_dev_open (struct block_device *device, fmode_t mode) { PRINTK ( "Open%s\n", device->bd_disk->disk_name); return 0;} Release block device static int block_dev_release (struct gendisk *gendisk, fmode_t mode) { PRINTK (" Release%s\n ", Gendisk->disk_name); return 0;} Similar character device struct block_device_operations block_dev_fops = { . Owner &N Bsp = This_module,.open=block_dev_open,. release=block_dev_release};static int __init Block_dev_init ( void) { int ret; //Initialize request queue BLOCK_REQUEST_Q Ueue = Blk_init_queue (block_dev_do_request, NULL); if (!block_request_queue) { &N Bsp ret =-enomem; Goto Err_init_que ue; &nbsP } //Allocate disk Block_dev_disk = Alloc_disk (1); if (!block_dev_disk) { ret =-enomem; &N Bsp Goto err_alloc_disk; } strcpy (block_dev_ Disk->disk_name, block_diskname);//device file name Block_dev_disk->major = block_devicemajor;& nbsp Block_dev_disk->first_minor = 0; Block_dev_disk->fops = &block_ dev_fops; block_dev_disk->queue = block_request_queue;//Specify request queue Set_capacity (Block_dev_disk, block_dev_bytes>>9);//Set disk capacity Add_disk (Block_dev_disk) ;//Add disk return 0;err_alloc_disk: Blk_cleanup_queue (block_request_ Queue);err_init_queue: return ret;} static void __exit block_dev_exit (void) { Del_gendisk (block_dev_disk);//delete disk & nbsp Put_disk (block_dev_disk);//gendisk citations reduced by one Blk_cleanup_queue (block_request_queue); /Clear Request queue}module_init (block_dev_init); Module_exit (Block_dev_exit);
Test:
First step: Compile and install the driver
makefile;
Ifneq ($ (kernelrelease),)
obj-m: =QUEUE_BLOCK.O
Else
Kerneldir: =/home/litingting/gec2440/linux-2.6.30.4
All :
make-c $ (kerneldir) m=$ (PWD) modules Arch=arm cross_compile=arm-linux-
Clean :
rm-f *.o *.ko *.mod.o *.mod.c *.symvers modul* *.*~
endif
Next Queue_block.ko
Step two: Format the block device
For example, format the device as EXT2 file system format mkfs.ext2 /dev/queue_block
Step Three: Mount
Mount /dev/queue_block
An explanation of the mount is as follows:
A
I plugged the USB drive to the port, what can I do next to see what's on the USB drive? I'm not sure that your Linux system will automatically load. So, you should go to the/media directory and see if it has been loaded automatically. If so, there should be a directory in the/media, the name is similar to disk, you enter the directory is equal to enter your USB stick. If/media doesn't have what you want, mount it yourself! $mkdir/mnt/usb $mount-T Vfat/dev/sda/mnt/usb so that you can go to/mnt/usb directory to see, should have you want. If the mount command doesn't work, then you can change the/DEV/SDA to/dev/sdb or/DEV/SDC and try it! The-t option is used to set the file system type, and I assume that your USB stick is FAT32. (because most USB drives are like this) if it's another file system, you can look at it in man mount, similar to the method. B
Linux block device driver and its test