Header file
#include <linux/blkdev.h>
#include <linux/bio.h>
Blkdev.c
/********************************************************************* Header File ************************************ *********************************/#include<linux/init.h>#include<linux/module.h>#include<linux/errno.h>#include<linux/blkdev.h>#include<linux/bio.h>#include<linux/vmalloc.h>/********************************************************************* type definition *********************************** **********************************/typedefstructblkdev{intSize//Data Size Char*data;//Data Content structRequest_queue *queue;//Request Queue structGendisk *GD;//Disk Structure}blkdev;/********************************************************************* global variable *********************************** **********************************/Static intMajor//Main device numberBlkdev *blkdev;//Equipment Structure/********************************************************************* Request Queue *********************************** **********************************///Processing RequestsvoidBlk_transfer (Blkdev *blkdev, unsignedLongsector,unsignedLongNumberChar*buffer,intdirection) { //Calculate Sector locationUnsignedLongoffset, nbytes; Offset= Sector * +;//Set Sector locationnbytes = number * +;//Set Sector size//Processing Operation Requests if(direction) {//whether to write the requestmemcpy (blkdev->data + offset, buffer, nbytes);//write data to a sector}Else{//whether to read the requestmemcpy (buffer, Blkdev->data + offset, nbytes);//read data from Sectors }}//processing QueuesvoidBlk_request_queue (structRequest_queue *3) { //Get Queue Request structRequest *req; intIsend; Req=blk_fetch_request (q); while(req! = NULL) {//whether there is a request//Processing Queue RequestsBlk_transfer (Blkdev, Blk_rq_pos (req), blk_rq_cur_sectors (req), req->buffer, Rq_data_dir (req)); //Get Queue RequestIsend = __blk_end_request_cur (req,0); if(!isend) {//Is not the last requestreq =blk_fetch_request (q); } }}/********************************************************************* Device Method ********************************** ***********************************/structBlock_device_operations Blk_ops ={. Owner=This_module};/********************************************************************* Module Installation *********************************** **********************************///Mounting ModuleStatic intIblk_init (void){ //registering the device structureMajor = Register_blkdev (0,"iblk");//dynamically assign a master device number if(Major <=0){//If the allocation fails to returnPrintk"Register block Device fail!\n"); return-Ebusy; } //Assigning device StructuresBlkdev = Kmalloc (sizeof(Blkdev), Gfp_kernel); //Allocating device SpaceBlkdev->size =1024x768* +;//Sector size = number of sectors * per block sizeBlkdev->data = Vmalloc (blkdev->size); //Assigning a request queueBlkdev->queue =Blk_init_queue (Blk_request_queue, NULL); //set up a queue sectorBlk_queue_logical_block_size (Blkdev->queue, +); //Allocating disk StructuresBLKDEV->GD = Alloc_disk (1); //Set Disk structureBlkdev->gd->major = major;//Main device numberBlkdev->gd->first_minor =0;//Starting device numberBlkdev->gd->fops = &blk_ops;//Device MethodBlkdev->gd->queue = blkdev->queue;//Request QueueBlkdev->gd->private_data = Blkdev;//Private Memberssprintf (Blkdev->gd->disk_name,"iblk%d",0);//Device file nameSet_capacity (BLKDEV->GD,1024x768);//Number of SectorsAdd_disk (BLKDEV->GD);//Set Disk structure return 0;}//Uninstalling the moduleStatic voidIblk_exit (void){ //freeing the disk structureDel_gendisk (blkdev->GD); //Release request QueueBlk_cleanup_queue (blkdev->queue); //free up structural spaceVfree (blkdev->data); //Release Device StructureKfree (Blkdev); //Unregister device StructureUnregister_blkdev (Major,"iblk");}/********************************************************************* Module Declaration *********************************** **********************************/Module_license ("GPL"); Module_author ("D"); Module_description (""); Module_version ("v1.0"); Module_init (Iblk_init); Module_exit (iblk_exit) ;
Makefile
Ifneq ($ (kernelrelease),) obj-M: = blkdev.oElsekdir:=/lib/modules/2.6 . -279. el6.i686/buildall: -C $ (kdir) m=$ (PWD) Modulesclean: -F *.ko *. ko.unsigned *.mod.c *.mod.o *.o *.order *. Symversendif
[Country EMBED strategy] [147] [Simple block device drive design]