#include <linux/kernel.h> #include <linux/sched.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/malloc.h> #include <linux/module.h> #include <linux/blkdev.h> // Niezbedne do poprawngo wlaczenia blk.h #define MAJOR_NR 50 #define DEVICE_NAME "simpleblk" #define DEVICE_OFF(d) #include <linux/blk.h> static char *buffer; // size rozmiar w MB, mozna zmienic ladujac modul int size=1; int nblocks; int simple_open(struct inode *inode,struct file *file) { MOD_INC_USE_COUNT; return 0; } void simple_release(struct inode *inode,struct file *file) { MOD_DEC_USE_COUNT; } struct file_operations simple_ops = { read: block_read, write:block_write, open:simple_open, release:simple_release}; #define SECTORSIZE 512 void simple_request() { char *start; int bytes; // Petla nieskonczona - bo INIT_REQUEST zawiera return while (1) { INIT_REQUEST; start=buffer+CURRENT->sector*SECTORSIZE; bytes=CURRENT->current_nr_sectors*SECTORSIZE; if (CURRENT->sector*SECTORSIZE+bytes > size) { printk(DEVICE_NAME ": buffer overrun\n"); end_request(0); } else { if (CURRENT->cmd==WRITE) { memcpy(start,CURRENT->buffer,bytes); } else if (CURRENT->cmd==READ) { memcpy(CURRENT->buffer,start,bytes); } else panic(DEVICE_NAME ": unknown command"); CURRENT->nr_sectors-=CURRENT->current_nr_sectors; end_request(1); } } } int init_module() { size*=(1024*1024); buffer=vmalloc(size); if (buffer==NULL) { printk(DEVICE_NAME ": Buffer allocation failed\n"); return -1; } if (register_blkdev(MAJOR_NR,DEVICE_NAME,&simple_ops)<0) { printk(DEVICE_NAME ": Device registration failed\n"); vfree(buffer); return -1; } nblocks=size/1024; blk_size[MAJOR_NR]=&nblocks; blk_dev[MAJOR_NR].request_fn=simple_request; printk(DEVICE_NAME ": Initialization successful\n"); printk(DEVICE_NAME ": %d blocks\n",nblocks); return 0; } void cleanup_module() { vfree(buffer); unregister_blkdev(MAJOR_NR,"simpleblk"); }