???????ioctl
????ioctl??Linux?????????????豸?????????y???????????м????????????????豸??????????????Щ?????????Щ??????????????????????ioctl????????????ж???????????? long (*unlocked_ioctl) (struct file *?? unsigned int?? unsigned long); ?????е???????????????????????Linux??????????????????ioctl()????
?????豸????    ???к?     ????      ??????
????8bit        8bit    2bit    13/14bit
?????????豸???????????????????????0~0xff????????????е?" ioctl-number.txt "???????????????????????????(????????t?????????)?????豸???????????????????????????????????????????2bit???????????????????????? _IOC_NONE ?? _IOC_READ ?? _IOC_WRITE ?? _IOC_READ|_IOC_WRITE ???????????????α???漰???????????С??????????????????????????????13??14λ???????????? _IO() ?? _IOR() ?? _IOW() ?? _IOWR() ??4?????????????????????????????????????????????type(?豸???????)??nr(???к????)??size(??????????)????????е?????????λ?????????????????л?????????ЩI/O?????????????豸?????а?????????????????????????????Щ???????????????????????????????豸???????????????4??:
????FIOCLEX:??file ioctl close on exec ???????????????????????exec()??????÷????????????????
????FIONCLEX:??file ioctl not close on exec???????FIOCLEX???????
????FIOQSIZE:????????????????С?????????豸?????????????ENOTTY????
????FIONBIO:??file ioctl non-blocking I/O ??????????flip->f_flags?е?O_NONBLOCK???
?????????????????????????????????????У???????????????????????????????????????????????
//mycmd.h
...
#include <asm/ioctl.h>
#define CMDT 'A'
#define KARG_SIZE 36
struct karg{
int kval;
char kbuf[KARG_SIZE];
};
#define CMD_OFF _IO(CMDT??0)
#define CMD_ON  _IO(CMDT??1)
#define CMD_R   _IOR(CMDT??2??struct karg)
#define CMD_W   _IOW(CMDT??3??struct karg)
...
//chrdev.c
static long demo_ioctl(struct file *filp?? unsigned int cmd?? unsigned long arg)
{
static struct karg karg = {
.kval = 0??
.kbuf = {0}??
};
struct karg *usr_arg;
switch(cmd){
case CMD_ON:
/* ???? */
break;
case CMD_OFF:
/* ??? */
break;
case CMD_R:
if(_IOC_SIZE(cmd) != sizeof(karg)){
return -EINVAL;
}
usr_arg = (struct karg *)arg;
if(copy_to_user(usr_arg?? &karg?? sizeof(karg))){
return -EAGAIN;
}
break;
case CMD_W:
if(_IOC_SIZE(cmd) != sizeof(karg)){
return -EINVAL;
}
usr_arg = (struct karg *)arg;
if(copy_from_user(&karg?? usr_arg?? sizeof(karg))){
return -EAGAIN;
}
break;
default:
;
};
return 0;
}
?????????豸???
??????????豸??飬?????????? cat /proc/devices ???????????????豸?????????????д?????????豸???????????????????????????豸???豸?????inode??????????????豸???豸?????????????????????????????????????豸???????????inode?????????豸???????豸??????????????? ??????? ?? ??????? ?? ????????豸??? ????? mknod /dev/xxx ?豸???? ???豸?? ???豸?? ???????????????????????? cat /proc/devices ???豸?????豸?????????????豸????豸????????????????????豸?????????????κ??????У??????? "/dev" ?????Linux???豸???????????????devtmpfs?????????????????豸?????????????豸????????????????????????豸????????豸?????ж????????????豸??????????????????????? rm ???ɡ????????????(lsmod)???豸??(/proc/devices)???豸?????(/dev)???????????????????????????????????????齫???????????????????
????????????????????????豸????????????????????豸?????????????????豸????????? ????????豸??? ??????????豸?????????????????????????????????????????????????:
????Device Drivers --->
????Generic Driver Options --->
????[*]Maintain a devtmpfs filesystem to mount at /dev
????[*] Automount devtmpfs at /dev??after the kernel mounted the rootfs
????OR
???????????????????????д??
????mount -t sysfs none sysfs /sys
????mdev -s //udev???
??????????Щ???????????????????豸????? "/sys" ???????????????????????豸?????????????????????API
????class_create(owner??name);
????struct device *device_create_vargs(struct class *cls?? struct device *parent??dev_t devt?? void *drvdata??const char *fmt?? va_list vargs);
????void class_destroy(struct class *cls);
????void device_destroy(struct class *cls?? dev_t devt);
????????????????????????????豸?? xxx_init() ?? xxx_exit() ?з????д???μ??????????????????????豸???
/* ??/sys?е????豸????? */
cls = class_create(THIS_MODULE??DEV_NAME);
/* ??cls???????д??????(??)?豸??? */
for(i= minor;i<(minor+cnt);i++){
devp = device_create(cls??NULL??MKDEV(major??i)??NULL??"%s%d"??DEV_NAME??i);
}
/* ??cls??????????????(??)?豸??? */
for(i= minor;i<(minor+cnt);i++){
device_destroy(cls??MKDEV(major??i));
}
/* ??/sys??????豸????? */
class_destroy(cls);           //??????ж??device??ж??class
???????????Щ?????????????????豸???????????????????д????????????в?????^ - ^