다음을 사용하여 사용자 정의 문자 장치에 쓰기
고양이 123 > /dev/chardev
준다
cat: 쓰기 오류: 잘못된 인수
권한을 666으로 변경하고 sudo로도 시도했습니다. 여전히 같은 결과입니다. 비슷한 방식으로 에코도 시도했습니다.
저는 아치리눅스 4.8을 사용하고 있습니다.
편집: 드라이버 코드
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
//Prototypes
static int __init init(void);
static void __exit cleanup(void);
static int device_open(struct inode *,struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
#define SUCCESS 0
#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices*/
#define BUF_LEN 80 /* Max length of the message from the device */
static int Major; //Major number of the devices
static int Device_Open = 0;
static char msg[BUF_LEN]; //Message given when asked
static char *msg_Ptr;
static struct file_operations fops = {
.read = device_read,
.write = device_write,
.open = device_open,
.release = device_release
};
static int __init init(){
Major = register_chrdev(0,DEVICE_NAME,&fops);
if(Major < 0){
printk(KERN_ALERT "Failure in registering the device. %d\n", Major);
return Major;
}
printk(KERN_INFO "%s registered with major %d \n",DEVICE_NAME,Major);
printk(KERN_INFO "create a device with 'mknod /dev/%s c %d 0'\n",DEVICE_NAME,Major);
printk(KERN_INFO "Try to cat and echo the file and shit man.\n");
return SUCCESS;
}
static void __exit cleanup(){
unregister_chrdev(Major, DEVICE_NAME);
printk(KERN_ALERT "Unregistered the device %s i guess? \n"DEVICE_NAME);
}
static int device_open(struct inode *inode,struct file *file){
static int counter = 0;
if(Device_Open)
return -EBUSY;
Device_Open++;
sprintf(msg, "I already told you %d times Hello world!\n", counter++);
msg_Ptr = msg;
try_module_get(THIS_MODULE);
return SUCCESS;
}
static int device_release(struct inode *inode,struct file *file){
Device_Open--;
module_put(THIS_MODULE);
return 0;
}
static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset){
int bytes_read = 0;
if(*msg_Ptr == 0)
return 0;
while(length && *msg_Ptr){
put_user(*(msg_Ptr++),buffer++);
length--;
bytes_read++;
}
return bytes_read;
}
static ssize_t device_write(struct file *filp,const char *buff, size_t len, loff_t *off){
printk(KERN_ALERT "You cannot write to this device.\n");
return -EINVAL;
}
module_init(init);
module_exit(cleanup);
그래서 여기에서 우리는 심지어 device_write 함수를 사용하고 그것을 fops 구조체에 .write에 할당했다는 것을 볼 수 있습니다. 그렇다면 쓰기 명령을 수락하고 해당 명령문을 로그에 인쇄해야 하는 것 아닌가요?
답변1
커널에서 각 드라이버는 파일에서 수행할 수 있는 다양한 작업(열기, 닫기, 읽기, 쓰기, 탐색, ioctl 등)에 대한 일련의 메서드를 제공합니다. 이러한 메서드는struct file_operations
. 장치의 경우 해당 특정 장치(예: 블록/문자, 메이저 번호 및 마이너 번호의 특정 조합)를 등록한 드라이버에서 메서드를 제공합니다.
드라이버는 일부 메서드만 구현할 수 있습니다. 기본값이 제공됩니다. 기본값은 일반적으로 아무것도 하지 않으며 성공(해당 메소드에 대해 아무것도 수행하지 않는 것이 합리적인 경우) 또는 EINVAL(합리적인 기본값이 없고 메소드가 없다는 것은 해당 기능이 지원되지 않음을 의미하는 경우)을 반환합니다.
write
"쓰기 오류: 잘못된 인수" 는 드라이버의 메서드가 EINVAL을 반환한다는 의미입니다 . 가장 가능성 있는 설명은 이 드라이버에 write
메서드가 전혀 없다는 것입니다. 드라이버가 특정 작업을 지원하지 않는 것은 상당히 일상적인 일입니다. 예를 들어 일부 드라이버는 ioctl만 지원하고 읽기/쓰기는 지원하지 않으며, 일부 드라이버는 본질적으로 단방향(예: 입력 장치)이고 읽기만 지원하고 쓰기는 지원하지 않거나 그 반대의 경우도 마찬가지입니다.
"잘못된 인수"는 권한과 관련이 없으며 장치가 수행할 수 있는 작업입니다. 쓰기 권한이 없지만 드라이버와 대화할 수 있는 권한이 있으면 권한 오류가 발생합니다. 단지 당신이 운전자에게 요청하는 것이 운전자에게는 전혀 개념이 없는 것일 뿐입니다.