????????豸??Linux?????豸??(????????????豸???????豸)??????豸??????????????I/O?豸?????????豸????????豸????????????豸??????????????????????????????????? ls -l /dev ?????????????????豸????? c ??????豸?? b ????豸???????豸??ж?????豸???????д?????????????豸???????????????д??????????????????????????д??????????豸?????
???????????
????Linux??н????????????????豸??????????????????????? struct file_operations ????????д????????????????????????????????????????????????Linux??????д??????"???+???"?????????????????д????ν?????????????????????open????豸????????????????VFS????????inode??????д??????????豸?????????inode?е?open???????????????????????????????????д??????????????????ó??????????????????????????????????????????????豸?????
#include <linux/cdev.h> //for struct cdev
#include <linux/fs.h>   //for struct file
#include <asm-generic/uaccess.h>    //for copy_to_user
#include <linux/errno.h>            //for error number
/* ????????????? */
/*
struct file_operations {
struct module *owner;   //THIS_MODULE
//???豸
ssize_t (*read) (struct file *?? char __user *?? size_t?? loff_t *);
//д?豸
ssize_t (*write) (struct file *?? const char __user *?? size_t?? loff_t *);
//??????????????
int (*mmap) (struct file *?? struct vm_area_struct *);
//??д?豸?????????豸?????????豸
long (*unlocked_ioctl) (struct file *?? unsigned int?? unsigned long);
//???豸
int (*open) (struct inode *?? struct file *);
//????豸
int (*release) (struct inode *?? struct file *);
//????豸
int (*flush) (struct file *?? fl_owner_t id);
//?????λ
loff_t (*llseek) (struct file *?? loff_t?? int);
//????
int (*fasync) (int?? struct file *?? int);
//POLL????
unsigned int (*poll) (struct file *?? struct poll_table_struct *);
??????
};
*/
ssize_t myread(struct file *filep?? char __user * user_buf?? size_t size?? loff_t* offset)
{
return 0;
}
struct file fops = {
.owner = THIS_MODULE??
.read = myread??
...
};
/* ????豸???????? */
struct cdev {
//public
struct module *owner;               //??????????THIS_MODULE??????????????
const struct file_operations *ops;  //???????????????:??????????/д??...??
dev_t dev;                          //?豸??????????
unsigned int count;                 //?豸????
//private
...
};
static int __init chrdev_init(void)
{
...
/* ????cdev?豸???? */
struct cdev *cdev_alloc(void);
/* ?????cdev?豸???? */
void cdev_init(struct cdev*?? const struct file_opeartions*);
/* ?????豸????????豸?? */
int register_chedev_region(dev_t from?? unsigned count?? const char* name);
/* ?????豸??????????豸?? */
int alloc_chedev_region(dev_t* dev?? unsigned baseminor?? unsigned count?? const char* name);
MKDEV(ma??mi)    //?????豸?????豸???????豸??
MAJOR(dev)      //??dev_t?????е?????豸??
MINOR(dev)      //??dev_t?????е?????豸??
/* ???????豸????cdev????? */
int cdev_add(struct cdev* ?? dev_t?? unsigned);
...
}
static void __exit chrdev_exit(void)
{
...
/* ????????cdev?豸???? */
void cdev_del(struct cdev* );
/* ????????cdev?豸???? */
void cdev_put(stuct cdev *);
/* ?????豸?? */
void unregister_chrdev_region(dev_t from?? unsigned count);
...
}
???????read??write
????Linux??????????????????????????????????????????????????????????PID????????????????????PID????????????????????????????????????????????????п????????????????????????/??
????long copy_from_user(void *to?? const void __user * from?? unsigned long n)
????long copy_to_user(void __user *to?? const void *from?? unsigned long n)
??????????????????????????????????????ú??????????????????????????????????????????е?read??write?????????????????????????????
????ssize_t myread(struct file *filep?? char __user * user_buf?? size_t size?? loff_t* offset)
????{
????long ret = 0;
????size = size > MAX_KBUF?MAX_KBUF:size;
????if(copy_to_user(user_buf?? kbuf??size)
????return -EAGAIN;
????}
????return 0;
????}