#c #linux #linux-kernel #linux-device-driver #kernel-module
Вопрос:
В своем проекте я решил попробовать создать устройство, которое может имитировать броски костей. Для этого я написал следующий модуль ядра.
//dicedriver.c
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/random.h>
#include <linux/version.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/device.h>
static dev_t fdevice;
static struct cdev my_cdev;
static struct class *deviceclass;
static int val;
unsigned char get_random_byte(int max) {
unsigned char c;
get_random_bytes(amp;c, 1);
return c%max;
}
static ssize_t my_read(struct file *file, char __user *buf, size_t count, loff_t *ppos){
val = get_random_byte(6) 1;
int len = sizeof(val);
if(count < len){
return -EINVAL;
}
if(*ppos != 0){
return 0;
}
if(copy_to_user(buf, amp;val, len)!=0){
printk(KERN_ALERT "ERROR while copying to buffer");
return -EINVAL;
}
*ppos = len;
return len;
}
static ssize_t my_write(struct file *file, const char *buf, size_t count, loff_t *ppos){
return 0;
}
int my_open(struct inode *inode, struct file *filep){
return 0;
}
int my_release(struct inode *inode, struct file *filep){
return 0;
}
static struct file_operations dice_fops = {
.owner = THIS_MODULE,
.read = my_read,
.release = my_release,
.write = my_write,
.open = my_open,
};
static int __init my_init(void){
int ret;
struct device *dev_ret;
ret = alloc_chrdev_region(amp;fdevice, 0, 1, "dice_device");
if(ret<0)
printk(KERN_ALERT "dice_device init error 1");
deviceclass = class_create(THIS_MODULE, "chardrv");
if(IS_ERR(deviceclass)){
printk(KERN_ALERT "dice_device init error 2");
unregister_chrdev_region(fdevice, 1);
return PTR_ERR(deviceclass);
}
dev_ret = device_create(deviceclass, NULL, fdevice, NULL, "dice_device");
if(IS_ERR(dev_ret)){
printk(KERN_ALERT "dice_device init error 3");
class_destroy(deviceclass);
unregister_chrdev_region(fdevice, 1);
return PTR_ERR(dev_ret);
}
cdev_init(amp;my_cdev, amp;dice_fops);
ret = cdev_add(amp;my_cdev, fdevice, 1);
if(ret<0){
printk(KERN_ALERT "dice_device init error 4");
device_destroy(deviceclass, fdevice);
class_destroy(deviceclass);
unregister_chrdev_region(fdevice, 1);
return ret;
}
printk(KERN_DEBUG "dice_device created sucessfully");
return 0;
}
static void __exit my_exit(void){
device_destroy(deviceclass, fdevice);
class_destroy(deviceclass);
unregister_chrdev_region(fdevice, 1);
printk(KERN_DEBUG "dice device removed successfully");
}
module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("NWLYNX");
MODULE_DESCRIPTION("DICE HELLO WORLD");
MODULE_VERSION("DEV");
Для тестирования того же самого, что я планирую сделать сначала, просто напечатав десять из этих случайных чисел, я создал еще один файл тестирования.
///testing.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){
int fd = 0, ret = 0;
int i=0;
char buf[20]="";
fd = open("/dev/dice_device", O_RDONLY);
printf("fd :%dn",fd);
for(i=0;i<10;i ){
ret = read(fd,buf,10);
printf("buf:%s,len:%dn",buf,ret);
}
close(fd);
return 0;
}
Проверив journalctl и попытавшись отладить мой dicedriver, я обнаружил , что он может успешно создать случайное число и сохранить его val
, но не может скопировать его buf
.
Любые намеки или предложения по этому поводу были бы полезны.
Комментарии:
1. Вы возвращаете значение int, но пытаетесь напечатать строку.
2. Ну ладно, спасибо @stark, твой комментарий помог мне