📄 sbull.c
字号:
#ifndef __KERNEL__# define __KERNEL__#endif#ifndef MODULE# define MODULE#endif#define WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE#define __NO_VERSION__#include <linux/version.h>#include <linux/module.h>char kernel_version[]=UTS_RELEASE;#include <linux/kernel.h>#include <linux/mm.h>#include <linux/types.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/sched.h>#include <linux/ioport.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/blkdev.h>#include <linux/blk.h>#include <linux/string.h>#include <asm/io.h>#include <asm/segment.h>#include <asm/uaccess.h>int sbull_major;struct device_struct{
const char *name;
struct file_operations *chops;
};
static struct device_struct blkdevs[MAX_BLKDEV];struct sbull_dev { void **data; int quantum; //the current quantum size int qset; //the current array size unsigned long size; unsigned int access_key; //used by sbulluid and sbullpriv unsigned int usage; //lock the device while using it unsigned int new_msg; struct sbull_dev *next;};extern struct sbull_dev *sbull; //device informationsbull_open(struct inode *inode,struct file *filp){ int num=MINOR(inode->i_rdev); if(num>=sbull->size) return -ENODEV; sbull->size=sbull->size+num; if(!sbull->usage) { check_disk_change(inode->i_rdev); if(!*(sbull->data)) return -ENOMEM; } sbull->usage++; MOD_INC_USE_COUNT; return 0;}static int sbull_trace;sbull_text(char *text){ if(sbull_trace){ console_print(text); console_print("\n"); }}#define MAX_BUF 100struct sbull_buf{ int buf_size; int *qhead,*qtail; char buffer[MAX_BUF]; struct sbull_buf *next;};int sbull_write(struct inode *inode,struct file *filp,const char *buffer,int count){ int i,length; struct sbull_buf *ptr; sbull_text("sbull_write"); if(MINOR(inode->i_rdev)!=0) return -EINVAL; if((ptr=kmalloc(sizeof(struct sbull_buf),GFP_KERNEL))==0) return -ENOMEM; length=count<MAX_BUF?count:MAX_BUF; if(verify_area(VERIFY_READ,buffer,length)) return -EFAULT; for(i=0;i<count&&i<MAX_BUF;++i){ ptr->buffer[i]=get_user_byte(buffer+i); if(sbull_trace) console_print("#"); } ptr->next=0; if(ptr->qhead==0) ptr->qhead=ptr; else ptr->qtail=ptr->next; ptr->qtail=ptr; if(sbull_trace) console_print("\n"); ptr->buf_size=i; return i;}int sbull_read(struct inode *inode,struct file *filp,char *buffer,int count){ int i,length; struct sbull_buf *ptr; sbull_text("sbull_read"); if(MINOR(inode->i_rdev)!=1) return -EINVAL; if(ptr->qhead==0) return -ENODATA; ptr=ptr->qhead; ptr->qhead=ptr->next; length=count<ptr->buf_size?count:ptr->buf_size; if(verify_area(VERIFY_WRITE,buffer,length)) return -EFAULT; for(i=0;i<count&&i<ptr->buf_size;++i){ put_user_byte(ptr->buffer[i],buffer+i); if(sbull_trace) console_print("r"); } if(sbull_trace) console_print("\n"); kfree_s(ptr,sizeof(struct sbull_buf)); return i;}int sbull_release(struct inode *inode,struct file *filp){ sbull->size=sbull->size+MINOR(inode->i_rdev); sbull->usage--; MOD_DEC_USE_COUNT; printk("This blkdev is in release!\n"); return 0; #ifdef DEBUG printk("sbull_release(%p,%p)\n",inode,filp); #endif}extern struct request *CURRENT;void sbull_request(void){ while(1){ INIT_REQUEST(); printk("request %p: cmd %i sec %li (nr.%li)\n", CURRENT, CURRENT->cmd, CURRENT->sector, CURRENT->current_nr_sectors); end_request(1); }}struct file_operations sbull_bdops={ NULL, sbull_read, sbull_write, NULL, NULL, NULL, NULL, sbull_open, sbull_release, NULL, NULL, NULL, NULL};int init_sbull(){ int result; printk("Hello! This is sbull!\n"); result=register_blkdev(0,"sbull",&sbull_bdops); if(result<0){ printk("Sbull: Can't get major number!\n"); return result; } if(sbull_major==0) sbull_major=result; return 0;}void cleanup_sbull(){ unregister_blkdev(sbull_major,"sbull"); printk("Sorry! The sbull is unloading now!\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -